1 /* Print information from ELF file in human-readable form.
2 Copyright (C) 1999-2018 Red Hat, Inc.
3 This file is part of elfutils.
4
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 elfutils is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <argp.h>
23 #include <assert.h>
24 #include <ctype.h>
25 #include <dwarf.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <gelf.h>
29 #include <inttypes.h>
30 #include <langinfo.h>
31 #include <libdw.h>
32 #include <libdwfl.h>
33 #include <libintl.h>
34 #include <locale.h>
35 #include <stdarg.h>
36 #include <stdbool.h>
37 #include <stdio.h>
38 #include <stdio_ext.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <strings.h>
42 #include <time.h>
43 #include <unistd.h>
44 #include <sys/stat.h>
45 #include <signal.h>
46
47 #include <libeu.h>
48 #include <system.h>
49 #include <printversion.h>
50 #include "../libelf/libelfP.h"
51 #include "../libelf/common.h"
52 #include "../libebl/libeblP.h"
53 #include "../libdwelf/libdwelf.h"
54 #include "../libdw/libdwP.h"
55 #include "../libdwfl/libdwflP.h"
56 #include "../libdw/memory-access.h"
57
58 #include "../libdw/known-dwarf.h"
59
60 #ifdef __linux__
61 #define CORE_SIGILL SIGILL
62 #define CORE_SIGBUS SIGBUS
63 #define CORE_SIGFPE SIGFPE
64 #define CORE_SIGSEGV SIGSEGV
65 #define CORE_SI_USER SI_USER
66 #else
67 /* We want the linux version of those as that is what shows up in the core files. */
68 #define CORE_SIGILL 4 /* Illegal instruction (ANSI). */
69 #define CORE_SIGBUS 7 /* BUS error (4.2 BSD). */
70 #define CORE_SIGFPE 8 /* Floating-point exception (ANSI). */
71 #define CORE_SIGSEGV 11 /* Segmentation violation (ANSI). */
72 #define CORE_SI_USER 0 /* Sent by kill, sigsend. */
73 #endif
74
75 /* Name and version of program. */
76 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
77
78 /* Bug report address. */
79 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
80
81 /* argp key value for --elf-section, non-ascii. */
82 #define ELF_INPUT_SECTION 256
83
84 /* argp key value for --dwarf-skeleton, non-ascii. */
85 #define DWARF_SKELETON 257
86
87 /* argp key value for --dyn-syms, non-ascii. */
88 #define PRINT_DYNSYM_TABLE 258
89
90 /* Terrible hack for hooking unrelated skeleton/split compile units,
91 see __libdw_link_skel_split in print_debug. */
92 static bool do_not_close_dwfl = false;
93
94 /* Definitions of arguments for argp functions. */
95 static const struct argp_option options[] =
96 {
97 { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 },
98 { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL,
99 N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF "
100 "input data"), 0 },
101 { "dwarf-skeleton", DWARF_SKELETON, "FILE", 0,
102 N_("Used with -w to find the skeleton Compile Units in FILE associated "
103 "with the Split Compile units in a .dwo input file"), 0 },
104 { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
105 { "all", 'a', NULL, 0,
106 N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
107 { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
108 { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
109 { "histogram", 'I', NULL, 0,
110 N_("Display histogram of bucket list lengths"), 0 },
111 { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
112 { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
113 { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
114 { "section-groups", 'g', NULL, 0, N_("Display the section groups"), 0 },
115 { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
116 { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
117 { "symbols", 's', "SECTION", OPTION_ARG_OPTIONAL,
118 N_("Display the symbol table sections"), 0 },
119 { "dyn-syms", PRINT_DYNSYM_TABLE, NULL, 0,
120 N_("Display (only) the dynamic symbol table"), 0 },
121 { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
122 { "notes", 'n', "SECTION", OPTION_ARG_OPTIONAL, N_("Display the ELF notes"), 0 },
123 { "arch-specific", 'A', NULL, 0,
124 N_("Display architecture specific information, if any"), 0 },
125 { "exception", 'e', NULL, 0,
126 N_("Display sections for exception handling"), 0 },
127
128 { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
129 { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
130 N_("Display DWARF section content. SECTION can be one of abbrev, addr, "
131 "aranges, decodedaranges, frame, gdb_index, info, info+, loc, line, "
132 "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 },
133 { "hex-dump", 'x', "SECTION", 0,
134 N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
135 { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
136 N_("Print string contents of sections"), 0 },
137 { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
138 { "archive-index", 'c', NULL, 0,
139 N_("Display the symbol index of an archive"), 0 },
140
141 { NULL, 0, NULL, 0, N_("Output control:"), 0 },
142 { "numeric-addresses", 'N', NULL, 0,
143 N_("Do not find symbol names for addresses in DWARF data"), 0 },
144 { "unresolved-address-offsets", 'U', NULL, 0,
145 N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
146 { "wide", 'W', NULL, 0,
147 N_("Ignored for compatibility (lines always wide)"), 0 },
148 { "decompress", 'z', NULL, 0,
149 N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 },
150 { NULL, 0, NULL, 0, NULL, 0 }
151 };
152
153 /* Short description of program. */
154 static const char doc[] = N_("\
155 Print information from ELF file in human-readable form.");
156
157 /* Strings for arguments in help texts. */
158 static const char args_doc[] = N_("FILE...");
159
160 /* Prototype for option handler. */
161 static error_t parse_opt (int key, char *arg, struct argp_state *state);
162
163 /* Data structure to communicate with argp functions. */
164 static struct argp argp =
165 {
166 options, parse_opt, args_doc, doc, NULL, NULL, NULL
167 };
168
169 /* If non-null, the section from which we should read to (compressed) ELF. */
170 static const char *elf_input_section = NULL;
171
172 /* If non-null, the file that contains the skeleton CUs. */
173 static const char *dwarf_skeleton = NULL;
174
175 /* Flags set by the option controlling the output. */
176
177 /* True if dynamic segment should be printed. */
178 static bool print_dynamic_table;
179
180 /* True if the file header should be printed. */
181 static bool print_file_header;
182
183 /* True if the program headers should be printed. */
184 static bool print_program_header;
185
186 /* True if relocations should be printed. */
187 static bool print_relocations;
188
189 /* True if the section headers should be printed. */
190 static bool print_section_header;
191
192 /* True if the symbol table should be printed. */
193 static bool print_symbol_table;
194
195 /* True if (only) the dynsym table should be printed. */
196 static bool print_dynsym_table;
197
198 /* A specific section name, or NULL to print all symbol tables. */
199 static char *symbol_table_section;
200
201 /* A specific section name, or NULL to print all ELF notes. */
202 static char *notes_section;
203
204 /* True if the version information should be printed. */
205 static bool print_version_info;
206
207 /* True if section groups should be printed. */
208 static bool print_section_groups;
209
210 /* True if bucket list length histogram should be printed. */
211 static bool print_histogram;
212
213 /* True if the architecture specific data should be printed. */
214 static bool print_arch;
215
216 /* True if note section content should be printed. */
217 static bool print_notes;
218
219 /* True if SHF_STRINGS section content should be printed. */
220 static bool print_string_sections;
221
222 /* True if archive index should be printed. */
223 static bool print_archive_index;
224
225 /* True if any of the control options except print_archive_index is set. */
226 static bool any_control_option;
227
228 /* True if we should print addresses from DWARF in symbolic form. */
229 static bool print_address_names = true;
230
231 /* True if we should print raw values instead of relativized addresses. */
232 static bool print_unresolved_addresses = false;
233
234 /* True if we should print the .debug_aranges section using libdw. */
235 static bool decodedaranges = false;
236
237 /* True if we should print the .debug_aranges section using libdw. */
238 static bool decodedline = false;
239
240 /* True if we want to show more information about compressed sections. */
241 static bool print_decompress = false;
242
243 /* True if we want to show split compile units for debug_info skeletons. */
244 static bool show_split_units = false;
245
246 /* Select printing of debugging sections. */
247 static enum section_e
248 {
249 section_abbrev = 1, /* .debug_abbrev */
250 section_aranges = 2, /* .debug_aranges */
251 section_frame = 4, /* .debug_frame or .eh_frame & al. */
252 section_info = 8, /* .debug_info, (implies .debug_types) */
253 section_line = 16, /* .debug_line */
254 section_loc = 32, /* .debug_loc */
255 section_pubnames = 64, /* .debug_pubnames */
256 section_str = 128, /* .debug_str */
257 section_macinfo = 256, /* .debug_macinfo */
258 section_ranges = 512, /* .debug_ranges */
259 section_exception = 1024, /* .eh_frame & al. */
260 section_gdb_index = 2048, /* .gdb_index */
261 section_macro = 4096, /* .debug_macro */
262 section_addr = 8192, /* .debug_addr */
263 section_types = 16384, /* .debug_types (implied by .debug_info) */
264 section_all = (section_abbrev | section_aranges | section_frame
265 | section_info | section_line | section_loc
266 | section_pubnames | section_str | section_macinfo
267 | section_ranges | section_exception | section_gdb_index
268 | section_macro | section_addr | section_types)
269 } print_debug_sections, implicit_debug_sections;
270
271 /* Select hex dumping of sections. */
272 static struct section_argument *dump_data_sections;
273 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
274
275 /* Select string dumping of sections. */
276 static struct section_argument *string_sections;
277 static struct section_argument **string_sections_tail = &string_sections;
278
279 struct section_argument
280 {
281 struct section_argument *next;
282 const char *arg;
283 bool implicit;
284 };
285
286 /* Numbers of sections and program headers in the file. */
287 static size_t shnum;
288 static size_t phnum;
289
290
291 /* Declarations of local functions. */
292 static void process_file (int fd, const char *fname, bool only_one);
293 static void process_elf_file (Dwfl_Module *dwflmod, int fd);
294 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
295 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
296 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
297 static void print_scngrp (Ebl *ebl);
298 static void print_dynamic (Ebl *ebl);
299 static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
300 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
301 GElf_Shdr *shdr);
302 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
303 GElf_Shdr *shdr);
304 static void print_symtab (Ebl *ebl, int type);
305 static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
306 static void print_verinfo (Ebl *ebl);
307 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
308 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
309 static void handle_versym (Ebl *ebl, Elf_Scn *scn,
310 GElf_Shdr *shdr);
311 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
312 static void handle_hash (Ebl *ebl);
313 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
314 static void print_liblist (Ebl *ebl);
315 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
316 static void dump_data (Ebl *ebl);
317 static void dump_strings (Ebl *ebl);
318 static void print_strings (Ebl *ebl);
319 static void dump_archive_index (Elf *, const char *);
320
321
322 /* Looked up once with gettext in main. */
323 static char *yes_str;
324 static char *no_str;
325
326 static void
cleanup_list(struct section_argument * list)327 cleanup_list (struct section_argument *list)
328 {
329 while (list != NULL)
330 {
331 struct section_argument *a = list;
332 list = a->next;
333 free (a);
334 }
335 }
336
337 int
main(int argc,char * argv[])338 main (int argc, char *argv[])
339 {
340 /* We use no threads here which can interfere with handling a stream. */
341 (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
342
343 /* Set locale. */
344 setlocale (LC_ALL, "");
345
346 /* Initialize the message catalog. */
347 textdomain (PACKAGE_TARNAME);
348
349 /* Look up once. */
350 yes_str = gettext ("yes");
351 no_str = gettext ("no");
352
353 /* Parse and process arguments. */
354 int remaining;
355 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
356
357 /* Before we start tell the ELF library which version we are using. */
358 elf_version (EV_CURRENT);
359
360 /* Now process all the files given at the command line. */
361 bool only_one = remaining + 1 == argc;
362 do
363 {
364 /* Open the file. */
365 int fd = open (argv[remaining], O_RDONLY);
366 if (fd == -1)
367 {
368 error (0, errno, _("cannot open input file '%s'"), argv[remaining]);
369 continue;
370 }
371
372 process_file (fd, argv[remaining], only_one);
373
374 close (fd);
375 }
376 while (++remaining < argc);
377
378 cleanup_list (dump_data_sections);
379 cleanup_list (string_sections);
380
381 return error_message_count != 0;
382 }
383
384
385 /* Handle program arguments. */
386 static error_t
parse_opt(int key,char * arg,struct argp_state * state)387 parse_opt (int key, char *arg,
388 struct argp_state *state __attribute__ ((unused)))
389 {
390 void add_dump_section (const char *name, bool implicit)
391 {
392 struct section_argument *a = xmalloc (sizeof *a);
393 a->arg = name;
394 a->next = NULL;
395 a->implicit = implicit;
396 struct section_argument ***tailp
397 = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
398 **tailp = a;
399 *tailp = &a->next;
400 }
401
402 switch (key)
403 {
404 case 'a':
405 print_file_header = true;
406 print_program_header = true;
407 print_relocations = true;
408 print_section_header = true;
409 print_symbol_table = true;
410 print_version_info = true;
411 print_dynamic_table = true;
412 print_section_groups = true;
413 print_histogram = true;
414 print_arch = true;
415 print_notes = true;
416 implicit_debug_sections |= section_exception;
417 add_dump_section (".strtab", true);
418 add_dump_section (".dynstr", true);
419 add_dump_section (".comment", true);
420 any_control_option = true;
421 break;
422 case 'A':
423 print_arch = true;
424 any_control_option = true;
425 break;
426 case 'd':
427 print_dynamic_table = true;
428 any_control_option = true;
429 break;
430 case 'e':
431 print_debug_sections |= section_exception;
432 any_control_option = true;
433 break;
434 case 'g':
435 print_section_groups = true;
436 any_control_option = true;
437 break;
438 case 'h':
439 print_file_header = true;
440 any_control_option = true;
441 break;
442 case 'I':
443 print_histogram = true;
444 any_control_option = true;
445 break;
446 case 'l':
447 print_program_header = true;
448 any_control_option = true;
449 break;
450 case 'n':
451 print_notes = true;
452 any_control_option = true;
453 notes_section = arg;
454 break;
455 case 'r':
456 print_relocations = true;
457 any_control_option = true;
458 break;
459 case 'S':
460 print_section_header = true;
461 any_control_option = true;
462 break;
463 case 's':
464 print_symbol_table = true;
465 any_control_option = true;
466 symbol_table_section = arg;
467 break;
468 case PRINT_DYNSYM_TABLE:
469 print_dynsym_table = true;
470 any_control_option = true;
471 break;
472 case 'V':
473 print_version_info = true;
474 any_control_option = true;
475 break;
476 case 'c':
477 print_archive_index = true;
478 break;
479 case 'w':
480 if (arg == NULL)
481 {
482 print_debug_sections = section_all;
483 implicit_debug_sections = section_info;
484 show_split_units = true;
485 }
486 else if (strcmp (arg, "abbrev") == 0)
487 print_debug_sections |= section_abbrev;
488 else if (strcmp (arg, "addr") == 0)
489 {
490 print_debug_sections |= section_addr;
491 implicit_debug_sections |= section_info;
492 }
493 else if (strcmp (arg, "aranges") == 0)
494 print_debug_sections |= section_aranges;
495 else if (strcmp (arg, "decodedaranges") == 0)
496 {
497 print_debug_sections |= section_aranges;
498 decodedaranges = true;
499 }
500 else if (strcmp (arg, "ranges") == 0)
501 {
502 print_debug_sections |= section_ranges;
503 implicit_debug_sections |= section_info;
504 }
505 else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
506 print_debug_sections |= section_frame;
507 else if (strcmp (arg, "info") == 0)
508 {
509 print_debug_sections |= section_info;
510 print_debug_sections |= section_types;
511 }
512 else if (strcmp (arg, "info+") == 0)
513 {
514 print_debug_sections |= section_info;
515 print_debug_sections |= section_types;
516 show_split_units = true;
517 }
518 else if (strcmp (arg, "loc") == 0)
519 {
520 print_debug_sections |= section_loc;
521 implicit_debug_sections |= section_info;
522 }
523 else if (strcmp (arg, "line") == 0)
524 print_debug_sections |= section_line;
525 else if (strcmp (arg, "decodedline") == 0)
526 {
527 print_debug_sections |= section_line;
528 decodedline = true;
529 }
530 else if (strcmp (arg, "pubnames") == 0)
531 print_debug_sections |= section_pubnames;
532 else if (strcmp (arg, "str") == 0)
533 {
534 print_debug_sections |= section_str;
535 /* For mapping string offset tables to CUs. */
536 implicit_debug_sections |= section_info;
537 }
538 else if (strcmp (arg, "macinfo") == 0)
539 print_debug_sections |= section_macinfo;
540 else if (strcmp (arg, "macro") == 0)
541 print_debug_sections |= section_macro;
542 else if (strcmp (arg, "exception") == 0)
543 print_debug_sections |= section_exception;
544 else if (strcmp (arg, "gdb_index") == 0)
545 print_debug_sections |= section_gdb_index;
546 else
547 {
548 fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"),
549 arg);
550 argp_help (&argp, stderr, ARGP_HELP_SEE,
551 program_invocation_short_name);
552 exit (1);
553 }
554 any_control_option = true;
555 break;
556 case 'p':
557 any_control_option = true;
558 if (arg == NULL)
559 {
560 print_string_sections = true;
561 break;
562 }
563 FALLTHROUGH;
564 case 'x':
565 add_dump_section (arg, false);
566 any_control_option = true;
567 break;
568 case 'N':
569 print_address_names = false;
570 break;
571 case 'U':
572 print_unresolved_addresses = true;
573 break;
574 case ARGP_KEY_NO_ARGS:
575 fputs (gettext ("Missing file name.\n"), stderr);
576 goto do_argp_help;
577 case ARGP_KEY_FINI:
578 if (! any_control_option && ! print_archive_index)
579 {
580 fputs (gettext ("No operation specified.\n"), stderr);
581 do_argp_help:
582 argp_help (&argp, stderr, ARGP_HELP_SEE,
583 program_invocation_short_name);
584 exit (EXIT_FAILURE);
585 }
586 break;
587 case 'W': /* Ignored. */
588 break;
589 case 'z':
590 print_decompress = true;
591 break;
592 case ELF_INPUT_SECTION:
593 if (arg == NULL)
594 elf_input_section = ".gnu_debugdata";
595 else
596 elf_input_section = arg;
597 break;
598 case DWARF_SKELETON:
599 dwarf_skeleton = arg;
600 break;
601 default:
602 return ARGP_ERR_UNKNOWN;
603 }
604 return 0;
605 }
606
607
608 /* Create a file descriptor to read the data from the
609 elf_input_section given a file descriptor to an ELF file. */
610 static int
open_input_section(int fd)611 open_input_section (int fd)
612 {
613 size_t shnums;
614 size_t cnt;
615 size_t shstrndx;
616 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
617 if (elf == NULL)
618 {
619 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
620 elf_errmsg (-1));
621 return -1;
622 }
623
624 if (elf_getshdrnum (elf, &shnums) < 0)
625 {
626 error (0, 0, gettext ("cannot determine number of sections: %s"),
627 elf_errmsg (-1));
628 open_error:
629 elf_end (elf);
630 return -1;
631 }
632
633 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
634 {
635 error (0, 0, gettext ("cannot get section header string table index"));
636 goto open_error;
637 }
638
639 for (cnt = 0; cnt < shnums; ++cnt)
640 {
641 Elf_Scn *scn = elf_getscn (elf, cnt);
642 if (scn == NULL)
643 {
644 error (0, 0, gettext ("cannot get section: %s"),
645 elf_errmsg (-1));
646 goto open_error;
647 }
648
649 GElf_Shdr shdr_mem;
650 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
651 if (unlikely (shdr == NULL))
652 {
653 error (0, 0, gettext ("cannot get section header: %s"),
654 elf_errmsg (-1));
655 goto open_error;
656 }
657
658 const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
659 if (sname == NULL)
660 {
661 error (0, 0, gettext ("cannot get section name"));
662 goto open_error;
663 }
664
665 if (strcmp (sname, elf_input_section) == 0)
666 {
667 Elf_Data *data = elf_rawdata (scn, NULL);
668 if (data == NULL)
669 {
670 error (0, 0, gettext ("cannot get %s content: %s"),
671 sname, elf_errmsg (-1));
672 goto open_error;
673 }
674
675 /* Create (and immediately unlink) a temporary file to store
676 section data in to create a file descriptor for it. */
677 const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
678 static const char suffix[] = "/readelfXXXXXX";
679 int tmplen = strlen (tmpdir) + sizeof (suffix);
680 char *tempname = alloca (tmplen);
681 sprintf (tempname, "%s%s", tmpdir, suffix);
682
683 int sfd = mkstemp (tempname);
684 if (sfd == -1)
685 {
686 error (0, 0, gettext ("cannot create temp file '%s'"),
687 tempname);
688 goto open_error;
689 }
690 unlink (tempname);
691
692 ssize_t size = data->d_size;
693 if (write_retry (sfd, data->d_buf, size) != size)
694 {
695 error (0, 0, gettext ("cannot write section data"));
696 goto open_error;
697 }
698
699 if (elf_end (elf) != 0)
700 {
701 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
702 elf_errmsg (-1));
703 return -1;
704 }
705
706 if (lseek (sfd, 0, SEEK_SET) == -1)
707 {
708 error (0, 0, gettext ("error while rewinding file descriptor"));
709 return -1;
710 }
711
712 return sfd;
713 }
714 }
715
716 /* Named section not found. */
717 if (elf_end (elf) != 0)
718 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
719 elf_errmsg (-1));
720 return -1;
721 }
722
723 /* Check if the file is an archive, and if so dump its index. */
724 static void
check_archive_index(int fd,const char * fname,bool only_one)725 check_archive_index (int fd, const char *fname, bool only_one)
726 {
727 /* Create an `Elf' descriptor. */
728 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
729 if (elf == NULL)
730 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
731 elf_errmsg (-1));
732 else
733 {
734 if (elf_kind (elf) == ELF_K_AR)
735 {
736 if (!only_one)
737 printf ("\n%s:\n\n", fname);
738 dump_archive_index (elf, fname);
739 }
740 else
741 error (0, 0,
742 gettext ("'%s' is not an archive, cannot print archive index"),
743 fname);
744
745 /* Now we can close the descriptor. */
746 if (elf_end (elf) != 0)
747 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
748 elf_errmsg (-1));
749 }
750 }
751
752 /* Trivial callback used for checking if we opened an archive. */
753 static int
count_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)754 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
755 void **userdata __attribute__ ((unused)),
756 const char *name __attribute__ ((unused)),
757 Dwarf_Addr base __attribute__ ((unused)),
758 void *arg)
759 {
760 if (*(bool *) arg)
761 return DWARF_CB_ABORT;
762 *(bool *) arg = true;
763 return DWARF_CB_OK;
764 }
765
766 struct process_dwflmod_args
767 {
768 int fd;
769 bool only_one;
770 };
771
772 static int
process_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)773 process_dwflmod (Dwfl_Module *dwflmod,
774 void **userdata __attribute__ ((unused)),
775 const char *name __attribute__ ((unused)),
776 Dwarf_Addr base __attribute__ ((unused)),
777 void *arg)
778 {
779 const struct process_dwflmod_args *a = arg;
780
781 /* Print the file name. */
782 if (!a->only_one)
783 {
784 const char *fname;
785 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
786
787 printf ("\n%s:\n\n", fname);
788 }
789
790 process_elf_file (dwflmod, a->fd);
791
792 return DWARF_CB_OK;
793 }
794
795 /* Stub libdwfl callback, only the ELF handle already open is ever used.
796 Only used for finding the alternate debug file if the Dwarf comes from
797 the main file. We are not interested in separate debuginfo. */
798 static int
find_no_debuginfo(Dwfl_Module * mod,void ** userdata,const char * modname,Dwarf_Addr base,const char * file_name,const char * debuglink_file,GElf_Word debuglink_crc,char ** debuginfo_file_name)799 find_no_debuginfo (Dwfl_Module *mod,
800 void **userdata,
801 const char *modname,
802 Dwarf_Addr base,
803 const char *file_name,
804 const char *debuglink_file,
805 GElf_Word debuglink_crc,
806 char **debuginfo_file_name)
807 {
808 Dwarf_Addr dwbias;
809 dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
810
811 /* We are only interested if the Dwarf has been setup on the main
812 elf file but is only missing the alternate debug link. If dwbias
813 hasn't even been setup, this is searching for separate debuginfo
814 for the main elf. We don't care in that case. */
815 if (dwbias == (Dwarf_Addr) -1)
816 return -1;
817
818 return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
819 file_name, debuglink_file,
820 debuglink_crc, debuginfo_file_name);
821 }
822
823 static Dwfl *
create_dwfl(int fd,const char * fname)824 create_dwfl (int fd, const char *fname)
825 {
826 /* Duplicate an fd for dwfl_report_offline to swallow. */
827 int dwfl_fd = dup (fd);
828 if (unlikely (dwfl_fd < 0))
829 error (EXIT_FAILURE, errno, "dup");
830
831 /* Use libdwfl in a trivial way to open the libdw handle for us.
832 This takes care of applying relocations to DWARF data in ET_REL files. */
833 static const Dwfl_Callbacks callbacks =
834 {
835 .section_address = dwfl_offline_section_address,
836 .find_debuginfo = find_no_debuginfo
837 };
838 Dwfl *dwfl = dwfl_begin (&callbacks);
839 if (likely (dwfl != NULL))
840 /* Let 0 be the logical address of the file (or first in archive). */
841 dwfl->offline_next_address = 0;
842 if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
843 {
844 struct stat st;
845 if (fstat (dwfl_fd, &st) != 0)
846 error (0, errno, gettext ("cannot stat input file"));
847 else if (unlikely (st.st_size == 0))
848 error (0, 0, gettext ("input file is empty"));
849 else
850 error (0, 0, gettext ("failed reading '%s': %s"),
851 fname, dwfl_errmsg (-1));
852 close (dwfl_fd); /* Consumed on success, not on failure. */
853 dwfl = NULL;
854 }
855 else
856 dwfl_report_end (dwfl, NULL, NULL);
857
858 return dwfl;
859 }
860
861 /* Process one input file. */
862 static void
process_file(int fd,const char * fname,bool only_one)863 process_file (int fd, const char *fname, bool only_one)
864 {
865 if (print_archive_index)
866 check_archive_index (fd, fname, only_one);
867
868 if (!any_control_option)
869 return;
870
871 if (elf_input_section != NULL)
872 {
873 /* Replace fname and fd with section content. */
874 char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
875 sprintf (fnname, "%s:%s", fname, elf_input_section);
876 fd = open_input_section (fd);
877 if (fd == -1)
878 {
879 error (0, 0, gettext ("No such section '%s' in '%s'"),
880 elf_input_section, fname);
881 return;
882 }
883 fname = fnname;
884 }
885
886 Dwfl *dwfl = create_dwfl (fd, fname);
887 if (dwfl != NULL)
888 {
889 if (only_one)
890 {
891 /* Clear ONLY_ONE if we have multiple modules, from an archive. */
892 bool seen = false;
893 only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
894 }
895
896 /* Process the one or more modules gleaned from this file. */
897 struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
898 dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
899 }
900 /* Terrible hack for hooking unrelated skeleton/split compile units,
901 see __libdw_link_skel_split in print_debug. */
902 if (! do_not_close_dwfl)
903 dwfl_end (dwfl);
904
905 /* Need to close the replaced fd if we created it. Caller takes
906 care of original. */
907 if (elf_input_section != NULL)
908 close (fd);
909 }
910
911 /* Check whether there are any compressed sections in the ELF file. */
912 static bool
elf_contains_chdrs(Elf * elf)913 elf_contains_chdrs (Elf *elf)
914 {
915 Elf_Scn *scn = NULL;
916 while ((scn = elf_nextscn (elf, scn)) != NULL)
917 {
918 GElf_Shdr shdr_mem;
919 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
920 if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
921 return true;
922 }
923 return false;
924 }
925
926 /* Process one ELF file. */
927 static void
process_elf_file(Dwfl_Module * dwflmod,int fd)928 process_elf_file (Dwfl_Module *dwflmod, int fd)
929 {
930 GElf_Addr dwflbias;
931 Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
932
933 GElf_Ehdr ehdr_mem;
934 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
935
936 if (ehdr == NULL)
937 {
938 error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
939 return;
940 }
941
942 Ebl *ebl = ebl_openbackend (elf);
943 if (unlikely (ebl == NULL))
944 {
945 ebl_error:
946 error (0, errno, gettext ("cannot create EBL handle"));
947 return;
948 }
949
950 /* Determine the number of sections. */
951 if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
952 error (EXIT_FAILURE, 0,
953 gettext ("cannot determine number of sections: %s"),
954 elf_errmsg (-1));
955
956 /* Determine the number of phdrs. */
957 if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
958 error (EXIT_FAILURE, 0,
959 gettext ("cannot determine number of program headers: %s"),
960 elf_errmsg (-1));
961
962 /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
963 may have applied relocation to some sections. If there are any
964 compressed sections, any pass (or libdw/libdwfl) might have
965 uncompressed them. So we need to get a fresh Elf handle on the
966 file to display those. */
967 bool print_unchanged = ((print_section_header
968 || print_relocations
969 || dump_data_sections != NULL
970 || print_notes)
971 && (ehdr->e_type == ET_REL
972 || elf_contains_chdrs (ebl->elf)));
973
974 Elf *pure_elf = NULL;
975 Ebl *pure_ebl = ebl;
976 if (print_unchanged)
977 {
978 /* Read the file afresh. */
979 off_t aroff = elf_getaroff (elf);
980 pure_elf = dwelf_elf_begin (fd);
981 if (aroff > 0)
982 {
983 /* Archive member. */
984 (void) elf_rand (pure_elf, aroff);
985 Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
986 elf_end (pure_elf);
987 pure_elf = armem;
988 }
989 if (pure_elf == NULL)
990 {
991 error (0, 0, gettext ("cannot read ELF: %s"), elf_errmsg (-1));
992 return;
993 }
994 pure_ebl = ebl_openbackend (pure_elf);
995 if (pure_ebl == NULL)
996 goto ebl_error;
997 }
998
999 if (print_file_header)
1000 print_ehdr (ebl, ehdr);
1001 if (print_section_header)
1002 print_shdr (pure_ebl, ehdr);
1003 if (print_program_header)
1004 print_phdr (ebl, ehdr);
1005 if (print_section_groups)
1006 print_scngrp (ebl);
1007 if (print_dynamic_table)
1008 print_dynamic (ebl);
1009 if (print_relocations)
1010 print_relocs (pure_ebl, ehdr);
1011 if (print_histogram)
1012 handle_hash (ebl);
1013 if (print_symbol_table || print_dynsym_table)
1014 print_symtab (ebl, SHT_DYNSYM);
1015 if (print_version_info)
1016 print_verinfo (ebl);
1017 if (print_symbol_table)
1018 print_symtab (ebl, SHT_SYMTAB);
1019 if (print_arch)
1020 print_liblist (ebl);
1021 if (print_arch)
1022 print_attributes (ebl, ehdr);
1023 if (dump_data_sections != NULL)
1024 dump_data (pure_ebl);
1025 if (string_sections != NULL)
1026 dump_strings (ebl);
1027 if ((print_debug_sections | implicit_debug_sections) != 0)
1028 print_debug (dwflmod, ebl, ehdr);
1029 if (print_notes)
1030 handle_notes (pure_ebl, ehdr);
1031 if (print_string_sections)
1032 print_strings (ebl);
1033
1034 ebl_closebackend (ebl);
1035
1036 if (pure_ebl != ebl)
1037 {
1038 ebl_closebackend (pure_ebl);
1039 elf_end (pure_elf);
1040 }
1041 }
1042
1043
1044 /* Print file type. */
1045 static void
print_file_type(unsigned short int e_type)1046 print_file_type (unsigned short int e_type)
1047 {
1048 if (likely (e_type <= ET_CORE))
1049 {
1050 static const char *const knowntypes[] =
1051 {
1052 N_("NONE (None)"),
1053 N_("REL (Relocatable file)"),
1054 N_("EXEC (Executable file)"),
1055 N_("DYN (Shared object file)"),
1056 N_("CORE (Core file)")
1057 };
1058 puts (gettext (knowntypes[e_type]));
1059 }
1060 else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
1061 printf (gettext ("OS Specific: (%x)\n"), e_type);
1062 else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
1063 printf (gettext ("Processor Specific: (%x)\n"), e_type);
1064 else
1065 puts ("???");
1066 }
1067
1068
1069 /* Print ELF header. */
1070 static void
print_ehdr(Ebl * ebl,GElf_Ehdr * ehdr)1071 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
1072 {
1073 fputs_unlocked (gettext ("ELF Header:\n Magic: "), stdout);
1074 for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
1075 printf (" %02hhx", ehdr->e_ident[cnt]);
1076
1077 printf (gettext ("\n Class: %s\n"),
1078 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
1079 : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
1080 : "\?\?\?");
1081
1082 printf (gettext (" Data: %s\n"),
1083 ehdr->e_ident[EI_DATA] == ELFDATA2LSB
1084 ? "2's complement, little endian"
1085 : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
1086 ? "2's complement, big endian" : "\?\?\?");
1087
1088 printf (gettext (" Ident Version: %hhd %s\n"),
1089 ehdr->e_ident[EI_VERSION],
1090 ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
1091 : "(\?\?\?)");
1092
1093 char buf[512];
1094 printf (gettext (" OS/ABI: %s\n"),
1095 ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
1096
1097 printf (gettext (" ABI Version: %hhd\n"),
1098 ehdr->e_ident[EI_ABIVERSION]);
1099
1100 fputs_unlocked (gettext (" Type: "), stdout);
1101 print_file_type (ehdr->e_type);
1102
1103 const char *machine = dwelf_elf_e_machine_string (ehdr->e_machine);
1104 if (machine != NULL)
1105 printf (gettext (" Machine: %s\n"), machine);
1106 else
1107 printf (gettext (" Machine: <unknown>: 0x%x\n"),
1108 ehdr->e_machine);
1109
1110 printf (gettext (" Version: %d %s\n"),
1111 ehdr->e_version,
1112 ehdr->e_version == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
1113
1114 printf (gettext (" Entry point address: %#" PRIx64 "\n"),
1115 ehdr->e_entry);
1116
1117 printf (gettext (" Start of program headers: %" PRId64 " %s\n"),
1118 ehdr->e_phoff, gettext ("(bytes into file)"));
1119
1120 printf (gettext (" Start of section headers: %" PRId64 " %s\n"),
1121 ehdr->e_shoff, gettext ("(bytes into file)"));
1122
1123 printf (gettext (" Flags: %s\n"),
1124 ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
1125
1126 printf (gettext (" Size of this header: %" PRId16 " %s\n"),
1127 ehdr->e_ehsize, gettext ("(bytes)"));
1128
1129 printf (gettext (" Size of program header entries: %" PRId16 " %s\n"),
1130 ehdr->e_phentsize, gettext ("(bytes)"));
1131
1132 printf (gettext (" Number of program headers entries: %" PRId16),
1133 ehdr->e_phnum);
1134 if (ehdr->e_phnum == PN_XNUM)
1135 {
1136 GElf_Shdr shdr_mem;
1137 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1138 if (shdr != NULL)
1139 printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
1140 (uint32_t) shdr->sh_info);
1141 else
1142 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1143 }
1144 fputc_unlocked ('\n', stdout);
1145
1146 printf (gettext (" Size of section header entries: %" PRId16 " %s\n"),
1147 ehdr->e_shentsize, gettext ("(bytes)"));
1148
1149 printf (gettext (" Number of section headers entries: %" PRId16),
1150 ehdr->e_shnum);
1151 if (ehdr->e_shnum == 0)
1152 {
1153 GElf_Shdr shdr_mem;
1154 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1155 if (shdr != NULL)
1156 printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
1157 (uint32_t) shdr->sh_size);
1158 else
1159 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1160 }
1161 fputc_unlocked ('\n', stdout);
1162
1163 if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1164 {
1165 GElf_Shdr shdr_mem;
1166 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1167 if (shdr != NULL)
1168 /* We managed to get the zeroth section. */
1169 snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
1170 (uint32_t) shdr->sh_link);
1171 else
1172 {
1173 strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
1174 buf[sizeof (buf) - 1] = '\0';
1175 }
1176
1177 printf (gettext (" Section header string table index: XINDEX%s\n\n"),
1178 buf);
1179 }
1180 else
1181 printf (gettext (" Section header string table index: %" PRId16 "\n\n"),
1182 ehdr->e_shstrndx);
1183 }
1184
1185
1186 static const char *
get_visibility_type(int value)1187 get_visibility_type (int value)
1188 {
1189 switch (value)
1190 {
1191 case STV_DEFAULT:
1192 return "DEFAULT";
1193 case STV_INTERNAL:
1194 return "INTERNAL";
1195 case STV_HIDDEN:
1196 return "HIDDEN";
1197 case STV_PROTECTED:
1198 return "PROTECTED";
1199 default:
1200 return "???";
1201 }
1202 }
1203
1204 static const char *
elf_ch_type_name(unsigned int code)1205 elf_ch_type_name (unsigned int code)
1206 {
1207 if (code == 0)
1208 return "NONE";
1209
1210 if (code == ELFCOMPRESS_ZLIB)
1211 return "ZLIB";
1212
1213 return "UNKNOWN";
1214 }
1215
1216 /* Print the section headers. */
1217 static void
print_shdr(Ebl * ebl,GElf_Ehdr * ehdr)1218 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1219 {
1220 size_t cnt;
1221 size_t shstrndx;
1222
1223 if (! print_file_header)
1224 {
1225 size_t sections;
1226 if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0))
1227 error (EXIT_FAILURE, 0,
1228 gettext ("cannot get number of sections: %s"),
1229 elf_errmsg (-1));
1230
1231 printf (gettext ("\
1232 There are %zd section headers, starting at offset %#" PRIx64 ":\n\
1233 \n"),
1234 sections, ehdr->e_shoff);
1235 }
1236
1237 /* Get the section header string table index. */
1238 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1239 error (EXIT_FAILURE, 0,
1240 gettext ("cannot get section header string table index: %s"),
1241 elf_errmsg (-1));
1242
1243 puts (gettext ("Section Headers:"));
1244
1245 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1246 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1247 else
1248 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1249
1250 if (print_decompress)
1251 {
1252 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1253 puts (gettext (" [Compression Size Al]"));
1254 else
1255 puts (gettext (" [Compression Size Al]"));
1256 }
1257
1258 for (cnt = 0; cnt < shnum; ++cnt)
1259 {
1260 Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1261
1262 if (unlikely (scn == NULL))
1263 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1264 elf_errmsg (-1));
1265
1266 /* Get the section header. */
1267 GElf_Shdr shdr_mem;
1268 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1269 if (unlikely (shdr == NULL))
1270 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
1271 elf_errmsg (-1));
1272
1273 char flagbuf[20];
1274 char *cp = flagbuf;
1275 if (shdr->sh_flags & SHF_WRITE)
1276 *cp++ = 'W';
1277 if (shdr->sh_flags & SHF_ALLOC)
1278 *cp++ = 'A';
1279 if (shdr->sh_flags & SHF_EXECINSTR)
1280 *cp++ = 'X';
1281 if (shdr->sh_flags & SHF_MERGE)
1282 *cp++ = 'M';
1283 if (shdr->sh_flags & SHF_STRINGS)
1284 *cp++ = 'S';
1285 if (shdr->sh_flags & SHF_INFO_LINK)
1286 *cp++ = 'I';
1287 if (shdr->sh_flags & SHF_LINK_ORDER)
1288 *cp++ = 'L';
1289 if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1290 *cp++ = 'N';
1291 if (shdr->sh_flags & SHF_GROUP)
1292 *cp++ = 'G';
1293 if (shdr->sh_flags & SHF_TLS)
1294 *cp++ = 'T';
1295 if (shdr->sh_flags & SHF_COMPRESSED)
1296 *cp++ = 'C';
1297 if (shdr->sh_flags & SHF_ORDERED)
1298 *cp++ = 'O';
1299 if (shdr->sh_flags & SHF_EXCLUDE)
1300 *cp++ = 'E';
1301 *cp = '\0';
1302
1303 const char *sname;
1304 char buf[128];
1305 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>";
1306 printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1307 " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1308 " %2" PRId64 "\n",
1309 cnt, sname,
1310 ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1311 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1312 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1313 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1314 shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1315 shdr->sh_addralign);
1316
1317 if (print_decompress)
1318 {
1319 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1320 {
1321 GElf_Chdr chdr;
1322 if (gelf_getchdr (scn, &chdr) != NULL)
1323 printf (" [ELF %s (%" PRId32 ") %0*" PRIx64
1324 " %2" PRId64 "]\n",
1325 elf_ch_type_name (chdr.ch_type),
1326 chdr.ch_type,
1327 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8,
1328 chdr.ch_size, chdr.ch_addralign);
1329 else
1330 error (0, 0,
1331 gettext ("bad compression header for section %zd: %s"),
1332 elf_ndxscn (scn), elf_errmsg (-1));
1333 }
1334 else if (strncmp(".zdebug", sname, strlen (".zdebug")) == 0)
1335 {
1336 ssize_t size;
1337 if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0)
1338 printf (" [GNU ZLIB %0*zx ]\n",
1339 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size);
1340 else
1341 error (0, 0,
1342 gettext ("bad gnu compressed size for section %zd: %s"),
1343 elf_ndxscn (scn), elf_errmsg (-1));
1344 }
1345 }
1346 }
1347
1348 fputc_unlocked ('\n', stdout);
1349 }
1350
1351
1352 /* Print the program header. */
1353 static void
print_phdr(Ebl * ebl,GElf_Ehdr * ehdr)1354 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1355 {
1356 if (phnum == 0)
1357 /* No program header, this is OK in relocatable objects. */
1358 return;
1359
1360 puts (gettext ("Program Headers:"));
1361 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1362 puts (gettext ("\
1363 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1364 else
1365 puts (gettext ("\
1366 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1367
1368 /* Process all program headers. */
1369 bool has_relro = false;
1370 GElf_Addr relro_from = 0;
1371 GElf_Addr relro_to = 0;
1372 for (size_t cnt = 0; cnt < phnum; ++cnt)
1373 {
1374 char buf[128];
1375 GElf_Phdr mem;
1376 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1377
1378 /* If for some reason the header cannot be returned show this. */
1379 if (unlikely (phdr == NULL))
1380 {
1381 puts (" ???");
1382 continue;
1383 }
1384
1385 printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1386 " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1387 ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1388 phdr->p_offset,
1389 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1390 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1391 phdr->p_filesz,
1392 phdr->p_memsz,
1393 phdr->p_flags & PF_R ? 'R' : ' ',
1394 phdr->p_flags & PF_W ? 'W' : ' ',
1395 phdr->p_flags & PF_X ? 'E' : ' ',
1396 phdr->p_align);
1397
1398 if (phdr->p_type == PT_INTERP)
1399 {
1400 /* If we are sure the file offset is valid then we can show
1401 the user the name of the interpreter. We check whether
1402 there is a section at the file offset. Normally there
1403 would be a section called ".interp". But in separate
1404 .debug files it is a NOBITS section (and so doesn't match
1405 with gelf_offscn). Which probably means the offset is
1406 not valid another reason could be because the ELF file
1407 just doesn't contain any section headers, in that case
1408 just play it safe and don't display anything. */
1409
1410 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1411 GElf_Shdr shdr_mem;
1412 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1413
1414 size_t maxsize;
1415 char *filedata = elf_rawfile (ebl->elf, &maxsize);
1416
1417 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
1418 && filedata != NULL && phdr->p_offset < maxsize
1419 && phdr->p_filesz <= maxsize - phdr->p_offset
1420 && memchr (filedata + phdr->p_offset, '\0',
1421 phdr->p_filesz) != NULL)
1422 printf (gettext ("\t[Requesting program interpreter: %s]\n"),
1423 filedata + phdr->p_offset);
1424 }
1425 else if (phdr->p_type == PT_GNU_RELRO)
1426 {
1427 has_relro = true;
1428 relro_from = phdr->p_vaddr;
1429 relro_to = relro_from + phdr->p_memsz;
1430 }
1431 }
1432
1433 size_t sections;
1434 if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0))
1435 error (EXIT_FAILURE, 0,
1436 gettext ("cannot get number of sections: %s"),
1437 elf_errmsg (-1));
1438
1439 if (sections == 0)
1440 /* No sections in the file. Punt. */
1441 return;
1442
1443 /* Get the section header string table index. */
1444 size_t shstrndx;
1445 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1446 error (EXIT_FAILURE, 0,
1447 gettext ("cannot get section header string table index"));
1448
1449 puts (gettext ("\n Section to Segment mapping:\n Segment Sections..."));
1450
1451 for (size_t cnt = 0; cnt < phnum; ++cnt)
1452 {
1453 /* Print the segment number. */
1454 printf (" %2.2zu ", cnt);
1455
1456 GElf_Phdr phdr_mem;
1457 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1458 /* This must not happen. */
1459 if (unlikely (phdr == NULL))
1460 error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
1461 elf_errmsg (-1));
1462
1463 /* Iterate over the sections. */
1464 bool in_relro = false;
1465 bool in_ro = false;
1466 for (size_t inner = 1; inner < shnum; ++inner)
1467 {
1468 Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1469 /* This should not happen. */
1470 if (unlikely (scn == NULL))
1471 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1472 elf_errmsg (-1));
1473
1474 /* Get the section header. */
1475 GElf_Shdr shdr_mem;
1476 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1477 if (unlikely (shdr == NULL))
1478 error (EXIT_FAILURE, 0,
1479 gettext ("cannot get section header: %s"),
1480 elf_errmsg (-1));
1481
1482 if (shdr->sh_size > 0
1483 /* Compare allocated sections by VMA, unallocated
1484 sections by file offset. */
1485 && (shdr->sh_flags & SHF_ALLOC
1486 ? (shdr->sh_addr >= phdr->p_vaddr
1487 && (shdr->sh_addr + shdr->sh_size
1488 <= phdr->p_vaddr + phdr->p_memsz))
1489 : (shdr->sh_offset >= phdr->p_offset
1490 && (shdr->sh_offset + shdr->sh_size
1491 <= phdr->p_offset + phdr->p_filesz))))
1492 {
1493 if (has_relro && !in_relro
1494 && shdr->sh_addr >= relro_from
1495 && shdr->sh_addr + shdr->sh_size <= relro_to)
1496 {
1497 fputs_unlocked (" [RELRO:", stdout);
1498 in_relro = true;
1499 }
1500 else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1501 {
1502 fputs_unlocked ("]", stdout);
1503 in_relro = false;
1504 }
1505 else if (has_relro && in_relro
1506 && shdr->sh_addr + shdr->sh_size > relro_to)
1507 fputs_unlocked ("] <RELRO:", stdout);
1508 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1509 {
1510 if (!in_ro)
1511 {
1512 fputs_unlocked (" [RO:", stdout);
1513 in_ro = true;
1514 }
1515 }
1516 else
1517 {
1518 /* Determine the segment this section is part of. */
1519 size_t cnt2;
1520 GElf_Phdr phdr2_mem;
1521 GElf_Phdr *phdr2 = NULL;
1522 for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1523 {
1524 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1525
1526 if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1527 && shdr->sh_addr >= phdr2->p_vaddr
1528 && (shdr->sh_addr + shdr->sh_size
1529 <= phdr2->p_vaddr + phdr2->p_memsz))
1530 break;
1531 }
1532
1533 if (cnt2 < phnum)
1534 {
1535 if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1536 {
1537 fputs_unlocked (" [RO:", stdout);
1538 in_ro = true;
1539 }
1540 else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1541 {
1542 fputs_unlocked ("]", stdout);
1543 in_ro = false;
1544 }
1545 }
1546 }
1547
1548 printf (" %s",
1549 elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1550
1551 /* Signal that this sectin is only partially covered. */
1552 if (has_relro && in_relro
1553 && shdr->sh_addr + shdr->sh_size > relro_to)
1554 {
1555 fputs_unlocked (">", stdout);
1556 in_relro = false;
1557 }
1558 }
1559 }
1560 if (in_relro || in_ro)
1561 fputs_unlocked ("]", stdout);
1562
1563 /* Finish the line. */
1564 fputc_unlocked ('\n', stdout);
1565 }
1566 }
1567
1568
1569 static const char *
section_name(Ebl * ebl,GElf_Shdr * shdr)1570 section_name (Ebl *ebl, GElf_Shdr *shdr)
1571 {
1572 size_t shstrndx;
1573 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
1574 return "???";
1575 return elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "???";
1576 }
1577
1578
1579 static void
handle_scngrp(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1580 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1581 {
1582 /* Get the data of the section. */
1583 Elf_Data *data = elf_getdata (scn, NULL);
1584
1585 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1586 GElf_Shdr symshdr_mem;
1587 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1588 Elf_Data *symdata = elf_getdata (symscn, NULL);
1589
1590 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1591 || symdata == NULL)
1592 return;
1593
1594 /* Get the section header string table index. */
1595 size_t shstrndx;
1596 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1597 error (EXIT_FAILURE, 0,
1598 gettext ("cannot get section header string table index"));
1599
1600 Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1601
1602 GElf_Sym sym_mem;
1603 GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1604
1605 printf ((grpref[0] & GRP_COMDAT)
1606 ? ngettext ("\
1607 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1608 "\
1609 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1610 data->d_size / sizeof (Elf32_Word) - 1)
1611 : ngettext ("\
1612 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1613 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1614 data->d_size / sizeof (Elf32_Word) - 1),
1615 elf_ndxscn (scn),
1616 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1617 (sym == NULL ? NULL
1618 : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1619 ?: gettext ("<INVALID SYMBOL>"),
1620 data->d_size / sizeof (Elf32_Word) - 1);
1621
1622 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1623 {
1624 GElf_Shdr grpshdr_mem;
1625 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1626 &grpshdr_mem);
1627
1628 const char *str;
1629 printf (" [%2u] %s\n",
1630 grpref[cnt],
1631 grpshdr != NULL
1632 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1633 ? str : gettext ("<INVALID SECTION>"));
1634 }
1635 }
1636
1637
1638 static void
print_scngrp(Ebl * ebl)1639 print_scngrp (Ebl *ebl)
1640 {
1641 /* Find all relocation sections and handle them. */
1642 Elf_Scn *scn = NULL;
1643
1644 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1645 {
1646 /* Handle the section if it is a symbol table. */
1647 GElf_Shdr shdr_mem;
1648 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1649
1650 if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1651 {
1652 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1653 {
1654 if (elf_compress (scn, 0, 0) < 0)
1655 printf ("WARNING: %s [%zd]\n",
1656 gettext ("Couldn't uncompress section"),
1657 elf_ndxscn (scn));
1658 shdr = gelf_getshdr (scn, &shdr_mem);
1659 if (unlikely (shdr == NULL))
1660 error (EXIT_FAILURE, 0,
1661 gettext ("cannot get section [%zd] header: %s"),
1662 elf_ndxscn (scn),
1663 elf_errmsg (-1));
1664 }
1665 handle_scngrp (ebl, scn, shdr);
1666 }
1667 }
1668 }
1669
1670
1671 static const struct flags
1672 {
1673 int mask;
1674 const char *str;
1675 } dt_flags[] =
1676 {
1677 { DF_ORIGIN, "ORIGIN" },
1678 { DF_SYMBOLIC, "SYMBOLIC" },
1679 { DF_TEXTREL, "TEXTREL" },
1680 { DF_BIND_NOW, "BIND_NOW" },
1681 { DF_STATIC_TLS, "STATIC_TLS" }
1682 };
1683 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1684
1685 static const struct flags dt_flags_1[] =
1686 {
1687 { DF_1_NOW, "NOW" },
1688 { DF_1_GLOBAL, "GLOBAL" },
1689 { DF_1_GROUP, "GROUP" },
1690 { DF_1_NODELETE, "NODELETE" },
1691 { DF_1_LOADFLTR, "LOADFLTR" },
1692 { DF_1_INITFIRST, "INITFIRST" },
1693 { DF_1_NOOPEN, "NOOPEN" },
1694 { DF_1_ORIGIN, "ORIGIN" },
1695 { DF_1_DIRECT, "DIRECT" },
1696 { DF_1_TRANS, "TRANS" },
1697 { DF_1_INTERPOSE, "INTERPOSE" },
1698 { DF_1_NODEFLIB, "NODEFLIB" },
1699 { DF_1_NODUMP, "NODUMP" },
1700 { DF_1_CONFALT, "CONFALT" },
1701 { DF_1_ENDFILTEE, "ENDFILTEE" },
1702 { DF_1_DISPRELDNE, "DISPRELDNE" },
1703 { DF_1_DISPRELPND, "DISPRELPND" },
1704 };
1705 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1706
1707 static const struct flags dt_feature_1[] =
1708 {
1709 { DTF_1_PARINIT, "PARINIT" },
1710 { DTF_1_CONFEXP, "CONFEXP" }
1711 };
1712 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1713 / sizeof (dt_feature_1[0]));
1714
1715 static const struct flags dt_posflag_1[] =
1716 {
1717 { DF_P1_LAZYLOAD, "LAZYLOAD" },
1718 { DF_P1_GROUPPERM, "GROUPPERM" }
1719 };
1720 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1721 / sizeof (dt_posflag_1[0]));
1722
1723
1724 static void
print_flags(int class,GElf_Xword d_val,const struct flags * flags,int nflags)1725 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1726 int nflags)
1727 {
1728 bool first = true;
1729 int cnt;
1730
1731 for (cnt = 0; cnt < nflags; ++cnt)
1732 if (d_val & flags[cnt].mask)
1733 {
1734 if (!first)
1735 putchar_unlocked (' ');
1736 fputs_unlocked (flags[cnt].str, stdout);
1737 d_val &= ~flags[cnt].mask;
1738 first = false;
1739 }
1740
1741 if (d_val != 0)
1742 {
1743 if (!first)
1744 putchar_unlocked (' ');
1745 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1746 }
1747
1748 putchar_unlocked ('\n');
1749 }
1750
1751
1752 static void
print_dt_flags(int class,GElf_Xword d_val)1753 print_dt_flags (int class, GElf_Xword d_val)
1754 {
1755 print_flags (class, d_val, dt_flags, ndt_flags);
1756 }
1757
1758
1759 static void
print_dt_flags_1(int class,GElf_Xword d_val)1760 print_dt_flags_1 (int class, GElf_Xword d_val)
1761 {
1762 print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1763 }
1764
1765
1766 static void
print_dt_feature_1(int class,GElf_Xword d_val)1767 print_dt_feature_1 (int class, GElf_Xword d_val)
1768 {
1769 print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1770 }
1771
1772
1773 static void
print_dt_posflag_1(int class,GElf_Xword d_val)1774 print_dt_posflag_1 (int class, GElf_Xword d_val)
1775 {
1776 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1777 }
1778
1779
1780 static void
handle_dynamic(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1781 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1782 {
1783 int class = gelf_getclass (ebl->elf);
1784 GElf_Shdr glink_mem;
1785 GElf_Shdr *glink;
1786 Elf_Data *data;
1787 size_t cnt;
1788 size_t shstrndx;
1789 size_t sh_entsize;
1790
1791 /* Get the data of the section. */
1792 data = elf_getdata (scn, NULL);
1793 if (data == NULL)
1794 return;
1795
1796 /* Get the section header string table index. */
1797 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1798 error (EXIT_FAILURE, 0,
1799 gettext ("cannot get section header string table index"));
1800
1801 sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1802
1803 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1804 if (glink == NULL)
1805 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
1806 elf_ndxscn (scn));
1807
1808 printf (ngettext ("\
1809 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1810 "\
1811 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1812 shdr->sh_size / sh_entsize),
1813 (unsigned long int) (shdr->sh_size / sh_entsize),
1814 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1815 shdr->sh_offset,
1816 (int) shdr->sh_link,
1817 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1818 fputs_unlocked (gettext (" Type Value\n"), stdout);
1819
1820 for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1821 {
1822 GElf_Dyn dynmem;
1823 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1824 if (dyn == NULL)
1825 break;
1826
1827 char buf[64];
1828 printf (" %-17s ",
1829 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1830
1831 switch (dyn->d_tag)
1832 {
1833 case DT_NULL:
1834 case DT_DEBUG:
1835 case DT_BIND_NOW:
1836 case DT_TEXTREL:
1837 /* No further output. */
1838 fputc_unlocked ('\n', stdout);
1839 break;
1840
1841 case DT_NEEDED:
1842 printf (gettext ("Shared library: [%s]\n"),
1843 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1844 break;
1845
1846 case DT_SONAME:
1847 printf (gettext ("Library soname: [%s]\n"),
1848 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1849 break;
1850
1851 case DT_RPATH:
1852 printf (gettext ("Library rpath: [%s]\n"),
1853 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1854 break;
1855
1856 case DT_RUNPATH:
1857 printf (gettext ("Library runpath: [%s]\n"),
1858 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1859 break;
1860
1861 case DT_PLTRELSZ:
1862 case DT_RELASZ:
1863 case DT_STRSZ:
1864 case DT_RELSZ:
1865 case DT_RELAENT:
1866 case DT_SYMENT:
1867 case DT_RELENT:
1868 case DT_PLTPADSZ:
1869 case DT_MOVEENT:
1870 case DT_MOVESZ:
1871 case DT_INIT_ARRAYSZ:
1872 case DT_FINI_ARRAYSZ:
1873 case DT_SYMINSZ:
1874 case DT_SYMINENT:
1875 case DT_GNU_CONFLICTSZ:
1876 case DT_GNU_LIBLISTSZ:
1877 printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1878 break;
1879
1880 case DT_VERDEFNUM:
1881 case DT_VERNEEDNUM:
1882 case DT_RELACOUNT:
1883 case DT_RELCOUNT:
1884 printf ("%" PRId64 "\n", dyn->d_un.d_val);
1885 break;
1886
1887 case DT_PLTREL:;
1888 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1889 NULL, 0);
1890 puts (tagname ?: "???");
1891 break;
1892
1893 case DT_FLAGS:
1894 print_dt_flags (class, dyn->d_un.d_val);
1895 break;
1896
1897 case DT_FLAGS_1:
1898 print_dt_flags_1 (class, dyn->d_un.d_val);
1899 break;
1900
1901 case DT_FEATURE_1:
1902 print_dt_feature_1 (class, dyn->d_un.d_val);
1903 break;
1904
1905 case DT_POSFLAG_1:
1906 print_dt_posflag_1 (class, dyn->d_un.d_val);
1907 break;
1908
1909 default:
1910 printf ("%#0*" PRIx64 "\n",
1911 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1912 break;
1913 }
1914 }
1915 }
1916
1917
1918 /* Print the dynamic segment. */
1919 static void
print_dynamic(Ebl * ebl)1920 print_dynamic (Ebl *ebl)
1921 {
1922 for (size_t i = 0; i < phnum; ++i)
1923 {
1924 GElf_Phdr phdr_mem;
1925 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1926
1927 if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1928 {
1929 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1930 GElf_Shdr shdr_mem;
1931 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1932 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1933 handle_dynamic (ebl, scn, shdr);
1934 break;
1935 }
1936 }
1937 }
1938
1939
1940 /* Print relocations. */
1941 static void
print_relocs(Ebl * ebl,GElf_Ehdr * ehdr)1942 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1943 {
1944 /* Find all relocation sections and handle them. */
1945 Elf_Scn *scn = NULL;
1946
1947 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1948 {
1949 /* Handle the section if it is a symbol table. */
1950 GElf_Shdr shdr_mem;
1951 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1952
1953 if (likely (shdr != NULL))
1954 {
1955 if (shdr->sh_type == SHT_REL)
1956 handle_relocs_rel (ebl, ehdr, scn, shdr);
1957 else if (shdr->sh_type == SHT_RELA)
1958 handle_relocs_rela (ebl, ehdr, scn, shdr);
1959 }
1960 }
1961 }
1962
1963
1964 /* Handle a relocation section. */
1965 static void
handle_relocs_rel(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)1966 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1967 {
1968 int class = gelf_getclass (ebl->elf);
1969 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1970 int nentries = shdr->sh_size / sh_entsize;
1971
1972 /* Get the data of the section. */
1973 Elf_Data *data = elf_getdata (scn, NULL);
1974 if (data == NULL)
1975 return;
1976
1977 /* Get the symbol table information. */
1978 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1979 GElf_Shdr symshdr_mem;
1980 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1981 Elf_Data *symdata = elf_getdata (symscn, NULL);
1982
1983 /* Get the section header of the section the relocations are for. */
1984 GElf_Shdr destshdr_mem;
1985 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1986 &destshdr_mem);
1987
1988 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1989 {
1990 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1991 shdr->sh_offset);
1992 return;
1993 }
1994
1995 /* Search for the optional extended section index table. */
1996 Elf_Data *xndxdata = NULL;
1997 int xndxscnidx = elf_scnshndx (scn);
1998 if (unlikely (xndxscnidx > 0))
1999 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2000
2001 /* Get the section header string table index. */
2002 size_t shstrndx;
2003 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2004 error (EXIT_FAILURE, 0,
2005 gettext ("cannot get section header string table index"));
2006
2007 if (shdr->sh_info != 0)
2008 printf (ngettext ("\
2009 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2010 "\
2011 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2012 nentries),
2013 elf_ndxscn (scn),
2014 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2015 (unsigned int) shdr->sh_info,
2016 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2017 shdr->sh_offset,
2018 nentries);
2019 else
2020 /* The .rel.dyn section does not refer to a specific section but
2021 instead of section index zero. Do not try to print a section
2022 name. */
2023 printf (ngettext ("\
2024 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2025 "\
2026 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2027 nentries),
2028 (unsigned int) elf_ndxscn (scn),
2029 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2030 shdr->sh_offset,
2031 nentries);
2032 fputs_unlocked (class == ELFCLASS32
2033 ? gettext ("\
2034 Offset Type Value Name\n")
2035 : gettext ("\
2036 Offset Type Value Name\n"),
2037 stdout);
2038
2039 int is_statically_linked = 0;
2040 for (int cnt = 0; cnt < nentries; ++cnt)
2041 {
2042 GElf_Rel relmem;
2043 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
2044 if (likely (rel != NULL))
2045 {
2046 char buf[128];
2047 GElf_Sym symmem;
2048 Elf32_Word xndx;
2049 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2050 GELF_R_SYM (rel->r_info),
2051 &symmem, &xndx);
2052 if (unlikely (sym == NULL))
2053 {
2054 /* As a special case we have to handle relocations in static
2055 executables. This only happens for IRELATIVE relocations
2056 (so far). There is no symbol table. */
2057 if (is_statically_linked == 0)
2058 {
2059 /* Find the program header and look for a PT_INTERP entry. */
2060 is_statically_linked = -1;
2061 if (ehdr->e_type == ET_EXEC)
2062 {
2063 is_statically_linked = 1;
2064
2065 for (size_t inner = 0; inner < phnum; ++inner)
2066 {
2067 GElf_Phdr phdr_mem;
2068 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2069 &phdr_mem);
2070 if (phdr != NULL && phdr->p_type == PT_INTERP)
2071 {
2072 is_statically_linked = -1;
2073 break;
2074 }
2075 }
2076 }
2077 }
2078
2079 if (is_statically_linked > 0 && shdr->sh_link == 0)
2080 printf ("\
2081 %#0*" PRIx64 " %-20s %*s %s\n",
2082 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2083 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2084 /* Avoid the leading R_ which isn't carrying any
2085 information. */
2086 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2087 buf, sizeof (buf)) + 2
2088 : gettext ("<INVALID RELOC>"),
2089 class == ELFCLASS32 ? 10 : 18, "",
2090 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2091 else
2092 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
2093 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2094 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2095 /* Avoid the leading R_ which isn't carrying any
2096 information. */
2097 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2098 buf, sizeof (buf)) + 2
2099 : gettext ("<INVALID RELOC>"),
2100 gettext ("INVALID SYMBOL"),
2101 (long int) GELF_R_SYM (rel->r_info));
2102 }
2103 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2104 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
2105 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2106 likely (ebl_reloc_type_check (ebl,
2107 GELF_R_TYPE (rel->r_info)))
2108 /* Avoid the leading R_ which isn't carrying any
2109 information. */
2110 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2111 buf, sizeof (buf)) + 2
2112 : gettext ("<INVALID RELOC>"),
2113 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2114 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2115 else
2116 {
2117 /* This is a relocation against a STT_SECTION symbol. */
2118 GElf_Shdr secshdr_mem;
2119 GElf_Shdr *secshdr;
2120 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2121 sym->st_shndx == SHN_XINDEX
2122 ? xndx : sym->st_shndx),
2123 &secshdr_mem);
2124
2125 if (unlikely (secshdr == NULL))
2126 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
2127 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2128 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2129 /* Avoid the leading R_ which isn't carrying any
2130 information. */
2131 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2132 buf, sizeof (buf)) + 2
2133 : gettext ("<INVALID RELOC>"),
2134 gettext ("INVALID SECTION"),
2135 (long int) (sym->st_shndx == SHN_XINDEX
2136 ? xndx : sym->st_shndx));
2137 else
2138 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
2139 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2140 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2141 /* Avoid the leading R_ which isn't carrying any
2142 information. */
2143 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2144 buf, sizeof (buf)) + 2
2145 : gettext ("<INVALID RELOC>"),
2146 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2147 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2148 }
2149 }
2150 }
2151 }
2152
2153
2154 /* Handle a relocation section. */
2155 static void
handle_relocs_rela(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)2156 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2157 {
2158 int class = gelf_getclass (ebl->elf);
2159 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
2160 int nentries = shdr->sh_size / sh_entsize;
2161
2162 /* Get the data of the section. */
2163 Elf_Data *data = elf_getdata (scn, NULL);
2164 if (data == NULL)
2165 return;
2166
2167 /* Get the symbol table information. */
2168 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2169 GElf_Shdr symshdr_mem;
2170 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2171 Elf_Data *symdata = elf_getdata (symscn, NULL);
2172
2173 /* Get the section header of the section the relocations are for. */
2174 GElf_Shdr destshdr_mem;
2175 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2176 &destshdr_mem);
2177
2178 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2179 {
2180 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2181 shdr->sh_offset);
2182 return;
2183 }
2184
2185 /* Search for the optional extended section index table. */
2186 Elf_Data *xndxdata = NULL;
2187 int xndxscnidx = elf_scnshndx (scn);
2188 if (unlikely (xndxscnidx > 0))
2189 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2190
2191 /* Get the section header string table index. */
2192 size_t shstrndx;
2193 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2194 error (EXIT_FAILURE, 0,
2195 gettext ("cannot get section header string table index"));
2196
2197 if (shdr->sh_info != 0)
2198 printf (ngettext ("\
2199 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2200 "\
2201 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2202 nentries),
2203 elf_ndxscn (scn),
2204 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2205 (unsigned int) shdr->sh_info,
2206 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2207 shdr->sh_offset,
2208 nentries);
2209 else
2210 /* The .rela.dyn section does not refer to a specific section but
2211 instead of section index zero. Do not try to print a section
2212 name. */
2213 printf (ngettext ("\
2214 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2215 "\
2216 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2217 nentries),
2218 (unsigned int) elf_ndxscn (scn),
2219 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2220 shdr->sh_offset,
2221 nentries);
2222 fputs_unlocked (class == ELFCLASS32
2223 ? gettext ("\
2224 Offset Type Value Addend Name\n")
2225 : gettext ("\
2226 Offset Type Value Addend Name\n"),
2227 stdout);
2228
2229 int is_statically_linked = 0;
2230 for (int cnt = 0; cnt < nentries; ++cnt)
2231 {
2232 GElf_Rela relmem;
2233 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2234 if (likely (rel != NULL))
2235 {
2236 char buf[64];
2237 GElf_Sym symmem;
2238 Elf32_Word xndx;
2239 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2240 GELF_R_SYM (rel->r_info),
2241 &symmem, &xndx);
2242
2243 if (unlikely (sym == NULL))
2244 {
2245 /* As a special case we have to handle relocations in static
2246 executables. This only happens for IRELATIVE relocations
2247 (so far). There is no symbol table. */
2248 if (is_statically_linked == 0)
2249 {
2250 /* Find the program header and look for a PT_INTERP entry. */
2251 is_statically_linked = -1;
2252 if (ehdr->e_type == ET_EXEC)
2253 {
2254 is_statically_linked = 1;
2255
2256 for (size_t inner = 0; inner < phnum; ++inner)
2257 {
2258 GElf_Phdr phdr_mem;
2259 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2260 &phdr_mem);
2261 if (phdr != NULL && phdr->p_type == PT_INTERP)
2262 {
2263 is_statically_linked = -1;
2264 break;
2265 }
2266 }
2267 }
2268 }
2269
2270 if (is_statically_linked > 0 && shdr->sh_link == 0)
2271 printf ("\
2272 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
2273 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2274 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2275 /* Avoid the leading R_ which isn't carrying any
2276 information. */
2277 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2278 buf, sizeof (buf)) + 2
2279 : gettext ("<INVALID RELOC>"),
2280 class == ELFCLASS32 ? 10 : 18, "",
2281 rel->r_addend,
2282 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2283 else
2284 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2285 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2286 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2287 /* Avoid the leading R_ which isn't carrying any
2288 information. */
2289 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2290 buf, sizeof (buf)) + 2
2291 : gettext ("<INVALID RELOC>"),
2292 gettext ("INVALID SYMBOL"),
2293 (long int) GELF_R_SYM (rel->r_info));
2294 }
2295 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2296 printf ("\
2297 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2298 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2299 likely (ebl_reloc_type_check (ebl,
2300 GELF_R_TYPE (rel->r_info)))
2301 /* Avoid the leading R_ which isn't carrying any
2302 information. */
2303 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2304 buf, sizeof (buf)) + 2
2305 : gettext ("<INVALID RELOC>"),
2306 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2307 rel->r_addend,
2308 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2309 else
2310 {
2311 /* This is a relocation against a STT_SECTION symbol. */
2312 GElf_Shdr secshdr_mem;
2313 GElf_Shdr *secshdr;
2314 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2315 sym->st_shndx == SHN_XINDEX
2316 ? xndx : sym->st_shndx),
2317 &secshdr_mem);
2318
2319 if (unlikely (secshdr == NULL))
2320 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2321 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2322 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2323 /* Avoid the leading R_ which isn't carrying any
2324 information. */
2325 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2326 buf, sizeof (buf)) + 2
2327 : gettext ("<INVALID RELOC>"),
2328 gettext ("INVALID SECTION"),
2329 (long int) (sym->st_shndx == SHN_XINDEX
2330 ? xndx : sym->st_shndx));
2331 else
2332 printf ("\
2333 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2334 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2335 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2336 /* Avoid the leading R_ which isn't carrying any
2337 information. */
2338 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2339 buf, sizeof (buf)) + 2
2340 : gettext ("<INVALID RELOC>"),
2341 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2342 rel->r_addend,
2343 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2344 }
2345 }
2346 }
2347 }
2348
2349
2350 /* Print the program header. */
2351 static void
print_symtab(Ebl * ebl,int type)2352 print_symtab (Ebl *ebl, int type)
2353 {
2354 /* Find the symbol table(s). For this we have to search through the
2355 section table. */
2356 Elf_Scn *scn = NULL;
2357
2358 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2359 {
2360 /* Handle the section if it is a symbol table. */
2361 GElf_Shdr shdr_mem;
2362 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2363
2364 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2365 {
2366 if (symbol_table_section != NULL)
2367 {
2368 /* Get the section header string table index. */
2369 size_t shstrndx;
2370 const char *sname;
2371 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2372 error (EXIT_FAILURE, 0,
2373 gettext ("cannot get section header string table index"));
2374 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
2375 if (sname == NULL || strcmp (sname, symbol_table_section) != 0)
2376 continue;
2377 }
2378
2379 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
2380 {
2381 if (elf_compress (scn, 0, 0) < 0)
2382 printf ("WARNING: %s [%zd]\n",
2383 gettext ("Couldn't uncompress section"),
2384 elf_ndxscn (scn));
2385 shdr = gelf_getshdr (scn, &shdr_mem);
2386 if (unlikely (shdr == NULL))
2387 error (EXIT_FAILURE, 0,
2388 gettext ("cannot get section [%zd] header: %s"),
2389 elf_ndxscn (scn), elf_errmsg (-1));
2390 }
2391 handle_symtab (ebl, scn, shdr);
2392 }
2393 }
2394 }
2395
2396
2397 static void
handle_symtab(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2398 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2399 {
2400 Elf_Data *versym_data = NULL;
2401 Elf_Data *verneed_data = NULL;
2402 Elf_Data *verdef_data = NULL;
2403 Elf_Data *xndx_data = NULL;
2404 int class = gelf_getclass (ebl->elf);
2405 Elf32_Word verneed_stridx = 0;
2406 Elf32_Word verdef_stridx = 0;
2407
2408 /* Get the data of the section. */
2409 Elf_Data *data = elf_getdata (scn, NULL);
2410 if (data == NULL)
2411 return;
2412
2413 /* Find out whether we have other sections we might need. */
2414 Elf_Scn *runscn = NULL;
2415 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2416 {
2417 GElf_Shdr runshdr_mem;
2418 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2419
2420 if (likely (runshdr != NULL))
2421 {
2422 if (runshdr->sh_type == SHT_GNU_versym
2423 && runshdr->sh_link == elf_ndxscn (scn))
2424 /* Bingo, found the version information. Now get the data. */
2425 versym_data = elf_getdata (runscn, NULL);
2426 else if (runshdr->sh_type == SHT_GNU_verneed)
2427 {
2428 /* This is the information about the needed versions. */
2429 verneed_data = elf_getdata (runscn, NULL);
2430 verneed_stridx = runshdr->sh_link;
2431 }
2432 else if (runshdr->sh_type == SHT_GNU_verdef)
2433 {
2434 /* This is the information about the defined versions. */
2435 verdef_data = elf_getdata (runscn, NULL);
2436 verdef_stridx = runshdr->sh_link;
2437 }
2438 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2439 && runshdr->sh_link == elf_ndxscn (scn))
2440 /* Extended section index. */
2441 xndx_data = elf_getdata (runscn, NULL);
2442 }
2443 }
2444
2445 /* Get the section header string table index. */
2446 size_t shstrndx;
2447 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2448 error (EXIT_FAILURE, 0,
2449 gettext ("cannot get section header string table index"));
2450
2451 GElf_Shdr glink_mem;
2452 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2453 &glink_mem);
2454 if (glink == NULL)
2455 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2456 elf_ndxscn (scn));
2457
2458 /* Now we can compute the number of entries in the section. */
2459 unsigned int nsyms = data->d_size / (class == ELFCLASS32
2460 ? sizeof (Elf32_Sym)
2461 : sizeof (Elf64_Sym));
2462
2463 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2464 "\nSymbol table [%2u] '%s' contains %u entries:\n",
2465 nsyms),
2466 (unsigned int) elf_ndxscn (scn),
2467 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2468 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
2469 " %lu local symbols String table: [%2u] '%s'\n",
2470 shdr->sh_info),
2471 (unsigned long int) shdr->sh_info,
2472 (unsigned int) shdr->sh_link,
2473 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2474
2475 fputs_unlocked (class == ELFCLASS32
2476 ? gettext ("\
2477 Num: Value Size Type Bind Vis Ndx Name\n")
2478 : gettext ("\
2479 Num: Value Size Type Bind Vis Ndx Name\n"),
2480 stdout);
2481
2482 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2483 {
2484 char typebuf[64];
2485 char bindbuf[64];
2486 char scnbuf[64];
2487 Elf32_Word xndx;
2488 GElf_Sym sym_mem;
2489 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2490
2491 if (unlikely (sym == NULL))
2492 continue;
2493
2494 /* Determine the real section index. */
2495 if (likely (sym->st_shndx != SHN_XINDEX))
2496 xndx = sym->st_shndx;
2497
2498 printf (gettext ("\
2499 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2500 cnt,
2501 class == ELFCLASS32 ? 8 : 16,
2502 sym->st_value,
2503 sym->st_size,
2504 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2505 typebuf, sizeof (typebuf)),
2506 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2507 bindbuf, sizeof (bindbuf)),
2508 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2509 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2510 sizeof (scnbuf), NULL, shnum),
2511 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2512
2513 if (versym_data != NULL)
2514 {
2515 /* Get the version information. */
2516 GElf_Versym versym_mem;
2517 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2518
2519 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2520 {
2521 bool is_nobits = false;
2522 bool check_def = xndx != SHN_UNDEF;
2523
2524 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2525 {
2526 GElf_Shdr symshdr_mem;
2527 GElf_Shdr *symshdr =
2528 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2529
2530 is_nobits = (symshdr != NULL
2531 && symshdr->sh_type == SHT_NOBITS);
2532 }
2533
2534 if (is_nobits || ! check_def)
2535 {
2536 /* We must test both. */
2537 GElf_Vernaux vernaux_mem;
2538 GElf_Vernaux *vernaux = NULL;
2539 size_t vn_offset = 0;
2540
2541 GElf_Verneed verneed_mem;
2542 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2543 &verneed_mem);
2544 while (verneed != NULL)
2545 {
2546 size_t vna_offset = vn_offset;
2547
2548 vernaux = gelf_getvernaux (verneed_data,
2549 vna_offset += verneed->vn_aux,
2550 &vernaux_mem);
2551 while (vernaux != NULL
2552 && vernaux->vna_other != *versym
2553 && vernaux->vna_next != 0)
2554 {
2555 /* Update the offset. */
2556 vna_offset += vernaux->vna_next;
2557
2558 vernaux = (vernaux->vna_next == 0
2559 ? NULL
2560 : gelf_getvernaux (verneed_data,
2561 vna_offset,
2562 &vernaux_mem));
2563 }
2564
2565 /* Check whether we found the version. */
2566 if (vernaux != NULL && vernaux->vna_other == *versym)
2567 /* Found it. */
2568 break;
2569
2570 vn_offset += verneed->vn_next;
2571 verneed = (verneed->vn_next == 0
2572 ? NULL
2573 : gelf_getverneed (verneed_data, vn_offset,
2574 &verneed_mem));
2575 }
2576
2577 if (vernaux != NULL && vernaux->vna_other == *versym)
2578 {
2579 printf ("@%s (%u)",
2580 elf_strptr (ebl->elf, verneed_stridx,
2581 vernaux->vna_name),
2582 (unsigned int) vernaux->vna_other);
2583 check_def = 0;
2584 }
2585 else if (unlikely (! is_nobits))
2586 error (0, 0, gettext ("bad dynamic symbol"));
2587 else
2588 check_def = 1;
2589 }
2590
2591 if (check_def && *versym != 0x8001)
2592 {
2593 /* We must test both. */
2594 size_t vd_offset = 0;
2595
2596 GElf_Verdef verdef_mem;
2597 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2598 &verdef_mem);
2599 while (verdef != NULL)
2600 {
2601 if (verdef->vd_ndx == (*versym & 0x7fff))
2602 /* Found the definition. */
2603 break;
2604
2605 vd_offset += verdef->vd_next;
2606 verdef = (verdef->vd_next == 0
2607 ? NULL
2608 : gelf_getverdef (verdef_data, vd_offset,
2609 &verdef_mem));
2610 }
2611
2612 if (verdef != NULL)
2613 {
2614 GElf_Verdaux verdaux_mem;
2615 GElf_Verdaux *verdaux
2616 = gelf_getverdaux (verdef_data,
2617 vd_offset + verdef->vd_aux,
2618 &verdaux_mem);
2619
2620 if (verdaux != NULL)
2621 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2622 elf_strptr (ebl->elf, verdef_stridx,
2623 verdaux->vda_name));
2624 }
2625 }
2626 }
2627 }
2628
2629 putchar_unlocked ('\n');
2630 }
2631 }
2632
2633
2634 /* Print version information. */
2635 static void
print_verinfo(Ebl * ebl)2636 print_verinfo (Ebl *ebl)
2637 {
2638 /* Find the version information sections. For this we have to
2639 search through the section table. */
2640 Elf_Scn *scn = NULL;
2641
2642 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2643 {
2644 /* Handle the section if it is part of the versioning handling. */
2645 GElf_Shdr shdr_mem;
2646 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2647
2648 if (likely (shdr != NULL))
2649 {
2650 if (shdr->sh_type == SHT_GNU_verneed)
2651 handle_verneed (ebl, scn, shdr);
2652 else if (shdr->sh_type == SHT_GNU_verdef)
2653 handle_verdef (ebl, scn, shdr);
2654 else if (shdr->sh_type == SHT_GNU_versym)
2655 handle_versym (ebl, scn, shdr);
2656 }
2657 }
2658 }
2659
2660
2661 static const char *
get_ver_flags(unsigned int flags)2662 get_ver_flags (unsigned int flags)
2663 {
2664 static char buf[32];
2665 char *endp;
2666
2667 if (flags == 0)
2668 return gettext ("none");
2669
2670 if (flags & VER_FLG_BASE)
2671 endp = stpcpy (buf, "BASE ");
2672 else
2673 endp = buf;
2674
2675 if (flags & VER_FLG_WEAK)
2676 {
2677 if (endp != buf)
2678 endp = stpcpy (endp, "| ");
2679
2680 endp = stpcpy (endp, "WEAK ");
2681 }
2682
2683 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2684 {
2685 strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2686 buf[sizeof (buf) - 1] = '\0';
2687 }
2688
2689 return buf;
2690 }
2691
2692
2693 static void
handle_verneed(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2694 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2695 {
2696 int class = gelf_getclass (ebl->elf);
2697
2698 /* Get the data of the section. */
2699 Elf_Data *data = elf_getdata (scn, NULL);
2700 if (data == NULL)
2701 return;
2702
2703 /* Get the section header string table index. */
2704 size_t shstrndx;
2705 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2706 error (EXIT_FAILURE, 0,
2707 gettext ("cannot get section header string table index"));
2708
2709 GElf_Shdr glink_mem;
2710 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2711 &glink_mem);
2712 if (glink == NULL)
2713 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2714 elf_ndxscn (scn));
2715
2716 printf (ngettext ("\
2717 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2718 "\
2719 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2720 shdr->sh_info),
2721 (unsigned int) elf_ndxscn (scn),
2722 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2723 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2724 shdr->sh_offset,
2725 (unsigned int) shdr->sh_link,
2726 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2727
2728 unsigned int offset = 0;
2729 for (int cnt = shdr->sh_info; --cnt >= 0; )
2730 {
2731 /* Get the data at the next offset. */
2732 GElf_Verneed needmem;
2733 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2734 if (unlikely (need == NULL))
2735 break;
2736
2737 printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"),
2738 offset, (unsigned short int) need->vn_version,
2739 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2740 (unsigned short int) need->vn_cnt);
2741
2742 unsigned int auxoffset = offset + need->vn_aux;
2743 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2744 {
2745 GElf_Vernaux auxmem;
2746 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2747 if (unlikely (aux == NULL))
2748 break;
2749
2750 printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"),
2751 auxoffset,
2752 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2753 get_ver_flags (aux->vna_flags),
2754 (unsigned short int) aux->vna_other);
2755
2756 if (aux->vna_next == 0)
2757 break;
2758
2759 auxoffset += aux->vna_next;
2760 }
2761
2762 /* Find the next offset. */
2763 if (need->vn_next == 0)
2764 break;
2765
2766 offset += need->vn_next;
2767 }
2768 }
2769
2770
2771 static void
handle_verdef(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2772 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2773 {
2774 /* Get the data of the section. */
2775 Elf_Data *data = elf_getdata (scn, NULL);
2776 if (data == NULL)
2777 return;
2778
2779 /* Get the section header string table index. */
2780 size_t shstrndx;
2781 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2782 error (EXIT_FAILURE, 0,
2783 gettext ("cannot get section header string table index"));
2784
2785 GElf_Shdr glink_mem;
2786 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2787 &glink_mem);
2788 if (glink == NULL)
2789 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2790 elf_ndxscn (scn));
2791
2792 int class = gelf_getclass (ebl->elf);
2793 printf (ngettext ("\
2794 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2795 "\
2796 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2797 shdr->sh_info),
2798 (unsigned int) elf_ndxscn (scn),
2799 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2800 shdr->sh_info,
2801 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2802 shdr->sh_offset,
2803 (unsigned int) shdr->sh_link,
2804 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2805
2806 unsigned int offset = 0;
2807 for (int cnt = shdr->sh_info; --cnt >= 0; )
2808 {
2809 /* Get the data at the next offset. */
2810 GElf_Verdef defmem;
2811 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2812 if (unlikely (def == NULL))
2813 break;
2814
2815 unsigned int auxoffset = offset + def->vd_aux;
2816 GElf_Verdaux auxmem;
2817 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2818 if (unlikely (aux == NULL))
2819 break;
2820
2821 printf (gettext ("\
2822 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
2823 offset, def->vd_version,
2824 get_ver_flags (def->vd_flags),
2825 def->vd_ndx,
2826 def->vd_cnt,
2827 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2828
2829 auxoffset += aux->vda_next;
2830 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2831 {
2832 aux = gelf_getverdaux (data, auxoffset, &auxmem);
2833 if (unlikely (aux == NULL))
2834 break;
2835
2836 printf (gettext (" %#06x: Parent %d: %s\n"),
2837 auxoffset, cnt2,
2838 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2839
2840 if (aux->vda_next == 0)
2841 break;
2842
2843 auxoffset += aux->vda_next;
2844 }
2845
2846 /* Find the next offset. */
2847 if (def->vd_next == 0)
2848 break;
2849 offset += def->vd_next;
2850 }
2851 }
2852
2853
2854 static void
handle_versym(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2855 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2856 {
2857 int class = gelf_getclass (ebl->elf);
2858 const char **vername;
2859 const char **filename;
2860
2861 /* Get the data of the section. */
2862 Elf_Data *data = elf_getdata (scn, NULL);
2863 if (data == NULL)
2864 return;
2865
2866 /* Get the section header string table index. */
2867 size_t shstrndx;
2868 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2869 error (EXIT_FAILURE, 0,
2870 gettext ("cannot get section header string table index"));
2871
2872 /* We have to find the version definition section and extract the
2873 version names. */
2874 Elf_Scn *defscn = NULL;
2875 Elf_Scn *needscn = NULL;
2876
2877 Elf_Scn *verscn = NULL;
2878 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2879 {
2880 GElf_Shdr vershdr_mem;
2881 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2882
2883 if (likely (vershdr != NULL))
2884 {
2885 if (vershdr->sh_type == SHT_GNU_verdef)
2886 defscn = verscn;
2887 else if (vershdr->sh_type == SHT_GNU_verneed)
2888 needscn = verscn;
2889 }
2890 }
2891
2892 size_t nvername;
2893 if (defscn != NULL || needscn != NULL)
2894 {
2895 /* We have a version information (better should have). Now get
2896 the version names. First find the maximum version number. */
2897 nvername = 0;
2898 if (defscn != NULL)
2899 {
2900 /* Run through the version definitions and find the highest
2901 index. */
2902 unsigned int offset = 0;
2903 Elf_Data *defdata;
2904 GElf_Shdr defshdrmem;
2905 GElf_Shdr *defshdr;
2906
2907 defdata = elf_getdata (defscn, NULL);
2908 if (unlikely (defdata == NULL))
2909 return;
2910
2911 defshdr = gelf_getshdr (defscn, &defshdrmem);
2912 if (unlikely (defshdr == NULL))
2913 return;
2914
2915 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2916 {
2917 GElf_Verdef defmem;
2918 GElf_Verdef *def;
2919
2920 /* Get the data at the next offset. */
2921 def = gelf_getverdef (defdata, offset, &defmem);
2922 if (unlikely (def == NULL))
2923 break;
2924
2925 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2926
2927 if (def->vd_next == 0)
2928 break;
2929 offset += def->vd_next;
2930 }
2931 }
2932 if (needscn != NULL)
2933 {
2934 unsigned int offset = 0;
2935 Elf_Data *needdata;
2936 GElf_Shdr needshdrmem;
2937 GElf_Shdr *needshdr;
2938
2939 needdata = elf_getdata (needscn, NULL);
2940 if (unlikely (needdata == NULL))
2941 return;
2942
2943 needshdr = gelf_getshdr (needscn, &needshdrmem);
2944 if (unlikely (needshdr == NULL))
2945 return;
2946
2947 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2948 {
2949 GElf_Verneed needmem;
2950 GElf_Verneed *need;
2951 unsigned int auxoffset;
2952 int cnt2;
2953
2954 /* Get the data at the next offset. */
2955 need = gelf_getverneed (needdata, offset, &needmem);
2956 if (unlikely (need == NULL))
2957 break;
2958
2959 /* Run through the auxiliary entries. */
2960 auxoffset = offset + need->vn_aux;
2961 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2962 {
2963 GElf_Vernaux auxmem;
2964 GElf_Vernaux *aux;
2965
2966 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2967 if (unlikely (aux == NULL))
2968 break;
2969
2970 nvername = MAX (nvername,
2971 (size_t) (aux->vna_other & 0x7fff));
2972
2973 if (aux->vna_next == 0)
2974 break;
2975 auxoffset += aux->vna_next;
2976 }
2977
2978 if (need->vn_next == 0)
2979 break;
2980 offset += need->vn_next;
2981 }
2982 }
2983
2984 /* This is the number of versions we know about. */
2985 ++nvername;
2986
2987 /* Allocate the array. */
2988 vername = (const char **) alloca (nvername * sizeof (const char *));
2989 memset(vername, 0, nvername * sizeof (const char *));
2990 filename = (const char **) alloca (nvername * sizeof (const char *));
2991 memset(filename, 0, nvername * sizeof (const char *));
2992
2993 /* Run through the data structures again and collect the strings. */
2994 if (defscn != NULL)
2995 {
2996 /* Run through the version definitions and find the highest
2997 index. */
2998 unsigned int offset = 0;
2999 Elf_Data *defdata;
3000 GElf_Shdr defshdrmem;
3001 GElf_Shdr *defshdr;
3002
3003 defdata = elf_getdata (defscn, NULL);
3004 if (unlikely (defdata == NULL))
3005 return;
3006
3007 defshdr = gelf_getshdr (defscn, &defshdrmem);
3008 if (unlikely (defshdr == NULL))
3009 return;
3010
3011 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
3012 {
3013
3014 /* Get the data at the next offset. */
3015 GElf_Verdef defmem;
3016 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
3017 if (unlikely (def == NULL))
3018 break;
3019
3020 GElf_Verdaux auxmem;
3021 GElf_Verdaux *aux = gelf_getverdaux (defdata,
3022 offset + def->vd_aux,
3023 &auxmem);
3024 if (unlikely (aux == NULL))
3025 break;
3026
3027 vername[def->vd_ndx & 0x7fff]
3028 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
3029 filename[def->vd_ndx & 0x7fff] = NULL;
3030
3031 if (def->vd_next == 0)
3032 break;
3033 offset += def->vd_next;
3034 }
3035 }
3036 if (needscn != NULL)
3037 {
3038 unsigned int offset = 0;
3039
3040 Elf_Data *needdata = elf_getdata (needscn, NULL);
3041 GElf_Shdr needshdrmem;
3042 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
3043 if (unlikely (needdata == NULL || needshdr == NULL))
3044 return;
3045
3046 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
3047 {
3048 /* Get the data at the next offset. */
3049 GElf_Verneed needmem;
3050 GElf_Verneed *need = gelf_getverneed (needdata, offset,
3051 &needmem);
3052 if (unlikely (need == NULL))
3053 break;
3054
3055 /* Run through the auxiliary entries. */
3056 unsigned int auxoffset = offset + need->vn_aux;
3057 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
3058 {
3059 GElf_Vernaux auxmem;
3060 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
3061 &auxmem);
3062 if (unlikely (aux == NULL))
3063 break;
3064
3065 vername[aux->vna_other & 0x7fff]
3066 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
3067 filename[aux->vna_other & 0x7fff]
3068 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
3069
3070 if (aux->vna_next == 0)
3071 break;
3072 auxoffset += aux->vna_next;
3073 }
3074
3075 if (need->vn_next == 0)
3076 break;
3077 offset += need->vn_next;
3078 }
3079 }
3080 }
3081 else
3082 {
3083 vername = NULL;
3084 nvername = 1;
3085 filename = NULL;
3086 }
3087
3088 GElf_Shdr glink_mem;
3089 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
3090 &glink_mem);
3091 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
3092 if (glink == NULL)
3093 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
3094 elf_ndxscn (scn));
3095
3096 /* Print the header. */
3097 printf (ngettext ("\
3098 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
3099 "\
3100 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
3101 shdr->sh_size / sh_entsize),
3102 (unsigned int) elf_ndxscn (scn),
3103 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3104 (int) (shdr->sh_size / sh_entsize),
3105 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
3106 shdr->sh_offset,
3107 (unsigned int) shdr->sh_link,
3108 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3109
3110 /* Now we can finally look at the actual contents of this section. */
3111 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
3112 {
3113 if (cnt % 2 == 0)
3114 printf ("\n %4d:", cnt);
3115
3116 GElf_Versym symmem;
3117 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
3118 if (sym == NULL)
3119 break;
3120
3121 switch (*sym)
3122 {
3123 ssize_t n;
3124 case 0:
3125 fputs_unlocked (gettext (" 0 *local* "),
3126 stdout);
3127 break;
3128
3129 case 1:
3130 fputs_unlocked (gettext (" 1 *global* "),
3131 stdout);
3132 break;
3133
3134 default:
3135 n = printf ("%4d%c%s",
3136 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
3137 (vername != NULL
3138 && (unsigned int) (*sym & 0x7fff) < nvername)
3139 ? vername[*sym & 0x7fff] : "???");
3140 if ((unsigned int) (*sym & 0x7fff) < nvername
3141 && filename != NULL && filename[*sym & 0x7fff] != NULL)
3142 n += printf ("(%s)", filename[*sym & 0x7fff]);
3143 printf ("%*s", MAX (0, 33 - (int) n), " ");
3144 break;
3145 }
3146 }
3147 putchar_unlocked ('\n');
3148 }
3149
3150
3151 static void
print_hash_info(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx,uint_fast32_t maxlength,Elf32_Word nbucket,uint_fast32_t nsyms,uint32_t * lengths,const char * extrastr)3152 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
3153 uint_fast32_t maxlength, Elf32_Word nbucket,
3154 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
3155 {
3156 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
3157
3158 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3159 ++counts[lengths[cnt]];
3160
3161 GElf_Shdr glink_mem;
3162 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
3163 shdr->sh_link),
3164 &glink_mem);
3165 if (glink == NULL)
3166 {
3167 error (0, 0, gettext ("invalid sh_link value in section %zu"),
3168 elf_ndxscn (scn));
3169 return;
3170 }
3171
3172 printf (ngettext ("\
3173 \nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
3174 "\
3175 \nHistogram for bucket list length in section [%2u] '%s' (total of %d buckets):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
3176 nbucket),
3177 (unsigned int) elf_ndxscn (scn),
3178 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3179 (int) nbucket,
3180 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
3181 shdr->sh_addr,
3182 shdr->sh_offset,
3183 (unsigned int) shdr->sh_link,
3184 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3185
3186 if (extrastr != NULL)
3187 fputs (extrastr, stdout);
3188
3189 if (likely (nbucket > 0))
3190 {
3191 uint64_t success = 0;
3192
3193 /* xgettext:no-c-format */
3194 fputs_unlocked (gettext ("\
3195 Length Number % of total Coverage\n"), stdout);
3196 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
3197 counts[0], (counts[0] * 100.0) / nbucket);
3198
3199 uint64_t nzero_counts = 0;
3200 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3201 {
3202 nzero_counts += counts[cnt] * cnt;
3203 printf (gettext ("\
3204 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
3205 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
3206 (nzero_counts * 100.0) / nsyms);
3207 }
3208
3209 Elf32_Word acc = 0;
3210 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3211 {
3212 acc += cnt;
3213 success += counts[cnt] * acc;
3214 }
3215
3216 printf (gettext ("\
3217 Average number of tests: successful lookup: %f\n\
3218 unsuccessful lookup: %f\n"),
3219 (double) success / (double) nzero_counts,
3220 (double) nzero_counts / (double) nbucket);
3221 }
3222
3223 free (counts);
3224 }
3225
3226
3227 /* This function handles the traditional System V-style hash table format. */
3228 static void
handle_sysv_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3229 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3230 {
3231 Elf_Data *data = elf_getdata (scn, NULL);
3232 if (unlikely (data == NULL))
3233 {
3234 error (0, 0, gettext ("cannot get data for section %d: %s"),
3235 (int) elf_ndxscn (scn), elf_errmsg (-1));
3236 return;
3237 }
3238
3239 if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
3240 {
3241 invalid_data:
3242 error (0, 0, gettext ("invalid data in sysv.hash section %d"),
3243 (int) elf_ndxscn (scn));
3244 return;
3245 }
3246
3247 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3248 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
3249
3250 uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
3251 if (used_buf > data->d_size)
3252 goto invalid_data;
3253
3254 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
3255 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
3256
3257 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3258
3259 uint_fast32_t maxlength = 0;
3260 uint_fast32_t nsyms = 0;
3261 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3262 {
3263 Elf32_Word inner = bucket[cnt];
3264 Elf32_Word chain_len = 0;
3265 while (inner > 0 && inner < nchain)
3266 {
3267 ++nsyms;
3268 ++chain_len;
3269 if (chain_len > nchain)
3270 {
3271 error (0, 0, gettext ("invalid chain in sysv.hash section %d"),
3272 (int) elf_ndxscn (scn));
3273 free (lengths);
3274 return;
3275 }
3276 if (maxlength < ++lengths[cnt])
3277 ++maxlength;
3278
3279 inner = chain[inner];
3280 }
3281 }
3282
3283 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3284 lengths, NULL);
3285
3286 free (lengths);
3287 }
3288
3289
3290 /* This function handles the incorrect, System V-style hash table
3291 format some 64-bit architectures use. */
3292 static void
handle_sysv_hash64(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3293 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3294 {
3295 Elf_Data *data = elf_getdata (scn, NULL);
3296 if (unlikely (data == NULL))
3297 {
3298 error (0, 0, gettext ("cannot get data for section %d: %s"),
3299 (int) elf_ndxscn (scn), elf_errmsg (-1));
3300 return;
3301 }
3302
3303 if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3304 {
3305 invalid_data:
3306 error (0, 0, gettext ("invalid data in sysv.hash64 section %d"),
3307 (int) elf_ndxscn (scn));
3308 return;
3309 }
3310
3311 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3312 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3313
3314 uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
3315 if (maxwords < 2
3316 || maxwords - 2 < nbucket
3317 || maxwords - 2 - nbucket < nchain)
3318 goto invalid_data;
3319
3320 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3321 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3322
3323 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3324
3325 uint_fast32_t maxlength = 0;
3326 uint_fast32_t nsyms = 0;
3327 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3328 {
3329 Elf64_Xword inner = bucket[cnt];
3330 Elf64_Xword chain_len = 0;
3331 while (inner > 0 && inner < nchain)
3332 {
3333 ++nsyms;
3334 ++chain_len;
3335 if (chain_len > nchain)
3336 {
3337 error (0, 0, gettext ("invalid chain in sysv.hash64 section %d"),
3338 (int) elf_ndxscn (scn));
3339 free (lengths);
3340 return;
3341 }
3342 if (maxlength < ++lengths[cnt])
3343 ++maxlength;
3344
3345 inner = chain[inner];
3346 }
3347 }
3348
3349 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3350 lengths, NULL);
3351
3352 free (lengths);
3353 }
3354
3355
3356 /* This function handles the GNU-style hash table format. */
3357 static void
handle_gnu_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3358 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3359 {
3360 uint32_t *lengths = NULL;
3361 Elf_Data *data = elf_getdata (scn, NULL);
3362 if (unlikely (data == NULL))
3363 {
3364 error (0, 0, gettext ("cannot get data for section %d: %s"),
3365 (int) elf_ndxscn (scn), elf_errmsg (-1));
3366 return;
3367 }
3368
3369 if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3370 {
3371 invalid_data:
3372 free (lengths);
3373 error (0, 0, gettext ("invalid data in gnu.hash section %d"),
3374 (int) elf_ndxscn (scn));
3375 return;
3376 }
3377
3378 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3379 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3380
3381 /* Next comes the size of the bitmap. It's measured in words for
3382 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3383 64 bit archs. There is always a bloom filter present, so zero is
3384 an invalid value. */
3385 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3386 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3387 bitmask_words *= 2;
3388
3389 if (bitmask_words == 0)
3390 goto invalid_data;
3391
3392 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3393
3394 /* Is there still room for the sym chain?
3395 Use uint64_t calculation to prevent 32bit overlow. */
3396 uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3397 uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3398 if (used_buf > data->d_size)
3399 goto invalid_data;
3400
3401 lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3402
3403 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3404 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3405 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3406 + nbucket];
3407
3408 /* Compute distribution of chain lengths. */
3409 uint_fast32_t maxlength = 0;
3410 uint_fast32_t nsyms = 0;
3411 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3412 if (bucket[cnt] != 0)
3413 {
3414 Elf32_Word inner = bucket[cnt] - symbias;
3415 do
3416 {
3417 ++nsyms;
3418 if (maxlength < ++lengths[cnt])
3419 ++maxlength;
3420 if (inner >= max_nsyms)
3421 goto invalid_data;
3422 }
3423 while ((chain[inner++] & 1) == 0);
3424 }
3425
3426 /* Count bits in bitmask. */
3427 uint_fast32_t nbits = 0;
3428 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3429 {
3430 uint_fast32_t word = bitmask[cnt];
3431
3432 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3433 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3434 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3435 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3436 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3437 }
3438
3439 char *str;
3440 if (unlikely (asprintf (&str, gettext ("\
3441 Symbol Bias: %u\n\
3442 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3443 (unsigned int) symbias,
3444 bitmask_words * sizeof (Elf32_Word),
3445 ((nbits * 100 + 50)
3446 / (uint_fast32_t) (bitmask_words
3447 * sizeof (Elf32_Word) * 8)),
3448 (unsigned int) shift) == -1))
3449 error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3450
3451 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3452 lengths, str);
3453
3454 free (str);
3455 free (lengths);
3456 }
3457
3458
3459 /* Find the symbol table(s). For this we have to search through the
3460 section table. */
3461 static void
handle_hash(Ebl * ebl)3462 handle_hash (Ebl *ebl)
3463 {
3464 /* Get the section header string table index. */
3465 size_t shstrndx;
3466 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3467 error (EXIT_FAILURE, 0,
3468 gettext ("cannot get section header string table index"));
3469
3470 Elf_Scn *scn = NULL;
3471 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3472 {
3473 /* Handle the section if it is a symbol table. */
3474 GElf_Shdr shdr_mem;
3475 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3476
3477 if (likely (shdr != NULL))
3478 {
3479 if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH)
3480 && (shdr->sh_flags & SHF_COMPRESSED) != 0)
3481 {
3482 if (elf_compress (scn, 0, 0) < 0)
3483 printf ("WARNING: %s [%zd]\n",
3484 gettext ("Couldn't uncompress section"),
3485 elf_ndxscn (scn));
3486 shdr = gelf_getshdr (scn, &shdr_mem);
3487 if (unlikely (shdr == NULL))
3488 error (EXIT_FAILURE, 0,
3489 gettext ("cannot get section [%zd] header: %s"),
3490 elf_ndxscn (scn), elf_errmsg (-1));
3491 }
3492
3493 if (shdr->sh_type == SHT_HASH)
3494 {
3495 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3496 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3497 else
3498 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3499 }
3500 else if (shdr->sh_type == SHT_GNU_HASH)
3501 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3502 }
3503 }
3504 }
3505
3506
3507 static void
print_liblist(Ebl * ebl)3508 print_liblist (Ebl *ebl)
3509 {
3510 /* Find the library list sections. For this we have to search
3511 through the section table. */
3512 Elf_Scn *scn = NULL;
3513
3514 /* Get the section header string table index. */
3515 size_t shstrndx;
3516 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3517 error (EXIT_FAILURE, 0,
3518 gettext ("cannot get section header string table index"));
3519
3520 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3521 {
3522 GElf_Shdr shdr_mem;
3523 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3524
3525 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3526 {
3527 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3528 int nentries = shdr->sh_size / sh_entsize;
3529 printf (ngettext ("\
3530 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3531 "\
3532 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3533 nentries),
3534 elf_ndxscn (scn),
3535 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3536 shdr->sh_offset,
3537 nentries);
3538
3539 Elf_Data *data = elf_getdata (scn, NULL);
3540 if (data == NULL)
3541 return;
3542
3543 puts (gettext ("\
3544 Library Time Stamp Checksum Version Flags"));
3545
3546 for (int cnt = 0; cnt < nentries; ++cnt)
3547 {
3548 GElf_Lib lib_mem;
3549 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3550 if (unlikely (lib == NULL))
3551 continue;
3552
3553 time_t t = (time_t) lib->l_time_stamp;
3554 struct tm *tm = gmtime (&t);
3555 if (unlikely (tm == NULL))
3556 continue;
3557
3558 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3559 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3560 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3561 tm->tm_hour, tm->tm_min, tm->tm_sec,
3562 (unsigned int) lib->l_checksum,
3563 (unsigned int) lib->l_version,
3564 (unsigned int) lib->l_flags);
3565 }
3566 }
3567 }
3568 }
3569
3570 static void
print_attributes(Ebl * ebl,const GElf_Ehdr * ehdr)3571 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3572 {
3573 /* Find the object attributes sections. For this we have to search
3574 through the section table. */
3575 Elf_Scn *scn = NULL;
3576
3577 /* Get the section header string table index. */
3578 size_t shstrndx;
3579 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3580 error (EXIT_FAILURE, 0,
3581 gettext ("cannot get section header string table index"));
3582
3583 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3584 {
3585 GElf_Shdr shdr_mem;
3586 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3587
3588 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3589 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3590 || ehdr->e_machine != EM_ARM)
3591 && (shdr->sh_type != SHT_CSKY_ATTRIBUTES
3592 || ehdr->e_machine != EM_CSKY)))
3593 continue;
3594
3595 printf (gettext ("\
3596 \nObject attributes section [%2zu] '%s' of %" PRIu64
3597 " bytes at offset %#0" PRIx64 ":\n"),
3598 elf_ndxscn (scn),
3599 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3600 shdr->sh_size, shdr->sh_offset);
3601
3602 Elf_Data *data = elf_rawdata (scn, NULL);
3603 if (unlikely (data == NULL || data->d_size == 0))
3604 return;
3605
3606 const unsigned char *p = data->d_buf;
3607
3608 /* There is only one 'version', A. */
3609 if (unlikely (*p++ != 'A'))
3610 return;
3611
3612 fputs_unlocked (gettext (" Owner Size\n"), stdout);
3613
3614 inline size_t left (void)
3615 {
3616 return (const unsigned char *) data->d_buf + data->d_size - p;
3617 }
3618
3619 /* Loop over the sections. */
3620 while (left () >= 4)
3621 {
3622 /* Section length. */
3623 uint32_t len;
3624 memcpy (&len, p, sizeof len);
3625
3626 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3627 CONVERT (len);
3628
3629 if (unlikely (len > left ()))
3630 break;
3631
3632 /* Section vendor name. */
3633 const unsigned char *name = p + sizeof len;
3634 p += len;
3635
3636 unsigned const char *q = memchr (name, '\0', len);
3637 if (unlikely (q == NULL))
3638 break;
3639 ++q;
3640
3641 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
3642
3643 bool gnu_vendor = (q - name == sizeof "gnu"
3644 && !memcmp (name, "gnu", sizeof "gnu"));
3645
3646 /* Loop over subsections. */
3647 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3648 || gnu_vendor)
3649 while (q < p)
3650 {
3651 const unsigned char *const sub = q;
3652
3653 unsigned int subsection_tag;
3654 get_uleb128 (subsection_tag, q, p);
3655 if (unlikely (q >= p))
3656 break;
3657
3658 uint32_t subsection_len;
3659 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3660 break;
3661
3662 memcpy (&subsection_len, q, sizeof subsection_len);
3663
3664 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3665 CONVERT (subsection_len);
3666
3667 /* Don't overflow, ptrdiff_t might be 32bits, but signed. */
3668 if (unlikely (subsection_len == 0
3669 || subsection_len >= (uint32_t) PTRDIFF_MAX
3670 || p - sub < (ptrdiff_t) subsection_len))
3671 break;
3672
3673 const unsigned char *r = q + sizeof subsection_len;
3674 q = sub + subsection_len;
3675
3676 switch (subsection_tag)
3677 {
3678 default:
3679 /* Unknown subsection, print and skip. */
3680 printf (gettext (" %-4u %12" PRIu32 "\n"),
3681 subsection_tag, subsection_len);
3682 break;
3683
3684 case 1: /* Tag_File */
3685 printf (gettext (" File: %11" PRIu32 "\n"),
3686 subsection_len);
3687
3688 while (r < q)
3689 {
3690 unsigned int tag;
3691 get_uleb128 (tag, r, q);
3692 if (unlikely (r >= q))
3693 break;
3694
3695 /* GNU style tags have either a uleb128 value,
3696 when lowest bit is not set, or a string
3697 when the lowest bit is set.
3698 "compatibility" (32) is special. It has
3699 both a string and a uleb128 value. For
3700 non-gnu we assume 6 till 31 only take ints.
3701 XXX see arm backend, do we need a separate
3702 hook? */
3703 uint64_t value = 0;
3704 const char *string = NULL;
3705 if (tag == 32 || (tag & 1) == 0
3706 || (! gnu_vendor && (tag > 5 && tag < 32)))
3707 {
3708 get_uleb128 (value, r, q);
3709 if (r > q)
3710 break;
3711 }
3712 if (tag == 32
3713 || ((tag & 1) != 0
3714 && (gnu_vendor
3715 || (! gnu_vendor && tag > 32)))
3716 || (! gnu_vendor && tag > 3 && tag < 6))
3717 {
3718 string = (const char *) r;
3719 r = memchr (r, '\0', q - r);
3720 if (r == NULL)
3721 break;
3722 ++r;
3723 }
3724
3725 const char *tag_name = NULL;
3726 const char *value_name = NULL;
3727 ebl_check_object_attribute (ebl, (const char *) name,
3728 tag, value,
3729 &tag_name, &value_name);
3730
3731 if (tag_name != NULL)
3732 {
3733 if (tag == 32)
3734 printf (gettext (" %s: %" PRId64 ", %s\n"),
3735 tag_name, value, string);
3736 else if (string == NULL && value_name == NULL)
3737 printf (gettext (" %s: %" PRId64 "\n"),
3738 tag_name, value);
3739 else
3740 printf (gettext (" %s: %s\n"),
3741 tag_name, string ?: value_name);
3742 }
3743 else
3744 {
3745 /* For "gnu" vendor 32 "compatibility" has
3746 already been handled above. */
3747 assert (tag != 32
3748 || strcmp ((const char *) name, "gnu"));
3749 if (string == NULL)
3750 printf (gettext (" %u: %" PRId64 "\n"),
3751 tag, value);
3752 else
3753 printf (gettext (" %u: %s\n"),
3754 tag, string);
3755 }
3756 }
3757 }
3758 }
3759 }
3760 }
3761 }
3762
3763
3764 void
print_dwarf_addr(Dwfl_Module * dwflmod,int address_size,Dwarf_Addr address,Dwarf_Addr raw)3765 print_dwarf_addr (Dwfl_Module *dwflmod,
3766 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3767 {
3768 /* See if there is a name we can give for this address. */
3769 GElf_Sym sym;
3770 GElf_Off off = 0;
3771 const char *name = (print_address_names && ! print_unresolved_addresses)
3772 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3773 : NULL;
3774
3775 const char *scn;
3776 if (print_unresolved_addresses)
3777 {
3778 address = raw;
3779 scn = NULL;
3780 }
3781 else
3782 {
3783 /* Relativize the address. */
3784 int n = dwfl_module_relocations (dwflmod);
3785 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3786
3787 /* In an ET_REL file there is a section name to refer to. */
3788 scn = (i < 0 ? NULL
3789 : dwfl_module_relocation_info (dwflmod, i, NULL));
3790 }
3791
3792 if ((name != NULL
3793 ? (off != 0
3794 ? (scn != NULL
3795 ? (address_size == 0
3796 ? printf ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">",
3797 scn, address, name, off)
3798 : printf ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">",
3799 scn, 2 + address_size * 2, address,
3800 name, off))
3801 : (address_size == 0
3802 ? printf ("%#" PRIx64 " <%s+%#" PRIx64 ">",
3803 address, name, off)
3804 : printf ("%#0*" PRIx64 " <%s+%#" PRIx64 ">",
3805 2 + address_size * 2, address,
3806 name, off)))
3807 : (scn != NULL
3808 ? (address_size == 0
3809 ? printf ("%s+%#" PRIx64 " <%s>", scn, address, name)
3810 : printf ("%s+%#0*" PRIx64 " <%s>",
3811 scn, 2 + address_size * 2, address, name))
3812 : (address_size == 0
3813 ? printf ("%#" PRIx64 " <%s>", address, name)
3814 : printf ("%#0*" PRIx64 " <%s>",
3815 2 + address_size * 2, address, name))))
3816 : (scn != NULL
3817 ? (address_size == 0
3818 ? printf ("%s+%#" PRIx64, scn, address)
3819 : printf ("%s+%#0*" PRIx64, scn, 2 + address_size * 2, address))
3820 : (address_size == 0
3821 ? printf ("%#" PRIx64, address)
3822 : printf ("%#0*" PRIx64, 2 + address_size * 2, address)))) < 0)
3823 error (EXIT_FAILURE, 0, _("sprintf failure"));
3824 }
3825
3826
3827 static const char *
dwarf_tag_string(unsigned int tag)3828 dwarf_tag_string (unsigned int tag)
3829 {
3830 switch (tag)
3831 {
3832 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3833 DWARF_ALL_KNOWN_DW_TAG
3834 #undef DWARF_ONE_KNOWN_DW_TAG
3835 default:
3836 return NULL;
3837 }
3838 }
3839
3840
3841 static const char *
dwarf_attr_string(unsigned int attrnum)3842 dwarf_attr_string (unsigned int attrnum)
3843 {
3844 switch (attrnum)
3845 {
3846 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3847 DWARF_ALL_KNOWN_DW_AT
3848 #undef DWARF_ONE_KNOWN_DW_AT
3849 default:
3850 return NULL;
3851 }
3852 }
3853
3854
3855 static const char *
dwarf_form_string(unsigned int form)3856 dwarf_form_string (unsigned int form)
3857 {
3858 switch (form)
3859 {
3860 #define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3861 DWARF_ALL_KNOWN_DW_FORM
3862 #undef DWARF_ONE_KNOWN_DW_FORM
3863 default:
3864 return NULL;
3865 }
3866 }
3867
3868
3869 static const char *
dwarf_lang_string(unsigned int lang)3870 dwarf_lang_string (unsigned int lang)
3871 {
3872 switch (lang)
3873 {
3874 #define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
3875 DWARF_ALL_KNOWN_DW_LANG
3876 #undef DWARF_ONE_KNOWN_DW_LANG
3877 default:
3878 return NULL;
3879 }
3880 }
3881
3882
3883 static const char *
dwarf_inline_string(unsigned int code)3884 dwarf_inline_string (unsigned int code)
3885 {
3886 static const char *const known[] =
3887 {
3888 #define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3889 DWARF_ALL_KNOWN_DW_INL
3890 #undef DWARF_ONE_KNOWN_DW_INL
3891 };
3892
3893 if (likely (code < sizeof (known) / sizeof (known[0])))
3894 return known[code];
3895
3896 return NULL;
3897 }
3898
3899
3900 static const char *
dwarf_encoding_string(unsigned int code)3901 dwarf_encoding_string (unsigned int code)
3902 {
3903 static const char *const known[] =
3904 {
3905 #define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3906 DWARF_ALL_KNOWN_DW_ATE
3907 #undef DWARF_ONE_KNOWN_DW_ATE
3908 };
3909
3910 if (likely (code < sizeof (known) / sizeof (known[0])))
3911 return known[code];
3912
3913 return NULL;
3914 }
3915
3916
3917 static const char *
dwarf_access_string(unsigned int code)3918 dwarf_access_string (unsigned int code)
3919 {
3920 static const char *const known[] =
3921 {
3922 #define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3923 DWARF_ALL_KNOWN_DW_ACCESS
3924 #undef DWARF_ONE_KNOWN_DW_ACCESS
3925 };
3926
3927 if (likely (code < sizeof (known) / sizeof (known[0])))
3928 return known[code];
3929
3930 return NULL;
3931 }
3932
3933
3934 static const char *
dwarf_defaulted_string(unsigned int code)3935 dwarf_defaulted_string (unsigned int code)
3936 {
3937 static const char *const known[] =
3938 {
3939 #define DWARF_ONE_KNOWN_DW_DEFAULTED(NAME, CODE) [CODE] = #NAME,
3940 DWARF_ALL_KNOWN_DW_DEFAULTED
3941 #undef DWARF_ONE_KNOWN_DW_DEFAULTED
3942 };
3943
3944 if (likely (code < sizeof (known) / sizeof (known[0])))
3945 return known[code];
3946
3947 return NULL;
3948 }
3949
3950
3951 static const char *
dwarf_visibility_string(unsigned int code)3952 dwarf_visibility_string (unsigned int code)
3953 {
3954 static const char *const known[] =
3955 {
3956 #define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3957 DWARF_ALL_KNOWN_DW_VIS
3958 #undef DWARF_ONE_KNOWN_DW_VIS
3959 };
3960
3961 if (likely (code < sizeof (known) / sizeof (known[0])))
3962 return known[code];
3963
3964 return NULL;
3965 }
3966
3967
3968 static const char *
dwarf_virtuality_string(unsigned int code)3969 dwarf_virtuality_string (unsigned int code)
3970 {
3971 static const char *const known[] =
3972 {
3973 #define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3974 DWARF_ALL_KNOWN_DW_VIRTUALITY
3975 #undef DWARF_ONE_KNOWN_DW_VIRTUALITY
3976 };
3977
3978 if (likely (code < sizeof (known) / sizeof (known[0])))
3979 return known[code];
3980
3981 return NULL;
3982 }
3983
3984
3985 static const char *
dwarf_identifier_case_string(unsigned int code)3986 dwarf_identifier_case_string (unsigned int code)
3987 {
3988 static const char *const known[] =
3989 {
3990 #define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3991 DWARF_ALL_KNOWN_DW_ID
3992 #undef DWARF_ONE_KNOWN_DW_ID
3993 };
3994
3995 if (likely (code < sizeof (known) / sizeof (known[0])))
3996 return known[code];
3997
3998 return NULL;
3999 }
4000
4001
4002 static const char *
dwarf_calling_convention_string(unsigned int code)4003 dwarf_calling_convention_string (unsigned int code)
4004 {
4005 static const char *const known[] =
4006 {
4007 #define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
4008 DWARF_ALL_KNOWN_DW_CC
4009 #undef DWARF_ONE_KNOWN_DW_CC
4010 };
4011
4012 if (likely (code < sizeof (known) / sizeof (known[0])))
4013 return known[code];
4014
4015 return NULL;
4016 }
4017
4018
4019 static const char *
dwarf_ordering_string(unsigned int code)4020 dwarf_ordering_string (unsigned int code)
4021 {
4022 static const char *const known[] =
4023 {
4024 #define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
4025 DWARF_ALL_KNOWN_DW_ORD
4026 #undef DWARF_ONE_KNOWN_DW_ORD
4027 };
4028
4029 if (likely (code < sizeof (known) / sizeof (known[0])))
4030 return known[code];
4031
4032 return NULL;
4033 }
4034
4035
4036 static const char *
dwarf_discr_list_string(unsigned int code)4037 dwarf_discr_list_string (unsigned int code)
4038 {
4039 static const char *const known[] =
4040 {
4041 #define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
4042 DWARF_ALL_KNOWN_DW_DSC
4043 #undef DWARF_ONE_KNOWN_DW_DSC
4044 };
4045
4046 if (likely (code < sizeof (known) / sizeof (known[0])))
4047 return known[code];
4048
4049 return NULL;
4050 }
4051
4052
4053 static const char *
dwarf_locexpr_opcode_string(unsigned int code)4054 dwarf_locexpr_opcode_string (unsigned int code)
4055 {
4056 static const char *const known[] =
4057 {
4058 /* Normally we can't affort building huge table of 64K entries,
4059 most of them zero, just because there are a couple defined
4060 values at the far end. In case of opcodes, it's OK. */
4061 #define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
4062 DWARF_ALL_KNOWN_DW_OP
4063 #undef DWARF_ONE_KNOWN_DW_OP
4064 };
4065
4066 if (likely (code < sizeof (known) / sizeof (known[0])))
4067 return known[code];
4068
4069 return NULL;
4070 }
4071
4072
4073 static const char *
dwarf_unit_string(unsigned int type)4074 dwarf_unit_string (unsigned int type)
4075 {
4076 switch (type)
4077 {
4078 #define DWARF_ONE_KNOWN_DW_UT(NAME, CODE) case CODE: return #NAME;
4079 DWARF_ALL_KNOWN_DW_UT
4080 #undef DWARF_ONE_KNOWN_DW_UT
4081 default:
4082 return NULL;
4083 }
4084 }
4085
4086
4087 static const char *
dwarf_range_list_encoding_string(unsigned int kind)4088 dwarf_range_list_encoding_string (unsigned int kind)
4089 {
4090 switch (kind)
4091 {
4092 #define DWARF_ONE_KNOWN_DW_RLE(NAME, CODE) case CODE: return #NAME;
4093 DWARF_ALL_KNOWN_DW_RLE
4094 #undef DWARF_ONE_KNOWN_DW_RLE
4095 default:
4096 return NULL;
4097 }
4098 }
4099
4100
4101 static const char *
dwarf_loc_list_encoding_string(unsigned int kind)4102 dwarf_loc_list_encoding_string (unsigned int kind)
4103 {
4104 switch (kind)
4105 {
4106 #define DWARF_ONE_KNOWN_DW_LLE(NAME, CODE) case CODE: return #NAME;
4107 DWARF_ALL_KNOWN_DW_LLE
4108 #undef DWARF_ONE_KNOWN_DW_LLE
4109 default:
4110 return NULL;
4111 }
4112 }
4113
4114
4115 static const char *
dwarf_line_content_description_string(unsigned int kind)4116 dwarf_line_content_description_string (unsigned int kind)
4117 {
4118 switch (kind)
4119 {
4120 #define DWARF_ONE_KNOWN_DW_LNCT(NAME, CODE) case CODE: return #NAME;
4121 DWARF_ALL_KNOWN_DW_LNCT
4122 #undef DWARF_ONE_KNOWN_DW_LNCT
4123 default:
4124 return NULL;
4125 }
4126 }
4127
4128
4129 /* Used by all dwarf_foo_name functions. */
4130 static const char *
string_or_unknown(const char * known,unsigned int code,unsigned int lo_user,unsigned int hi_user,bool print_unknown_num)4131 string_or_unknown (const char *known, unsigned int code,
4132 unsigned int lo_user, unsigned int hi_user,
4133 bool print_unknown_num)
4134 {
4135 static char unknown_buf[20];
4136
4137 if (likely (known != NULL))
4138 return known;
4139
4140 if (lo_user != 0 && code >= lo_user && code <= hi_user)
4141 {
4142 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
4143 code - lo_user);
4144 return unknown_buf;
4145 }
4146
4147 if (print_unknown_num)
4148 {
4149 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
4150 return unknown_buf;
4151 }
4152
4153 return "???";
4154 }
4155
4156
4157 static const char *
dwarf_tag_name(unsigned int tag)4158 dwarf_tag_name (unsigned int tag)
4159 {
4160 const char *ret = dwarf_tag_string (tag);
4161 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
4162 }
4163
4164 static const char *
dwarf_attr_name(unsigned int attr)4165 dwarf_attr_name (unsigned int attr)
4166 {
4167 const char *ret = dwarf_attr_string (attr);
4168 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
4169 }
4170
4171
4172 static const char *
dwarf_form_name(unsigned int form)4173 dwarf_form_name (unsigned int form)
4174 {
4175 const char *ret = dwarf_form_string (form);
4176 return string_or_unknown (ret, form, 0, 0, true);
4177 }
4178
4179
4180 static const char *
dwarf_lang_name(unsigned int lang)4181 dwarf_lang_name (unsigned int lang)
4182 {
4183 const char *ret = dwarf_lang_string (lang);
4184 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
4185 }
4186
4187
4188 static const char *
dwarf_inline_name(unsigned int code)4189 dwarf_inline_name (unsigned int code)
4190 {
4191 const char *ret = dwarf_inline_string (code);
4192 return string_or_unknown (ret, code, 0, 0, false);
4193 }
4194
4195
4196 static const char *
dwarf_encoding_name(unsigned int code)4197 dwarf_encoding_name (unsigned int code)
4198 {
4199 const char *ret = dwarf_encoding_string (code);
4200 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
4201 }
4202
4203
4204 static const char *
dwarf_access_name(unsigned int code)4205 dwarf_access_name (unsigned int code)
4206 {
4207 const char *ret = dwarf_access_string (code);
4208 return string_or_unknown (ret, code, 0, 0, false);
4209 }
4210
4211
4212 static const char *
dwarf_defaulted_name(unsigned int code)4213 dwarf_defaulted_name (unsigned int code)
4214 {
4215 const char *ret = dwarf_defaulted_string (code);
4216 return string_or_unknown (ret, code, 0, 0, false);
4217 }
4218
4219
4220 static const char *
dwarf_visibility_name(unsigned int code)4221 dwarf_visibility_name (unsigned int code)
4222 {
4223 const char *ret = dwarf_visibility_string (code);
4224 return string_or_unknown (ret, code, 0, 0, false);
4225 }
4226
4227
4228 static const char *
dwarf_virtuality_name(unsigned int code)4229 dwarf_virtuality_name (unsigned int code)
4230 {
4231 const char *ret = dwarf_virtuality_string (code);
4232 return string_or_unknown (ret, code, 0, 0, false);
4233 }
4234
4235
4236 static const char *
dwarf_identifier_case_name(unsigned int code)4237 dwarf_identifier_case_name (unsigned int code)
4238 {
4239 const char *ret = dwarf_identifier_case_string (code);
4240 return string_or_unknown (ret, code, 0, 0, false);
4241 }
4242
4243
4244 static const char *
dwarf_calling_convention_name(unsigned int code)4245 dwarf_calling_convention_name (unsigned int code)
4246 {
4247 const char *ret = dwarf_calling_convention_string (code);
4248 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
4249 }
4250
4251
4252 static const char *
dwarf_ordering_name(unsigned int code)4253 dwarf_ordering_name (unsigned int code)
4254 {
4255 const char *ret = dwarf_ordering_string (code);
4256 return string_or_unknown (ret, code, 0, 0, false);
4257 }
4258
4259
4260 static const char *
dwarf_discr_list_name(unsigned int code)4261 dwarf_discr_list_name (unsigned int code)
4262 {
4263 const char *ret = dwarf_discr_list_string (code);
4264 return string_or_unknown (ret, code, 0, 0, false);
4265 }
4266
4267
4268 static const char *
dwarf_unit_name(unsigned int type)4269 dwarf_unit_name (unsigned int type)
4270 {
4271 const char *ret = dwarf_unit_string (type);
4272 return string_or_unknown (ret, type, DW_UT_lo_user, DW_UT_hi_user, true);
4273 }
4274
4275
4276 static const char *
dwarf_range_list_encoding_name(unsigned int kind)4277 dwarf_range_list_encoding_name (unsigned int kind)
4278 {
4279 const char *ret = dwarf_range_list_encoding_string (kind);
4280 return string_or_unknown (ret, kind, 0, 0, false);
4281 }
4282
4283
4284 static const char *
dwarf_loc_list_encoding_name(unsigned int kind)4285 dwarf_loc_list_encoding_name (unsigned int kind)
4286 {
4287 const char *ret = dwarf_loc_list_encoding_string (kind);
4288 return string_or_unknown (ret, kind, 0, 0, false);
4289 }
4290
4291
4292 static const char *
dwarf_line_content_description_name(unsigned int kind)4293 dwarf_line_content_description_name (unsigned int kind)
4294 {
4295 const char *ret = dwarf_line_content_description_string (kind);
4296 return string_or_unknown (ret, kind, DW_LNCT_lo_user, DW_LNCT_hi_user,
4297 false);
4298 }
4299
4300
4301 static void
print_block(size_t n,const void * block)4302 print_block (size_t n, const void *block)
4303 {
4304 if (n == 0)
4305 puts (_("empty block"));
4306 else
4307 {
4308 printf (_("%zu byte block:"), n);
4309 const unsigned char *data = block;
4310 do
4311 printf (" %02x", *data++);
4312 while (--n > 0);
4313 putchar ('\n');
4314 }
4315 }
4316
4317 static void
print_bytes(size_t n,const unsigned char * bytes)4318 print_bytes (size_t n, const unsigned char *bytes)
4319 {
4320 while (n-- > 0)
4321 {
4322 printf ("%02x", *bytes++);
4323 if (n > 0)
4324 printf (" ");
4325 }
4326 }
4327
4328 static int
get_indexed_addr(Dwarf_CU * cu,Dwarf_Word idx,Dwarf_Addr * addr)4329 get_indexed_addr (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
4330 {
4331 if (cu == NULL)
4332 return -1;
4333
4334 Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
4335 if (debug_addr == NULL)
4336 return -1;
4337
4338 Dwarf_Off base = __libdw_cu_addr_base (cu);
4339 Dwarf_Word off = idx * cu->address_size;
4340 if (base > debug_addr->d_size
4341 || off > debug_addr->d_size - base
4342 || cu->address_size > debug_addr->d_size - base - off)
4343 return -1;
4344
4345 const unsigned char *addrp = debug_addr->d_buf + base + off;
4346 if (cu->address_size == 4)
4347 *addr = read_4ubyte_unaligned (cu->dbg, addrp);
4348 else
4349 *addr = read_8ubyte_unaligned (cu->dbg, addrp);
4350
4351 return 0;
4352 }
4353
4354 static void
print_ops(Dwfl_Module * dwflmod,Dwarf * dbg,int indent,int indentrest,unsigned int vers,unsigned int addrsize,unsigned int offset_size,struct Dwarf_CU * cu,Dwarf_Word len,const unsigned char * data)4355 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
4356 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
4357 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
4358 {
4359 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
4360
4361 if (len == 0)
4362 {
4363 printf ("%*s(empty)\n", indent, "");
4364 return;
4365 }
4366
4367 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
4368 #define CONSUME(n) NEED (n); else len -= (n)
4369
4370 Dwarf_Word offset = 0;
4371 while (len-- > 0)
4372 {
4373 uint_fast8_t op = *data++;
4374
4375 const char *op_name = dwarf_locexpr_opcode_string (op);
4376 if (unlikely (op_name == NULL))
4377 {
4378 static char buf[20];
4379 if (op >= DW_OP_lo_user)
4380 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
4381 else
4382 snprintf (buf, sizeof buf, "??? (%#x)", op);
4383 op_name = buf;
4384 }
4385
4386 switch (op)
4387 {
4388 case DW_OP_addr:;
4389 /* Address operand. */
4390 Dwarf_Word addr;
4391 NEED (addrsize);
4392 if (addrsize == 4)
4393 addr = read_4ubyte_unaligned (dbg, data);
4394 else if (addrsize == 8)
4395 addr = read_8ubyte_unaligned (dbg, data);
4396 else
4397 goto invalid;
4398 data += addrsize;
4399 CONSUME (addrsize);
4400
4401 printf ("%*s[%2" PRIuMAX "] %s ",
4402 indent, "", (uintmax_t) offset, op_name);
4403 print_dwarf_addr (dwflmod, 0, addr, addr);
4404 printf ("\n");
4405
4406 offset += 1 + addrsize;
4407 break;
4408
4409 case DW_OP_call_ref:
4410 case DW_OP_GNU_variable_value:
4411 /* Offset operand. */
4412 if (ref_size != 4 && ref_size != 8)
4413 goto invalid; /* Cannot be used in CFA. */
4414 NEED (ref_size);
4415 if (ref_size == 4)
4416 addr = read_4ubyte_unaligned (dbg, data);
4417 else
4418 addr = read_8ubyte_unaligned (dbg, data);
4419 data += ref_size;
4420 CONSUME (ref_size);
4421 /* addr is a DIE offset, so format it as one. */
4422 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4423 indent, "", (uintmax_t) offset,
4424 op_name, (uintmax_t) addr);
4425 offset += 1 + ref_size;
4426 break;
4427
4428 case DW_OP_deref_size:
4429 case DW_OP_xderef_size:
4430 case DW_OP_pick:
4431 case DW_OP_const1u:
4432 // XXX value might be modified by relocation
4433 NEED (1);
4434 printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 "\n",
4435 indent, "", (uintmax_t) offset,
4436 op_name, *((uint8_t *) data));
4437 ++data;
4438 --len;
4439 offset += 2;
4440 break;
4441
4442 case DW_OP_const2u:
4443 NEED (2);
4444 // XXX value might be modified by relocation
4445 printf ("%*s[%2" PRIuMAX "] %s %" PRIu16 "\n",
4446 indent, "", (uintmax_t) offset,
4447 op_name, read_2ubyte_unaligned (dbg, data));
4448 CONSUME (2);
4449 data += 2;
4450 offset += 3;
4451 break;
4452
4453 case DW_OP_const4u:
4454 NEED (4);
4455 // XXX value might be modified by relocation
4456 printf ("%*s[%2" PRIuMAX "] %s %" PRIu32 "\n",
4457 indent, "", (uintmax_t) offset,
4458 op_name, read_4ubyte_unaligned (dbg, data));
4459 CONSUME (4);
4460 data += 4;
4461 offset += 5;
4462 break;
4463
4464 case DW_OP_const8u:
4465 NEED (8);
4466 // XXX value might be modified by relocation
4467 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4468 indent, "", (uintmax_t) offset,
4469 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4470 CONSUME (8);
4471 data += 8;
4472 offset += 9;
4473 break;
4474
4475 case DW_OP_const1s:
4476 NEED (1);
4477 // XXX value might be modified by relocation
4478 printf ("%*s[%2" PRIuMAX "] %s %" PRId8 "\n",
4479 indent, "", (uintmax_t) offset,
4480 op_name, *((int8_t *) data));
4481 ++data;
4482 --len;
4483 offset += 2;
4484 break;
4485
4486 case DW_OP_const2s:
4487 NEED (2);
4488 // XXX value might be modified by relocation
4489 printf ("%*s[%2" PRIuMAX "] %s %" PRId16 "\n",
4490 indent, "", (uintmax_t) offset,
4491 op_name, read_2sbyte_unaligned (dbg, data));
4492 CONSUME (2);
4493 data += 2;
4494 offset += 3;
4495 break;
4496
4497 case DW_OP_const4s:
4498 NEED (4);
4499 // XXX value might be modified by relocation
4500 printf ("%*s[%2" PRIuMAX "] %s %" PRId32 "\n",
4501 indent, "", (uintmax_t) offset,
4502 op_name, read_4sbyte_unaligned (dbg, data));
4503 CONSUME (4);
4504 data += 4;
4505 offset += 5;
4506 break;
4507
4508 case DW_OP_const8s:
4509 NEED (8);
4510 // XXX value might be modified by relocation
4511 printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4512 indent, "", (uintmax_t) offset,
4513 op_name, read_8sbyte_unaligned (dbg, data));
4514 CONSUME (8);
4515 data += 8;
4516 offset += 9;
4517 break;
4518
4519 case DW_OP_piece:
4520 case DW_OP_regx:
4521 case DW_OP_plus_uconst:
4522 case DW_OP_constu:;
4523 const unsigned char *start = data;
4524 uint64_t uleb;
4525 NEED (1);
4526 get_uleb128 (uleb, data, data + len);
4527 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4528 indent, "", (uintmax_t) offset, op_name, uleb);
4529 CONSUME (data - start);
4530 offset += 1 + (data - start);
4531 break;
4532
4533 case DW_OP_addrx:
4534 case DW_OP_GNU_addr_index:
4535 case DW_OP_constx:
4536 case DW_OP_GNU_const_index:;
4537 start = data;
4538 NEED (1);
4539 get_uleb128 (uleb, data, data + len);
4540 printf ("%*s[%2" PRIuMAX "] %s [%" PRIu64 "] ",
4541 indent, "", (uintmax_t) offset, op_name, uleb);
4542 CONSUME (data - start);
4543 offset += 1 + (data - start);
4544 if (get_indexed_addr (cu, uleb, &addr) != 0)
4545 printf ("???\n");
4546 else
4547 {
4548 print_dwarf_addr (dwflmod, 0, addr, addr);
4549 printf ("\n");
4550 }
4551 break;
4552
4553 case DW_OP_bit_piece:
4554 start = data;
4555 uint64_t uleb2;
4556 NEED (1);
4557 get_uleb128 (uleb, data, data + len);
4558 NEED (1);
4559 get_uleb128 (uleb2, data, data + len);
4560 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4561 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4562 CONSUME (data - start);
4563 offset += 1 + (data - start);
4564 break;
4565
4566 case DW_OP_fbreg:
4567 case DW_OP_breg0 ... DW_OP_breg31:
4568 case DW_OP_consts:
4569 start = data;
4570 int64_t sleb;
4571 NEED (1);
4572 get_sleb128 (sleb, data, data + len);
4573 printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4574 indent, "", (uintmax_t) offset, op_name, sleb);
4575 CONSUME (data - start);
4576 offset += 1 + (data - start);
4577 break;
4578
4579 case DW_OP_bregx:
4580 start = data;
4581 NEED (1);
4582 get_uleb128 (uleb, data, data + len);
4583 NEED (1);
4584 get_sleb128 (sleb, data, data + len);
4585 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4586 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4587 CONSUME (data - start);
4588 offset += 1 + (data - start);
4589 break;
4590
4591 case DW_OP_call2:
4592 NEED (2);
4593 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx16 "]\n",
4594 indent, "", (uintmax_t) offset, op_name,
4595 read_2ubyte_unaligned (dbg, data));
4596 CONSUME (2);
4597 data += 2;
4598 offset += 3;
4599 break;
4600
4601 case DW_OP_call4:
4602 NEED (4);
4603 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx32 "]\n",
4604 indent, "", (uintmax_t) offset, op_name,
4605 read_4ubyte_unaligned (dbg, data));
4606 CONSUME (4);
4607 data += 4;
4608 offset += 5;
4609 break;
4610
4611 case DW_OP_skip:
4612 case DW_OP_bra:
4613 NEED (2);
4614 printf ("%*s[%2" PRIuMAX "] %s %" PRIuMAX "\n",
4615 indent, "", (uintmax_t) offset, op_name,
4616 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4617 CONSUME (2);
4618 data += 2;
4619 offset += 3;
4620 break;
4621
4622 case DW_OP_implicit_value:
4623 start = data;
4624 NEED (1);
4625 get_uleb128 (uleb, data, data + len);
4626 printf ("%*s[%2" PRIuMAX "] %s: ",
4627 indent, "", (uintmax_t) offset, op_name);
4628 NEED (uleb);
4629 print_block (uleb, data);
4630 data += uleb;
4631 CONSUME (data - start);
4632 offset += 1 + (data - start);
4633 break;
4634
4635 case DW_OP_implicit_pointer:
4636 case DW_OP_GNU_implicit_pointer:
4637 /* DIE offset operand. */
4638 start = data;
4639 NEED (ref_size);
4640 if (ref_size != 4 && ref_size != 8)
4641 goto invalid; /* Cannot be used in CFA. */
4642 if (ref_size == 4)
4643 addr = read_4ubyte_unaligned (dbg, data);
4644 else
4645 addr = read_8ubyte_unaligned (dbg, data);
4646 data += ref_size;
4647 /* Byte offset operand. */
4648 NEED (1);
4649 get_sleb128 (sleb, data, data + len);
4650
4651 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4652 indent, "", (intmax_t) offset,
4653 op_name, (uintmax_t) addr, sleb);
4654 CONSUME (data - start);
4655 offset += 1 + (data - start);
4656 break;
4657
4658 case DW_OP_entry_value:
4659 case DW_OP_GNU_entry_value:
4660 /* Size plus expression block. */
4661 start = data;
4662 NEED (1);
4663 get_uleb128 (uleb, data, data + len);
4664 printf ("%*s[%2" PRIuMAX "] %s:\n",
4665 indent, "", (uintmax_t) offset, op_name);
4666 NEED (uleb);
4667 print_ops (dwflmod, dbg, indent + 5, indent + 5, vers,
4668 addrsize, offset_size, cu, uleb, data);
4669 data += uleb;
4670 CONSUME (data - start);
4671 offset += 1 + (data - start);
4672 break;
4673
4674 case DW_OP_const_type:
4675 case DW_OP_GNU_const_type:
4676 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4677 unsigned size plus block. */
4678 start = data;
4679 NEED (1);
4680 get_uleb128 (uleb, data, data + len);
4681 if (! print_unresolved_addresses && cu != NULL)
4682 uleb += cu->start;
4683 NEED (1);
4684 uint8_t usize = *(uint8_t *) data++;
4685 NEED (usize);
4686 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] ",
4687 indent, "", (uintmax_t) offset, op_name, uleb);
4688 print_block (usize, data);
4689 data += usize;
4690 CONSUME (data - start);
4691 offset += 1 + (data - start);
4692 break;
4693
4694 case DW_OP_regval_type:
4695 case DW_OP_GNU_regval_type:
4696 /* uleb128 register number, uleb128 CU relative
4697 DW_TAG_base_type DIE offset. */
4698 start = data;
4699 NEED (1);
4700 get_uleb128 (uleb, data, data + len);
4701 NEED (1);
4702 get_uleb128 (uleb2, data, data + len);
4703 if (! print_unresolved_addresses && cu != NULL)
4704 uleb2 += cu->start;
4705 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4706 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4707 CONSUME (data - start);
4708 offset += 1 + (data - start);
4709 break;
4710
4711 case DW_OP_deref_type:
4712 case DW_OP_GNU_deref_type:
4713 /* 1-byte unsigned size of value, uleb128 CU relative
4714 DW_TAG_base_type DIE offset. */
4715 start = data;
4716 NEED (1);
4717 usize = *(uint8_t *) data++;
4718 NEED (1);
4719 get_uleb128 (uleb, data, data + len);
4720 if (! print_unresolved_addresses && cu != NULL)
4721 uleb += cu->start;
4722 printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4723 indent, "", (uintmax_t) offset,
4724 op_name, usize, uleb);
4725 CONSUME (data - start);
4726 offset += 1 + (data - start);
4727 break;
4728
4729 case DW_OP_xderef_type:
4730 /* 1-byte unsigned size of value, uleb128 base_type DIE offset. */
4731 start = data;
4732 NEED (1);
4733 usize = *(uint8_t *) data++;
4734 NEED (1);
4735 get_uleb128 (uleb, data, data + len);
4736 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4737 indent, "", (uintmax_t) offset,
4738 op_name, usize, uleb);
4739 CONSUME (data - start);
4740 offset += 1 + (data - start);
4741 break;
4742
4743 case DW_OP_convert:
4744 case DW_OP_GNU_convert:
4745 case DW_OP_reinterpret:
4746 case DW_OP_GNU_reinterpret:
4747 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4748 for conversion to untyped. */
4749 start = data;
4750 NEED (1);
4751 get_uleb128 (uleb, data, data + len);
4752 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4753 uleb += cu->start;
4754 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4755 indent, "", (uintmax_t) offset, op_name, uleb);
4756 CONSUME (data - start);
4757 offset += 1 + (data - start);
4758 break;
4759
4760 case DW_OP_GNU_parameter_ref:
4761 /* 4 byte CU relative reference to the abstract optimized away
4762 DW_TAG_formal_parameter. */
4763 NEED (4);
4764 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4765 if (! print_unresolved_addresses && cu != NULL)
4766 param_off += cu->start;
4767 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4768 indent, "", (uintmax_t) offset, op_name, param_off);
4769 CONSUME (4);
4770 data += 4;
4771 offset += 5;
4772 break;
4773
4774 default:
4775 /* No Operand. */
4776 printf ("%*s[%2" PRIuMAX "] %s\n",
4777 indent, "", (uintmax_t) offset, op_name);
4778 ++offset;
4779 break;
4780 }
4781
4782 indent = indentrest;
4783 continue;
4784
4785 invalid:
4786 printf (gettext ("%*s[%2" PRIuMAX "] %s <TRUNCATED>\n"),
4787 indent, "", (uintmax_t) offset, op_name);
4788 break;
4789 }
4790 }
4791
4792
4793 struct listptr
4794 {
4795 Dwarf_Off offset:(64 - 3);
4796 bool addr64:1;
4797 bool dwarf64:1;
4798 bool warned:1;
4799 struct Dwarf_CU *cu;
4800 unsigned int attr;
4801 };
4802
4803 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4804 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4805
4806 static Dwarf_Addr
cudie_base(Dwarf_Die * cudie)4807 cudie_base (Dwarf_Die *cudie)
4808 {
4809 Dwarf_Addr base;
4810 /* Find the base address of the compilation unit. It will normally
4811 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4812 address could be overridden by DW_AT_entry_pc. It's been
4813 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4814 compilation units with discontinuous ranges. */
4815 if (unlikely (dwarf_lowpc (cudie, &base) != 0))
4816 {
4817 Dwarf_Attribute attr_mem;
4818 if (dwarf_formaddr (dwarf_attr (cudie, DW_AT_entry_pc, &attr_mem),
4819 &base) != 0)
4820 base = 0;
4821 }
4822 return base;
4823 }
4824
4825 static Dwarf_Addr
listptr_base(struct listptr * p)4826 listptr_base (struct listptr *p)
4827 {
4828 Dwarf_Die cu = CUDIE (p->cu);
4829 return cudie_base (&cu);
4830 }
4831
4832 static int
compare_listptr(const void * a,const void * b,void * arg)4833 compare_listptr (const void *a, const void *b, void *arg)
4834 {
4835 const char *name = arg;
4836 struct listptr *p1 = (void *) a;
4837 struct listptr *p2 = (void *) b;
4838
4839 if (p1->offset < p2->offset)
4840 return -1;
4841 if (p1->offset > p2->offset)
4842 return 1;
4843
4844 if (!p1->warned && !p2->warned)
4845 {
4846 if (p1->addr64 != p2->addr64)
4847 {
4848 p1->warned = p2->warned = true;
4849 error (0, 0,
4850 gettext ("%s %#" PRIx64 " used with different address sizes"),
4851 name, (uint64_t) p1->offset);
4852 }
4853 if (p1->dwarf64 != p2->dwarf64)
4854 {
4855 p1->warned = p2->warned = true;
4856 error (0, 0,
4857 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4858 name, (uint64_t) p1->offset);
4859 }
4860 if (listptr_base (p1) != listptr_base (p2))
4861 {
4862 p1->warned = p2->warned = true;
4863 error (0, 0,
4864 gettext ("%s %#" PRIx64 " used with different base addresses"),
4865 name, (uint64_t) p1->offset);
4866 }
4867 if (p1->attr != p2 ->attr)
4868 {
4869 p1->warned = p2->warned = true;
4870 error (0, 0,
4871 gettext ("%s %#" PRIx64
4872 " used with different attribute %s and %s"),
4873 name, (uint64_t) p1->offset, dwarf_attr_name (p2->attr),
4874 dwarf_attr_name (p2->attr));
4875 }
4876 }
4877
4878 return 0;
4879 }
4880
4881 struct listptr_table
4882 {
4883 size_t n;
4884 size_t alloc;
4885 struct listptr *table;
4886 };
4887
4888 static struct listptr_table known_locsptr;
4889 static struct listptr_table known_loclistsptr;
4890 static struct listptr_table known_rangelistptr;
4891 static struct listptr_table known_rnglistptr;
4892 static struct listptr_table known_addrbases;
4893 static struct listptr_table known_stroffbases;
4894
4895 static void
reset_listptr(struct listptr_table * table)4896 reset_listptr (struct listptr_table *table)
4897 {
4898 free (table->table);
4899 table->table = NULL;
4900 table->n = table->alloc = 0;
4901 }
4902
4903 /* Returns false if offset doesn't fit. See struct listptr. */
4904 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)4905 notice_listptr (enum section_e section, struct listptr_table *table,
4906 uint_fast8_t address_size, uint_fast8_t offset_size,
4907 struct Dwarf_CU *cu, Dwarf_Off offset, unsigned int attr)
4908 {
4909 if (print_debug_sections & section)
4910 {
4911 if (table->n == table->alloc)
4912 {
4913 if (table->alloc == 0)
4914 table->alloc = 128;
4915 else
4916 table->alloc *= 2;
4917 table->table = xrealloc (table->table,
4918 table->alloc * sizeof table->table[0]);
4919 }
4920
4921 struct listptr *p = &table->table[table->n++];
4922
4923 *p = (struct listptr)
4924 {
4925 .addr64 = address_size == 8,
4926 .dwarf64 = offset_size == 8,
4927 .offset = offset,
4928 .cu = cu,
4929 .attr = attr
4930 };
4931
4932 if (p->offset != offset)
4933 {
4934 table->n--;
4935 return false;
4936 }
4937 }
4938 return true;
4939 }
4940
4941 static void
sort_listptr(struct listptr_table * table,const char * name)4942 sort_listptr (struct listptr_table *table, const char *name)
4943 {
4944 if (table->n > 0)
4945 qsort_r (table->table, table->n, sizeof table->table[0],
4946 &compare_listptr, (void *) name);
4947 }
4948
4949 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)4950 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4951 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4952 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4953 unsigned char **readp, unsigned char *endp,
4954 unsigned int *attr)
4955 {
4956 if (table->n == 0)
4957 return false;
4958
4959 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4960 ++*idxp;
4961
4962 struct listptr *p = &table->table[*idxp];
4963
4964 if (*idxp == table->n
4965 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4966 {
4967 *readp = endp;
4968 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4969 offset);
4970 return true;
4971 }
4972
4973 if (p->offset != (Dwarf_Off) offset)
4974 {
4975 *readp += p->offset - offset;
4976 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4977 offset, (Dwarf_Off) p->offset - offset);
4978 return true;
4979 }
4980
4981 if (address_sizep != NULL)
4982 *address_sizep = listptr_address_size (p);
4983 if (offset_sizep != NULL)
4984 *offset_sizep = listptr_offset_size (p);
4985 if (base != NULL)
4986 *base = listptr_base (p);
4987 if (cu != NULL)
4988 *cu = p->cu;
4989 if (attr != NULL)
4990 *attr = p->attr;
4991
4992 return false;
4993 }
4994
4995 static Dwarf_Off
next_listptr_offset(struct listptr_table * table,size_t idx)4996 next_listptr_offset (struct listptr_table *table, size_t idx)
4997 {
4998 /* Note that multiple attributes could in theory point to the same loclist
4999 offset, so make sure we pick one that is bigger than the current one.
5000 The table is sorted on offset. */
5001 Dwarf_Off offset = table->table[idx].offset;
5002 while (++idx < table->n)
5003 {
5004 Dwarf_Off next = table->table[idx].offset;
5005 if (next > offset)
5006 return next;
5007 }
5008 return 0;
5009 }
5010
5011 /* Returns the listptr associated with the given index, or NULL. */
5012 static struct listptr *
get_listptr(struct listptr_table * table,size_t idx)5013 get_listptr (struct listptr_table *table, size_t idx)
5014 {
5015 if (idx >= table->n)
5016 return NULL;
5017 return &table->table[idx];
5018 }
5019
5020 /* Returns the next index, base address and CU associated with the
5021 list unit offsets. If there is none false is returned, otherwise
5022 true. Assumes the table has been sorted. */
5023 static bool
listptr_cu(struct listptr_table * table,size_t * idxp,Dwarf_Off start,Dwarf_Off end,Dwarf_Addr * base,struct Dwarf_CU ** cu)5024 listptr_cu (struct listptr_table *table, size_t *idxp,
5025 Dwarf_Off start, Dwarf_Off end,
5026 Dwarf_Addr *base, struct Dwarf_CU **cu)
5027 {
5028 while (*idxp < table->n
5029 && table->table[*idxp].offset < start)
5030 ++*idxp;
5031
5032 if (*idxp < table->n
5033 && table->table[*idxp].offset >= start
5034 && table->table[*idxp].offset < end)
5035 {
5036 struct listptr *p = &table->table[*idxp];
5037 *base = listptr_base (p);
5038 *cu = p->cu;
5039 ++*idxp;
5040 return true;
5041 }
5042
5043 return false;
5044 }
5045
5046 static void
print_debug_abbrev_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5047 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5048 Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
5049 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5050 {
5051 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
5052 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
5053
5054 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
5055 " [ Code]\n"),
5056 elf_ndxscn (scn), section_name (ebl, shdr),
5057 (uint64_t) shdr->sh_offset);
5058
5059 Dwarf_Off offset = 0;
5060 while (offset < sh_size)
5061 {
5062 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
5063 offset);
5064
5065 while (1)
5066 {
5067 size_t length;
5068 Dwarf_Abbrev abbrev;
5069
5070 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
5071 if (res != 0)
5072 {
5073 if (unlikely (res < 0))
5074 {
5075 printf (gettext ("\
5076 *** error while reading abbreviation: %s\n"),
5077 dwarf_errmsg (-1));
5078 return;
5079 }
5080
5081 /* This is the NUL byte at the end of the section. */
5082 ++offset;
5083 break;
5084 }
5085
5086 /* We know these calls can never fail. */
5087 unsigned int code = dwarf_getabbrevcode (&abbrev);
5088 unsigned int tag = dwarf_getabbrevtag (&abbrev);
5089 int has_children = dwarf_abbrevhaschildren (&abbrev);
5090
5091 printf (gettext (" [%5u] offset: %" PRId64
5092 ", children: %s, tag: %s\n"),
5093 code, (int64_t) offset,
5094 has_children ? yes_str : no_str,
5095 dwarf_tag_name (tag));
5096
5097 size_t cnt = 0;
5098 unsigned int name;
5099 unsigned int form;
5100 Dwarf_Sword data;
5101 Dwarf_Off enoffset;
5102 while (dwarf_getabbrevattr_data (&abbrev, cnt, &name, &form,
5103 &data, &enoffset) == 0)
5104 {
5105 printf (" attr: %s, form: %s",
5106 dwarf_attr_name (name), dwarf_form_name (form));
5107 if (form == DW_FORM_implicit_const)
5108 printf (" (%" PRId64 ")", data);
5109 printf (", offset: %#" PRIx64 "\n", (uint64_t) enoffset);
5110 ++cnt;
5111 }
5112
5113 offset += length;
5114 }
5115 }
5116 }
5117
5118
5119 static void
print_debug_addr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5120 print_debug_addr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5121 Ebl *ebl, GElf_Ehdr *ehdr,
5122 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5123 {
5124 printf (gettext ("\
5125 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5126 elf_ndxscn (scn), section_name (ebl, shdr),
5127 (uint64_t) shdr->sh_offset);
5128
5129 if (shdr->sh_size == 0)
5130 return;
5131
5132 /* We like to get the section from libdw to make sure they are relocated. */
5133 Elf_Data *data = (dbg->sectiondata[IDX_debug_addr]
5134 ?: elf_rawdata (scn, NULL));
5135 if (unlikely (data == NULL))
5136 {
5137 error (0, 0, gettext ("cannot get .debug_addr section data: %s"),
5138 elf_errmsg (-1));
5139 return;
5140 }
5141
5142 size_t idx = 0;
5143 sort_listptr (&known_addrbases, "addr_base");
5144
5145 const unsigned char *start = (const unsigned char *) data->d_buf;
5146 const unsigned char *readp = start;
5147 const unsigned char *readendp = ((const unsigned char *) data->d_buf
5148 + data->d_size);
5149
5150 while (readp < readendp)
5151 {
5152 /* We cannot really know whether or not there is an header. The
5153 DebugFission extension to DWARF4 doesn't add one. The DWARF5
5154 .debug_addr variant does. Whether or not we have an header,
5155 DW_AT_[GNU_]addr_base points at "index 0". So if the current
5156 offset equals the CU addr_base then we can just start
5157 printing addresses. If there is no CU with an exact match
5158 then we'll try to parse the header first. */
5159 Dwarf_Off off = (Dwarf_Off) (readp
5160 - (const unsigned char *) data->d_buf);
5161
5162 printf ("Table at offset %" PRIx64 " ", off);
5163
5164 struct listptr *listptr = get_listptr (&known_addrbases, idx++);
5165 const unsigned char *next_unitp;
5166
5167 uint64_t unit_length;
5168 uint16_t version;
5169 uint8_t address_size;
5170 uint8_t segment_size;
5171 if (listptr == NULL)
5172 {
5173 error (0, 0, "Warning: No CU references .debug_addr after %" PRIx64,
5174 off);
5175
5176 /* We will have to assume it is just addresses to the end... */
5177 address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5178 next_unitp = readendp;
5179 printf ("Unknown CU:\n");
5180 }
5181 else
5182 {
5183 Dwarf_Die cudie;
5184 if (dwarf_cu_die (listptr->cu, &cudie,
5185 NULL, NULL, NULL, NULL,
5186 NULL, NULL) == NULL)
5187 printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
5188 else
5189 printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
5190
5191 if (listptr->offset == off)
5192 {
5193 address_size = listptr_address_size (listptr);
5194 segment_size = 0;
5195 version = 4;
5196
5197 /* The addresses start here, but where do they end? */
5198 listptr = get_listptr (&known_addrbases, idx);
5199 if (listptr == NULL)
5200 next_unitp = readendp;
5201 else if (listptr->cu->version < 5)
5202 {
5203 next_unitp = start + listptr->offset;
5204 if (listptr->offset < off || listptr->offset > data->d_size)
5205 {
5206 error (0, 0,
5207 "Warning: Bad address base for next unit at %"
5208 PRIx64, off);
5209 next_unitp = readendp;
5210 }
5211 }
5212 else
5213 {
5214 /* Tricky, we don't have a header for this unit, but
5215 there is one for the next. We will have to
5216 "guess" how big it is and subtract it from the
5217 offset (because that points after the header). */
5218 unsigned int offset_size = listptr_offset_size (listptr);
5219 Dwarf_Off next_off = (listptr->offset
5220 - (offset_size == 4 ? 4 : 12) /* len */
5221 - 2 /* version */
5222 - 1 /* address size */
5223 - 1); /* segment selector size */
5224 next_unitp = start + next_off;
5225 if (next_off < off || next_off > data->d_size)
5226 {
5227 error (0, 0,
5228 "Warning: Couldn't calculate .debug_addr "
5229 " unit lenght at %" PRIx64, off);
5230 next_unitp = readendp;
5231 }
5232 }
5233 unit_length = (uint64_t) (next_unitp - readp);
5234
5235 /* Pretend we have a header. */
5236 printf ("\n");
5237 printf (gettext (" Length: %8" PRIu64 "\n"),
5238 unit_length);
5239 printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
5240 printf (gettext (" Address size: %8" PRIu64 "\n"),
5241 (uint64_t) address_size);
5242 printf (gettext (" Segment size: %8" PRIu64 "\n"),
5243 (uint64_t) segment_size);
5244 printf ("\n");
5245 }
5246 else
5247 {
5248 /* OK, we have to parse an header first. */
5249 unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5250 if (unlikely (unit_length == 0xffffffff))
5251 {
5252 if (unlikely (readp > readendp - 8))
5253 {
5254 invalid_data:
5255 error (0, 0, "Invalid data");
5256 return;
5257 }
5258 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5259 }
5260 printf ("\n");
5261 printf (gettext (" Length: %8" PRIu64 "\n"),
5262 unit_length);
5263
5264 /* We need at least 2-bytes (version) + 1-byte
5265 (addr_size) + 1-byte (segment_size) = 4 bytes to
5266 complete the header. And this unit cannot go beyond
5267 the section data. */
5268 if (readp > readendp - 4
5269 || unit_length < 4
5270 || unit_length > (uint64_t) (readendp - readp))
5271 goto invalid_data;
5272
5273 next_unitp = readp + unit_length;
5274
5275 version = read_2ubyte_unaligned_inc (dbg, readp);
5276 printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
5277
5278 if (version != 5)
5279 {
5280 error (0, 0, gettext ("Unknown version"));
5281 goto next_unit;
5282 }
5283
5284 address_size = *readp++;
5285 printf (gettext (" Address size: %8" PRIu64 "\n"),
5286 (uint64_t) address_size);
5287
5288 if (address_size != 4 && address_size != 8)
5289 {
5290 error (0, 0, gettext ("unsupported address size"));
5291 goto next_unit;
5292 }
5293
5294 segment_size = *readp++;
5295 printf (gettext (" Segment size: %8" PRIu64 "\n"),
5296 (uint64_t) segment_size);
5297 printf ("\n");
5298
5299 if (segment_size != 0)
5300 {
5301 error (0, 0, gettext ("unsupported segment size"));
5302 goto next_unit;
5303 }
5304
5305 if (listptr->offset != (Dwarf_Off) (readp - start))
5306 {
5307 error (0, 0, "Address index doesn't start after header");
5308 goto next_unit;
5309 }
5310 }
5311 }
5312
5313 int digits = 1;
5314 size_t addresses = (next_unitp - readp) / address_size;
5315 while (addresses >= 10)
5316 {
5317 ++digits;
5318 addresses /= 10;
5319 }
5320
5321 unsigned int uidx = 0;
5322 size_t index_offset = readp - (const unsigned char *) data->d_buf;
5323 printf (" Addresses start at offset 0x%zx:\n", index_offset);
5324 while (readp <= next_unitp - address_size)
5325 {
5326 Dwarf_Addr addr = read_addr_unaligned_inc (address_size, dbg,
5327 readp);
5328 printf (" [%*u] ", digits, uidx++);
5329 print_dwarf_addr (dwflmod, address_size, addr, addr);
5330 printf ("\n");
5331 }
5332 printf ("\n");
5333
5334 if (readp != next_unitp)
5335 error (0, 0, "extra %zd bytes at end of unit",
5336 (size_t) (next_unitp - readp));
5337
5338 next_unit:
5339 readp = next_unitp;
5340 }
5341 }
5342
5343 /* Print content of DWARF .debug_aranges section. We fortunately do
5344 not have to know a bit about the structure of the section, libdwarf
5345 takes care of it. */
5346 static void
print_decoded_aranges_section(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5347 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5348 GElf_Shdr *shdr, Dwarf *dbg)
5349 {
5350 Dwarf_Aranges *aranges;
5351 size_t cnt;
5352 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
5353 {
5354 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
5355 dwarf_errmsg (-1));
5356 return;
5357 }
5358
5359 GElf_Shdr glink_mem;
5360 GElf_Shdr *glink;
5361 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
5362 if (glink == NULL)
5363 {
5364 error (0, 0, gettext ("invalid sh_link value in section %zu"),
5365 elf_ndxscn (scn));
5366 return;
5367 }
5368
5369 printf (ngettext ("\
5370 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
5371 "\
5372 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
5373 cnt),
5374 elf_ndxscn (scn), section_name (ebl, shdr),
5375 (uint64_t) shdr->sh_offset, cnt);
5376
5377 /* Compute floor(log16(cnt)). */
5378 size_t tmp = cnt;
5379 int digits = 1;
5380 while (tmp >= 16)
5381 {
5382 ++digits;
5383 tmp >>= 4;
5384 }
5385
5386 for (size_t n = 0; n < cnt; ++n)
5387 {
5388 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
5389 if (unlikely (runp == NULL))
5390 {
5391 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
5392 return;
5393 }
5394
5395 Dwarf_Addr start;
5396 Dwarf_Word length;
5397 Dwarf_Off offset;
5398
5399 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
5400 printf (gettext (" [%*zu] ???\n"), digits, n);
5401 else
5402 printf (gettext (" [%*zu] start: %0#*" PRIx64
5403 ", length: %5" PRIu64 ", CU DIE offset: %6"
5404 PRId64 "\n"),
5405 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
5406 (uint64_t) start, (uint64_t) length, (int64_t) offset);
5407 }
5408 }
5409
5410
5411 /* Print content of DWARF .debug_aranges section. */
5412 static void
print_debug_aranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5413 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5414 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5415 GElf_Shdr *shdr, Dwarf *dbg)
5416 {
5417 if (decodedaranges)
5418 {
5419 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
5420 return;
5421 }
5422
5423 Elf_Data *data = (dbg->sectiondata[IDX_debug_aranges]
5424 ?: elf_rawdata (scn, NULL));
5425
5426 if (unlikely (data == NULL))
5427 {
5428 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
5429 elf_errmsg (-1));
5430 return;
5431 }
5432
5433 printf (gettext ("\
5434 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5435 elf_ndxscn (scn), section_name (ebl, shdr),
5436 (uint64_t) shdr->sh_offset);
5437
5438 const unsigned char *readp = data->d_buf;
5439 const unsigned char *readendp = readp + data->d_size;
5440
5441 while (readp < readendp)
5442 {
5443 const unsigned char *hdrstart = readp;
5444 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
5445
5446 printf (gettext ("\nTable at offset %zu:\n"), start_offset);
5447 if (readp + 4 > readendp)
5448 {
5449 invalid_data:
5450 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5451 elf_ndxscn (scn), section_name (ebl, shdr));
5452 return;
5453 }
5454
5455 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
5456 unsigned int length_bytes = 4;
5457 if (length == DWARF3_LENGTH_64_BIT)
5458 {
5459 if (readp + 8 > readendp)
5460 goto invalid_data;
5461 length = read_8ubyte_unaligned_inc (dbg, readp);
5462 length_bytes = 8;
5463 }
5464
5465 const unsigned char *nexthdr = readp + length;
5466 printf (gettext ("\n Length: %6" PRIu64 "\n"),
5467 (uint64_t) length);
5468
5469 if (unlikely (length > (size_t) (readendp - readp)))
5470 goto invalid_data;
5471
5472 if (length == 0)
5473 continue;
5474
5475 if (readp + 2 > readendp)
5476 goto invalid_data;
5477 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5478 printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
5479 version);
5480 if (version != 2)
5481 {
5482 error (0, 0, gettext ("unsupported aranges version"));
5483 goto next_table;
5484 }
5485
5486 Dwarf_Word offset;
5487 if (readp + length_bytes > readendp)
5488 goto invalid_data;
5489 if (length_bytes == 8)
5490 offset = read_8ubyte_unaligned_inc (dbg, readp);
5491 else
5492 offset = read_4ubyte_unaligned_inc (dbg, readp);
5493 printf (gettext (" CU offset: %6" PRIx64 "\n"),
5494 (uint64_t) offset);
5495
5496 if (readp + 1 > readendp)
5497 goto invalid_data;
5498 unsigned int address_size = *readp++;
5499 printf (gettext (" Address size: %6" PRIu64 "\n"),
5500 (uint64_t) address_size);
5501 if (address_size != 4 && address_size != 8)
5502 {
5503 error (0, 0, gettext ("unsupported address size"));
5504 goto next_table;
5505 }
5506
5507 if (readp + 1 > readendp)
5508 goto invalid_data;
5509 unsigned int segment_size = *readp++;
5510 printf (gettext (" Segment size: %6" PRIu64 "\n\n"),
5511 (uint64_t) segment_size);
5512 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5513 {
5514 error (0, 0, gettext ("unsupported segment size"));
5515 goto next_table;
5516 }
5517
5518 /* Round the address to the next multiple of 2*address_size. */
5519 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
5520 % (2 * address_size));
5521
5522 while (readp < nexthdr)
5523 {
5524 Dwarf_Word range_address;
5525 Dwarf_Word range_length;
5526 Dwarf_Word segment = 0;
5527 if (readp + 2 * address_size + segment_size > readendp)
5528 goto invalid_data;
5529 if (address_size == 4)
5530 {
5531 range_address = read_4ubyte_unaligned_inc (dbg, readp);
5532 range_length = read_4ubyte_unaligned_inc (dbg, readp);
5533 }
5534 else
5535 {
5536 range_address = read_8ubyte_unaligned_inc (dbg, readp);
5537 range_length = read_8ubyte_unaligned_inc (dbg, readp);
5538 }
5539
5540 if (segment_size == 4)
5541 segment = read_4ubyte_unaligned_inc (dbg, readp);
5542 else if (segment_size == 8)
5543 segment = read_8ubyte_unaligned_inc (dbg, readp);
5544
5545 if (range_address == 0 && range_length == 0 && segment == 0)
5546 break;
5547
5548 printf (" ");
5549 print_dwarf_addr (dwflmod, address_size, range_address,
5550 range_address);
5551 printf ("..");
5552 print_dwarf_addr (dwflmod, address_size,
5553 range_address + range_length - 1,
5554 range_length);
5555 if (segment_size != 0)
5556 printf (" (%" PRIx64 ")\n", (uint64_t) segment);
5557 else
5558 printf ("\n");
5559 }
5560
5561 next_table:
5562 if (readp != nexthdr)
5563 {
5564 size_t padding = nexthdr - readp;
5565 printf (gettext (" %zu padding bytes\n"), padding);
5566 readp = nexthdr;
5567 }
5568 }
5569 }
5570
5571
5572 static bool is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu);
5573
5574 /* Returns true and sets cu and cu_base if the given Dwarf is a split
5575 DWARF (.dwo) file. */
5576 static bool
split_dwarf_cu_base(Dwarf * dbg,Dwarf_CU ** cu,Dwarf_Addr * cu_base)5577 split_dwarf_cu_base (Dwarf *dbg, Dwarf_CU **cu, Dwarf_Addr *cu_base)
5578 {
5579 uint64_t id;
5580 if (is_split_dwarf (dbg, &id, cu))
5581 {
5582 Dwarf_Die cudie;
5583 if (dwarf_cu_info (*cu, NULL, NULL, &cudie, NULL, NULL, NULL, NULL) == 0)
5584 {
5585 *cu_base = cudie_base (&cudie);
5586 return true;
5587 }
5588 }
5589 return false;
5590 }
5591
5592 /* Print content of DWARF .debug_rnglists section. */
5593 static void
print_debug_rnglists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5594 print_debug_rnglists_section (Dwfl_Module *dwflmod,
5595 Ebl *ebl,
5596 GElf_Ehdr *ehdr __attribute__ ((unused)),
5597 Elf_Scn *scn, GElf_Shdr *shdr,
5598 Dwarf *dbg __attribute__((unused)))
5599 {
5600 printf (gettext ("\
5601 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5602 elf_ndxscn (scn), section_name (ebl, shdr),
5603 (uint64_t) shdr->sh_offset);
5604
5605 Elf_Data *data =(dbg->sectiondata[IDX_debug_rnglists]
5606 ?: elf_rawdata (scn, NULL));
5607 if (unlikely (data == NULL))
5608 {
5609 error (0, 0, gettext ("cannot get .debug_rnglists content: %s"),
5610 elf_errmsg (-1));
5611 return;
5612 }
5613
5614 /* For the listptr to get the base address/CU. */
5615 sort_listptr (&known_rnglistptr, "rnglistptr");
5616 size_t listptr_idx = 0;
5617
5618 const unsigned char *readp = data->d_buf;
5619 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5620 + data->d_size);
5621 while (readp < dataend)
5622 {
5623 if (unlikely (readp > dataend - 4))
5624 {
5625 invalid_data:
5626 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5627 elf_ndxscn (scn), section_name (ebl, shdr));
5628 return;
5629 }
5630
5631 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5632 printf (gettext ("Table at Offset 0x%" PRIx64 ":\n\n"),
5633 (uint64_t) offset);
5634
5635 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5636 unsigned int offset_size = 4;
5637 if (unlikely (unit_length == 0xffffffff))
5638 {
5639 if (unlikely (readp > dataend - 8))
5640 goto invalid_data;
5641
5642 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5643 offset_size = 8;
5644 }
5645 printf (gettext (" Length: %8" PRIu64 "\n"), unit_length);
5646
5647 /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
5648 bytes to complete the header. And this unit cannot go beyond
5649 the section data. */
5650 if (readp > dataend - 8
5651 || unit_length < 8
5652 || unit_length > (uint64_t) (dataend - readp))
5653 goto invalid_data;
5654
5655 const unsigned char *nexthdr = readp + unit_length;
5656
5657 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5658 printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
5659
5660 if (version != 5)
5661 {
5662 error (0, 0, gettext ("Unknown version"));
5663 goto next_table;
5664 }
5665
5666 uint8_t address_size = *readp++;
5667 printf (gettext (" Address size: %8" PRIu64 "\n"),
5668 (uint64_t) address_size);
5669
5670 if (address_size != 4 && address_size != 8)
5671 {
5672 error (0, 0, gettext ("unsupported address size"));
5673 goto next_table;
5674 }
5675
5676 uint8_t segment_size = *readp++;
5677 printf (gettext (" Segment size: %8" PRIu64 "\n"),
5678 (uint64_t) segment_size);
5679
5680 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5681 {
5682 error (0, 0, gettext ("unsupported segment size"));
5683 goto next_table;
5684 }
5685
5686 uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
5687 printf (gettext (" Offset entries: %8" PRIu64 "\n"),
5688 (uint64_t) offset_entry_count);
5689
5690 /* We need the CU that uses this unit to get the initial base address. */
5691 Dwarf_Addr cu_base = 0;
5692 struct Dwarf_CU *cu = NULL;
5693 if (listptr_cu (&known_rnglistptr, &listptr_idx,
5694 (Dwarf_Off) offset,
5695 (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
5696 &cu_base, &cu)
5697 || split_dwarf_cu_base (dbg, &cu, &cu_base))
5698 {
5699 Dwarf_Die cudie;
5700 if (dwarf_cu_die (cu, &cudie,
5701 NULL, NULL, NULL, NULL,
5702 NULL, NULL) == NULL)
5703 printf (gettext (" Unknown CU base: "));
5704 else
5705 printf (gettext (" CU [%6" PRIx64 "] base: "),
5706 dwarf_dieoffset (&cudie));
5707 print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
5708 printf ("\n");
5709 }
5710 else
5711 printf (gettext (" Not associated with a CU.\n"));
5712
5713 printf ("\n");
5714
5715 const unsigned char *offset_array_start = readp;
5716 if (offset_entry_count > 0)
5717 {
5718 uint64_t max_entries = (unit_length - 8) / offset_size;
5719 if (offset_entry_count > max_entries)
5720 {
5721 error (0, 0,
5722 gettext ("too many offset entries for unit length"));
5723 offset_entry_count = max_entries;
5724 }
5725
5726 printf (gettext (" Offsets starting at 0x%" PRIx64 ":\n"),
5727 (uint64_t) (offset_array_start
5728 - (unsigned char *) data->d_buf));
5729 for (uint32_t idx = 0; idx < offset_entry_count; idx++)
5730 {
5731 printf (" [%6" PRIu32 "] ", idx);
5732 if (offset_size == 4)
5733 {
5734 uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
5735 printf ("0x%" PRIx32 "\n", off);
5736 }
5737 else
5738 {
5739 uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
5740 printf ("0x%" PRIx64 "\n", off);
5741 }
5742 }
5743 printf ("\n");
5744 }
5745
5746 Dwarf_Addr base = cu_base;
5747 bool start_of_list = true;
5748 while (readp < nexthdr)
5749 {
5750 uint8_t kind = *readp++;
5751 uint64_t op1, op2;
5752
5753 /* Skip padding. */
5754 if (start_of_list && kind == DW_RLE_end_of_list)
5755 continue;
5756
5757 if (start_of_list)
5758 {
5759 base = cu_base;
5760 printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
5761 (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
5762 (uint64_t) (readp - offset_array_start - 1));
5763 start_of_list = false;
5764 }
5765
5766 printf (" %s", dwarf_range_list_encoding_name (kind));
5767 switch (kind)
5768 {
5769 case DW_RLE_end_of_list:
5770 start_of_list = true;
5771 printf ("\n\n");
5772 break;
5773
5774 case DW_RLE_base_addressx:
5775 if ((uint64_t) (nexthdr - readp) < 1)
5776 {
5777 invalid_range:
5778 error (0, 0, gettext ("invalid range list data"));
5779 goto next_table;
5780 }
5781 get_uleb128 (op1, readp, nexthdr);
5782 printf (" %" PRIx64 "\n", op1);
5783 if (! print_unresolved_addresses)
5784 {
5785 Dwarf_Addr addr;
5786 if (get_indexed_addr (cu, op1, &addr) != 0)
5787 printf (" ???\n");
5788 else
5789 {
5790 printf (" ");
5791 print_dwarf_addr (dwflmod, address_size, addr, addr);
5792 printf ("\n");
5793 }
5794 }
5795 break;
5796
5797 case DW_RLE_startx_endx:
5798 if ((uint64_t) (nexthdr - readp) < 1)
5799 goto invalid_range;
5800 get_uleb128 (op1, readp, nexthdr);
5801 if ((uint64_t) (nexthdr - readp) < 1)
5802 goto invalid_range;
5803 get_uleb128 (op2, readp, nexthdr);
5804 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5805 if (! print_unresolved_addresses)
5806 {
5807 Dwarf_Addr addr1;
5808 Dwarf_Addr addr2;
5809 if (get_indexed_addr (cu, op1, &addr1) != 0
5810 || get_indexed_addr (cu, op2, &addr2) != 0)
5811 {
5812 printf (" ???..\n");
5813 printf (" ???\n");
5814 }
5815 else
5816 {
5817 printf (" ");
5818 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
5819 printf ("..\n ");
5820 print_dwarf_addr (dwflmod, address_size,
5821 addr2 - 1, addr2);
5822 printf ("\n");
5823 }
5824 }
5825 break;
5826
5827 case DW_RLE_startx_length:
5828 if ((uint64_t) (nexthdr - readp) < 1)
5829 goto invalid_range;
5830 get_uleb128 (op1, readp, nexthdr);
5831 if ((uint64_t) (nexthdr - readp) < 1)
5832 goto invalid_range;
5833 get_uleb128 (op2, readp, nexthdr);
5834 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5835 if (! print_unresolved_addresses)
5836 {
5837 Dwarf_Addr addr1;
5838 Dwarf_Addr addr2;
5839 if (get_indexed_addr (cu, op1, &addr1) != 0)
5840 {
5841 printf (" ???..\n");
5842 printf (" ???\n");
5843 }
5844 else
5845 {
5846 addr2 = addr1 + op2;
5847 printf (" ");
5848 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
5849 printf ("..\n ");
5850 print_dwarf_addr (dwflmod, address_size,
5851 addr2 - 1, addr2);
5852 printf ("\n");
5853 }
5854 }
5855 break;
5856
5857 case DW_RLE_offset_pair:
5858 if ((uint64_t) (nexthdr - readp) < 1)
5859 goto invalid_range;
5860 get_uleb128 (op1, readp, nexthdr);
5861 if ((uint64_t) (nexthdr - readp) < 1)
5862 goto invalid_range;
5863 get_uleb128 (op2, readp, nexthdr);
5864 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5865 if (! print_unresolved_addresses)
5866 {
5867 op1 += base;
5868 op2 += base;
5869 printf (" ");
5870 print_dwarf_addr (dwflmod, address_size, op1, op1);
5871 printf ("..\n ");
5872 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5873 printf ("\n");
5874 }
5875 break;
5876
5877 case DW_RLE_base_address:
5878 if (address_size == 4)
5879 {
5880 if ((uint64_t) (nexthdr - readp) < 4)
5881 goto invalid_range;
5882 op1 = read_4ubyte_unaligned_inc (dbg, readp);
5883 }
5884 else
5885 {
5886 if ((uint64_t) (nexthdr - readp) < 8)
5887 goto invalid_range;
5888 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5889 }
5890 base = op1;
5891 printf (" 0x%" PRIx64 "\n", base);
5892 if (! print_unresolved_addresses)
5893 {
5894 printf (" ");
5895 print_dwarf_addr (dwflmod, address_size, base, base);
5896 printf ("\n");
5897 }
5898 break;
5899
5900 case DW_RLE_start_end:
5901 if (address_size == 4)
5902 {
5903 if ((uint64_t) (nexthdr - readp) < 8)
5904 goto invalid_range;
5905 op1 = read_4ubyte_unaligned_inc (dbg, readp);
5906 op2 = read_4ubyte_unaligned_inc (dbg, readp);
5907 }
5908 else
5909 {
5910 if ((uint64_t) (nexthdr - readp) < 16)
5911 goto invalid_range;
5912 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5913 op2 = read_8ubyte_unaligned_inc (dbg, readp);
5914 }
5915 printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
5916 if (! print_unresolved_addresses)
5917 {
5918 printf (" ");
5919 print_dwarf_addr (dwflmod, address_size, op1, op1);
5920 printf ("..\n ");
5921 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5922 printf ("\n");
5923 }
5924 break;
5925
5926 case DW_RLE_start_length:
5927 if (address_size == 4)
5928 {
5929 if ((uint64_t) (nexthdr - readp) < 4)
5930 goto invalid_range;
5931 op1 = read_4ubyte_unaligned_inc (dbg, readp);
5932 }
5933 else
5934 {
5935 if ((uint64_t) (nexthdr - readp) < 8)
5936 goto invalid_range;
5937 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5938 }
5939 if ((uint64_t) (nexthdr - readp) < 1)
5940 goto invalid_range;
5941 get_uleb128 (op2, readp, nexthdr);
5942 printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
5943 if (! print_unresolved_addresses)
5944 {
5945 op2 = op1 + op2;
5946 printf (" ");
5947 print_dwarf_addr (dwflmod, address_size, op1, op1);
5948 printf ("..\n ");
5949 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5950 printf ("\n");
5951 }
5952 break;
5953
5954 default:
5955 goto invalid_range;
5956 }
5957 }
5958
5959 next_table:
5960 if (readp != nexthdr)
5961 {
5962 size_t padding = nexthdr - readp;
5963 printf (gettext (" %zu padding bytes\n\n"), padding);
5964 readp = nexthdr;
5965 }
5966 }
5967 }
5968
5969 /* Print content of DWARF .debug_ranges section. */
5970 static void
print_debug_ranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5971 print_debug_ranges_section (Dwfl_Module *dwflmod,
5972 Ebl *ebl, GElf_Ehdr *ehdr,
5973 Elf_Scn *scn, GElf_Shdr *shdr,
5974 Dwarf *dbg)
5975 {
5976 Elf_Data *data = (dbg->sectiondata[IDX_debug_ranges]
5977 ?: elf_rawdata (scn, NULL));
5978 if (unlikely (data == NULL))
5979 {
5980 error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
5981 elf_errmsg (-1));
5982 return;
5983 }
5984
5985 printf (gettext ("\
5986 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5987 elf_ndxscn (scn), section_name (ebl, shdr),
5988 (uint64_t) shdr->sh_offset);
5989
5990 sort_listptr (&known_rangelistptr, "rangelistptr");
5991 size_t listptr_idx = 0;
5992
5993 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5994
5995 bool first = true;
5996 Dwarf_Addr base = 0;
5997 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
5998 unsigned char *readp = data->d_buf;
5999 Dwarf_CU *last_cu = NULL;
6000 while (readp < endp)
6001 {
6002 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6003 Dwarf_CU *cu = last_cu;
6004
6005 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
6006 &address_size, NULL, &base, &cu,
6007 offset, &readp, endp, NULL))
6008 continue;
6009
6010 if (last_cu != cu)
6011 {
6012 Dwarf_Die cudie;
6013 if (dwarf_cu_die (cu, &cudie,
6014 NULL, NULL, NULL, NULL,
6015 NULL, NULL) == NULL)
6016 printf (gettext ("\n Unknown CU base: "));
6017 else
6018 printf (gettext ("\n CU [%6" PRIx64 "] base: "),
6019 dwarf_dieoffset (&cudie));
6020 print_dwarf_addr (dwflmod, address_size, base, base);
6021 printf ("\n");
6022 }
6023 last_cu = cu;
6024
6025 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6026 {
6027 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
6028 break;
6029 }
6030
6031 Dwarf_Addr begin;
6032 Dwarf_Addr end;
6033 if (address_size == 8)
6034 {
6035 begin = read_8ubyte_unaligned_inc (dbg, readp);
6036 end = read_8ubyte_unaligned_inc (dbg, readp);
6037 }
6038 else
6039 {
6040 begin = read_4ubyte_unaligned_inc (dbg, readp);
6041 end = read_4ubyte_unaligned_inc (dbg, readp);
6042 if (begin == (Dwarf_Addr) (uint32_t) -1)
6043 begin = (Dwarf_Addr) -1l;
6044 }
6045
6046 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
6047 {
6048 printf (gettext (" [%6tx] base address\n "), offset);
6049 print_dwarf_addr (dwflmod, address_size, end, end);
6050 printf ("\n");
6051 base = end;
6052 }
6053 else if (begin == 0 && end == 0) /* End of list entry. */
6054 {
6055 if (first)
6056 printf (gettext (" [%6tx] empty list\n"), offset);
6057 first = true;
6058 }
6059 else
6060 {
6061 /* We have an address range entry. */
6062 if (first) /* First address range entry in a list. */
6063 printf (" [%6tx] ", offset);
6064 else
6065 printf (" ");
6066
6067 printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
6068 if (! print_unresolved_addresses)
6069 {
6070 printf (" ");
6071 print_dwarf_addr (dwflmod, address_size, base + begin,
6072 base + begin);
6073 printf ("..\n ");
6074 print_dwarf_addr (dwflmod, address_size,
6075 base + end - 1, base + end);
6076 printf ("\n");
6077 }
6078
6079 first = false;
6080 }
6081 }
6082 }
6083
6084 #define REGNAMESZ 16
6085 static const char *
register_info(Ebl * ebl,unsigned int regno,const Ebl_Register_Location * loc,char name[REGNAMESZ],int * bits,int * type)6086 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
6087 char name[REGNAMESZ], int *bits, int *type)
6088 {
6089 const char *set;
6090 const char *pfx;
6091 int ignore;
6092 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
6093 bits ?: &ignore, type ?: &ignore);
6094 if (n <= 0)
6095 {
6096 if (loc != NULL)
6097 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
6098 else
6099 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
6100 if (bits != NULL)
6101 *bits = loc != NULL ? loc->bits : 0;
6102 if (type != NULL)
6103 *type = DW_ATE_unsigned;
6104 set = "??? unrecognized";
6105 }
6106 else
6107 {
6108 if (bits != NULL && *bits <= 0)
6109 *bits = loc != NULL ? loc->bits : 0;
6110 if (type != NULL && *type == DW_ATE_void)
6111 *type = DW_ATE_unsigned;
6112
6113 }
6114 return set;
6115 }
6116
6117 static const unsigned char *
read_encoded(unsigned int encoding,const unsigned char * readp,const unsigned char * const endp,uint64_t * res,Dwarf * dbg)6118 read_encoded (unsigned int encoding, const unsigned char *readp,
6119 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
6120 {
6121 if ((encoding & 0xf) == DW_EH_PE_absptr)
6122 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
6123 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
6124
6125 switch (encoding & 0xf)
6126 {
6127 case DW_EH_PE_uleb128:
6128 get_uleb128 (*res, readp, endp);
6129 break;
6130 case DW_EH_PE_sleb128:
6131 get_sleb128 (*res, readp, endp);
6132 break;
6133 case DW_EH_PE_udata2:
6134 if (readp + 2 > endp)
6135 goto invalid;
6136 *res = read_2ubyte_unaligned_inc (dbg, readp);
6137 break;
6138 case DW_EH_PE_udata4:
6139 if (readp + 4 > endp)
6140 goto invalid;
6141 *res = read_4ubyte_unaligned_inc (dbg, readp);
6142 break;
6143 case DW_EH_PE_udata8:
6144 if (readp + 8 > endp)
6145 goto invalid;
6146 *res = read_8ubyte_unaligned_inc (dbg, readp);
6147 break;
6148 case DW_EH_PE_sdata2:
6149 if (readp + 2 > endp)
6150 goto invalid;
6151 *res = read_2sbyte_unaligned_inc (dbg, readp);
6152 break;
6153 case DW_EH_PE_sdata4:
6154 if (readp + 4 > endp)
6155 goto invalid;
6156 *res = read_4sbyte_unaligned_inc (dbg, readp);
6157 break;
6158 case DW_EH_PE_sdata8:
6159 if (readp + 8 > endp)
6160 goto invalid;
6161 *res = read_8sbyte_unaligned_inc (dbg, readp);
6162 break;
6163 default:
6164 invalid:
6165 error (1, 0,
6166 gettext ("invalid encoding"));
6167 }
6168
6169 return readp;
6170 }
6171
6172
6173 static void
print_cfa_program(const unsigned char * readp,const unsigned char * const endp,Dwarf_Word vma_base,unsigned int code_align,int data_align,unsigned int version,unsigned int ptr_size,unsigned int encoding,Dwfl_Module * dwflmod,Ebl * ebl,Dwarf * dbg)6174 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
6175 Dwarf_Word vma_base, unsigned int code_align,
6176 int data_align,
6177 unsigned int version, unsigned int ptr_size,
6178 unsigned int encoding,
6179 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
6180 {
6181 char regnamebuf[REGNAMESZ];
6182 const char *regname (unsigned int regno)
6183 {
6184 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
6185 return regnamebuf;
6186 }
6187
6188 puts ("\n Program:");
6189 Dwarf_Word pc = vma_base;
6190 while (readp < endp)
6191 {
6192 unsigned int opcode = *readp++;
6193
6194 if (opcode < DW_CFA_advance_loc)
6195 /* Extended opcode. */
6196 switch (opcode)
6197 {
6198 uint64_t op1;
6199 int64_t sop1;
6200 uint64_t op2;
6201 int64_t sop2;
6202
6203 case DW_CFA_nop:
6204 puts (" nop");
6205 break;
6206 case DW_CFA_set_loc:
6207 if ((uint64_t) (endp - readp) < 1)
6208 goto invalid;
6209 readp = read_encoded (encoding, readp, endp, &op1, dbg);
6210 printf (" set_loc %#" PRIx64 " to %#" PRIx64 "\n",
6211 op1, pc = vma_base + op1);
6212 break;
6213 case DW_CFA_advance_loc1:
6214 if ((uint64_t) (endp - readp) < 1)
6215 goto invalid;
6216 printf (" advance_loc1 %u to %#" PRIx64 "\n",
6217 *readp, pc += *readp * code_align);
6218 ++readp;
6219 break;
6220 case DW_CFA_advance_loc2:
6221 if ((uint64_t) (endp - readp) < 2)
6222 goto invalid;
6223 op1 = read_2ubyte_unaligned_inc (dbg, readp);
6224 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
6225 op1, pc += op1 * code_align);
6226 break;
6227 case DW_CFA_advance_loc4:
6228 if ((uint64_t) (endp - readp) < 4)
6229 goto invalid;
6230 op1 = read_4ubyte_unaligned_inc (dbg, readp);
6231 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
6232 op1, pc += op1 * code_align);
6233 break;
6234 case DW_CFA_offset_extended:
6235 if ((uint64_t) (endp - readp) < 1)
6236 goto invalid;
6237 get_uleb128 (op1, readp, endp);
6238 if ((uint64_t) (endp - readp) < 1)
6239 goto invalid;
6240 get_uleb128 (op2, readp, endp);
6241 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
6242 "\n",
6243 op1, regname (op1), op2 * data_align);
6244 break;
6245 case DW_CFA_restore_extended:
6246 if ((uint64_t) (endp - readp) < 1)
6247 goto invalid;
6248 get_uleb128 (op1, readp, endp);
6249 printf (" restore_extended r%" PRIu64 " (%s)\n",
6250 op1, regname (op1));
6251 break;
6252 case DW_CFA_undefined:
6253 if ((uint64_t) (endp - readp) < 1)
6254 goto invalid;
6255 get_uleb128 (op1, readp, endp);
6256 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
6257 break;
6258 case DW_CFA_same_value:
6259 if ((uint64_t) (endp - readp) < 1)
6260 goto invalid;
6261 get_uleb128 (op1, readp, endp);
6262 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
6263 break;
6264 case DW_CFA_register:
6265 if ((uint64_t) (endp - readp) < 1)
6266 goto invalid;
6267 get_uleb128 (op1, readp, endp);
6268 if ((uint64_t) (endp - readp) < 1)
6269 goto invalid;
6270 get_uleb128 (op2, readp, endp);
6271 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
6272 op1, regname (op1), op2, regname (op2));
6273 break;
6274 case DW_CFA_remember_state:
6275 puts (" remember_state");
6276 break;
6277 case DW_CFA_restore_state:
6278 puts (" restore_state");
6279 break;
6280 case DW_CFA_def_cfa:
6281 if ((uint64_t) (endp - readp) < 1)
6282 goto invalid;
6283 get_uleb128 (op1, readp, endp);
6284 if ((uint64_t) (endp - readp) < 1)
6285 goto invalid;
6286 get_uleb128 (op2, readp, endp);
6287 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
6288 op1, regname (op1), op2);
6289 break;
6290 case DW_CFA_def_cfa_register:
6291 if ((uint64_t) (endp - readp) < 1)
6292 goto invalid;
6293 get_uleb128 (op1, readp, endp);
6294 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
6295 op1, regname (op1));
6296 break;
6297 case DW_CFA_def_cfa_offset:
6298 if ((uint64_t) (endp - readp) < 1)
6299 goto invalid;
6300 get_uleb128 (op1, readp, endp);
6301 printf (" def_cfa_offset %" PRIu64 "\n", op1);
6302 break;
6303 case DW_CFA_def_cfa_expression:
6304 if ((uint64_t) (endp - readp) < 1)
6305 goto invalid;
6306 get_uleb128 (op1, readp, endp); /* Length of DW_FORM_block. */
6307 printf (" def_cfa_expression %" PRIu64 "\n", op1);
6308 if ((uint64_t) (endp - readp) < op1)
6309 {
6310 invalid:
6311 fputs (gettext (" <INVALID DATA>\n"), stdout);
6312 return;
6313 }
6314 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6315 op1, readp);
6316 readp += op1;
6317 break;
6318 case DW_CFA_expression:
6319 if ((uint64_t) (endp - readp) < 1)
6320 goto invalid;
6321 get_uleb128 (op1, readp, endp);
6322 if ((uint64_t) (endp - readp) < 1)
6323 goto invalid;
6324 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
6325 printf (" expression r%" PRIu64 " (%s) \n",
6326 op1, regname (op1));
6327 if ((uint64_t) (endp - readp) < op2)
6328 goto invalid;
6329 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6330 op2, readp);
6331 readp += op2;
6332 break;
6333 case DW_CFA_offset_extended_sf:
6334 if ((uint64_t) (endp - readp) < 1)
6335 goto invalid;
6336 get_uleb128 (op1, readp, endp);
6337 if ((uint64_t) (endp - readp) < 1)
6338 goto invalid;
6339 get_sleb128 (sop2, readp, endp);
6340 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
6341 PRId64 "\n",
6342 op1, regname (op1), sop2 * data_align);
6343 break;
6344 case DW_CFA_def_cfa_sf:
6345 if ((uint64_t) (endp - readp) < 1)
6346 goto invalid;
6347 get_uleb128 (op1, readp, endp);
6348 if ((uint64_t) (endp - readp) < 1)
6349 goto invalid;
6350 get_sleb128 (sop2, readp, endp);
6351 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
6352 op1, regname (op1), sop2 * data_align);
6353 break;
6354 case DW_CFA_def_cfa_offset_sf:
6355 if ((uint64_t) (endp - readp) < 1)
6356 goto invalid;
6357 get_sleb128 (sop1, readp, endp);
6358 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
6359 break;
6360 case DW_CFA_val_offset:
6361 if ((uint64_t) (endp - readp) < 1)
6362 goto invalid;
6363 get_uleb128 (op1, readp, endp);
6364 if ((uint64_t) (endp - readp) < 1)
6365 goto invalid;
6366 get_uleb128 (op2, readp, endp);
6367 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
6368 op1, op2 * data_align);
6369 break;
6370 case DW_CFA_val_offset_sf:
6371 if ((uint64_t) (endp - readp) < 1)
6372 goto invalid;
6373 get_uleb128 (op1, readp, endp);
6374 if ((uint64_t) (endp - readp) < 1)
6375 goto invalid;
6376 get_sleb128 (sop2, readp, endp);
6377 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
6378 op1, sop2 * data_align);
6379 break;
6380 case DW_CFA_val_expression:
6381 if ((uint64_t) (endp - readp) < 1)
6382 goto invalid;
6383 get_uleb128 (op1, readp, endp);
6384 if ((uint64_t) (endp - readp) < 1)
6385 goto invalid;
6386 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
6387 printf (" val_expression r%" PRIu64 " (%s)\n",
6388 op1, regname (op1));
6389 if ((uint64_t) (endp - readp) < op2)
6390 goto invalid;
6391 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
6392 NULL, op2, readp);
6393 readp += op2;
6394 break;
6395 case DW_CFA_MIPS_advance_loc8:
6396 if ((uint64_t) (endp - readp) < 8)
6397 goto invalid;
6398 op1 = read_8ubyte_unaligned_inc (dbg, readp);
6399 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
6400 op1, pc += op1 * code_align);
6401 break;
6402 case DW_CFA_GNU_window_save:
6403 puts (" GNU_window_save");
6404 break;
6405 case DW_CFA_GNU_args_size:
6406 if ((uint64_t) (endp - readp) < 1)
6407 goto invalid;
6408 get_uleb128 (op1, readp, endp);
6409 printf (" args_size %" PRIu64 "\n", op1);
6410 break;
6411 default:
6412 printf (" ??? (%u)\n", opcode);
6413 break;
6414 }
6415 else if (opcode < DW_CFA_offset)
6416 printf (" advance_loc %u to %#" PRIx64 "\n",
6417 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
6418 else if (opcode < DW_CFA_restore)
6419 {
6420 uint64_t offset;
6421 if ((uint64_t) (endp - readp) < 1)
6422 goto invalid;
6423 get_uleb128 (offset, readp, endp);
6424 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
6425 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
6426 }
6427 else
6428 printf (" restore r%u (%s)\n",
6429 opcode & 0x3f, regname (opcode & 0x3f));
6430 }
6431 }
6432
6433
6434 static unsigned int
encoded_ptr_size(int encoding,unsigned int ptr_size)6435 encoded_ptr_size (int encoding, unsigned int ptr_size)
6436 {
6437 switch (encoding & 7)
6438 {
6439 case DW_EH_PE_udata4:
6440 return 4;
6441 case DW_EH_PE_udata8:
6442 return 8;
6443 case 0:
6444 return ptr_size;
6445 }
6446
6447 fprintf (stderr, "Unsupported pointer encoding: %#x, "
6448 "assuming pointer size of %d.\n", encoding, ptr_size);
6449 return ptr_size;
6450 }
6451
6452
6453 static unsigned int
print_encoding(unsigned int val)6454 print_encoding (unsigned int val)
6455 {
6456 switch (val & 0xf)
6457 {
6458 case DW_EH_PE_absptr:
6459 fputs ("absptr", stdout);
6460 break;
6461 case DW_EH_PE_uleb128:
6462 fputs ("uleb128", stdout);
6463 break;
6464 case DW_EH_PE_udata2:
6465 fputs ("udata2", stdout);
6466 break;
6467 case DW_EH_PE_udata4:
6468 fputs ("udata4", stdout);
6469 break;
6470 case DW_EH_PE_udata8:
6471 fputs ("udata8", stdout);
6472 break;
6473 case DW_EH_PE_sleb128:
6474 fputs ("sleb128", stdout);
6475 break;
6476 case DW_EH_PE_sdata2:
6477 fputs ("sdata2", stdout);
6478 break;
6479 case DW_EH_PE_sdata4:
6480 fputs ("sdata4", stdout);
6481 break;
6482 case DW_EH_PE_sdata8:
6483 fputs ("sdata8", stdout);
6484 break;
6485 default:
6486 /* We did not use any of the bits after all. */
6487 return val;
6488 }
6489
6490 return val & ~0xf;
6491 }
6492
6493
6494 static unsigned int
print_relinfo(unsigned int val)6495 print_relinfo (unsigned int val)
6496 {
6497 switch (val & 0x70)
6498 {
6499 case DW_EH_PE_pcrel:
6500 fputs ("pcrel", stdout);
6501 break;
6502 case DW_EH_PE_textrel:
6503 fputs ("textrel", stdout);
6504 break;
6505 case DW_EH_PE_datarel:
6506 fputs ("datarel", stdout);
6507 break;
6508 case DW_EH_PE_funcrel:
6509 fputs ("funcrel", stdout);
6510 break;
6511 case DW_EH_PE_aligned:
6512 fputs ("aligned", stdout);
6513 break;
6514 default:
6515 return val;
6516 }
6517
6518 return val & ~0x70;
6519 }
6520
6521
6522 static void
print_encoding_base(const char * pfx,unsigned int fde_encoding)6523 print_encoding_base (const char *pfx, unsigned int fde_encoding)
6524 {
6525 printf ("(%s", pfx);
6526
6527 if (fde_encoding == DW_EH_PE_omit)
6528 puts ("omit)");
6529 else
6530 {
6531 unsigned int w = fde_encoding;
6532
6533 w = print_encoding (w);
6534
6535 if (w & 0x70)
6536 {
6537 if (w != fde_encoding)
6538 fputc_unlocked (' ', stdout);
6539
6540 w = print_relinfo (w);
6541 }
6542
6543 if (w != 0)
6544 printf ("%s%x", w != fde_encoding ? " " : "", w);
6545
6546 puts (")");
6547 }
6548 }
6549
6550
6551 static void
print_debug_frame_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6552 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6553 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6554 {
6555 size_t shstrndx;
6556 /* We know this call will succeed since it did in the caller. */
6557 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
6558 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
6559
6560 /* Needed if we find PC-relative addresses. */
6561 GElf_Addr bias;
6562 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
6563 {
6564 error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
6565 return;
6566 }
6567
6568 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
6569 Elf_Data *data = (is_eh_frame
6570 ? elf_rawdata (scn, NULL)
6571 : (dbg->sectiondata[IDX_debug_frame]
6572 ?: elf_rawdata (scn, NULL)));
6573
6574 if (unlikely (data == NULL))
6575 {
6576 error (0, 0, gettext ("cannot get %s content: %s"),
6577 scnname, elf_errmsg (-1));
6578 return;
6579 }
6580
6581 if (is_eh_frame)
6582 printf (gettext ("\
6583 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6584 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6585 else
6586 printf (gettext ("\
6587 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6588 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6589
6590 struct cieinfo
6591 {
6592 ptrdiff_t cie_offset;
6593 const char *augmentation;
6594 unsigned int code_alignment_factor;
6595 unsigned int data_alignment_factor;
6596 uint8_t address_size;
6597 uint8_t fde_encoding;
6598 uint8_t lsda_encoding;
6599 struct cieinfo *next;
6600 } *cies = NULL;
6601
6602 const unsigned char *readp = data->d_buf;
6603 const unsigned char *const dataend = ((unsigned char *) data->d_buf
6604 + data->d_size);
6605 while (readp < dataend)
6606 {
6607 if (unlikely (readp + 4 > dataend))
6608 {
6609 invalid_data:
6610 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6611 elf_ndxscn (scn), scnname);
6612 return;
6613 }
6614
6615 /* At the beginning there must be a CIE. There can be multiple,
6616 hence we test tis in a loop. */
6617 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6618
6619 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
6620 unsigned int length = 4;
6621 if (unlikely (unit_length == 0xffffffff))
6622 {
6623 if (unlikely (readp + 8 > dataend))
6624 goto invalid_data;
6625
6626 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
6627 length = 8;
6628 }
6629
6630 if (unlikely (unit_length == 0))
6631 {
6632 printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
6633 continue;
6634 }
6635
6636 Dwarf_Word maxsize = dataend - readp;
6637 if (unlikely (unit_length > maxsize))
6638 goto invalid_data;
6639
6640 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6641
6642 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
6643 const unsigned char *const cieend = readp + unit_length;
6644 if (unlikely (cieend > dataend))
6645 goto invalid_data;
6646
6647 Dwarf_Off cie_id;
6648 if (length == 4)
6649 {
6650 if (unlikely (cieend - readp < 4))
6651 goto invalid_data;
6652 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
6653 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
6654 cie_id = DW_CIE_ID_64;
6655 }
6656 else
6657 {
6658 if (unlikely (cieend - readp < 8))
6659 goto invalid_data;
6660 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
6661 }
6662
6663 uint_fast8_t version = 2;
6664 unsigned int code_alignment_factor;
6665 int data_alignment_factor;
6666 unsigned int fde_encoding = 0;
6667 unsigned int lsda_encoding = 0;
6668 Dwarf_Word initial_location = 0;
6669 Dwarf_Word vma_base = 0;
6670
6671 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
6672 {
6673 if (unlikely (cieend - readp < 2))
6674 goto invalid_data;
6675 version = *readp++;
6676 const char *const augmentation = (const char *) readp;
6677 readp = memchr (readp, '\0', cieend - readp);
6678 if (unlikely (readp == NULL))
6679 goto invalid_data;
6680 ++readp;
6681
6682 uint_fast8_t segment_size = 0;
6683 if (version >= 4)
6684 {
6685 if (cieend - readp < 5)
6686 goto invalid_data;
6687 ptr_size = *readp++;
6688 segment_size = *readp++;
6689 }
6690
6691 if (cieend - readp < 1)
6692 goto invalid_data;
6693 get_uleb128 (code_alignment_factor, readp, cieend);
6694 if (cieend - readp < 1)
6695 goto invalid_data;
6696 get_sleb128 (data_alignment_factor, readp, cieend);
6697
6698 /* In some variant for unwind data there is another field. */
6699 if (strcmp (augmentation, "eh") == 0)
6700 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6701
6702 unsigned int return_address_register;
6703 if (cieend - readp < 1)
6704 goto invalid_data;
6705 if (unlikely (version == 1))
6706 return_address_register = *readp++;
6707 else
6708 get_uleb128 (return_address_register, readp, cieend);
6709
6710 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
6711 " CIE_id: %" PRIu64 "\n"
6712 " version: %u\n"
6713 " augmentation: \"%s\"\n",
6714 offset, (uint64_t) unit_length, (uint64_t) cie_id,
6715 version, augmentation);
6716 if (version >= 4)
6717 printf (" address_size: %u\n"
6718 " segment_size: %u\n",
6719 ptr_size, segment_size);
6720 printf (" code_alignment_factor: %u\n"
6721 " data_alignment_factor: %d\n"
6722 " return_address_register: %u\n",
6723 code_alignment_factor,
6724 data_alignment_factor, return_address_register);
6725
6726 if (augmentation[0] == 'z')
6727 {
6728 unsigned int augmentationlen;
6729 get_uleb128 (augmentationlen, readp, cieend);
6730
6731 if (augmentationlen > (size_t) (cieend - readp))
6732 {
6733 error (0, 0, gettext ("invalid augmentation length"));
6734 readp = cieend;
6735 continue;
6736 }
6737
6738 const char *hdr = "Augmentation data:";
6739 const char *cp = augmentation + 1;
6740 while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
6741 {
6742 printf (" %-26s%#x ", hdr, *readp);
6743 hdr = "";
6744
6745 if (*cp == 'R')
6746 {
6747 fde_encoding = *readp++;
6748 print_encoding_base (gettext ("FDE address encoding: "),
6749 fde_encoding);
6750 }
6751 else if (*cp == 'L')
6752 {
6753 lsda_encoding = *readp++;
6754 print_encoding_base (gettext ("LSDA pointer encoding: "),
6755 lsda_encoding);
6756 }
6757 else if (*cp == 'P')
6758 {
6759 /* Personality. This field usually has a relocation
6760 attached pointing to __gcc_personality_v0. */
6761 const unsigned char *startp = readp;
6762 unsigned int encoding = *readp++;
6763 uint64_t val = 0;
6764 readp = read_encoded (encoding, readp,
6765 readp - 1 + augmentationlen,
6766 &val, dbg);
6767
6768 while (++startp < readp)
6769 printf ("%#x ", *startp);
6770
6771 putchar ('(');
6772 print_encoding (encoding);
6773 putchar (' ');
6774 switch (encoding & 0xf)
6775 {
6776 case DW_EH_PE_sleb128:
6777 case DW_EH_PE_sdata2:
6778 case DW_EH_PE_sdata4:
6779 printf ("%" PRId64 ")\n", val);
6780 break;
6781 default:
6782 printf ("%#" PRIx64 ")\n", val);
6783 break;
6784 }
6785 }
6786 else
6787 printf ("(%x)\n", *readp++);
6788
6789 ++cp;
6790 }
6791 }
6792
6793 if (likely (ptr_size == 4 || ptr_size == 8))
6794 {
6795 struct cieinfo *newp = alloca (sizeof (*newp));
6796 newp->cie_offset = offset;
6797 newp->augmentation = augmentation;
6798 newp->fde_encoding = fde_encoding;
6799 newp->lsda_encoding = lsda_encoding;
6800 newp->address_size = ptr_size;
6801 newp->code_alignment_factor = code_alignment_factor;
6802 newp->data_alignment_factor = data_alignment_factor;
6803 newp->next = cies;
6804 cies = newp;
6805 }
6806 }
6807 else
6808 {
6809 struct cieinfo *cie = cies;
6810 while (cie != NULL)
6811 if (is_eh_frame
6812 ? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
6813 : cie_id == (Dwarf_Off) cie->cie_offset)
6814 break;
6815 else
6816 cie = cie->next;
6817 if (unlikely (cie == NULL))
6818 {
6819 puts ("invalid CIE reference in FDE");
6820 return;
6821 }
6822
6823 /* Initialize from CIE data. */
6824 fde_encoding = cie->fde_encoding;
6825 lsda_encoding = cie->lsda_encoding;
6826 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
6827 code_alignment_factor = cie->code_alignment_factor;
6828 data_alignment_factor = cie->data_alignment_factor;
6829
6830 const unsigned char *base = readp;
6831 // XXX There are sometimes relocations for this value
6832 initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
6833 Dwarf_Word address_range
6834 = read_addr_unaligned_inc (ptr_size, dbg, readp);
6835
6836 /* pcrel for an FDE address is relative to the runtime
6837 address of the start_address field itself. Sign extend
6838 if necessary to make sure the calculation is done on the
6839 full 64 bit address even when initial_location only holds
6840 the lower 32 bits. */
6841 Dwarf_Addr pc_start = initial_location;
6842 if (ptr_size == 4)
6843 pc_start = (uint64_t) (int32_t) pc_start;
6844 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6845 pc_start += ((uint64_t) shdr->sh_addr
6846 + (base - (const unsigned char *) data->d_buf)
6847 - bias);
6848
6849 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
6850 " CIE_pointer: %" PRIu64 "\n"
6851 " initial_location: ",
6852 offset, (uint64_t) unit_length,
6853 cie->cie_offset, (uint64_t) cie_id);
6854 print_dwarf_addr (dwflmod, cie->address_size,
6855 pc_start, initial_location);
6856 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6857 {
6858 vma_base = (((uint64_t) shdr->sh_offset
6859 + (base - (const unsigned char *) data->d_buf)
6860 + (uint64_t) initial_location)
6861 & (ptr_size == 4
6862 ? UINT64_C (0xffffffff)
6863 : UINT64_C (0xffffffffffffffff)));
6864 printf (gettext (" (offset: %#" PRIx64 ")"),
6865 (uint64_t) vma_base);
6866 }
6867
6868 printf ("\n address_range: %#" PRIx64,
6869 (uint64_t) address_range);
6870 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6871 printf (gettext (" (end offset: %#" PRIx64 ")"),
6872 ((uint64_t) vma_base + (uint64_t) address_range)
6873 & (ptr_size == 4
6874 ? UINT64_C (0xffffffff)
6875 : UINT64_C (0xffffffffffffffff)));
6876 putchar ('\n');
6877
6878 if (cie->augmentation[0] == 'z')
6879 {
6880 unsigned int augmentationlen;
6881 if (cieend - readp < 1)
6882 goto invalid_data;
6883 get_uleb128 (augmentationlen, readp, cieend);
6884
6885 if (augmentationlen > (size_t) (cieend - readp))
6886 {
6887 error (0, 0, gettext ("invalid augmentation length"));
6888 readp = cieend;
6889 continue;
6890 }
6891
6892 if (augmentationlen > 0)
6893 {
6894 const char *hdr = "Augmentation data:";
6895 const char *cp = cie->augmentation + 1;
6896 unsigned int u = 0;
6897 while (*cp != '\0'
6898 && cp < cie->augmentation + augmentationlen + 1)
6899 {
6900 if (*cp == 'L')
6901 {
6902 uint64_t lsda_pointer;
6903 const unsigned char *p
6904 = read_encoded (lsda_encoding, &readp[u],
6905 &readp[augmentationlen],
6906 &lsda_pointer, dbg);
6907 u = p - readp;
6908 printf (gettext ("\
6909 %-26sLSDA pointer: %#" PRIx64 "\n"),
6910 hdr, lsda_pointer);
6911 hdr = "";
6912 }
6913 ++cp;
6914 }
6915
6916 while (u < augmentationlen)
6917 {
6918 printf (" %-26s%#x\n", hdr, readp[u++]);
6919 hdr = "";
6920 }
6921 }
6922
6923 readp += augmentationlen;
6924 }
6925 }
6926
6927 /* Handle the initialization instructions. */
6928 if (ptr_size != 4 && ptr_size !=8)
6929 printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
6930 else
6931 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
6932 data_alignment_factor, version, ptr_size,
6933 fde_encoding, dwflmod, ebl, dbg);
6934 readp = cieend;
6935 }
6936 }
6937
6938
6939 /* Returns the signedness (or false if it cannot be determined) and
6940 the byte size (or zero if it cannot be gotten) of the given DIE
6941 DW_AT_type attribute. Uses dwarf_peel_type and dwarf_aggregate_size. */
6942 static void
die_type_sign_bytes(Dwarf_Die * die,bool * is_signed,int * bytes)6943 die_type_sign_bytes (Dwarf_Die *die, bool *is_signed, int *bytes)
6944 {
6945 Dwarf_Attribute attr;
6946 Dwarf_Die type;
6947
6948 *bytes = 0;
6949 *is_signed = false;
6950
6951 if (dwarf_peel_type (dwarf_formref_die (dwarf_attr_integrate (die,
6952 DW_AT_type,
6953 &attr), &type),
6954 &type) == 0)
6955 {
6956 Dwarf_Word val;
6957 *is_signed = (dwarf_formudata (dwarf_attr (&type, DW_AT_encoding,
6958 &attr), &val) == 0
6959 && (val == DW_ATE_signed || val == DW_ATE_signed_char));
6960
6961 if (dwarf_aggregate_size (&type, &val) == 0)
6962 *bytes = val;
6963 }
6964 }
6965
6966 struct attrcb_args
6967 {
6968 Dwfl_Module *dwflmod;
6969 Dwarf *dbg;
6970 Dwarf_Die *dies;
6971 int level;
6972 bool silent;
6973 bool is_split;
6974 unsigned int version;
6975 unsigned int addrsize;
6976 unsigned int offset_size;
6977 struct Dwarf_CU *cu;
6978 };
6979
6980
6981 static int
attr_callback(Dwarf_Attribute * attrp,void * arg)6982 attr_callback (Dwarf_Attribute *attrp, void *arg)
6983 {
6984 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
6985 const int level = cbargs->level;
6986 Dwarf_Die *die = &cbargs->dies[level];
6987 bool is_split = cbargs->is_split;
6988
6989 unsigned int attr = dwarf_whatattr (attrp);
6990 if (unlikely (attr == 0))
6991 {
6992 if (!cbargs->silent)
6993 error (0, 0, gettext ("DIE [%" PRIx64 "] "
6994 "cannot get attribute code: %s"),
6995 dwarf_dieoffset (die), dwarf_errmsg (-1));
6996 return DWARF_CB_ABORT;
6997 }
6998
6999 unsigned int form = dwarf_whatform (attrp);
7000 if (unlikely (form == 0))
7001 {
7002 if (!cbargs->silent)
7003 error (0, 0, gettext ("DIE [%" PRIx64 "] "
7004 "cannot get attribute form: %s"),
7005 dwarf_dieoffset (die), dwarf_errmsg (-1));
7006 return DWARF_CB_ABORT;
7007 }
7008
7009 switch (form)
7010 {
7011 case DW_FORM_addr:
7012 case DW_FORM_addrx:
7013 case DW_FORM_addrx1:
7014 case DW_FORM_addrx2:
7015 case DW_FORM_addrx3:
7016 case DW_FORM_addrx4:
7017 case DW_FORM_GNU_addr_index:
7018 if (!cbargs->silent)
7019 {
7020 Dwarf_Addr addr;
7021 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
7022 {
7023 attrval_out:
7024 if (!cbargs->silent)
7025 error (0, 0, gettext ("DIE [%" PRIx64 "] "
7026 "cannot get attribute '%s' (%s) value: "
7027 "%s"),
7028 dwarf_dieoffset (die),
7029 dwarf_attr_name (attr),
7030 dwarf_form_name (form),
7031 dwarf_errmsg (-1));
7032 /* Don't ABORT, it might be other attributes can be resolved. */
7033 return DWARF_CB_OK;
7034 }
7035 if (form != DW_FORM_addr )
7036 {
7037 Dwarf_Word word;
7038 if (dwarf_formudata (attrp, &word) != 0)
7039 goto attrval_out;
7040 printf (" %*s%-20s (%s) [%" PRIx64 "] ",
7041 (int) (level * 2), "", dwarf_attr_name (attr),
7042 dwarf_form_name (form), word);
7043 }
7044 else
7045 printf (" %*s%-20s (%s) ",
7046 (int) (level * 2), "", dwarf_attr_name (attr),
7047 dwarf_form_name (form));
7048 print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr, addr);
7049 printf ("\n");
7050 }
7051 break;
7052
7053 case DW_FORM_indirect:
7054 case DW_FORM_strp:
7055 case DW_FORM_line_strp:
7056 case DW_FORM_strx:
7057 case DW_FORM_strx1:
7058 case DW_FORM_strx2:
7059 case DW_FORM_strx3:
7060 case DW_FORM_strx4:
7061 case DW_FORM_string:
7062 case DW_FORM_GNU_strp_alt:
7063 case DW_FORM_GNU_str_index:
7064 if (cbargs->silent)
7065 break;
7066 const char *str = dwarf_formstring (attrp);
7067 if (unlikely (str == NULL))
7068 goto attrval_out;
7069 printf (" %*s%-20s (%s) \"%s\"\n",
7070 (int) (level * 2), "", dwarf_attr_name (attr),
7071 dwarf_form_name (form), str);
7072 break;
7073
7074 case DW_FORM_ref_addr:
7075 case DW_FORM_ref_udata:
7076 case DW_FORM_ref8:
7077 case DW_FORM_ref4:
7078 case DW_FORM_ref2:
7079 case DW_FORM_ref1:
7080 case DW_FORM_GNU_ref_alt:
7081 case DW_FORM_ref_sup4:
7082 case DW_FORM_ref_sup8:
7083 if (cbargs->silent)
7084 break;
7085 Dwarf_Die ref;
7086 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
7087 goto attrval_out;
7088
7089 printf (" %*s%-20s (%s) ",
7090 (int) (level * 2), "", dwarf_attr_name (attr),
7091 dwarf_form_name (form));
7092 if (is_split)
7093 printf ("{%6" PRIxMAX "}\n", (uintmax_t) dwarf_dieoffset (&ref));
7094 else
7095 printf ("[%6" PRIxMAX "]\n", (uintmax_t) dwarf_dieoffset (&ref));
7096 break;
7097
7098 case DW_FORM_ref_sig8:
7099 if (cbargs->silent)
7100 break;
7101 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
7102 (int) (level * 2), "", dwarf_attr_name (attr),
7103 dwarf_form_name (form),
7104 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
7105 break;
7106
7107 case DW_FORM_sec_offset:
7108 case DW_FORM_rnglistx:
7109 case DW_FORM_loclistx:
7110 case DW_FORM_implicit_const:
7111 case DW_FORM_udata:
7112 case DW_FORM_sdata:
7113 case DW_FORM_data8: /* Note no data16 here, we see that as block. */
7114 case DW_FORM_data4:
7115 case DW_FORM_data2:
7116 case DW_FORM_data1:;
7117 Dwarf_Word num;
7118 if (unlikely (dwarf_formudata (attrp, &num) != 0))
7119 goto attrval_out;
7120
7121 const char *valuestr = NULL;
7122 bool as_hex_id = false;
7123 switch (attr)
7124 {
7125 /* This case can take either a constant or a loclistptr. */
7126 case DW_AT_data_member_location:
7127 if (form != DW_FORM_sec_offset
7128 && (cbargs->version >= 4
7129 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
7130 {
7131 if (!cbargs->silent)
7132 printf (" %*s%-20s (%s) %" PRIuMAX "\n",
7133 (int) (level * 2), "", dwarf_attr_name (attr),
7134 dwarf_form_name (form), (uintmax_t) num);
7135 return DWARF_CB_OK;
7136 }
7137 FALLTHROUGH;
7138
7139 /* These cases always take a loclist[ptr] and no constant. */
7140 case DW_AT_location:
7141 case DW_AT_data_location:
7142 case DW_AT_vtable_elem_location:
7143 case DW_AT_string_length:
7144 case DW_AT_use_location:
7145 case DW_AT_frame_base:
7146 case DW_AT_return_addr:
7147 case DW_AT_static_link:
7148 case DW_AT_segment:
7149 case DW_AT_GNU_call_site_value:
7150 case DW_AT_GNU_call_site_data_value:
7151 case DW_AT_GNU_call_site_target:
7152 case DW_AT_GNU_call_site_target_clobbered:
7153 case DW_AT_GNU_locviews:
7154 {
7155 bool nlpt;
7156 if (cbargs->cu->version < 5)
7157 {
7158 if (! cbargs->is_split)
7159 {
7160 nlpt = notice_listptr (section_loc, &known_locsptr,
7161 cbargs->addrsize,
7162 cbargs->offset_size,
7163 cbargs->cu, num, attr);
7164 }
7165 else
7166 nlpt = true;
7167 }
7168 else
7169 {
7170 /* Only register for a real section offset. Otherwise
7171 it is a DW_FORM_loclistx which is just an index
7172 number and we should already have registered the
7173 section offset for the index when we saw the
7174 DW_AT_loclists_base CU attribute. */
7175 if (form == DW_FORM_sec_offset)
7176 nlpt = notice_listptr (section_loc, &known_loclistsptr,
7177 cbargs->addrsize, cbargs->offset_size,
7178 cbargs->cu, num, attr);
7179 else
7180 nlpt = true;
7181
7182 }
7183
7184 if (!cbargs->silent)
7185 {
7186 if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7187 printf (" %*s%-20s (%s) location list [%6"
7188 PRIxMAX "]%s\n",
7189 (int) (level * 2), "", dwarf_attr_name (attr),
7190 dwarf_form_name (form), (uintmax_t) num,
7191 nlpt ? "" : " <WARNING offset too big>");
7192 else
7193 printf (" %*s%-20s (%s) location index [%6"
7194 PRIxMAX "]\n",
7195 (int) (level * 2), "", dwarf_attr_name (attr),
7196 dwarf_form_name (form), (uintmax_t) num);
7197 }
7198 }
7199 return DWARF_CB_OK;
7200
7201 case DW_AT_loclists_base:
7202 {
7203 bool nlpt = notice_listptr (section_loc, &known_loclistsptr,
7204 cbargs->addrsize, cbargs->offset_size,
7205 cbargs->cu, num, attr);
7206
7207 if (!cbargs->silent)
7208 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
7209 (int) (level * 2), "", dwarf_attr_name (attr),
7210 dwarf_form_name (form), (uintmax_t) num,
7211 nlpt ? "" : " <WARNING offset too big>");
7212 }
7213 return DWARF_CB_OK;
7214
7215 case DW_AT_ranges:
7216 case DW_AT_start_scope:
7217 {
7218 bool nlpt;
7219 if (cbargs->cu->version < 5)
7220 nlpt = notice_listptr (section_ranges, &known_rangelistptr,
7221 cbargs->addrsize, cbargs->offset_size,
7222 cbargs->cu, num, attr);
7223 else
7224 {
7225 /* Only register for a real section offset. Otherwise
7226 it is a DW_FORM_rangelistx which is just an index
7227 number and we should already have registered the
7228 section offset for the index when we saw the
7229 DW_AT_rnglists_base CU attribute. */
7230 if (form == DW_FORM_sec_offset)
7231 nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7232 cbargs->addrsize, cbargs->offset_size,
7233 cbargs->cu, num, attr);
7234 else
7235 nlpt = true;
7236 }
7237
7238 if (!cbargs->silent)
7239 {
7240 if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7241 printf (" %*s%-20s (%s) range list [%6"
7242 PRIxMAX "]%s\n",
7243 (int) (level * 2), "", dwarf_attr_name (attr),
7244 dwarf_form_name (form), (uintmax_t) num,
7245 nlpt ? "" : " <WARNING offset too big>");
7246 else
7247 printf (" %*s%-20s (%s) range index [%6"
7248 PRIxMAX "]\n",
7249 (int) (level * 2), "", dwarf_attr_name (attr),
7250 dwarf_form_name (form), (uintmax_t) num);
7251 }
7252 }
7253 return DWARF_CB_OK;
7254
7255 case DW_AT_rnglists_base:
7256 {
7257 bool nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7258 cbargs->addrsize, cbargs->offset_size,
7259 cbargs->cu, num, attr);
7260 if (!cbargs->silent)
7261 printf (" %*s%-20s (%s) range list [%6"
7262 PRIxMAX "]%s\n",
7263 (int) (level * 2), "", dwarf_attr_name (attr),
7264 dwarf_form_name (form), (uintmax_t) num,
7265 nlpt ? "" : " <WARNING offset too big>");
7266 }
7267 return DWARF_CB_OK;
7268
7269 case DW_AT_addr_base:
7270 case DW_AT_GNU_addr_base:
7271 {
7272 bool addrbase = notice_listptr (section_addr, &known_addrbases,
7273 cbargs->addrsize,
7274 cbargs->offset_size,
7275 cbargs->cu, num, attr);
7276 if (!cbargs->silent)
7277 printf (" %*s%-20s (%s) address base [%6"
7278 PRIxMAX "]%s\n",
7279 (int) (level * 2), "", dwarf_attr_name (attr),
7280 dwarf_form_name (form), (uintmax_t) num,
7281 addrbase ? "" : " <WARNING offset too big>");
7282 }
7283 return DWARF_CB_OK;
7284
7285 case DW_AT_str_offsets_base:
7286 {
7287 bool stroffbase = notice_listptr (section_str, &known_stroffbases,
7288 cbargs->addrsize,
7289 cbargs->offset_size,
7290 cbargs->cu, num, attr);
7291 if (!cbargs->silent)
7292 printf (" %*s%-20s (%s) str offsets base [%6"
7293 PRIxMAX "]%s\n",
7294 (int) (level * 2), "", dwarf_attr_name (attr),
7295 dwarf_form_name (form), (uintmax_t) num,
7296 stroffbase ? "" : " <WARNING offset too big>");
7297 }
7298 return DWARF_CB_OK;
7299
7300 case DW_AT_language:
7301 valuestr = dwarf_lang_name (num);
7302 break;
7303 case DW_AT_encoding:
7304 valuestr = dwarf_encoding_name (num);
7305 break;
7306 case DW_AT_accessibility:
7307 valuestr = dwarf_access_name (num);
7308 break;
7309 case DW_AT_defaulted:
7310 valuestr = dwarf_defaulted_name (num);
7311 break;
7312 case DW_AT_visibility:
7313 valuestr = dwarf_visibility_name (num);
7314 break;
7315 case DW_AT_virtuality:
7316 valuestr = dwarf_virtuality_name (num);
7317 break;
7318 case DW_AT_identifier_case:
7319 valuestr = dwarf_identifier_case_name (num);
7320 break;
7321 case DW_AT_calling_convention:
7322 valuestr = dwarf_calling_convention_name (num);
7323 break;
7324 case DW_AT_inline:
7325 valuestr = dwarf_inline_name (num);
7326 break;
7327 case DW_AT_ordering:
7328 valuestr = dwarf_ordering_name (num);
7329 break;
7330 case DW_AT_decl_file:
7331 case DW_AT_call_file:
7332 {
7333 if (cbargs->silent)
7334 break;
7335
7336 /* Try to get the actual file, the current interface only
7337 gives us full paths, but we only want to show the file
7338 name for now. */
7339 Dwarf_Die cudie;
7340 if (dwarf_cu_die (cbargs->cu, &cudie,
7341 NULL, NULL, NULL, NULL, NULL, NULL) != NULL)
7342 {
7343 Dwarf_Files *files;
7344 size_t nfiles;
7345 if (dwarf_getsrcfiles (&cudie, &files, &nfiles) == 0)
7346 {
7347 valuestr = dwarf_filesrc (files, num, NULL, NULL);
7348 if (valuestr != NULL)
7349 {
7350 char *filename = strrchr (valuestr, '/');
7351 if (filename != NULL)
7352 valuestr = filename + 1;
7353 }
7354 else
7355 error (0, 0, gettext ("invalid file (%" PRId64 "): %s"),
7356 num, dwarf_errmsg (-1));
7357 }
7358 else
7359 error (0, 0, gettext ("no srcfiles for CU [%" PRIx64 "]"),
7360 dwarf_dieoffset (&cudie));
7361 }
7362 else
7363 error (0, 0, gettext ("couldn't get DWARF CU: %s"),
7364 dwarf_errmsg (-1));
7365 if (valuestr == NULL)
7366 valuestr = "???";
7367 }
7368 break;
7369 case DW_AT_GNU_dwo_id:
7370 as_hex_id = true;
7371 break;
7372
7373 default:
7374 /* Nothing. */
7375 break;
7376 }
7377
7378 if (cbargs->silent)
7379 break;
7380
7381 /* When highpc is in constant form it is relative to lowpc.
7382 In that case also show the address. */
7383 Dwarf_Addr highpc;
7384 if (attr == DW_AT_high_pc && dwarf_highpc (die, &highpc) == 0)
7385 {
7386 printf (" %*s%-20s (%s) %" PRIuMAX " (",
7387 (int) (level * 2), "", dwarf_attr_name (attr),
7388 dwarf_form_name (form), (uintmax_t) num);
7389 print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, highpc, highpc);
7390 printf (")\n");
7391 }
7392 else
7393 {
7394 if (as_hex_id)
7395 {
7396 printf (" %*s%-20s (%s) 0x%.16" PRIx64 "\n",
7397 (int) (level * 2), "", dwarf_attr_name (attr),
7398 dwarf_form_name (form), num);
7399 }
7400 else
7401 {
7402 Dwarf_Sword snum = 0;
7403 bool is_signed;
7404 int bytes = 0;
7405 if (attr == DW_AT_const_value)
7406 die_type_sign_bytes (die, &is_signed, &bytes);
7407 else
7408 is_signed = (form == DW_FORM_sdata
7409 || form == DW_FORM_implicit_const);
7410
7411 if (is_signed)
7412 if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
7413 goto attrval_out;
7414
7415 if (valuestr == NULL)
7416 {
7417 printf (" %*s%-20s (%s) ",
7418 (int) (level * 2), "", dwarf_attr_name (attr),
7419 dwarf_form_name (form));
7420 }
7421 else
7422 {
7423 printf (" %*s%-20s (%s) %s (",
7424 (int) (level * 2), "", dwarf_attr_name (attr),
7425 dwarf_form_name (form), valuestr);
7426 }
7427
7428 switch (bytes)
7429 {
7430 case 1:
7431 if (is_signed)
7432 printf ("%" PRId8, (int8_t) snum);
7433 else
7434 printf ("%" PRIu8, (uint8_t) num);
7435 break;
7436
7437 case 2:
7438 if (is_signed)
7439 printf ("%" PRId16, (int16_t) snum);
7440 else
7441 printf ("%" PRIu16, (uint16_t) num);
7442 break;
7443
7444 case 4:
7445 if (is_signed)
7446 printf ("%" PRId32, (int32_t) snum);
7447 else
7448 printf ("%" PRIu32, (uint32_t) num);
7449 break;
7450
7451 case 8:
7452 if (is_signed)
7453 printf ("%" PRId64, (int64_t) snum);
7454 else
7455 printf ("%" PRIu64, (uint64_t) num);
7456 break;
7457
7458 default:
7459 if (is_signed)
7460 printf ("%" PRIdMAX, (intmax_t) snum);
7461 else
7462 printf ("%" PRIuMAX, (uintmax_t) num);
7463 break;
7464 }
7465
7466 /* Make clear if we switched from a signed encoding to
7467 an unsigned value. */
7468 if (attr == DW_AT_const_value
7469 && (form == DW_FORM_sdata || form == DW_FORM_implicit_const)
7470 && !is_signed)
7471 printf (" (%" PRIdMAX ")", (intmax_t) num);
7472
7473 if (valuestr == NULL)
7474 printf ("\n");
7475 else
7476 printf (")\n");
7477 }
7478 }
7479 break;
7480
7481 case DW_FORM_flag:
7482 if (cbargs->silent)
7483 break;
7484 bool flag;
7485 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
7486 goto attrval_out;
7487
7488 printf (" %*s%-20s (%s) %s\n",
7489 (int) (level * 2), "", dwarf_attr_name (attr),
7490 dwarf_form_name (form), flag ? yes_str : no_str);
7491 break;
7492
7493 case DW_FORM_flag_present:
7494 if (cbargs->silent)
7495 break;
7496 printf (" %*s%-20s (%s) %s\n",
7497 (int) (level * 2), "", dwarf_attr_name (attr),
7498 dwarf_form_name (form), yes_str);
7499 break;
7500
7501 case DW_FORM_exprloc:
7502 case DW_FORM_block4:
7503 case DW_FORM_block2:
7504 case DW_FORM_block1:
7505 case DW_FORM_block:
7506 case DW_FORM_data16: /* DWARF5 calls this a constant class. */
7507 if (cbargs->silent)
7508 break;
7509 Dwarf_Block block;
7510 if (unlikely (dwarf_formblock (attrp, &block) != 0))
7511 goto attrval_out;
7512
7513 printf (" %*s%-20s (%s) ",
7514 (int) (level * 2), "", dwarf_attr_name (attr),
7515 dwarf_form_name (form));
7516
7517 switch (attr)
7518 {
7519 default:
7520 if (form != DW_FORM_exprloc)
7521 {
7522 print_block (block.length, block.data);
7523 break;
7524 }
7525 FALLTHROUGH;
7526
7527 case DW_AT_location:
7528 case DW_AT_data_location:
7529 case DW_AT_data_member_location:
7530 case DW_AT_vtable_elem_location:
7531 case DW_AT_string_length:
7532 case DW_AT_use_location:
7533 case DW_AT_frame_base:
7534 case DW_AT_return_addr:
7535 case DW_AT_static_link:
7536 case DW_AT_allocated:
7537 case DW_AT_associated:
7538 case DW_AT_bit_size:
7539 case DW_AT_bit_offset:
7540 case DW_AT_bit_stride:
7541 case DW_AT_byte_size:
7542 case DW_AT_byte_stride:
7543 case DW_AT_count:
7544 case DW_AT_lower_bound:
7545 case DW_AT_upper_bound:
7546 case DW_AT_GNU_call_site_value:
7547 case DW_AT_GNU_call_site_data_value:
7548 case DW_AT_GNU_call_site_target:
7549 case DW_AT_GNU_call_site_target_clobbered:
7550 if (form != DW_FORM_data16)
7551 {
7552 putchar ('\n');
7553 print_ops (cbargs->dwflmod, cbargs->dbg,
7554 12 + level * 2, 12 + level * 2,
7555 cbargs->version, cbargs->addrsize, cbargs->offset_size,
7556 attrp->cu, block.length, block.data);
7557 }
7558 else
7559 print_block (block.length, block.data);
7560 break;
7561
7562 case DW_AT_discr_list:
7563 if (block.length == 0)
7564 puts ("<default>");
7565 else if (form != DW_FORM_data16)
7566 {
7567 const unsigned char *readp = block.data;
7568 const unsigned char *readendp = readp + block.length;
7569
7570 /* See if we are dealing with a signed or unsigned
7571 values. If the parent of this variant DIE is a
7572 variant_part then it will either have a discriminant
7573 which points to the member which type is the
7574 discriminant type. Or the variant_part itself has a
7575 type representing the discriminant. */
7576 bool is_signed = false;
7577 if (level > 0)
7578 {
7579 Dwarf_Die *parent = &cbargs->dies[level - 1];
7580 if (dwarf_tag (die) == DW_TAG_variant
7581 && dwarf_tag (parent) == DW_TAG_variant_part)
7582 {
7583 Dwarf_Die member;
7584 Dwarf_Attribute discr_attr;
7585 int bytes;
7586 if (dwarf_formref_die (dwarf_attr (parent,
7587 DW_AT_discr,
7588 &discr_attr),
7589 &member) != NULL)
7590 die_type_sign_bytes (&member, &is_signed, &bytes);
7591 else
7592 die_type_sign_bytes (parent, &is_signed, &bytes);
7593 }
7594 }
7595 while (readp < readendp)
7596 {
7597 int d = (int) *readp++;
7598 printf ("%s ", dwarf_discr_list_name (d));
7599 if (readp >= readendp)
7600 goto attrval_out;
7601
7602 Dwarf_Word val;
7603 Dwarf_Sword sval;
7604 if (d == DW_DSC_label)
7605 {
7606 if (is_signed)
7607 {
7608 get_sleb128 (sval, readp, readendp);
7609 printf ("%" PRId64 "", sval);
7610 }
7611 else
7612 {
7613 get_uleb128 (val, readp, readendp);
7614 printf ("%" PRIu64 "", val);
7615 }
7616 }
7617 else if (d == DW_DSC_range)
7618 {
7619 if (is_signed)
7620 {
7621 get_sleb128 (sval, readp, readendp);
7622 printf ("%" PRId64 "..", sval);
7623 if (readp >= readendp)
7624 goto attrval_out;
7625 get_sleb128 (sval, readp, readendp);
7626 printf ("%" PRId64 "", sval);
7627 }
7628 else
7629 {
7630 get_uleb128 (val, readp, readendp);
7631 printf ("%" PRIu64 "..", val);
7632 if (readp >= readendp)
7633 goto attrval_out;
7634 get_uleb128 (val, readp, readendp);
7635 printf ("%" PRIu64 "", val);
7636 }
7637 }
7638 else
7639 {
7640 print_block (readendp - readp, readp);
7641 break;
7642 }
7643 if (readp < readendp)
7644 printf (", ");
7645 }
7646 putchar ('\n');
7647 }
7648 else
7649 print_block (block.length, block.data);
7650 break;
7651 }
7652 break;
7653
7654 default:
7655 if (cbargs->silent)
7656 break;
7657 printf (" %*s%-20s (%s) ???\n",
7658 (int) (level * 2), "", dwarf_attr_name (attr),
7659 dwarf_form_name (form));
7660 break;
7661 }
7662
7663 return DWARF_CB_OK;
7664 }
7665
7666 static void
print_debug_units(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg,bool debug_types)7667 print_debug_units (Dwfl_Module *dwflmod,
7668 Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
7669 Elf_Scn *scn, GElf_Shdr *shdr,
7670 Dwarf *dbg, bool debug_types)
7671 {
7672 const bool silent = !(print_debug_sections & section_info) && !debug_types;
7673 const char *secname = section_name (ebl, shdr);
7674
7675 if (!silent)
7676 printf (gettext ("\
7677 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
7678 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
7679
7680 /* If the section is empty we don't have to do anything. */
7681 if (!silent && shdr->sh_size == 0)
7682 return;
7683
7684 int maxdies = 20;
7685 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
7686
7687 /* New compilation unit. */
7688 Dwarf_Half version;
7689
7690 Dwarf_Die result;
7691 Dwarf_Off abbroffset;
7692 uint8_t addrsize;
7693 uint8_t offsize;
7694 uint64_t unit_id;
7695 Dwarf_Off subdie_off;
7696
7697 int unit_res;
7698 Dwarf_CU *cu;
7699 Dwarf_CU cu_mem;
7700 uint8_t unit_type;
7701 Dwarf_Die cudie;
7702
7703 /* We cheat a little because we want to see only the CUs from .debug_info
7704 or .debug_types. We know the Dwarf_CU struct layout. Set it up at
7705 the end of .debug_info if we want .debug_types only. Check the returned
7706 Dwarf_CU is still in the expected section. */
7707 if (debug_types)
7708 {
7709 cu_mem.dbg = dbg;
7710 cu_mem.end = dbg->sectiondata[IDX_debug_info]->d_size;
7711 cu_mem.sec_idx = IDX_debug_info;
7712 cu = &cu_mem;
7713 }
7714 else
7715 cu = NULL;
7716
7717 next_cu:
7718 unit_res = dwarf_get_units (dbg, cu, &cu, &version, &unit_type,
7719 &cudie, NULL);
7720 if (unit_res == 1)
7721 goto do_return;
7722
7723 if (unit_res == -1)
7724 {
7725 if (!silent)
7726 error (0, 0, gettext ("cannot get next unit: %s"), dwarf_errmsg (-1));
7727 goto do_return;
7728 }
7729
7730 if (cu->sec_idx != (size_t) (debug_types ? IDX_debug_types : IDX_debug_info))
7731 goto do_return;
7732
7733 dwarf_cu_die (cu, &result, NULL, &abbroffset, &addrsize, &offsize,
7734 &unit_id, &subdie_off);
7735
7736 if (!silent)
7737 {
7738 Dwarf_Off offset = cu->start;
7739 if (debug_types && version < 5)
7740 {
7741 Dwarf_Die typedie;
7742 Dwarf_Off dieoffset;
7743 dieoffset = dwarf_dieoffset (dwarf_offdie_types (dbg, subdie_off,
7744 &typedie));
7745 printf (gettext (" Type unit at offset %" PRIu64 ":\n"
7746 " Version: %" PRIu16
7747 ", Abbreviation section offset: %" PRIu64
7748 ", Address size: %" PRIu8
7749 ", Offset size: %" PRIu8
7750 "\n Type signature: %#" PRIx64
7751 ", Type offset: %#" PRIx64 " [%" PRIx64 "]\n"),
7752 (uint64_t) offset, version, abbroffset, addrsize, offsize,
7753 unit_id, (uint64_t) subdie_off, dieoffset);
7754 }
7755 else
7756 {
7757 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
7758 " Version: %" PRIu16
7759 ", Abbreviation section offset: %" PRIu64
7760 ", Address size: %" PRIu8
7761 ", Offset size: %" PRIu8 "\n"),
7762 (uint64_t) offset, version, abbroffset, addrsize, offsize);
7763
7764 if (version >= 5 || (unit_type != DW_UT_compile
7765 && unit_type != DW_UT_partial))
7766 {
7767 printf (gettext (" Unit type: %s (%" PRIu8 ")"),
7768 dwarf_unit_name (unit_type), unit_type);
7769 if (unit_type == DW_UT_type
7770 || unit_type == DW_UT_skeleton
7771 || unit_type == DW_UT_split_compile
7772 || unit_type == DW_UT_split_type)
7773 printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7774 if (unit_type == DW_UT_type
7775 || unit_type == DW_UT_split_type)
7776 {
7777 Dwarf_Die typedie;
7778 Dwarf_Off dieoffset;
7779 dwarf_cu_info (cu, NULL, NULL, NULL, &typedie,
7780 NULL, NULL, NULL);
7781 dieoffset = dwarf_dieoffset (&typedie);
7782 printf (", Unit DIE off: %#" PRIx64 " [%" PRIx64 "]",
7783 subdie_off, dieoffset);
7784 }
7785 printf ("\n");
7786 }
7787 }
7788 }
7789
7790 if (version < 2 || version > 5
7791 || unit_type < DW_UT_compile || unit_type > DW_UT_split_type)
7792 {
7793 if (!silent)
7794 error (0, 0, gettext ("unknown version (%d) or unit type (%d)"),
7795 version, unit_type);
7796 goto next_cu;
7797 }
7798
7799 struct attrcb_args args =
7800 {
7801 .dwflmod = dwflmod,
7802 .silent = silent,
7803 .version = version,
7804 .addrsize = addrsize,
7805 .offset_size = offsize
7806 };
7807
7808 bool is_split = false;
7809 int level = 0;
7810 dies[0] = cudie;
7811 args.cu = dies[0].cu;
7812 args.dbg = dbg;
7813 args.is_split = is_split;
7814
7815 /* We might return here again for the split CU subdie. */
7816 do_cu:
7817 do
7818 {
7819 Dwarf_Off offset = dwarf_dieoffset (&dies[level]);
7820 if (unlikely (offset == (Dwarf_Off) -1))
7821 {
7822 if (!silent)
7823 error (0, 0, gettext ("cannot get DIE offset: %s"),
7824 dwarf_errmsg (-1));
7825 goto do_return;
7826 }
7827
7828 int tag = dwarf_tag (&dies[level]);
7829 if (unlikely (tag == DW_TAG_invalid))
7830 {
7831 if (!silent)
7832 error (0, 0, gettext ("cannot get tag of DIE at offset [%" PRIx64
7833 "] in section '%s': %s"),
7834 (uint64_t) offset, secname, dwarf_errmsg (-1));
7835 goto do_return;
7836 }
7837
7838 if (!silent)
7839 {
7840 unsigned int code = dwarf_getabbrevcode (dies[level].abbrev);
7841 if (is_split)
7842 printf (" {%6" PRIx64 "} ", (uint64_t) offset);
7843 else
7844 printf (" [%6" PRIx64 "] ", (uint64_t) offset);
7845 printf ("%*s%-20s abbrev: %u\n", (int) (level * 2), "",
7846 dwarf_tag_name (tag), code);
7847 }
7848
7849 /* Print the attribute values. */
7850 args.level = level;
7851 args.dies = dies;
7852 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
7853
7854 /* Make room for the next level's DIE. */
7855 if (level + 1 == maxdies)
7856 dies = (Dwarf_Die *) xrealloc (dies,
7857 (maxdies += 10)
7858 * sizeof (Dwarf_Die));
7859
7860 int res = dwarf_child (&dies[level], &dies[level + 1]);
7861 if (res > 0)
7862 {
7863 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
7864 if (level-- == 0)
7865 break;
7866
7867 if (unlikely (res == -1))
7868 {
7869 if (!silent)
7870 error (0, 0, gettext ("cannot get next DIE: %s\n"),
7871 dwarf_errmsg (-1));
7872 goto do_return;
7873 }
7874 }
7875 else if (unlikely (res < 0))
7876 {
7877 if (!silent)
7878 error (0, 0, gettext ("cannot get next DIE: %s"),
7879 dwarf_errmsg (-1));
7880 goto do_return;
7881 }
7882 else
7883 ++level;
7884 }
7885 while (level >= 0);
7886
7887 /* We might want to show the split compile unit if this was a skeleton.
7888 We need to scan it if we are requesting printing .debug_ranges for
7889 DWARF4 since GNU DebugFission uses "offsets" into the main ranges
7890 section. */
7891 if (unit_type == DW_UT_skeleton
7892 && ((!silent && show_split_units)
7893 || (version < 5 && (print_debug_sections & section_ranges) != 0)))
7894 {
7895 Dwarf_Die subdie;
7896 if (dwarf_cu_info (cu, NULL, NULL, NULL, &subdie, NULL, NULL, NULL) != 0
7897 || dwarf_tag (&subdie) == DW_TAG_invalid)
7898 {
7899 if (!silent)
7900 {
7901 Dwarf_Attribute dwo_at;
7902 const char *dwo_name =
7903 (dwarf_formstring (dwarf_attr (&cudie, DW_AT_dwo_name,
7904 &dwo_at))
7905 ?: (dwarf_formstring (dwarf_attr (&cudie, DW_AT_GNU_dwo_name,
7906 &dwo_at))
7907 ?: "<unknown>"));
7908 fprintf (stderr,
7909 "Could not find split unit '%s', id: %" PRIx64 "\n",
7910 dwo_name, unit_id);
7911 }
7912 }
7913 else
7914 {
7915 Dwarf_CU *split_cu = subdie.cu;
7916 dwarf_cu_die (split_cu, &result, NULL, &abbroffset,
7917 &addrsize, &offsize, &unit_id, &subdie_off);
7918 Dwarf_Off offset = cu->start;
7919
7920 if (!silent)
7921 {
7922 printf (gettext (" Split compilation unit at offset %"
7923 PRIu64 ":\n"
7924 " Version: %" PRIu16
7925 ", Abbreviation section offset: %" PRIu64
7926 ", Address size: %" PRIu8
7927 ", Offset size: %" PRIu8 "\n"),
7928 (uint64_t) offset, version, abbroffset,
7929 addrsize, offsize);
7930 printf (gettext (" Unit type: %s (%" PRIu8 ")"),
7931 dwarf_unit_name (unit_type), unit_type);
7932 printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7933 printf ("\n");
7934 }
7935
7936 unit_type = DW_UT_split_compile;
7937 is_split = true;
7938 level = 0;
7939 dies[0] = subdie;
7940 args.cu = dies[0].cu;
7941 args.dbg = split_cu->dbg;
7942 args.is_split = is_split;
7943 goto do_cu;
7944 }
7945 }
7946
7947 /* And again... */
7948 goto next_cu;
7949
7950 do_return:
7951 free (dies);
7952 }
7953
7954 static void
print_debug_info_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7955 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7956 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7957 {
7958 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
7959 }
7960
7961 static void
print_debug_types_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7962 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7963 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7964 {
7965 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
7966 }
7967
7968
7969 static void
print_decoded_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7970 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
7971 GElf_Ehdr *ehdr __attribute__ ((unused)),
7972 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7973 {
7974 printf (gettext ("\
7975 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
7976 elf_ndxscn (scn), section_name (ebl, shdr),
7977 (uint64_t) shdr->sh_offset);
7978
7979 size_t address_size
7980 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
7981
7982 Dwarf_Lines *lines;
7983 size_t nlines;
7984 Dwarf_Off off, next_off = 0;
7985 Dwarf_CU *cu = NULL;
7986 while (dwarf_next_lines (dbg, off = next_off, &next_off, &cu, NULL, NULL,
7987 &lines, &nlines) == 0)
7988 {
7989 Dwarf_Die cudie;
7990 if (cu != NULL && dwarf_cu_info (cu, NULL, NULL, &cudie,
7991 NULL, NULL, NULL, NULL) == 0)
7992 printf (" CU [%" PRIx64 "] %s\n",
7993 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
7994 else
7995 {
7996 /* DWARF5 lines can be independent of any CU, but they probably
7997 are used by some CU. Determine the CU this block is for. */
7998 Dwarf_Off cuoffset;
7999 Dwarf_Off ncuoffset = 0;
8000 size_t hsize;
8001 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
8002 NULL, NULL, NULL) == 0)
8003 {
8004 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
8005 continue;
8006 Dwarf_Attribute stmt_list;
8007 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
8008 continue;
8009 Dwarf_Word lineoff;
8010 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
8011 continue;
8012 if (lineoff == off)
8013 {
8014 /* Found the CU. */
8015 cu = cudie.cu;
8016 break;
8017 }
8018 }
8019
8020 if (cu != NULL)
8021 printf (" CU [%" PRIx64 "] %s\n",
8022 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8023 else
8024 printf (" No CU\n");
8025 }
8026
8027 printf (" line:col SBPE* disc isa op address"
8028 " (Statement Block Prologue Epilogue *End)\n");
8029 const char *last_file = "";
8030 for (size_t n = 0; n < nlines; n++)
8031 {
8032 Dwarf_Line *line = dwarf_onesrcline (lines, n);
8033 if (line == NULL)
8034 {
8035 printf (" dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
8036 continue;
8037 }
8038 Dwarf_Word mtime, length;
8039 const char *file = dwarf_linesrc (line, &mtime, &length);
8040 if (file == NULL)
8041 {
8042 printf (" <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
8043 last_file = "";
8044 }
8045 else if (strcmp (last_file, file) != 0)
8046 {
8047 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
8048 file, mtime, length);
8049 last_file = file;
8050 }
8051
8052 int lineno, colno;
8053 bool statement, endseq, block, prologue_end, epilogue_begin;
8054 unsigned int lineop, isa, disc;
8055 Dwarf_Addr address;
8056 dwarf_lineaddr (line, &address);
8057 dwarf_lineno (line, &lineno);
8058 dwarf_linecol (line, &colno);
8059 dwarf_lineop_index (line, &lineop);
8060 dwarf_linebeginstatement (line, &statement);
8061 dwarf_lineendsequence (line, &endseq);
8062 dwarf_lineblock (line, &block);
8063 dwarf_lineprologueend (line, &prologue_end);
8064 dwarf_lineepiloguebegin (line, &epilogue_begin);
8065 dwarf_lineisa (line, &isa);
8066 dwarf_linediscriminator (line, &disc);
8067
8068 /* End sequence is special, it is one byte past. */
8069 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d ",
8070 lineno, colno,
8071 (statement ? 'S' : ' '),
8072 (block ? 'B' : ' '),
8073 (prologue_end ? 'P' : ' '),
8074 (epilogue_begin ? 'E' : ' '),
8075 (endseq ? '*' : ' '),
8076 disc, isa, lineop);
8077 print_dwarf_addr (dwflmod, address_size,
8078 address - (endseq ? 1 : 0), address);
8079 printf ("\n");
8080
8081 if (endseq)
8082 printf("\n");
8083 }
8084 }
8085 }
8086
8087
8088 /* Print the value of a form.
8089 Returns new value of readp, or readendp on failure. */
8090 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)8091 print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
8092 const unsigned char *readendp, unsigned int offset_len,
8093 Dwarf_Off str_offsets_base)
8094 {
8095 Dwarf_Word val;
8096 unsigned char *endp;
8097 Elf_Data *data;
8098 char *str;
8099 switch (form)
8100 {
8101 case DW_FORM_data1:
8102 if (readendp - readp < 1)
8103 {
8104 invalid_data:
8105 error (0, 0, "invalid data");
8106 return readendp;
8107 }
8108 val = *readp++;
8109 printf (" %" PRIx8, (unsigned int) val);
8110 break;
8111
8112 case DW_FORM_data2:
8113 if (readendp - readp < 2)
8114 goto invalid_data;
8115 val = read_2ubyte_unaligned_inc (dbg, readp);
8116 printf(" %" PRIx16, (unsigned int) val);
8117 break;
8118
8119 case DW_FORM_data4:
8120 if (readendp - readp < 4)
8121 goto invalid_data;
8122 val = read_4ubyte_unaligned_inc (dbg, readp);
8123 printf (" %" PRIx32, (unsigned int) val);
8124 break;
8125
8126 case DW_FORM_data8:
8127 if (readendp - readp < 8)
8128 goto invalid_data;
8129 val = read_8ubyte_unaligned_inc (dbg, readp);
8130 printf (" %" PRIx64, val);
8131 break;
8132
8133 case DW_FORM_sdata:
8134 if (readendp - readp < 1)
8135 goto invalid_data;
8136 get_sleb128 (val, readp, readendp);
8137 printf (" %" PRIx64, val);
8138 break;
8139
8140 case DW_FORM_udata:
8141 if (readendp - readp < 1)
8142 goto invalid_data;
8143 get_uleb128 (val, readp, readendp);
8144 printf (" %" PRIx64, val);
8145 break;
8146
8147 case DW_FORM_block:
8148 if (readendp - readp < 1)
8149 goto invalid_data;
8150 get_uleb128 (val, readp, readendp);
8151 if ((size_t) (readendp - readp) < val)
8152 goto invalid_data;
8153 print_bytes (val, readp);
8154 readp += val;
8155 break;
8156
8157 case DW_FORM_block1:
8158 if (readendp - readp < 1)
8159 goto invalid_data;
8160 val = *readp++;
8161 if ((size_t) (readendp - readp) < val)
8162 goto invalid_data;
8163 print_bytes (val, readp);
8164 readp += val;
8165 break;
8166
8167 case DW_FORM_block2:
8168 if (readendp - readp < 2)
8169 goto invalid_data;
8170 val = read_2ubyte_unaligned_inc (dbg, readp);
8171 if ((size_t) (readendp - readp) < val)
8172 goto invalid_data;
8173 print_bytes (val, readp);
8174 readp += val;
8175 break;
8176
8177 case DW_FORM_block4:
8178 if (readendp - readp < 4)
8179 goto invalid_data;
8180 val = read_4ubyte_unaligned_inc (dbg, readp);
8181 if ((size_t) (readendp - readp) < val)
8182 goto invalid_data;
8183 print_bytes (val, readp);
8184 readp += val;
8185 break;
8186
8187 case DW_FORM_data16:
8188 if (readendp - readp < 16)
8189 goto invalid_data;
8190 print_bytes (16, readp);
8191 readp += 16;
8192 break;
8193
8194 case DW_FORM_flag:
8195 if (readendp - readp < 1)
8196 goto invalid_data;
8197 val = *readp++;
8198 printf ("%s", val != 0 ? yes_str : no_str);
8199 break;
8200
8201 case DW_FORM_string:
8202 endp = memchr (readp, '\0', readendp - readp);
8203 if (endp == NULL)
8204 goto invalid_data;
8205 printf ("%s", readp);
8206 readp = endp + 1;
8207 break;
8208
8209 case DW_FORM_strp:
8210 case DW_FORM_line_strp:
8211 case DW_FORM_strp_sup:
8212 if ((size_t) (readendp - readp) < offset_len)
8213 goto invalid_data;
8214 if (offset_len == 8)
8215 val = read_8ubyte_unaligned_inc (dbg, readp);
8216 else
8217 val = read_4ubyte_unaligned_inc (dbg, readp);
8218 if (form == DW_FORM_strp)
8219 data = dbg->sectiondata[IDX_debug_str];
8220 else if (form == DW_FORM_line_strp)
8221 data = dbg->sectiondata[IDX_debug_line_str];
8222 else /* form == DW_FORM_strp_sup */
8223 {
8224 Dwarf *alt = dwarf_getalt (dbg);
8225 data = alt != NULL ? alt->sectiondata[IDX_debug_str] : NULL;
8226 }
8227 if (data == NULL || val >= data->d_size
8228 || memchr (data->d_buf + val, '\0', data->d_size - val) == NULL)
8229 str = "???";
8230 else
8231 str = (char *) data->d_buf + val;
8232 printf ("%s (%" PRIu64 ")", str, val);
8233 break;
8234
8235 case DW_FORM_sec_offset:
8236 if ((size_t) (readendp - readp) < offset_len)
8237 goto invalid_data;
8238 if (offset_len == 8)
8239 val = read_8ubyte_unaligned_inc (dbg, readp);
8240 else
8241 val = read_4ubyte_unaligned_inc (dbg, readp);
8242 printf ("[%" PRIx64 "]", val);
8243 break;
8244
8245 case DW_FORM_strx:
8246 case DW_FORM_GNU_str_index:
8247 if (readendp - readp < 1)
8248 goto invalid_data;
8249 get_uleb128 (val, readp, readendp);
8250 strx_val:
8251 data = dbg->sectiondata[IDX_debug_str_offsets];
8252 if (data == NULL
8253 || data->d_size - str_offsets_base < val)
8254 str = "???";
8255 else
8256 {
8257 const unsigned char *strreadp = data->d_buf + str_offsets_base + val;
8258 const unsigned char *strreadendp = data->d_buf + data->d_size;
8259 if ((size_t) (strreadendp - strreadp) < offset_len)
8260 str = "???";
8261 else
8262 {
8263 Dwarf_Off idx;
8264 if (offset_len == 8)
8265 idx = read_8ubyte_unaligned (dbg, strreadp);
8266 else
8267 idx = read_4ubyte_unaligned (dbg, strreadp);
8268
8269 data = dbg->sectiondata[IDX_debug_str];
8270 if (data == NULL || idx >= data->d_size
8271 || memchr (data->d_buf + idx, '\0',
8272 data->d_size - idx) == NULL)
8273 str = "???";
8274 else
8275 str = (char *) data->d_buf + idx;
8276 }
8277 }
8278 printf ("%s (%" PRIu64 ")", str, val);
8279 break;
8280
8281 case DW_FORM_strx1:
8282 if (readendp - readp < 1)
8283 goto invalid_data;
8284 val = *readp++;
8285 goto strx_val;
8286
8287 case DW_FORM_strx2:
8288 if (readendp - readp < 2)
8289 goto invalid_data;
8290 val = read_2ubyte_unaligned_inc (dbg, readp);
8291 goto strx_val;
8292
8293 case DW_FORM_strx3:
8294 if (readendp - readp < 3)
8295 goto invalid_data;
8296 val = read_3ubyte_unaligned_inc (dbg, readp);
8297 goto strx_val;
8298
8299 case DW_FORM_strx4:
8300 if (readendp - readp < 4)
8301 goto invalid_data;
8302 val = read_4ubyte_unaligned_inc (dbg, readp);
8303 goto strx_val;
8304
8305 default:
8306 error (0, 0, gettext ("unknown form: %s"), dwarf_form_name (form));
8307 return readendp;
8308 }
8309
8310 return readp;
8311 }
8312
8313 static void
print_debug_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8314 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8315 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8316 {
8317 if (decodedline)
8318 {
8319 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
8320 return;
8321 }
8322
8323 printf (gettext ("\
8324 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
8325 elf_ndxscn (scn), section_name (ebl, shdr),
8326 (uint64_t) shdr->sh_offset);
8327
8328 if (shdr->sh_size == 0)
8329 return;
8330
8331 /* There is no functionality in libdw to read the information in the
8332 way it is represented here. Hardcode the decoder. */
8333 Elf_Data *data = (dbg->sectiondata[IDX_debug_line]
8334 ?: elf_rawdata (scn, NULL));
8335 if (unlikely (data == NULL))
8336 {
8337 error (0, 0, gettext ("cannot get line data section data: %s"),
8338 elf_errmsg (-1));
8339 return;
8340 }
8341
8342 const unsigned char *linep = (const unsigned char *) data->d_buf;
8343 const unsigned char *lineendp;
8344
8345 while (linep
8346 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
8347 {
8348 size_t start_offset = linep - (const unsigned char *) data->d_buf;
8349
8350 printf (gettext ("\nTable at offset %zu:\n"), start_offset);
8351
8352 if (unlikely (linep + 4 > lineendp))
8353 goto invalid_data;
8354 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
8355 unsigned int length = 4;
8356 if (unlikely (unit_length == 0xffffffff))
8357 {
8358 if (unlikely (linep + 8 > lineendp))
8359 {
8360 invalid_data:
8361 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
8362 elf_ndxscn (scn), section_name (ebl, shdr));
8363 return;
8364 }
8365 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
8366 length = 8;
8367 }
8368
8369 /* Check whether we have enough room in the section. */
8370 if (unlikely (unit_length > (size_t) (lineendp - linep)))
8371 goto invalid_data;
8372 lineendp = linep + unit_length;
8373
8374 /* The next element of the header is the version identifier. */
8375 if ((size_t) (lineendp - linep) < 2)
8376 goto invalid_data;
8377 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
8378
8379 size_t address_size
8380 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
8381 unsigned char segment_selector_size = 0;
8382 if (version > 4)
8383 {
8384 if ((size_t) (lineendp - linep) < 2)
8385 goto invalid_data;
8386 address_size = *linep++;
8387 segment_selector_size = *linep++;
8388 }
8389
8390 /* Next comes the header length. */
8391 Dwarf_Word header_length;
8392 if (length == 4)
8393 {
8394 if ((size_t) (lineendp - linep) < 4)
8395 goto invalid_data;
8396 header_length = read_4ubyte_unaligned_inc (dbg, linep);
8397 }
8398 else
8399 {
8400 if ((size_t) (lineendp - linep) < 8)
8401 goto invalid_data;
8402 header_length = read_8ubyte_unaligned_inc (dbg, linep);
8403 }
8404
8405 /* Next the minimum instruction length. */
8406 if ((size_t) (lineendp - linep) < 1)
8407 goto invalid_data;
8408 uint_fast8_t minimum_instr_len = *linep++;
8409
8410 /* Next the maximum operations per instruction, in version 4 format. */
8411 uint_fast8_t max_ops_per_instr;
8412 if (version < 4)
8413 max_ops_per_instr = 1;
8414 else
8415 {
8416 if ((size_t) (lineendp - linep) < 1)
8417 goto invalid_data;
8418 max_ops_per_instr = *linep++;
8419 }
8420
8421 /* We need at least 4 more bytes. */
8422 if ((size_t) (lineendp - linep) < 4)
8423 goto invalid_data;
8424
8425 /* Then the flag determining the default value of the is_stmt
8426 register. */
8427 uint_fast8_t default_is_stmt = *linep++;
8428
8429 /* Now the line base. */
8430 int_fast8_t line_base = *linep++;
8431
8432 /* And the line range. */
8433 uint_fast8_t line_range = *linep++;
8434
8435 /* The opcode base. */
8436 uint_fast8_t opcode_base = *linep++;
8437
8438 /* Print what we got so far. */
8439 printf (gettext ("\n"
8440 " Length: %" PRIu64 "\n"
8441 " DWARF version: %" PRIuFAST16 "\n"
8442 " Prologue length: %" PRIu64 "\n"
8443 " Address size: %zd\n"
8444 " Segment selector size: %zd\n"
8445 " Min instruction length: %" PRIuFAST8 "\n"
8446 " Max operations per instruction: %" PRIuFAST8 "\n"
8447 " Initial value if 'is_stmt': %" PRIuFAST8 "\n"
8448 " Line base: %" PRIdFAST8 "\n"
8449 " Line range: %" PRIuFAST8 "\n"
8450 " Opcode base: %" PRIuFAST8 "\n"
8451 "\n"
8452 "Opcodes:\n"),
8453 (uint64_t) unit_length, version, (uint64_t) header_length,
8454 address_size, (size_t) segment_selector_size,
8455 minimum_instr_len, max_ops_per_instr,
8456 default_is_stmt, line_base,
8457 line_range, opcode_base);
8458
8459 if (version < 2 || version > 5)
8460 {
8461 error (0, 0, gettext ("cannot handle .debug_line version: %u\n"),
8462 (unsigned int) version);
8463 linep = lineendp;
8464 continue;
8465 }
8466
8467 if (address_size != 4 && address_size != 8)
8468 {
8469 error (0, 0, gettext ("cannot handle address size: %u\n"),
8470 (unsigned int) address_size);
8471 linep = lineendp;
8472 continue;
8473 }
8474
8475 if (segment_selector_size != 0)
8476 {
8477 error (0, 0, gettext ("cannot handle segment selector size: %u\n"),
8478 (unsigned int) segment_selector_size);
8479 linep = lineendp;
8480 continue;
8481 }
8482
8483 if (unlikely (linep + opcode_base - 1 >= lineendp))
8484 {
8485 invalid_unit:
8486 error (0, 0,
8487 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
8488 linep - (const unsigned char *) data->d_buf,
8489 elf_ndxscn (scn), section_name (ebl, shdr));
8490 linep = lineendp;
8491 continue;
8492 }
8493 int opcode_base_l10 = 1;
8494 unsigned int tmp = opcode_base;
8495 while (tmp > 10)
8496 {
8497 tmp /= 10;
8498 ++opcode_base_l10;
8499 }
8500 const uint8_t *standard_opcode_lengths = linep - 1;
8501 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
8502 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
8503 " [%*" PRIuFAST8 "] %hhu arguments\n",
8504 (int) linep[cnt - 1]),
8505 opcode_base_l10, cnt, linep[cnt - 1]);
8506 linep += opcode_base - 1;
8507
8508 if (unlikely (linep >= lineendp))
8509 goto invalid_unit;
8510
8511 Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, NULL);
8512
8513 puts (gettext ("\nDirectory table:"));
8514 if (version > 4)
8515 {
8516 struct encpair { uint16_t desc; uint16_t form; };
8517 struct encpair enc[256];
8518
8519 printf (gettext (" ["));
8520 if ((size_t) (lineendp - linep) < 1)
8521 goto invalid_data;
8522 unsigned char directory_entry_format_count = *linep++;
8523 for (int i = 0; i < directory_entry_format_count; i++)
8524 {
8525 uint16_t desc, form;
8526 if ((size_t) (lineendp - linep) < 1)
8527 goto invalid_data;
8528 get_uleb128 (desc, linep, lineendp);
8529 if ((size_t) (lineendp - linep) < 1)
8530 goto invalid_data;
8531 get_uleb128 (form, linep, lineendp);
8532
8533 enc[i].desc = desc;
8534 enc[i].form = form;
8535
8536 printf ("%s(%s)",
8537 dwarf_line_content_description_name (desc),
8538 dwarf_form_name (form));
8539 if (i + 1 < directory_entry_format_count)
8540 printf (", ");
8541 }
8542 printf ("]\n");
8543
8544 uint64_t directories_count;
8545 if ((size_t) (lineendp - linep) < 1)
8546 goto invalid_data;
8547 get_uleb128 (directories_count, linep, lineendp);
8548
8549 if (directory_entry_format_count == 0
8550 && directories_count != 0)
8551 goto invalid_data;
8552
8553 for (uint64_t i = 0; i < directories_count; i++)
8554 {
8555 printf (" %-5" PRIu64 " ", i);
8556 for (int j = 0; j < directory_entry_format_count; j++)
8557 {
8558 linep = print_form_data (dbg, enc[j].form,
8559 linep, lineendp, length,
8560 str_offsets_base);
8561 if (j + 1 < directory_entry_format_count)
8562 printf (", ");
8563 }
8564 printf ("\n");
8565 if (linep >= lineendp)
8566 goto invalid_unit;
8567 }
8568 }
8569 else
8570 {
8571 while (linep < lineendp && *linep != 0)
8572 {
8573 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
8574 if (unlikely (endp == NULL))
8575 goto invalid_unit;
8576
8577 printf (" %s\n", (char *) linep);
8578
8579 linep = endp + 1;
8580 }
8581 if (linep >= lineendp || *linep != 0)
8582 goto invalid_unit;
8583 /* Skip the final NUL byte. */
8584 ++linep;
8585 }
8586
8587 if (unlikely (linep >= lineendp))
8588 goto invalid_unit;
8589
8590 puts (gettext ("\nFile name table:"));
8591 if (version > 4)
8592 {
8593 struct encpair { uint16_t desc; uint16_t form; };
8594 struct encpair enc[256];
8595
8596 printf (gettext (" ["));
8597 if ((size_t) (lineendp - linep) < 1)
8598 goto invalid_data;
8599 unsigned char file_name_format_count = *linep++;
8600 for (int i = 0; i < file_name_format_count; i++)
8601 {
8602 uint64_t desc, form;
8603 if ((size_t) (lineendp - linep) < 1)
8604 goto invalid_data;
8605 get_uleb128 (desc, linep, lineendp);
8606 if ((size_t) (lineendp - linep) < 1)
8607 goto invalid_data;
8608 get_uleb128 (form, linep, lineendp);
8609
8610 if (! libdw_valid_user_form (form))
8611 goto invalid_data;
8612
8613 enc[i].desc = desc;
8614 enc[i].form = form;
8615
8616 printf ("%s(%s)",
8617 dwarf_line_content_description_name (desc),
8618 dwarf_form_name (form));
8619 if (i + 1 < file_name_format_count)
8620 printf (", ");
8621 }
8622 printf ("]\n");
8623
8624 uint64_t file_name_count;
8625 if ((size_t) (lineendp - linep) < 1)
8626 goto invalid_data;
8627 get_uleb128 (file_name_count, linep, lineendp);
8628
8629 if (file_name_format_count == 0
8630 && file_name_count != 0)
8631 goto invalid_data;
8632
8633 for (uint64_t i = 0; i < file_name_count; i++)
8634 {
8635 printf (" %-5" PRIu64 " ", i);
8636 for (int j = 0; j < file_name_format_count; j++)
8637 {
8638 linep = print_form_data (dbg, enc[j].form,
8639 linep, lineendp, length,
8640 str_offsets_base);
8641 if (j + 1 < file_name_format_count)
8642 printf (", ");
8643 }
8644 printf ("\n");
8645 if (linep >= lineendp)
8646 goto invalid_unit;
8647 }
8648 }
8649 else
8650 {
8651 puts (gettext (" Entry Dir Time Size Name"));
8652 for (unsigned int cnt = 1; linep < lineendp && *linep != 0; ++cnt)
8653 {
8654 /* First comes the file name. */
8655 char *fname = (char *) linep;
8656 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
8657 if (unlikely (endp == NULL))
8658 goto invalid_unit;
8659 linep = endp + 1;
8660
8661 /* Then the index. */
8662 unsigned int diridx;
8663 if (lineendp - linep < 1)
8664 goto invalid_unit;
8665 get_uleb128 (diridx, linep, lineendp);
8666
8667 /* Next comes the modification time. */
8668 unsigned int mtime;
8669 if (lineendp - linep < 1)
8670 goto invalid_unit;
8671 get_uleb128 (mtime, linep, lineendp);
8672
8673 /* Finally the length of the file. */
8674 unsigned int fsize;
8675 if (lineendp - linep < 1)
8676 goto invalid_unit;
8677 get_uleb128 (fsize, linep, lineendp);
8678
8679 printf (" %-5u %-5u %-9u %-9u %s\n",
8680 cnt, diridx, mtime, fsize, fname);
8681 }
8682 if (linep >= lineendp || *linep != '\0')
8683 goto invalid_unit;
8684 /* Skip the final NUL byte. */
8685 ++linep;
8686 }
8687
8688 puts (gettext ("\nLine number statements:"));
8689 Dwarf_Word address = 0;
8690 unsigned int op_index = 0;
8691 size_t line = 1;
8692 uint_fast8_t is_stmt = default_is_stmt;
8693
8694 /* Apply the "operation advance" from a special opcode
8695 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
8696 unsigned int op_addr_advance;
8697 bool show_op_index;
8698 inline void advance_pc (unsigned int op_advance)
8699 {
8700 op_addr_advance = minimum_instr_len * ((op_index + op_advance)
8701 / max_ops_per_instr);
8702 address += op_addr_advance;
8703 show_op_index = (op_index > 0 ||
8704 (op_index + op_advance) % max_ops_per_instr > 0);
8705 op_index = (op_index + op_advance) % max_ops_per_instr;
8706 }
8707
8708 if (max_ops_per_instr == 0)
8709 {
8710 error (0, 0,
8711 gettext ("invalid maximum operations per instruction is zero"));
8712 linep = lineendp;
8713 continue;
8714 }
8715
8716 while (linep < lineendp)
8717 {
8718 size_t offset = linep - (const unsigned char *) data->d_buf;
8719 unsigned int u128;
8720 int s128;
8721
8722 /* Read the opcode. */
8723 unsigned int opcode = *linep++;
8724
8725 printf (" [%6" PRIx64 "]", (uint64_t)offset);
8726 /* Is this a special opcode? */
8727 if (likely (opcode >= opcode_base))
8728 {
8729 if (unlikely (line_range == 0))
8730 goto invalid_unit;
8731
8732 /* Yes. Handling this is quite easy since the opcode value
8733 is computed with
8734
8735 opcode = (desired line increment - line_base)
8736 + (line_range * address advance) + opcode_base
8737 */
8738 int line_increment = (line_base
8739 + (opcode - opcode_base) % line_range);
8740
8741 /* Perform the increments. */
8742 line += line_increment;
8743 advance_pc ((opcode - opcode_base) / line_range);
8744
8745 printf (gettext (" special opcode %u: address+%u = "),
8746 opcode, op_addr_advance);
8747 print_dwarf_addr (dwflmod, 0, address, address);
8748 if (show_op_index)
8749 printf (gettext (", op_index = %u, line%+d = %zu\n"),
8750 op_index, line_increment, line);
8751 else
8752 printf (gettext (", line%+d = %zu\n"),
8753 line_increment, line);
8754 }
8755 else if (opcode == 0)
8756 {
8757 /* This an extended opcode. */
8758 if (unlikely (linep + 2 > lineendp))
8759 goto invalid_unit;
8760
8761 /* The length. */
8762 unsigned int len = *linep++;
8763
8764 if (unlikely (linep + len > lineendp))
8765 goto invalid_unit;
8766
8767 /* The sub-opcode. */
8768 opcode = *linep++;
8769
8770 printf (gettext (" extended opcode %u: "), opcode);
8771
8772 switch (opcode)
8773 {
8774 case DW_LNE_end_sequence:
8775 puts (gettext (" end of sequence"));
8776
8777 /* Reset the registers we care about. */
8778 address = 0;
8779 op_index = 0;
8780 line = 1;
8781 is_stmt = default_is_stmt;
8782 break;
8783
8784 case DW_LNE_set_address:
8785 op_index = 0;
8786 if (unlikely ((size_t) (lineendp - linep) < address_size))
8787 goto invalid_unit;
8788 if (address_size == 4)
8789 address = read_4ubyte_unaligned_inc (dbg, linep);
8790 else
8791 address = read_8ubyte_unaligned_inc (dbg, linep);
8792 {
8793 printf (gettext (" set address to "));
8794 print_dwarf_addr (dwflmod, 0, address, address);
8795 printf ("\n");
8796 }
8797 break;
8798
8799 case DW_LNE_define_file:
8800 {
8801 char *fname = (char *) linep;
8802 unsigned char *endp = memchr (linep, '\0',
8803 lineendp - linep);
8804 if (unlikely (endp == NULL))
8805 goto invalid_unit;
8806 linep = endp + 1;
8807
8808 unsigned int diridx;
8809 if (lineendp - linep < 1)
8810 goto invalid_unit;
8811 get_uleb128 (diridx, linep, lineendp);
8812 Dwarf_Word mtime;
8813 if (lineendp - linep < 1)
8814 goto invalid_unit;
8815 get_uleb128 (mtime, linep, lineendp);
8816 Dwarf_Word filelength;
8817 if (lineendp - linep < 1)
8818 goto invalid_unit;
8819 get_uleb128 (filelength, linep, lineendp);
8820
8821 printf (gettext ("\
8822 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
8823 diridx, (uint64_t) mtime, (uint64_t) filelength,
8824 fname);
8825 }
8826 break;
8827
8828 case DW_LNE_set_discriminator:
8829 /* Takes one ULEB128 parameter, the discriminator. */
8830 if (unlikely (standard_opcode_lengths[opcode] != 1
8831 || lineendp - linep < 1))
8832 goto invalid_unit;
8833
8834 get_uleb128 (u128, linep, lineendp);
8835 printf (gettext (" set discriminator to %u\n"), u128);
8836 break;
8837
8838 default:
8839 /* Unknown, ignore it. */
8840 puts (gettext (" unknown opcode"));
8841 linep += len - 1;
8842 break;
8843 }
8844 }
8845 else if (opcode <= DW_LNS_set_isa)
8846 {
8847 /* This is a known standard opcode. */
8848 switch (opcode)
8849 {
8850 case DW_LNS_copy:
8851 /* Takes no argument. */
8852 puts (gettext (" copy"));
8853 break;
8854
8855 case DW_LNS_advance_pc:
8856 /* Takes one uleb128 parameter which is added to the
8857 address. */
8858 if (lineendp - linep < 1)
8859 goto invalid_unit;
8860 get_uleb128 (u128, linep, lineendp);
8861 advance_pc (u128);
8862 {
8863 printf (gettext (" advance address by %u to "),
8864 op_addr_advance);
8865 print_dwarf_addr (dwflmod, 0, address, address);
8866 if (show_op_index)
8867 printf (gettext (", op_index to %u"), op_index);
8868 printf ("\n");
8869 }
8870 break;
8871
8872 case DW_LNS_advance_line:
8873 /* Takes one sleb128 parameter which is added to the
8874 line. */
8875 if (lineendp - linep < 1)
8876 goto invalid_unit;
8877 get_sleb128 (s128, linep, lineendp);
8878 line += s128;
8879 printf (gettext ("\
8880 advance line by constant %d to %" PRId64 "\n"),
8881 s128, (int64_t) line);
8882 break;
8883
8884 case DW_LNS_set_file:
8885 /* Takes one uleb128 parameter which is stored in file. */
8886 if (lineendp - linep < 1)
8887 goto invalid_unit;
8888 get_uleb128 (u128, linep, lineendp);
8889 printf (gettext (" set file to %" PRIu64 "\n"),
8890 (uint64_t) u128);
8891 break;
8892
8893 case DW_LNS_set_column:
8894 /* Takes one uleb128 parameter which is stored in column. */
8895 if (unlikely (standard_opcode_lengths[opcode] != 1
8896 || lineendp - linep < 1))
8897 goto invalid_unit;
8898
8899 get_uleb128 (u128, linep, lineendp);
8900 printf (gettext (" set column to %" PRIu64 "\n"),
8901 (uint64_t) u128);
8902 break;
8903
8904 case DW_LNS_negate_stmt:
8905 /* Takes no argument. */
8906 is_stmt = 1 - is_stmt;
8907 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
8908 "is_stmt", is_stmt);
8909 break;
8910
8911 case DW_LNS_set_basic_block:
8912 /* Takes no argument. */
8913 puts (gettext (" set basic block flag"));
8914 break;
8915
8916 case DW_LNS_const_add_pc:
8917 /* Takes no argument. */
8918
8919 if (unlikely (line_range == 0))
8920 goto invalid_unit;
8921
8922 advance_pc ((255 - opcode_base) / line_range);
8923 {
8924 printf (gettext (" advance address by constant %u to "),
8925 op_addr_advance);
8926 print_dwarf_addr (dwflmod, 0, address, address);
8927 if (show_op_index)
8928 printf (gettext (", op_index to %u"), op_index);
8929 printf ("\n");
8930 }
8931 break;
8932
8933 case DW_LNS_fixed_advance_pc:
8934 /* Takes one 16 bit parameter which is added to the
8935 address. */
8936 if (unlikely (standard_opcode_lengths[opcode] != 1
8937 || lineendp - linep < 2))
8938 goto invalid_unit;
8939
8940 u128 = read_2ubyte_unaligned_inc (dbg, linep);
8941 address += u128;
8942 op_index = 0;
8943 {
8944 printf (gettext ("\
8945 advance address by fixed value %u to \n"),
8946 u128);
8947 print_dwarf_addr (dwflmod, 0, address, address);
8948 printf ("\n");
8949 }
8950 break;
8951
8952 case DW_LNS_set_prologue_end:
8953 /* Takes no argument. */
8954 puts (gettext (" set prologue end flag"));
8955 break;
8956
8957 case DW_LNS_set_epilogue_begin:
8958 /* Takes no argument. */
8959 puts (gettext (" set epilogue begin flag"));
8960 break;
8961
8962 case DW_LNS_set_isa:
8963 /* Takes one uleb128 parameter which is stored in isa. */
8964 if (unlikely (standard_opcode_lengths[opcode] != 1
8965 || lineendp - linep < 1))
8966 goto invalid_unit;
8967
8968 get_uleb128 (u128, linep, lineendp);
8969 printf (gettext (" set isa to %u\n"), u128);
8970 break;
8971 }
8972 }
8973 else
8974 {
8975 /* This is a new opcode the generator but not we know about.
8976 Read the parameters associated with it but then discard
8977 everything. Read all the parameters for this opcode. */
8978 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
8979 " unknown opcode with %" PRIu8 " parameters:",
8980 standard_opcode_lengths[opcode]),
8981 standard_opcode_lengths[opcode]);
8982 for (int n = standard_opcode_lengths[opcode];
8983 n > 0 && linep < lineendp; --n)
8984 {
8985 get_uleb128 (u128, linep, lineendp);
8986 if (n != standard_opcode_lengths[opcode])
8987 putc_unlocked (',', stdout);
8988 printf (" %u", u128);
8989 }
8990
8991 /* Next round, ignore this opcode. */
8992 continue;
8993 }
8994 }
8995 }
8996
8997 /* There must only be one data block. */
8998 assert (elf_getdata (scn, data) == NULL);
8999 }
9000
9001
9002 static void
print_debug_loclists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9003 print_debug_loclists_section (Dwfl_Module *dwflmod,
9004 Ebl *ebl,
9005 GElf_Ehdr *ehdr __attribute__ ((unused)),
9006 Elf_Scn *scn, GElf_Shdr *shdr,
9007 Dwarf *dbg)
9008 {
9009 printf (gettext ("\
9010 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9011 elf_ndxscn (scn), section_name (ebl, shdr),
9012 (uint64_t) shdr->sh_offset);
9013
9014 Elf_Data *data = (dbg->sectiondata[IDX_debug_loclists]
9015 ?: elf_rawdata (scn, NULL));
9016 if (unlikely (data == NULL))
9017 {
9018 error (0, 0, gettext ("cannot get .debug_loclists content: %s"),
9019 elf_errmsg (-1));
9020 return;
9021 }
9022
9023 /* For the listptr to get the base address/CU. */
9024 sort_listptr (&known_loclistsptr, "loclistsptr");
9025 size_t listptr_idx = 0;
9026
9027 const unsigned char *readp = data->d_buf;
9028 const unsigned char *const dataend = ((unsigned char *) data->d_buf
9029 + data->d_size);
9030 while (readp < dataend)
9031 {
9032 if (unlikely (readp > dataend - 4))
9033 {
9034 invalid_data:
9035 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
9036 elf_ndxscn (scn), section_name (ebl, shdr));
9037 return;
9038 }
9039
9040 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9041 printf (gettext ("Table at Offset 0x%" PRIx64 ":\n\n"),
9042 (uint64_t) offset);
9043
9044 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
9045 unsigned int offset_size = 4;
9046 if (unlikely (unit_length == 0xffffffff))
9047 {
9048 if (unlikely (readp > dataend - 8))
9049 goto invalid_data;
9050
9051 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
9052 offset_size = 8;
9053 }
9054 printf (gettext (" Length: %8" PRIu64 "\n"), unit_length);
9055
9056 /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
9057 bytes to complete the header. And this unit cannot go beyond
9058 the section data. */
9059 if (readp > dataend - 8
9060 || unit_length < 8
9061 || unit_length > (uint64_t) (dataend - readp))
9062 goto invalid_data;
9063
9064 const unsigned char *nexthdr = readp + unit_length;
9065
9066 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
9067 printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
9068
9069 if (version != 5)
9070 {
9071 error (0, 0, gettext ("Unknown version"));
9072 goto next_table;
9073 }
9074
9075 uint8_t address_size = *readp++;
9076 printf (gettext (" Address size: %8" PRIu64 "\n"),
9077 (uint64_t) address_size);
9078
9079 if (address_size != 4 && address_size != 8)
9080 {
9081 error (0, 0, gettext ("unsupported address size"));
9082 goto next_table;
9083 }
9084
9085 uint8_t segment_size = *readp++;
9086 printf (gettext (" Segment size: %8" PRIu64 "\n"),
9087 (uint64_t) segment_size);
9088
9089 if (segment_size != 0)
9090 {
9091 error (0, 0, gettext ("unsupported segment size"));
9092 goto next_table;
9093 }
9094
9095 uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
9096 printf (gettext (" Offset entries: %8" PRIu64 "\n"),
9097 (uint64_t) offset_entry_count);
9098
9099 /* We need the CU that uses this unit to get the initial base address. */
9100 Dwarf_Addr cu_base = 0;
9101 struct Dwarf_CU *cu = NULL;
9102 if (listptr_cu (&known_loclistsptr, &listptr_idx,
9103 (Dwarf_Off) offset,
9104 (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
9105 &cu_base, &cu)
9106 || split_dwarf_cu_base (dbg, &cu, &cu_base))
9107 {
9108 Dwarf_Die cudie;
9109 if (dwarf_cu_die (cu, &cudie,
9110 NULL, NULL, NULL, NULL,
9111 NULL, NULL) == NULL)
9112 printf (gettext (" Unknown CU base: "));
9113 else
9114 printf (gettext (" CU [%6" PRIx64 "] base: "),
9115 dwarf_dieoffset (&cudie));
9116 print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
9117 printf ("\n");
9118 }
9119 else
9120 printf (gettext (" Not associated with a CU.\n"));
9121
9122 printf ("\n");
9123
9124 const unsigned char *offset_array_start = readp;
9125 if (offset_entry_count > 0)
9126 {
9127 uint64_t max_entries = (unit_length - 8) / offset_size;
9128 if (offset_entry_count > max_entries)
9129 {
9130 error (0, 0,
9131 gettext ("too many offset entries for unit length"));
9132 offset_entry_count = max_entries;
9133 }
9134
9135 printf (gettext (" Offsets starting at 0x%" PRIx64 ":\n"),
9136 (uint64_t) (offset_array_start
9137 - (unsigned char *) data->d_buf));
9138 for (uint32_t idx = 0; idx < offset_entry_count; idx++)
9139 {
9140 printf (" [%6" PRIu32 "] ", idx);
9141 if (offset_size == 4)
9142 {
9143 uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
9144 printf ("0x%" PRIx32 "\n", off);
9145 }
9146 else
9147 {
9148 uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
9149 printf ("0x%" PRIx64 "\n", off);
9150 }
9151 }
9152 printf ("\n");
9153 }
9154
9155 Dwarf_Addr base = cu_base;
9156 bool start_of_list = true;
9157 while (readp < nexthdr)
9158 {
9159 uint8_t kind = *readp++;
9160 uint64_t op1, op2, len;
9161
9162 /* Skip padding. */
9163 if (start_of_list && kind == DW_LLE_end_of_list)
9164 continue;
9165
9166 if (start_of_list)
9167 {
9168 base = cu_base;
9169 printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9170 (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
9171 (uint64_t) (readp - offset_array_start - 1));
9172 start_of_list = false;
9173 }
9174
9175 printf (" %s", dwarf_loc_list_encoding_name (kind));
9176 switch (kind)
9177 {
9178 case DW_LLE_end_of_list:
9179 start_of_list = true;
9180 printf ("\n\n");
9181 break;
9182
9183 case DW_LLE_base_addressx:
9184 if ((uint64_t) (nexthdr - readp) < 1)
9185 {
9186 invalid_entry:
9187 error (0, 0, gettext ("invalid loclists data"));
9188 goto next_table;
9189 }
9190 get_uleb128 (op1, readp, nexthdr);
9191 printf (" %" PRIx64 "\n", op1);
9192 if (! print_unresolved_addresses)
9193 {
9194 Dwarf_Addr addr;
9195 if (get_indexed_addr (cu, op1, &addr) != 0)
9196 printf (" ???\n");
9197 else
9198 {
9199 printf (" ");
9200 print_dwarf_addr (dwflmod, address_size, addr, addr);
9201 printf ("\n");
9202 }
9203 }
9204 break;
9205
9206 case DW_LLE_startx_endx:
9207 if ((uint64_t) (nexthdr - readp) < 1)
9208 goto invalid_entry;
9209 get_uleb128 (op1, readp, nexthdr);
9210 if ((uint64_t) (nexthdr - readp) < 1)
9211 goto invalid_entry;
9212 get_uleb128 (op2, readp, nexthdr);
9213 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9214 if (! print_unresolved_addresses)
9215 {
9216 Dwarf_Addr addr1;
9217 Dwarf_Addr addr2;
9218 if (get_indexed_addr (cu, op1, &addr1) != 0
9219 || get_indexed_addr (cu, op2, &addr2) != 0)
9220 {
9221 printf (" ???..\n");
9222 printf (" ???\n");
9223 }
9224 else
9225 {
9226 printf (" ");
9227 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9228 printf ("..\n ");
9229 print_dwarf_addr (dwflmod, address_size,
9230 addr2 - 1, addr2);
9231 printf ("\n");
9232 }
9233 }
9234 if ((uint64_t) (nexthdr - readp) < 1)
9235 goto invalid_entry;
9236 get_uleb128 (len, readp, nexthdr);
9237 if ((uint64_t) (nexthdr - readp) < len)
9238 goto invalid_entry;
9239 print_ops (dwflmod, dbg, 8, 8, version,
9240 address_size, offset_size, cu, len, readp);
9241 readp += len;
9242 break;
9243
9244 case DW_LLE_startx_length:
9245 if ((uint64_t) (nexthdr - readp) < 1)
9246 goto invalid_entry;
9247 get_uleb128 (op1, readp, nexthdr);
9248 if ((uint64_t) (nexthdr - readp) < 1)
9249 goto invalid_entry;
9250 get_uleb128 (op2, readp, nexthdr);
9251 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9252 if (! print_unresolved_addresses)
9253 {
9254 Dwarf_Addr addr1;
9255 Dwarf_Addr addr2;
9256 if (get_indexed_addr (cu, op1, &addr1) != 0)
9257 {
9258 printf (" ???..\n");
9259 printf (" ???\n");
9260 }
9261 else
9262 {
9263 addr2 = addr1 + op2;
9264 printf (" ");
9265 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9266 printf ("..\n ");
9267 print_dwarf_addr (dwflmod, address_size,
9268 addr2 - 1, addr2);
9269 printf ("\n");
9270 }
9271 }
9272 if ((uint64_t) (nexthdr - readp) < 1)
9273 goto invalid_entry;
9274 get_uleb128 (len, readp, nexthdr);
9275 if ((uint64_t) (nexthdr - readp) < len)
9276 goto invalid_entry;
9277 print_ops (dwflmod, dbg, 8, 8, version,
9278 address_size, offset_size, cu, len, readp);
9279 readp += len;
9280 break;
9281
9282 case DW_LLE_offset_pair:
9283 if ((uint64_t) (nexthdr - readp) < 1)
9284 goto invalid_entry;
9285 get_uleb128 (op1, readp, nexthdr);
9286 if ((uint64_t) (nexthdr - readp) < 1)
9287 goto invalid_entry;
9288 get_uleb128 (op2, readp, nexthdr);
9289 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9290 if (! print_unresolved_addresses)
9291 {
9292 op1 += base;
9293 op2 += base;
9294 printf (" ");
9295 print_dwarf_addr (dwflmod, address_size, op1, op1);
9296 printf ("..\n ");
9297 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9298 printf ("\n");
9299 }
9300 if ((uint64_t) (nexthdr - readp) < 1)
9301 goto invalid_entry;
9302 get_uleb128 (len, readp, nexthdr);
9303 if ((uint64_t) (nexthdr - readp) < len)
9304 goto invalid_entry;
9305 print_ops (dwflmod, dbg, 8, 8, version,
9306 address_size, offset_size, cu, len, readp);
9307 readp += len;
9308 break;
9309
9310 case DW_LLE_default_location:
9311 if ((uint64_t) (nexthdr - readp) < 1)
9312 goto invalid_entry;
9313 get_uleb128 (len, readp, nexthdr);
9314 if ((uint64_t) (nexthdr - readp) < len)
9315 goto invalid_entry;
9316 print_ops (dwflmod, dbg, 8, 8, version,
9317 address_size, offset_size, cu, len, readp);
9318 readp += len;
9319 break;
9320
9321 case DW_LLE_base_address:
9322 if (address_size == 4)
9323 {
9324 if ((uint64_t) (nexthdr - readp) < 4)
9325 goto invalid_entry;
9326 op1 = read_4ubyte_unaligned_inc (dbg, readp);
9327 }
9328 else
9329 {
9330 if ((uint64_t) (nexthdr - readp) < 8)
9331 goto invalid_entry;
9332 op1 = read_8ubyte_unaligned_inc (dbg, readp);
9333 }
9334 base = op1;
9335 printf (" 0x%" PRIx64 "\n", base);
9336 if (! print_unresolved_addresses)
9337 {
9338 printf (" ");
9339 print_dwarf_addr (dwflmod, address_size, base, base);
9340 printf ("\n");
9341 }
9342 break;
9343
9344 case DW_LLE_start_end:
9345 if (address_size == 4)
9346 {
9347 if ((uint64_t) (nexthdr - readp) < 8)
9348 goto invalid_entry;
9349 op1 = read_4ubyte_unaligned_inc (dbg, readp);
9350 op2 = read_4ubyte_unaligned_inc (dbg, readp);
9351 }
9352 else
9353 {
9354 if ((uint64_t) (nexthdr - readp) < 16)
9355 goto invalid_entry;
9356 op1 = read_8ubyte_unaligned_inc (dbg, readp);
9357 op2 = read_8ubyte_unaligned_inc (dbg, readp);
9358 }
9359 printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
9360 if (! print_unresolved_addresses)
9361 {
9362 printf (" ");
9363 print_dwarf_addr (dwflmod, address_size, op1, op1);
9364 printf ("..\n ");
9365 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9366 printf ("\n");
9367 }
9368 if ((uint64_t) (nexthdr - readp) < 1)
9369 goto invalid_entry;
9370 get_uleb128 (len, readp, nexthdr);
9371 if ((uint64_t) (nexthdr - readp) < len)
9372 goto invalid_entry;
9373 print_ops (dwflmod, dbg, 8, 8, version,
9374 address_size, offset_size, cu, len, readp);
9375 readp += len;
9376 break;
9377
9378 case DW_LLE_start_length:
9379 if (address_size == 4)
9380 {
9381 if ((uint64_t) (nexthdr - readp) < 4)
9382 goto invalid_entry;
9383 op1 = read_4ubyte_unaligned_inc (dbg, readp);
9384 }
9385 else
9386 {
9387 if ((uint64_t) (nexthdr - readp) < 8)
9388 goto invalid_entry;
9389 op1 = read_8ubyte_unaligned_inc (dbg, readp);
9390 }
9391 if ((uint64_t) (nexthdr - readp) < 1)
9392 goto invalid_entry;
9393 get_uleb128 (op2, readp, nexthdr);
9394 printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
9395 if (! print_unresolved_addresses)
9396 {
9397 op2 = op1 + op2;
9398 printf (" ");
9399 print_dwarf_addr (dwflmod, address_size, op1, op1);
9400 printf ("..\n ");
9401 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9402 printf ("\n");
9403 }
9404 if ((uint64_t) (nexthdr - readp) < 1)
9405 goto invalid_entry;
9406 get_uleb128 (len, readp, nexthdr);
9407 if ((uint64_t) (nexthdr - readp) < len)
9408 goto invalid_entry;
9409 print_ops (dwflmod, dbg, 8, 8, version,
9410 address_size, offset_size, cu, len, readp);
9411 readp += len;
9412 break;
9413
9414 default:
9415 goto invalid_entry;
9416 }
9417 }
9418
9419 next_table:
9420 if (readp != nexthdr)
9421 {
9422 size_t padding = nexthdr - readp;
9423 printf (gettext (" %zu padding bytes\n\n"), padding);
9424 readp = nexthdr;
9425 }
9426 }
9427 }
9428
9429
9430 static void
print_debug_loc_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9431 print_debug_loc_section (Dwfl_Module *dwflmod,
9432 Ebl *ebl, GElf_Ehdr *ehdr,
9433 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9434 {
9435 Elf_Data *data = (dbg->sectiondata[IDX_debug_loc]
9436 ?: elf_rawdata (scn, NULL));
9437
9438 if (unlikely (data == NULL))
9439 {
9440 error (0, 0, gettext ("cannot get .debug_loc content: %s"),
9441 elf_errmsg (-1));
9442 return;
9443 }
9444
9445 printf (gettext ("\
9446 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9447 elf_ndxscn (scn), section_name (ebl, shdr),
9448 (uint64_t) shdr->sh_offset);
9449
9450 sort_listptr (&known_locsptr, "loclistptr");
9451 size_t listptr_idx = 0;
9452
9453 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
9454 uint_fast8_t offset_size = 4;
9455
9456 bool first = true;
9457 Dwarf_Addr base = 0;
9458 unsigned char *readp = data->d_buf;
9459 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
9460 Dwarf_CU *last_cu = NULL;
9461 while (readp < endp)
9462 {
9463 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9464 Dwarf_CU *cu = last_cu;
9465 unsigned int attr = 0;
9466
9467 if (first && skip_listptr_hole (&known_locsptr, &listptr_idx,
9468 &address_size, &offset_size, &base,
9469 &cu, offset, &readp, endp, &attr))
9470 continue;
9471
9472 if (last_cu != cu)
9473 {
9474 Dwarf_Die cudie;
9475 if (dwarf_cu_die (cu, &cudie,
9476 NULL, NULL, NULL, NULL,
9477 NULL, NULL) == NULL)
9478 printf (gettext ("\n Unknown CU base: "));
9479 else
9480 printf (gettext ("\n CU [%6" PRIx64 "] base: "),
9481 dwarf_dieoffset (&cudie));
9482 print_dwarf_addr (dwflmod, address_size, base, base);
9483 printf ("\n");
9484 }
9485 last_cu = cu;
9486
9487 if (attr == DW_AT_GNU_locviews)
9488 {
9489 Dwarf_Off next_off = next_listptr_offset (&known_locsptr,
9490 listptr_idx);
9491 const unsigned char *locp = readp;
9492 const unsigned char *locendp;
9493 if (next_off == 0
9494 || next_off > (size_t) (endp
9495 - (const unsigned char *) data->d_buf))
9496 locendp = endp;
9497 else
9498 locendp = (const unsigned char *) data->d_buf + next_off;
9499
9500 while (locp < locendp)
9501 {
9502 uint64_t v1, v2;
9503 get_uleb128 (v1, locp, locendp);
9504 if (locp >= locendp)
9505 {
9506 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
9507 break;
9508 }
9509 get_uleb128 (v2, locp, locendp);
9510 if (first) /* First view pair in a list. */
9511 printf (" [%6tx] ", offset);
9512 else
9513 printf (" ");
9514 printf ("view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
9515 first = false;
9516 }
9517
9518 first = true;
9519 readp = (unsigned char *) locendp;
9520 continue;
9521 }
9522
9523 /* GNU DebugFission encoded addresses as addrx. */
9524 bool is_debugfission = ((cu != NULL
9525 || split_dwarf_cu_base (dbg, &cu, &base))
9526 && (cu->version < 5
9527 && cu->unit_type == DW_UT_split_compile));
9528 if (!is_debugfission
9529 && unlikely (data->d_size - offset < (size_t) address_size * 2))
9530 {
9531 invalid_data:
9532 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
9533 break;
9534 }
9535
9536 Dwarf_Addr begin;
9537 Dwarf_Addr end;
9538 bool use_base = true;
9539 if (is_debugfission)
9540 {
9541 const unsigned char *locp = readp;
9542 const unsigned char *locendp = readp + data->d_size;
9543 if (locp >= locendp)
9544 goto invalid_data;
9545
9546 Dwarf_Word idx;
9547 unsigned char code = *locp++;
9548 switch (code)
9549 {
9550 case DW_LLE_GNU_end_of_list_entry:
9551 begin = 0;
9552 end = 0;
9553 break;
9554
9555 case DW_LLE_GNU_base_address_selection_entry:
9556 if (locp >= locendp)
9557 goto invalid_data;
9558 begin = (Dwarf_Addr) -1;
9559 get_uleb128 (idx, locp, locendp);
9560 if (get_indexed_addr (cu, idx, &end) != 0)
9561 end = idx; /* ... */
9562 break;
9563
9564 case DW_LLE_GNU_start_end_entry:
9565 if (locp >= locendp)
9566 goto invalid_data;
9567 get_uleb128 (idx, locp, locendp);
9568 if (get_indexed_addr (cu, idx, &begin) != 0)
9569 begin = idx; /* ... */
9570 if (locp >= locendp)
9571 goto invalid_data;
9572 get_uleb128 (idx, locp, locendp);
9573 if (get_indexed_addr (cu, idx, &end) != 0)
9574 end = idx; /* ... */
9575 use_base = false;
9576 break;
9577
9578 case DW_LLE_GNU_start_length_entry:
9579 if (locp >= locendp)
9580 goto invalid_data;
9581 get_uleb128 (idx, locp, locendp);
9582 if (get_indexed_addr (cu, idx, &begin) != 0)
9583 begin = idx; /* ... */
9584 if (locendp - locp < 4)
9585 goto invalid_data;
9586 end = read_4ubyte_unaligned_inc (dbg, locp);
9587 end += begin;
9588 use_base = false;
9589 break;
9590
9591 default:
9592 goto invalid_data;
9593 }
9594
9595 readp = (unsigned char *) locp;
9596 }
9597 else if (address_size == 8)
9598 {
9599 begin = read_8ubyte_unaligned_inc (dbg, readp);
9600 end = read_8ubyte_unaligned_inc (dbg, readp);
9601 }
9602 else
9603 {
9604 begin = read_4ubyte_unaligned_inc (dbg, readp);
9605 end = read_4ubyte_unaligned_inc (dbg, readp);
9606 if (begin == (Dwarf_Addr) (uint32_t) -1)
9607 begin = (Dwarf_Addr) -1l;
9608 }
9609
9610 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
9611 {
9612 printf (gettext (" [%6tx] base address\n "), offset);
9613 print_dwarf_addr (dwflmod, address_size, end, end);
9614 printf ("\n");
9615 base = end;
9616 }
9617 else if (begin == 0 && end == 0) /* End of list entry. */
9618 {
9619 if (first)
9620 printf (gettext (" [%6tx] empty list\n"), offset);
9621 first = true;
9622 }
9623 else
9624 {
9625 /* We have a location expression entry. */
9626 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
9627
9628 if (first) /* First entry in a list. */
9629 printf (" [%6tx] ", offset);
9630 else
9631 printf (" ");
9632
9633 printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
9634 if (! print_unresolved_addresses)
9635 {
9636 Dwarf_Addr dab = use_base ? base + begin : begin;
9637 Dwarf_Addr dae = use_base ? base + end : end;
9638 printf (" ");
9639 print_dwarf_addr (dwflmod, address_size, dab, dab);
9640 printf ("..\n ");
9641 print_dwarf_addr (dwflmod, address_size, dae - 1, dae);
9642 printf ("\n");
9643 }
9644
9645 if (endp - readp <= (ptrdiff_t) len)
9646 {
9647 fputs (gettext (" <INVALID DATA>\n"), stdout);
9648 break;
9649 }
9650
9651 print_ops (dwflmod, dbg, 11, 11,
9652 cu != NULL ? cu->version : 3,
9653 address_size, offset_size, cu, len, readp);
9654
9655 first = false;
9656 readp += len;
9657 }
9658 }
9659 }
9660
9661 struct mac_culist
9662 {
9663 Dwarf_Die die;
9664 Dwarf_Off offset;
9665 Dwarf_Files *files;
9666 struct mac_culist *next;
9667 };
9668
9669
9670 static int
mac_compare(const void * p1,const void * p2)9671 mac_compare (const void *p1, const void *p2)
9672 {
9673 struct mac_culist *m1 = (struct mac_culist *) p1;
9674 struct mac_culist *m2 = (struct mac_culist *) p2;
9675
9676 if (m1->offset < m2->offset)
9677 return -1;
9678 if (m1->offset > m2->offset)
9679 return 1;
9680 return 0;
9681 }
9682
9683
9684 static void
print_debug_macinfo_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9685 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9686 Ebl *ebl,
9687 GElf_Ehdr *ehdr __attribute__ ((unused)),
9688 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9689 {
9690 printf (gettext ("\
9691 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9692 elf_ndxscn (scn), section_name (ebl, shdr),
9693 (uint64_t) shdr->sh_offset);
9694 putc_unlocked ('\n', stdout);
9695
9696 /* There is no function in libdw to iterate over the raw content of
9697 the section but it is easy enough to do. */
9698 Elf_Data *data = (dbg->sectiondata[IDX_debug_macinfo]
9699 ?: elf_rawdata (scn, NULL));
9700 if (unlikely (data == NULL))
9701 {
9702 error (0, 0, gettext ("cannot get macro information section data: %s"),
9703 elf_errmsg (-1));
9704 return;
9705 }
9706
9707 /* Get the source file information for all CUs. */
9708 Dwarf_Off offset;
9709 Dwarf_Off ncu = 0;
9710 size_t hsize;
9711 struct mac_culist *culist = NULL;
9712 size_t nculist = 0;
9713 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9714 {
9715 Dwarf_Die cudie;
9716 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9717 continue;
9718
9719 Dwarf_Attribute attr;
9720 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
9721 continue;
9722
9723 Dwarf_Word macoff;
9724 if (dwarf_formudata (&attr, &macoff) != 0)
9725 continue;
9726
9727 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9728 newp->die = cudie;
9729 newp->offset = macoff;
9730 newp->files = NULL;
9731 newp->next = culist;
9732 culist = newp;
9733 ++nculist;
9734 }
9735
9736 /* Convert the list into an array for easier consumption. */
9737 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
9738 * sizeof (*cus));
9739 /* Add sentinel. */
9740 cus[nculist].offset = data->d_size;
9741 cus[nculist].files = (Dwarf_Files *) -1l;
9742 if (nculist > 0)
9743 {
9744 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
9745 {
9746 assert (cnt < nculist);
9747 cus[cnt] = *culist;
9748 culist = culist->next;
9749 }
9750
9751 /* Sort the array according to the offset in the .debug_macinfo
9752 section. Note we keep the sentinel at the end. */
9753 qsort (cus, nculist, sizeof (*cus), mac_compare);
9754 }
9755
9756 const unsigned char *readp = (const unsigned char *) data->d_buf;
9757 const unsigned char *readendp = readp + data->d_size;
9758 int level = 1;
9759
9760 while (readp < readendp)
9761 {
9762 unsigned int opcode = *readp++;
9763 unsigned int u128;
9764 unsigned int u128_2;
9765 const unsigned char *endp;
9766
9767 switch (opcode)
9768 {
9769 case DW_MACINFO_define:
9770 case DW_MACINFO_undef:
9771 case DW_MACINFO_vendor_ext:
9772 /* For the first two opcodes the parameters are
9773 line, string
9774 For the latter
9775 number, string.
9776 We can treat these cases together. */
9777 get_uleb128 (u128, readp, readendp);
9778
9779 endp = memchr (readp, '\0', readendp - readp);
9780 if (unlikely (endp == NULL))
9781 {
9782 printf (gettext ("\
9783 %*s*** non-terminated string at end of section"),
9784 level, "");
9785 return;
9786 }
9787
9788 if (opcode == DW_MACINFO_define)
9789 printf ("%*s#define %s, line %u\n",
9790 level, "", (char *) readp, u128);
9791 else if (opcode == DW_MACINFO_undef)
9792 printf ("%*s#undef %s, line %u\n",
9793 level, "", (char *) readp, u128);
9794 else
9795 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
9796
9797 readp = endp + 1;
9798 break;
9799
9800 case DW_MACINFO_start_file:
9801 /* The two parameters are line and file index, in this order. */
9802 get_uleb128 (u128, readp, readendp);
9803 if (readendp - readp < 1)
9804 {
9805 printf (gettext ("\
9806 %*s*** missing DW_MACINFO_start_file argument at end of section"),
9807 level, "");
9808 return;
9809 }
9810 get_uleb128 (u128_2, readp, readendp);
9811
9812 /* Find the CU DIE for this file. */
9813 size_t macoff = readp - (const unsigned char *) data->d_buf;
9814 const char *fname = "???";
9815 if (macoff >= cus[0].offset && cus[0].offset != data->d_size)
9816 {
9817 while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
9818 ++cus;
9819
9820 if (cus[0].files == NULL
9821 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
9822 cus[0].files = (Dwarf_Files *) -1l;
9823
9824 if (cus[0].files != (Dwarf_Files *) -1l)
9825 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
9826 ?: "???");
9827 }
9828
9829 printf ("%*sstart_file %u, [%u] %s\n",
9830 level, "", u128, u128_2, fname);
9831 ++level;
9832 break;
9833
9834 case DW_MACINFO_end_file:
9835 --level;
9836 printf ("%*send_file\n", level, "");
9837 /* Nothing more to do. */
9838 break;
9839
9840 default:
9841 // XXX gcc seems to generate files with a trailing zero.
9842 if (unlikely (opcode != 0 || readp != readendp))
9843 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
9844 break;
9845 }
9846 }
9847 }
9848
9849
9850 static void
print_debug_macro_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9851 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9852 Ebl *ebl,
9853 GElf_Ehdr *ehdr __attribute__ ((unused)),
9854 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9855 {
9856 printf (gettext ("\
9857 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9858 elf_ndxscn (scn), section_name (ebl, shdr),
9859 (uint64_t) shdr->sh_offset);
9860 putc_unlocked ('\n', stdout);
9861
9862 Elf_Data *data = elf_getdata (scn, NULL);
9863 if (unlikely (data == NULL))
9864 {
9865 error (0, 0, gettext ("cannot get macro information section data: %s"),
9866 elf_errmsg (-1));
9867 return;
9868 }
9869
9870 /* Get the source file information for all CUs. Uses same
9871 datastructure as macinfo. But uses offset field to directly
9872 match .debug_line offset. And just stored in a list. */
9873 Dwarf_Off offset;
9874 Dwarf_Off ncu = 0;
9875 size_t hsize;
9876 struct mac_culist *culist = NULL;
9877 size_t nculist = 0;
9878 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9879 {
9880 Dwarf_Die cudie;
9881 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9882 continue;
9883
9884 Dwarf_Attribute attr;
9885 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
9886 continue;
9887
9888 Dwarf_Word lineoff;
9889 if (dwarf_formudata (&attr, &lineoff) != 0)
9890 continue;
9891
9892 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9893 newp->die = cudie;
9894 newp->offset = lineoff;
9895 newp->files = NULL;
9896 newp->next = culist;
9897 culist = newp;
9898 ++nculist;
9899 }
9900
9901 const unsigned char *readp = (const unsigned char *) data->d_buf;
9902 const unsigned char *readendp = readp + data->d_size;
9903
9904 while (readp < readendp)
9905 {
9906 printf (gettext (" Offset: 0x%" PRIx64 "\n"),
9907 (uint64_t) (readp - (const unsigned char *) data->d_buf));
9908
9909 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
9910 // optional vendor extension macro entry table.
9911 if (readp + 2 > readendp)
9912 {
9913 invalid_data:
9914 error (0, 0, gettext ("invalid data"));
9915 return;
9916 }
9917 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
9918 printf (gettext (" Version: %" PRIu16 "\n"), vers);
9919
9920 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
9921 // 5 when it gets standardized.
9922 if (vers != 4 && vers != 5)
9923 {
9924 printf (gettext (" unknown version, cannot parse section\n"));
9925 return;
9926 }
9927
9928 if (readp + 1 > readendp)
9929 goto invalid_data;
9930 const unsigned char flag = *readp++;
9931 printf (gettext (" Flag: 0x%" PRIx8), flag);
9932 if (flag != 0)
9933 {
9934 printf (" (");
9935 if ((flag & 0x01) != 0)
9936 {
9937 printf ("offset_size");
9938 if ((flag & 0xFE) != 0)
9939 printf (", ");
9940 }
9941 if ((flag & 0x02) != 0)
9942 {
9943 printf ("debug_line_offset");
9944 if ((flag & 0xFC) != 0)
9945 printf (", ");
9946 }
9947 if ((flag & 0x04) != 0)
9948 {
9949 printf ("operands_table");
9950 if ((flag & 0xF8) != 0)
9951 printf (", ");
9952 }
9953 if ((flag & 0xF8) != 0)
9954 printf ("unknown");
9955 printf (")");
9956 }
9957 printf ("\n");
9958
9959 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
9960 printf (gettext (" Offset length: %" PRIu8 "\n"), offset_len);
9961 Dwarf_Off line_offset = -1;
9962 if (flag & 0x02)
9963 {
9964 if (offset_len == 8)
9965 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
9966 else
9967 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
9968 printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
9969 line_offset);
9970 }
9971
9972 struct mac_culist *cu = NULL;
9973 if (line_offset != (Dwarf_Off) -1)
9974 {
9975 cu = culist;
9976 while (cu != NULL && line_offset != cu->offset)
9977 cu = cu->next;
9978 }
9979
9980 Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, (cu != NULL
9981 ? cu->die.cu
9982 : NULL));
9983
9984 const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user + 1];
9985 memset (vendor, 0, sizeof vendor);
9986 if (flag & 0x04)
9987 {
9988 // 1 byte length, for each item, 1 byte opcode, uleb128 number
9989 // of arguments, for each argument 1 byte form code.
9990 if (readp + 1 > readendp)
9991 goto invalid_data;
9992 unsigned int tlen = *readp++;
9993 printf (gettext (" extension opcode table, %" PRIu8 " items:\n"),
9994 tlen);
9995 for (unsigned int i = 0; i < tlen; i++)
9996 {
9997 if (readp + 1 > readendp)
9998 goto invalid_data;
9999 unsigned int opcode = *readp++;
10000 printf (gettext (" [%" PRIx8 "]"), opcode);
10001 if (opcode < DW_MACRO_lo_user
10002 || opcode > DW_MACRO_hi_user)
10003 goto invalid_data;
10004 // Record the start of description for this vendor opcode.
10005 // uleb128 nr args, 1 byte per arg form.
10006 vendor[opcode - DW_MACRO_lo_user] = readp;
10007 if (readp + 1 > readendp)
10008 goto invalid_data;
10009 unsigned int args = *readp++;
10010 if (args > 0)
10011 {
10012 printf (gettext (" %" PRIu8 " arguments:"), args);
10013 while (args > 0)
10014 {
10015 if (readp + 1 > readendp)
10016 goto invalid_data;
10017 unsigned int form = *readp++;
10018 printf (" %s", dwarf_form_name (form));
10019 if (! libdw_valid_user_form (form))
10020 goto invalid_data;
10021 args--;
10022 if (args > 0)
10023 putchar_unlocked (',');
10024 }
10025 }
10026 else
10027 printf (gettext (" no arguments."));
10028 putchar_unlocked ('\n');
10029 }
10030 }
10031 putchar_unlocked ('\n');
10032
10033 int level = 1;
10034 if (readp + 1 > readendp)
10035 goto invalid_data;
10036 unsigned int opcode = *readp++;
10037 while (opcode != 0)
10038 {
10039 unsigned int u128;
10040 unsigned int u128_2;
10041 const unsigned char *endp;
10042 uint64_t off;
10043
10044 switch (opcode)
10045 {
10046 case DW_MACRO_start_file:
10047 get_uleb128 (u128, readp, readendp);
10048 if (readp >= readendp)
10049 goto invalid_data;
10050 get_uleb128 (u128_2, readp, readendp);
10051
10052 /* Find the CU DIE that matches this line offset. */
10053 const char *fname = "???";
10054 if (cu != NULL)
10055 {
10056 if (cu->files == NULL
10057 && dwarf_getsrcfiles (&cu->die, &cu->files,
10058 NULL) != 0)
10059 cu->files = (Dwarf_Files *) -1l;
10060
10061 if (cu->files != (Dwarf_Files *) -1l)
10062 fname = (dwarf_filesrc (cu->files, u128_2,
10063 NULL, NULL) ?: "???");
10064 }
10065 printf ("%*sstart_file %u, [%u] %s\n",
10066 level, "", u128, u128_2, fname);
10067 ++level;
10068 break;
10069
10070 case DW_MACRO_end_file:
10071 --level;
10072 printf ("%*send_file\n", level, "");
10073 break;
10074
10075 case DW_MACRO_define:
10076 get_uleb128 (u128, readp, readendp);
10077 endp = memchr (readp, '\0', readendp - readp);
10078 if (endp == NULL)
10079 goto invalid_data;
10080 printf ("%*s#define %s, line %u\n",
10081 level, "", readp, u128);
10082 readp = endp + 1;
10083 break;
10084
10085 case DW_MACRO_undef:
10086 get_uleb128 (u128, readp, readendp);
10087 endp = memchr (readp, '\0', readendp - readp);
10088 if (endp == NULL)
10089 goto invalid_data;
10090 printf ("%*s#undef %s, line %u\n",
10091 level, "", readp, u128);
10092 readp = endp + 1;
10093 break;
10094
10095 case DW_MACRO_define_strp:
10096 get_uleb128 (u128, readp, readendp);
10097 if (readp + offset_len > readendp)
10098 goto invalid_data;
10099 if (offset_len == 8)
10100 off = read_8ubyte_unaligned_inc (dbg, readp);
10101 else
10102 off = read_4ubyte_unaligned_inc (dbg, readp);
10103 printf ("%*s#define %s, line %u (indirect)\n",
10104 level, "", dwarf_getstring (dbg, off, NULL), u128);
10105 break;
10106
10107 case DW_MACRO_undef_strp:
10108 get_uleb128 (u128, readp, readendp);
10109 if (readp + offset_len > readendp)
10110 goto invalid_data;
10111 if (offset_len == 8)
10112 off = read_8ubyte_unaligned_inc (dbg, readp);
10113 else
10114 off = read_4ubyte_unaligned_inc (dbg, readp);
10115 printf ("%*s#undef %s, line %u (indirect)\n",
10116 level, "", dwarf_getstring (dbg, off, NULL), u128);
10117 break;
10118
10119 case DW_MACRO_import:
10120 if (readp + offset_len > readendp)
10121 goto invalid_data;
10122 if (offset_len == 8)
10123 off = read_8ubyte_unaligned_inc (dbg, readp);
10124 else
10125 off = read_4ubyte_unaligned_inc (dbg, readp);
10126 printf ("%*s#include offset 0x%" PRIx64 "\n",
10127 level, "", off);
10128 break;
10129
10130 case DW_MACRO_define_sup:
10131 get_uleb128 (u128, readp, readendp);
10132 if (readp + offset_len > readendp)
10133 goto invalid_data;
10134 printf ("%*s#define ", level, "");
10135 readp = print_form_data (dbg, DW_FORM_strp_sup,
10136 readp, readendp, offset_len,
10137 str_offsets_base);
10138 printf (", line %u (sup)\n", u128);
10139 break;
10140
10141 case DW_MACRO_undef_sup:
10142 get_uleb128 (u128, readp, readendp);
10143 if (readp + offset_len > readendp)
10144 goto invalid_data;
10145 printf ("%*s#undef ", level, "");
10146 readp = print_form_data (dbg, DW_FORM_strp_sup,
10147 readp, readendp, offset_len,
10148 str_offsets_base);
10149 printf (", line %u (sup)\n", u128);
10150 break;
10151
10152 case DW_MACRO_import_sup:
10153 if (readp + offset_len > readendp)
10154 goto invalid_data;
10155 if (offset_len == 8)
10156 off = read_8ubyte_unaligned_inc (dbg, readp);
10157 else
10158 off = read_4ubyte_unaligned_inc (dbg, readp);
10159 // XXX Needs support for reading from supplementary object file.
10160 printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
10161 level, "", off);
10162 break;
10163
10164 case DW_MACRO_define_strx:
10165 get_uleb128 (u128, readp, readendp);
10166 if (readp + offset_len > readendp)
10167 goto invalid_data;
10168 printf ("%*s#define ", level, "");
10169 readp = print_form_data (dbg, DW_FORM_strx,
10170 readp, readendp, offset_len,
10171 str_offsets_base);
10172 printf (", line %u (strx)\n", u128);
10173 break;
10174
10175 case DW_MACRO_undef_strx:
10176 get_uleb128 (u128, readp, readendp);
10177 if (readp + offset_len > readendp)
10178 goto invalid_data;
10179 printf ("%*s#undef ", level, "");
10180 readp = print_form_data (dbg, DW_FORM_strx,
10181 readp, readendp, offset_len,
10182 str_offsets_base);
10183 printf (", line %u (strx)\n", u128);
10184 break;
10185
10186 default:
10187 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
10188 if (opcode < DW_MACRO_lo_user
10189 || opcode > DW_MACRO_lo_user
10190 || vendor[opcode - DW_MACRO_lo_user] == NULL)
10191 goto invalid_data;
10192
10193 const unsigned char *op_desc;
10194 op_desc = vendor[opcode - DW_MACRO_lo_user];
10195
10196 // Just skip the arguments, we cannot really interpret them,
10197 // but print as much as we can.
10198 unsigned int args = *op_desc++;
10199 while (args > 0 && readp < readendp)
10200 {
10201 unsigned int form = *op_desc++;
10202 readp = print_form_data (dbg, form, readp, readendp,
10203 offset_len, str_offsets_base);
10204 args--;
10205 if (args > 0)
10206 printf (", ");
10207 }
10208 putchar_unlocked ('\n');
10209 }
10210
10211 if (readp + 1 > readendp)
10212 goto invalid_data;
10213 opcode = *readp++;
10214 if (opcode == 0)
10215 putchar_unlocked ('\n');
10216 }
10217 }
10218 }
10219
10220
10221 /* Callback for printing global names. */
10222 static int
print_pubnames(Dwarf * dbg,Dwarf_Global * global,void * arg)10223 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
10224 void *arg)
10225 {
10226 int *np = (int *) arg;
10227
10228 printf (gettext (" [%5d] DIE offset: %6" PRId64
10229 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
10230 (*np)++, global->die_offset, global->cu_offset, global->name);
10231
10232 return 0;
10233 }
10234
10235
10236 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
10237 static void
print_debug_pubnames_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10238 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10239 Ebl *ebl,
10240 GElf_Ehdr *ehdr __attribute__ ((unused)),
10241 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10242 {
10243 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10244 elf_ndxscn (scn), section_name (ebl, shdr),
10245 (uint64_t) shdr->sh_offset);
10246
10247 int n = 0;
10248 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
10249 }
10250
10251 /* Print the content of the DWARF string section '.debug_str'. */
10252 static void
print_debug_str_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10253 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10254 Ebl *ebl,
10255 GElf_Ehdr *ehdr __attribute__ ((unused)),
10256 Elf_Scn *scn, GElf_Shdr *shdr,
10257 Dwarf *dbg __attribute__ ((unused)))
10258 {
10259 Elf_Data *data = elf_rawdata (scn, NULL);
10260 const size_t sh_size = data ? data->d_size : 0;
10261
10262 /* Compute floor(log16(shdr->sh_size)). */
10263 GElf_Addr tmp = sh_size;
10264 int digits = 1;
10265 while (tmp >= 16)
10266 {
10267 ++digits;
10268 tmp >>= 4;
10269 }
10270 digits = MAX (4, digits);
10271
10272 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
10273 " %*s String\n"),
10274 elf_ndxscn (scn),
10275 section_name (ebl, shdr), (uint64_t) shdr->sh_offset,
10276 /* TRANS: the debugstr| prefix makes the string unique. */
10277 digits + 2, sgettext ("debugstr|Offset"));
10278
10279 Dwarf_Off offset = 0;
10280 while (offset < sh_size)
10281 {
10282 size_t len;
10283 const char *str = (const char *) data->d_buf + offset;
10284 const char *endp = memchr (str, '\0', sh_size - offset);
10285 if (unlikely (endp == NULL))
10286 {
10287 printf (gettext (" *** error, missing string terminator\n"));
10288 break;
10289 }
10290
10291 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
10292 len = endp - str;
10293 offset += len + 1;
10294 }
10295 }
10296
10297 static void
print_debug_str_offsets_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10298 print_debug_str_offsets_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10299 Ebl *ebl,
10300 GElf_Ehdr *ehdr __attribute__ ((unused)),
10301 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10302 {
10303 printf (gettext ("\
10304 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10305 elf_ndxscn (scn), section_name (ebl, shdr),
10306 (uint64_t) shdr->sh_offset);
10307
10308 if (shdr->sh_size == 0)
10309 return;
10310
10311 /* We like to get the section from libdw to make sure they are relocated. */
10312 Elf_Data *data = (dbg->sectiondata[IDX_debug_str_offsets]
10313 ?: elf_rawdata (scn, NULL));
10314 if (unlikely (data == NULL))
10315 {
10316 error (0, 0, gettext ("cannot get .debug_str_offsets section data: %s"),
10317 elf_errmsg (-1));
10318 return;
10319 }
10320
10321 size_t idx = 0;
10322 sort_listptr (&known_stroffbases, "str_offsets");
10323
10324 const unsigned char *start = (const unsigned char *) data->d_buf;
10325 const unsigned char *readp = start;
10326 const unsigned char *readendp = ((const unsigned char *) data->d_buf
10327 + data->d_size);
10328
10329 while (readp < readendp)
10330 {
10331 /* Most string offset tables will have a header. For split
10332 dwarf unit GNU DebugFission didn't add one. But they were
10333 also only defined for split units (main or skeleton units
10334 didn't have indirect strings). So if we don't have a
10335 DW_AT_str_offsets_base at all and this is offset zero, then
10336 just start printing offsets immediately, if this is a .dwo
10337 section. */
10338 Dwarf_Off off = (Dwarf_Off) (readp
10339 - (const unsigned char *) data->d_buf);
10340
10341 printf ("Table at offset %" PRIx64 " ", off);
10342
10343 struct listptr *listptr = get_listptr (&known_stroffbases, idx++);
10344 const unsigned char *next_unitp = readendp;
10345 uint8_t offset_size;
10346 bool has_header;
10347 if (listptr == NULL)
10348 {
10349 /* This can happen for .dwo files. There is only an header
10350 in the case this is a version 5 split DWARF file. */
10351 Dwarf_CU *cu;
10352 uint8_t unit_type;
10353 if (dwarf_get_units (dbg, NULL, &cu, NULL, &unit_type,
10354 NULL, NULL) != 0)
10355 {
10356 error (0, 0, "Warning: Cannot find any DWARF unit.");
10357 /* Just guess some values. */
10358 has_header = false;
10359 offset_size = 4;
10360 }
10361 else if (off == 0
10362 && (unit_type == DW_UT_split_type
10363 || unit_type == DW_UT_split_compile))
10364 {
10365 has_header = cu->version > 4;
10366 offset_size = cu->offset_size;
10367 }
10368 else
10369 {
10370 error (0, 0,
10371 "Warning: No CU references .debug_str_offsets after %"
10372 PRIx64, off);
10373 has_header = cu->version > 4;
10374 offset_size = cu->offset_size;
10375 }
10376 printf ("\n");
10377 }
10378 else
10379 {
10380 /* This must be DWARF5, since GNU DebugFission didn't define
10381 DW_AT_str_offsets_base. */
10382 has_header = true;
10383
10384 Dwarf_Die cudie;
10385 if (dwarf_cu_die (listptr->cu, &cudie,
10386 NULL, NULL, NULL, NULL,
10387 NULL, NULL) == NULL)
10388 printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
10389 else
10390 printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
10391 }
10392
10393 if (has_header)
10394 {
10395 uint64_t unit_length;
10396 uint16_t version;
10397 uint16_t padding;
10398
10399 unit_length = read_4ubyte_unaligned_inc (dbg, readp);
10400 if (unlikely (unit_length == 0xffffffff))
10401 {
10402 if (unlikely (readp > readendp - 8))
10403 {
10404 invalid_data:
10405 error (0, 0, "Invalid data");
10406 return;
10407 }
10408 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
10409 offset_size = 8;
10410 }
10411 else
10412 offset_size = 4;
10413
10414 printf ("\n");
10415 printf (gettext (" Length: %8" PRIu64 "\n"),
10416 unit_length);
10417 printf (gettext (" Offset size: %8" PRIu8 "\n"),
10418 offset_size);
10419
10420 /* We need at least 2-bytes (version) + 2-bytes (padding) =
10421 4 bytes to complete the header. And this unit cannot go
10422 beyond the section data. */
10423 if (readp > readendp - 4
10424 || unit_length < 4
10425 || unit_length > (uint64_t) (readendp - readp))
10426 goto invalid_data;
10427
10428 next_unitp = readp + unit_length;
10429
10430 version = read_2ubyte_unaligned_inc (dbg, readp);
10431 printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
10432
10433 if (version != 5)
10434 {
10435 error (0, 0, gettext ("Unknown version"));
10436 goto next_unit;
10437 }
10438
10439 padding = read_2ubyte_unaligned_inc (dbg, readp);
10440 printf (gettext (" Padding: %8" PRIx16 "\n"), padding);
10441
10442 if (listptr != NULL
10443 && listptr->offset != (Dwarf_Off) (readp - start))
10444 {
10445 error (0, 0, "String offsets index doesn't start after header");
10446 goto next_unit;
10447 }
10448
10449 printf ("\n");
10450 }
10451
10452 int digits = 1;
10453 size_t offsets = (next_unitp - readp) / offset_size;
10454 while (offsets >= 10)
10455 {
10456 ++digits;
10457 offsets /= 10;
10458 }
10459
10460 unsigned int uidx = 0;
10461 size_t index_offset = readp - (const unsigned char *) data->d_buf;
10462 printf (" Offsets start at 0x%zx:\n", index_offset);
10463 while (readp <= next_unitp - offset_size)
10464 {
10465 Dwarf_Word offset;
10466 if (offset_size == 4)
10467 offset = read_4ubyte_unaligned_inc (dbg, readp);
10468 else
10469 offset = read_8ubyte_unaligned_inc (dbg, readp);
10470 const char *str = dwarf_getstring (dbg, offset, NULL);
10471 printf (" [%*u] [%*" PRIx64 "] \"%s\"\n",
10472 digits, uidx++, (int) offset_size * 2, offset, str ?: "???");
10473 }
10474 printf ("\n");
10475
10476 if (readp != next_unitp)
10477 error (0, 0, "extra %zd bytes at end of unit",
10478 (size_t) (next_unitp - readp));
10479
10480 next_unit:
10481 readp = next_unitp;
10482 }
10483 }
10484
10485
10486 /* Print the content of the call frame search table section
10487 '.eh_frame_hdr'. */
10488 static void
print_debug_frame_hdr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10489 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10490 Ebl *ebl __attribute__ ((unused)),
10491 GElf_Ehdr *ehdr __attribute__ ((unused)),
10492 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10493 {
10494 printf (gettext ("\
10495 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
10496 elf_ndxscn (scn));
10497
10498 Elf_Data *data = elf_rawdata (scn, NULL);
10499
10500 if (unlikely (data == NULL))
10501 {
10502 error (0, 0, gettext ("cannot get %s content: %s"),
10503 ".eh_frame_hdr", elf_errmsg (-1));
10504 return;
10505 }
10506
10507 const unsigned char *readp = data->d_buf;
10508 const unsigned char *const dataend = ((unsigned char *) data->d_buf
10509 + data->d_size);
10510
10511 if (unlikely (readp + 4 > dataend))
10512 {
10513 invalid_data:
10514 error (0, 0, gettext ("invalid data"));
10515 return;
10516 }
10517
10518 unsigned int version = *readp++;
10519 unsigned int eh_frame_ptr_enc = *readp++;
10520 unsigned int fde_count_enc = *readp++;
10521 unsigned int table_enc = *readp++;
10522
10523 printf (" version: %u\n"
10524 " eh_frame_ptr_enc: %#x ",
10525 version, eh_frame_ptr_enc);
10526 print_encoding_base ("", eh_frame_ptr_enc);
10527 printf (" fde_count_enc: %#x ", fde_count_enc);
10528 print_encoding_base ("", fde_count_enc);
10529 printf (" table_enc: %#x ", table_enc);
10530 print_encoding_base ("", table_enc);
10531
10532 uint64_t eh_frame_ptr = 0;
10533 if (eh_frame_ptr_enc != DW_EH_PE_omit)
10534 {
10535 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
10536 dbg);
10537 if (unlikely (readp == NULL))
10538 goto invalid_data;
10539
10540 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
10541 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
10542 printf (" (offset: %#" PRIx64 ")",
10543 /* +4 because of the 4 byte header of the section. */
10544 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
10545
10546 putchar_unlocked ('\n');
10547 }
10548
10549 uint64_t fde_count = 0;
10550 if (fde_count_enc != DW_EH_PE_omit)
10551 {
10552 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
10553 if (unlikely (readp == NULL))
10554 goto invalid_data;
10555
10556 printf (" fde_count: %" PRIu64 "\n", fde_count);
10557 }
10558
10559 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
10560 return;
10561
10562 puts (" Table:");
10563
10564 /* Optimize for the most common case. */
10565 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
10566 while (fde_count > 0 && readp + 8 <= dataend)
10567 {
10568 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
10569 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
10570 + (int64_t) initial_location);
10571 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
10572 // XXX Possibly print symbol name or section offset for initial_offset
10573 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
10574 " fde=[%6" PRIx64 "]\n",
10575 initial_location, initial_offset,
10576 address, address - (eh_frame_ptr + 4));
10577 }
10578 else
10579 while (0 && readp < dataend)
10580 {
10581
10582 }
10583 }
10584
10585
10586 /* Print the content of the exception handling table section
10587 '.eh_frame_hdr'. */
10588 static void
print_debug_exception_table(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10589 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
10590 Ebl *ebl __attribute__ ((unused)),
10591 GElf_Ehdr *ehdr __attribute__ ((unused)),
10592 Elf_Scn *scn,
10593 GElf_Shdr *shdr __attribute__ ((unused)),
10594 Dwarf *dbg __attribute__ ((unused)))
10595 {
10596 printf (gettext ("\
10597 \nException handling table section [%2zu] '.gcc_except_table':\n"),
10598 elf_ndxscn (scn));
10599
10600 Elf_Data *data = elf_rawdata (scn, NULL);
10601
10602 if (unlikely (data == NULL))
10603 {
10604 error (0, 0, gettext ("cannot get %s content: %s"),
10605 ".gcc_except_table", elf_errmsg (-1));
10606 return;
10607 }
10608
10609 const unsigned char *readp = data->d_buf;
10610 const unsigned char *const dataend = readp + data->d_size;
10611
10612 if (unlikely (readp + 1 > dataend))
10613 {
10614 invalid_data:
10615 error (0, 0, gettext ("invalid data"));
10616 return;
10617 }
10618 unsigned int lpstart_encoding = *readp++;
10619 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding);
10620 print_encoding_base ("", lpstart_encoding);
10621 if (lpstart_encoding != DW_EH_PE_omit)
10622 {
10623 uint64_t lpstart;
10624 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
10625 printf (" LPStart: %#" PRIx64 "\n", lpstart);
10626 }
10627
10628 if (unlikely (readp + 1 > dataend))
10629 goto invalid_data;
10630 unsigned int ttype_encoding = *readp++;
10631 printf (gettext (" TType encoding: %#x "), ttype_encoding);
10632 print_encoding_base ("", ttype_encoding);
10633 const unsigned char *ttype_base = NULL;
10634 if (ttype_encoding != DW_EH_PE_omit)
10635 {
10636 unsigned int ttype_base_offset;
10637 get_uleb128 (ttype_base_offset, readp, dataend);
10638 printf (" TType base offset: %#x\n", ttype_base_offset);
10639 if ((size_t) (dataend - readp) > ttype_base_offset)
10640 ttype_base = readp + ttype_base_offset;
10641 }
10642
10643 if (unlikely (readp + 1 > dataend))
10644 goto invalid_data;
10645 unsigned int call_site_encoding = *readp++;
10646 printf (gettext (" Call site encoding: %#x "), call_site_encoding);
10647 print_encoding_base ("", call_site_encoding);
10648 unsigned int call_site_table_len;
10649 get_uleb128 (call_site_table_len, readp, dataend);
10650
10651 const unsigned char *const action_table = readp + call_site_table_len;
10652 if (unlikely (action_table > dataend))
10653 goto invalid_data;
10654 unsigned int u = 0;
10655 unsigned int max_action = 0;
10656 while (readp < action_table)
10657 {
10658 if (u == 0)
10659 puts (gettext ("\n Call site table:"));
10660
10661 uint64_t call_site_start;
10662 readp = read_encoded (call_site_encoding, readp, dataend,
10663 &call_site_start, dbg);
10664 uint64_t call_site_length;
10665 readp = read_encoded (call_site_encoding, readp, dataend,
10666 &call_site_length, dbg);
10667 uint64_t landing_pad;
10668 readp = read_encoded (call_site_encoding, readp, dataend,
10669 &landing_pad, dbg);
10670 unsigned int action;
10671 get_uleb128 (action, readp, dataend);
10672 max_action = MAX (action, max_action);
10673 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n"
10674 " Call site length: %" PRIu64 "\n"
10675 " Landing pad: %#" PRIx64 "\n"
10676 " Action: %u\n"),
10677 u++, call_site_start, call_site_length, landing_pad, action);
10678 }
10679 if (readp != action_table)
10680 goto invalid_data;
10681
10682 unsigned int max_ar_filter = 0;
10683 if (max_action > 0)
10684 {
10685 puts ("\n Action table:");
10686
10687 size_t maxdata = (size_t) (dataend - action_table);
10688 if (max_action > maxdata || maxdata - max_action < 1)
10689 {
10690 invalid_action_table:
10691 fputs (gettext (" <INVALID DATA>\n"), stdout);
10692 return;
10693 }
10694
10695 const unsigned char *const action_table_end
10696 = action_table + max_action + 1;
10697
10698 u = 0;
10699 do
10700 {
10701 int ar_filter;
10702 get_sleb128 (ar_filter, readp, action_table_end);
10703 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
10704 max_ar_filter = ar_filter;
10705 int ar_disp;
10706 if (readp >= action_table_end)
10707 goto invalid_action_table;
10708 get_sleb128 (ar_disp, readp, action_table_end);
10709
10710 printf (" [%4u] ar_filter: % d\n"
10711 " ar_disp: % -5d",
10712 u, ar_filter, ar_disp);
10713 if (abs (ar_disp) & 1)
10714 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
10715 else if (ar_disp != 0)
10716 puts (" -> ???");
10717 else
10718 putchar_unlocked ('\n');
10719 ++u;
10720 }
10721 while (readp < action_table_end);
10722 }
10723
10724 if (max_ar_filter > 0 && ttype_base != NULL)
10725 {
10726 unsigned char dsize;
10727 puts ("\n TType table:");
10728
10729 // XXX Not *4, size of encoding;
10730 switch (ttype_encoding & 7)
10731 {
10732 case DW_EH_PE_udata2:
10733 case DW_EH_PE_sdata2:
10734 dsize = 2;
10735 break;
10736 case DW_EH_PE_udata4:
10737 case DW_EH_PE_sdata4:
10738 dsize = 4;
10739 break;
10740 case DW_EH_PE_udata8:
10741 case DW_EH_PE_sdata8:
10742 dsize = 8;
10743 break;
10744 default:
10745 dsize = 0;
10746 error (1, 0, gettext ("invalid TType encoding"));
10747 }
10748
10749 if (max_ar_filter
10750 > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
10751 goto invalid_data;
10752
10753 readp = ttype_base - max_ar_filter * dsize;
10754 do
10755 {
10756 uint64_t ttype;
10757 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
10758 dbg);
10759 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
10760 }
10761 while (readp < ttype_base);
10762 }
10763 }
10764
10765 /* Print the content of the '.gdb_index' section.
10766 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
10767 */
10768 static void
print_gdb_index_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10769 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl,
10770 GElf_Ehdr *ehdr __attribute__ ((unused)),
10771 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10772 {
10773 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
10774 " contains %" PRId64 " bytes :\n"),
10775 elf_ndxscn (scn), section_name (ebl, shdr),
10776 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
10777
10778 Elf_Data *data = elf_rawdata (scn, NULL);
10779
10780 if (unlikely (data == NULL))
10781 {
10782 error (0, 0, gettext ("cannot get %s content: %s"),
10783 ".gdb_index", elf_errmsg (-1));
10784 return;
10785 }
10786
10787 // .gdb_index is always in little endian.
10788 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
10789 dbg = &dummy_dbg;
10790
10791 const unsigned char *readp = data->d_buf;
10792 const unsigned char *const dataend = readp + data->d_size;
10793
10794 if (unlikely (readp + 4 > dataend))
10795 {
10796 invalid_data:
10797 error (0, 0, gettext ("invalid data"));
10798 return;
10799 }
10800
10801 int32_t vers = read_4ubyte_unaligned (dbg, readp);
10802 printf (gettext (" Version: %" PRId32 "\n"), vers);
10803
10804 // The only difference between version 4 and version 5 is the
10805 // hash used for generating the table. Version 6 contains symbols
10806 // for inlined functions, older versions didn't. Version 7 adds
10807 // symbol kinds. Version 8 just indicates that it correctly includes
10808 // TUs for symbols.
10809 if (vers < 4 || vers > 8)
10810 {
10811 printf (gettext (" unknown version, cannot parse section\n"));
10812 return;
10813 }
10814
10815 readp += 4;
10816 if (unlikely (readp + 4 > dataend))
10817 goto invalid_data;
10818
10819 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
10820 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off);
10821
10822 readp += 4;
10823 if (unlikely (readp + 4 > dataend))
10824 goto invalid_data;
10825
10826 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
10827 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off);
10828
10829 readp += 4;
10830 if (unlikely (readp + 4 > dataend))
10831 goto invalid_data;
10832
10833 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
10834 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off);
10835
10836 readp += 4;
10837 if (unlikely (readp + 4 > dataend))
10838 goto invalid_data;
10839
10840 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
10841 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off);
10842
10843 readp += 4;
10844 if (unlikely (readp + 4 > dataend))
10845 goto invalid_data;
10846
10847 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
10848 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
10849
10850 if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
10851 < const_off))
10852 goto invalid_data;
10853
10854 readp = data->d_buf + cu_off;
10855
10856 const unsigned char *nextp = data->d_buf + tu_off;
10857 if (tu_off >= data->d_size)
10858 goto invalid_data;
10859
10860 size_t cu_nr = (nextp - readp) / 16;
10861
10862 printf (gettext ("\n CU list at offset %#" PRIx32
10863 " contains %zu entries:\n"),
10864 cu_off, cu_nr);
10865
10866 size_t n = 0;
10867 while (dataend - readp >= 16 && n < cu_nr)
10868 {
10869 uint64_t off = read_8ubyte_unaligned (dbg, readp);
10870 readp += 8;
10871
10872 uint64_t len = read_8ubyte_unaligned (dbg, readp);
10873 readp += 8;
10874
10875 printf (" [%4zu] start: %0#8" PRIx64
10876 ", length: %5" PRIu64 "\n", n, off, len);
10877 n++;
10878 }
10879
10880 readp = data->d_buf + tu_off;
10881 nextp = data->d_buf + addr_off;
10882 if (addr_off >= data->d_size)
10883 goto invalid_data;
10884
10885 size_t tu_nr = (nextp - readp) / 24;
10886
10887 printf (gettext ("\n TU list at offset %#" PRIx32
10888 " contains %zu entries:\n"),
10889 tu_off, tu_nr);
10890
10891 n = 0;
10892 while (dataend - readp >= 24 && n < tu_nr)
10893 {
10894 uint64_t off = read_8ubyte_unaligned (dbg, readp);
10895 readp += 8;
10896
10897 uint64_t type = read_8ubyte_unaligned (dbg, readp);
10898 readp += 8;
10899
10900 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
10901 readp += 8;
10902
10903 printf (" [%4zu] CU offset: %5" PRId64
10904 ", type offset: %5" PRId64
10905 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
10906 n++;
10907 }
10908
10909 readp = data->d_buf + addr_off;
10910 nextp = data->d_buf + sym_off;
10911 if (sym_off >= data->d_size)
10912 goto invalid_data;
10913
10914 size_t addr_nr = (nextp - readp) / 20;
10915
10916 printf (gettext ("\n Address list at offset %#" PRIx32
10917 " contains %zu entries:\n"),
10918 addr_off, addr_nr);
10919
10920 n = 0;
10921 while (dataend - readp >= 20 && n < addr_nr)
10922 {
10923 uint64_t low = read_8ubyte_unaligned (dbg, readp);
10924 readp += 8;
10925
10926 uint64_t high = read_8ubyte_unaligned (dbg, readp);
10927 readp += 8;
10928
10929 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
10930 readp += 4;
10931
10932 printf (" [%4zu] ", n);
10933 print_dwarf_addr (dwflmod, 8, low, low);
10934 printf ("..");
10935 print_dwarf_addr (dwflmod, 8, high - 1, high);
10936 printf (", CU index: %5" PRId32 "\n", idx);
10937 n++;
10938 }
10939
10940 const unsigned char *const_start = data->d_buf + const_off;
10941 if (const_off >= data->d_size)
10942 goto invalid_data;
10943
10944 readp = data->d_buf + sym_off;
10945 nextp = const_start;
10946 size_t sym_nr = (nextp - readp) / 8;
10947
10948 printf (gettext ("\n Symbol table at offset %#" PRIx32
10949 " contains %zu slots:\n"),
10950 addr_off, sym_nr);
10951
10952 n = 0;
10953 while (dataend - readp >= 8 && n < sym_nr)
10954 {
10955 uint32_t name = read_4ubyte_unaligned (dbg, readp);
10956 readp += 4;
10957
10958 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
10959 readp += 4;
10960
10961 if (name != 0 || vector != 0)
10962 {
10963 const unsigned char *sym = const_start + name;
10964 if (unlikely ((size_t) (dataend - const_start) < name
10965 || memchr (sym, '\0', dataend - sym) == NULL))
10966 goto invalid_data;
10967
10968 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
10969
10970 const unsigned char *readcus = const_start + vector;
10971 if (unlikely ((size_t) (dataend - const_start) < vector))
10972 goto invalid_data;
10973 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
10974 while (cus--)
10975 {
10976 uint32_t cu_kind, cu, kind;
10977 bool is_static;
10978 readcus += 4;
10979 if (unlikely (readcus + 4 > dataend))
10980 goto invalid_data;
10981 cu_kind = read_4ubyte_unaligned (dbg, readcus);
10982 cu = cu_kind & ((1 << 24) - 1);
10983 kind = (cu_kind >> 28) & 7;
10984 is_static = cu_kind & (1U << 31);
10985 if (cu > cu_nr - 1)
10986 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
10987 else
10988 printf ("%" PRId32, cu);
10989 if (kind != 0)
10990 {
10991 printf (" (");
10992 switch (kind)
10993 {
10994 case 1:
10995 printf ("type");
10996 break;
10997 case 2:
10998 printf ("var");
10999 break;
11000 case 3:
11001 printf ("func");
11002 break;
11003 case 4:
11004 printf ("other");
11005 break;
11006 default:
11007 printf ("unknown-0x%" PRIx32, kind);
11008 break;
11009 }
11010 printf (":%c)", (is_static ? 'S' : 'G'));
11011 }
11012 if (cus > 0)
11013 printf (", ");
11014 }
11015 printf ("\n");
11016 }
11017 n++;
11018 }
11019 }
11020
11021 /* Returns true and sets split DWARF CU id if there is a split compile
11022 unit in the given Dwarf, and no non-split units are found (before it). */
11023 static bool
is_split_dwarf(Dwarf * dbg,uint64_t * id,Dwarf_CU ** split_cu)11024 is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu)
11025 {
11026 Dwarf_CU *cu = NULL;
11027 while (dwarf_get_units (dbg, cu, &cu, NULL, NULL, NULL, NULL) == 0)
11028 {
11029 uint8_t unit_type;
11030 if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11031 id, NULL, NULL) != 0)
11032 return false;
11033
11034 if (unit_type != DW_UT_split_compile && unit_type != DW_UT_split_type)
11035 return false;
11036
11037 /* We really only care about the split compile unit, the types
11038 should be fine and self sufficient. Also they don't have an
11039 id that we can match with a skeleton unit. */
11040 if (unit_type == DW_UT_split_compile)
11041 {
11042 *split_cu = cu;
11043 return true;
11044 }
11045 }
11046
11047 return false;
11048 }
11049
11050 /* Check that there is one and only one Dwfl_Module, return in arg. */
11051 static int
getone_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)11052 getone_dwflmod (Dwfl_Module *dwflmod,
11053 void **userdata __attribute__ ((unused)),
11054 const char *name __attribute__ ((unused)),
11055 Dwarf_Addr base __attribute__ ((unused)),
11056 void *arg)
11057 {
11058 Dwfl_Module **m = (Dwfl_Module **) arg;
11059 if (*m != NULL)
11060 return DWARF_CB_ABORT;
11061 *m = dwflmod;
11062 return DWARF_CB_OK;
11063 }
11064
11065 static void
print_debug(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr)11066 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
11067 {
11068 /* Used for skeleton file, if necessary for split DWARF. */
11069 Dwfl *skel_dwfl = NULL;
11070 Dwfl_Module *skel_mod = NULL;
11071 char *skel_name = NULL;
11072 Dwarf *split_dbg = NULL;
11073 Dwarf_CU *split_cu = NULL;
11074
11075 /* Before we start the real work get a debug context descriptor. */
11076 Dwarf_Addr dwbias;
11077 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
11078 Dwarf dummy_dbg =
11079 {
11080 .elf = ebl->elf,
11081 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
11082 };
11083 if (dbg == NULL)
11084 {
11085 if ((print_debug_sections & ~section_exception) != 0)
11086 error (0, 0, gettext ("cannot get debug context descriptor: %s"),
11087 dwfl_errmsg (-1));
11088 dbg = &dummy_dbg;
11089 }
11090 else
11091 {
11092 /* If we are asked about a split dwarf (.dwo) file, use the user
11093 provided, or find the corresponding skeleton file. If we got
11094 a skeleton file, replace the given dwflmod and dbg, with one
11095 derived from the skeleton file to provide enough context. */
11096 uint64_t split_id;
11097 if (is_split_dwarf (dbg, &split_id, &split_cu))
11098 {
11099 if (dwarf_skeleton != NULL)
11100 skel_name = strdup (dwarf_skeleton);
11101 else
11102 {
11103 /* Replace file.dwo with file.o and see if that matches. */
11104 const char *fname;
11105 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL,
11106 &fname, NULL);
11107 if (fname != NULL)
11108 {
11109 size_t flen = strlen (fname);
11110 if (flen > 4 && strcmp (".dwo", fname + flen - 4) == 0)
11111 {
11112 skel_name = strdup (fname);
11113 if (skel_name != NULL)
11114 {
11115 skel_name[flen - 3] = 'o';
11116 skel_name[flen - 2] = '\0';
11117 }
11118 }
11119 }
11120 }
11121
11122 if (skel_name != NULL)
11123 {
11124 int skel_fd = open (skel_name, O_RDONLY);
11125 if (skel_fd == -1)
11126 fprintf (stderr, "Warning: Couldn't open DWARF skeleton file"
11127 " '%s'\n", skel_name);
11128 else
11129 skel_dwfl = create_dwfl (skel_fd, skel_name);
11130
11131 if (skel_dwfl != NULL)
11132 {
11133 if (dwfl_getmodules (skel_dwfl, &getone_dwflmod,
11134 &skel_mod, 0) != 0)
11135 {
11136 fprintf (stderr, "Warning: Bad DWARF skeleton,"
11137 " multiple modules '%s'\n", skel_name);
11138 dwfl_end (skel_dwfl);
11139 skel_mod = NULL;
11140 }
11141 }
11142 else if (skel_fd != -1)
11143 fprintf (stderr, "Warning: Couldn't create skeleton dwfl for"
11144 " '%s': %s\n", skel_name, dwfl_errmsg (-1));
11145
11146 if (skel_mod != NULL)
11147 {
11148 Dwarf *skel_dbg = dwfl_module_getdwarf (skel_mod, &dwbias);
11149 if (skel_dbg != NULL)
11150 {
11151 /* First check the skeleton CU DIE, only fetch
11152 the split DIE if we know the id matches to
11153 not unnecessary search for any split DIEs we
11154 don't need. */
11155 Dwarf_CU *cu = NULL;
11156 while (dwarf_get_units (skel_dbg, cu, &cu,
11157 NULL, NULL, NULL, NULL) == 0)
11158 {
11159 uint8_t unit_type;
11160 uint64_t skel_id;
11161 if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11162 &skel_id, NULL, NULL) == 0
11163 && unit_type == DW_UT_skeleton
11164 && split_id == skel_id)
11165 {
11166 Dwarf_Die subdie;
11167 if (dwarf_cu_info (cu, NULL, NULL, NULL,
11168 &subdie,
11169 NULL, NULL, NULL) == 0
11170 && dwarf_tag (&subdie) != DW_TAG_invalid)
11171 {
11172 split_dbg = dwarf_cu_getdwarf (subdie.cu);
11173 if (split_dbg == NULL)
11174 fprintf (stderr,
11175 "Warning: Couldn't get split_dbg:"
11176 " %s\n", dwarf_errmsg (-1));
11177 break;
11178 }
11179 else
11180 {
11181 /* Everything matches up, but not
11182 according to libdw. Which means
11183 the user knew better. So...
11184 Terrible hack... We can never
11185 destroy the underlying dwfl
11186 because it would free the wrong
11187 Dwarfs... So we leak memory...*/
11188 if (cu->split == NULL
11189 && dwarf_skeleton != NULL)
11190 {
11191 do_not_close_dwfl = true;
11192 __libdw_link_skel_split (cu, split_cu);
11193 split_dbg = dwarf_cu_getdwarf (split_cu);
11194 break;
11195 }
11196 else
11197 fprintf (stderr, "Warning: Couldn't get"
11198 " skeleton subdie: %s\n",
11199 dwarf_errmsg (-1));
11200 }
11201 }
11202 }
11203 if (split_dbg == NULL)
11204 fprintf (stderr, "Warning: '%s' didn't contain a skeleton for split id %" PRIx64 "\n", skel_name, split_id);
11205 }
11206 else
11207 fprintf (stderr, "Warning: Couldn't get skeleton DWARF:"
11208 " %s\n", dwfl_errmsg (-1));
11209 }
11210 }
11211
11212 if (split_dbg != NULL)
11213 {
11214 dbg = split_dbg;
11215 dwflmod = skel_mod;
11216 }
11217 else if (skel_name == NULL)
11218 fprintf (stderr,
11219 "Warning: split DWARF file, but no skeleton found.\n");
11220 }
11221 else if (dwarf_skeleton != NULL)
11222 fprintf (stderr, "Warning: DWARF skeleton given,"
11223 " but not a split DWARF file\n");
11224 }
11225
11226 /* Get the section header string table index. */
11227 size_t shstrndx;
11228 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
11229 error (EXIT_FAILURE, 0,
11230 gettext ("cannot get section header string table index"));
11231
11232 /* If the .debug_info section is listed as implicitly required then
11233 we must make sure to handle it before handling any other debug
11234 section. Various other sections depend on the CU DIEs being
11235 scanned (silently) first. */
11236 bool implicit_info = (implicit_debug_sections & section_info) != 0;
11237 bool explicit_info = (print_debug_sections & section_info) != 0;
11238 if (implicit_info)
11239 {
11240 Elf_Scn *scn = NULL;
11241 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11242 {
11243 GElf_Shdr shdr_mem;
11244 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11245
11246 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11247 {
11248 const char *name = elf_strptr (ebl->elf, shstrndx,
11249 shdr->sh_name);
11250 if (name == NULL)
11251 continue;
11252
11253 if (strcmp (name, ".debug_info") == 0
11254 || strcmp (name, ".debug_info.dwo") == 0
11255 || strcmp (name, ".zdebug_info") == 0
11256 || strcmp (name, ".zdebug_info.dwo") == 0)
11257 {
11258 print_debug_info_section (dwflmod, ebl, ehdr,
11259 scn, shdr, dbg);
11260 break;
11261 }
11262 }
11263 }
11264 print_debug_sections &= ~section_info;
11265 implicit_debug_sections &= ~section_info;
11266 }
11267
11268 /* Look through all the sections for the debugging sections to print. */
11269 Elf_Scn *scn = NULL;
11270 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11271 {
11272 GElf_Shdr shdr_mem;
11273 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11274
11275 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11276 {
11277 static const struct
11278 {
11279 const char *name;
11280 enum section_e bitmask;
11281 void (*fp) (Dwfl_Module *, Ebl *,
11282 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
11283 } debug_sections[] =
11284 {
11285 #define NEW_SECTION(name) \
11286 { ".debug_" #name, section_##name, print_debug_##name##_section }
11287 NEW_SECTION (abbrev),
11288 NEW_SECTION (addr),
11289 NEW_SECTION (aranges),
11290 NEW_SECTION (frame),
11291 NEW_SECTION (info),
11292 NEW_SECTION (types),
11293 NEW_SECTION (line),
11294 NEW_SECTION (loc),
11295 /* loclists is loc for DWARF5. */
11296 { ".debug_loclists", section_loc,
11297 print_debug_loclists_section },
11298 NEW_SECTION (pubnames),
11299 NEW_SECTION (str),
11300 /* A DWARF5 specialised debug string section. */
11301 { ".debug_line_str", section_str,
11302 print_debug_str_section },
11303 /* DWARF5 string offsets table. */
11304 { ".debug_str_offsets", section_str,
11305 print_debug_str_offsets_section },
11306 NEW_SECTION (macinfo),
11307 NEW_SECTION (macro),
11308 NEW_SECTION (ranges),
11309 /* rnglists is ranges for DWARF5. */
11310 { ".debug_rnglists", section_ranges,
11311 print_debug_rnglists_section },
11312 { ".eh_frame", section_frame | section_exception,
11313 print_debug_frame_section },
11314 { ".eh_frame_hdr", section_frame | section_exception,
11315 print_debug_frame_hdr_section },
11316 { ".gcc_except_table", section_frame | section_exception,
11317 print_debug_exception_table },
11318 { ".gdb_index", section_gdb_index, print_gdb_index_section }
11319 };
11320 const int ndebug_sections = (sizeof (debug_sections)
11321 / sizeof (debug_sections[0]));
11322 const char *name = elf_strptr (ebl->elf, shstrndx,
11323 shdr->sh_name);
11324 if (name == NULL)
11325 continue;
11326
11327 int n;
11328 for (n = 0; n < ndebug_sections; ++n)
11329 {
11330 size_t dbglen = strlen (debug_sections[n].name);
11331 size_t scnlen = strlen (name);
11332 if ((strncmp (name, debug_sections[n].name, dbglen) == 0
11333 && (dbglen == scnlen
11334 || (scnlen == dbglen + 4
11335 && strstr (name, ".dwo") == name + dbglen)))
11336 || (name[0] == '.' && name[1] == 'z'
11337 && debug_sections[n].name[1] == 'd'
11338 && strncmp (&name[2], &debug_sections[n].name[1],
11339 dbglen - 1) == 0
11340 && (scnlen == dbglen + 1
11341 || (scnlen == dbglen + 5
11342 && strstr (name, ".dwo") == name + dbglen + 1))))
11343 {
11344 if ((print_debug_sections | implicit_debug_sections)
11345 & debug_sections[n].bitmask)
11346 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
11347 break;
11348 }
11349 }
11350 }
11351 }
11352
11353 dwfl_end (skel_dwfl);
11354 free (skel_name);
11355
11356 /* Turn implicit and/or explicit back on in case we go over another file. */
11357 if (implicit_info)
11358 implicit_debug_sections |= section_info;
11359 if (explicit_info)
11360 print_debug_sections |= section_info;
11361
11362 reset_listptr (&known_locsptr);
11363 reset_listptr (&known_loclistsptr);
11364 reset_listptr (&known_rangelistptr);
11365 reset_listptr (&known_rnglistptr);
11366 reset_listptr (&known_addrbases);
11367 reset_listptr (&known_stroffbases);
11368 }
11369
11370
11371 #define ITEM_INDENT 4
11372 #define WRAP_COLUMN 75
11373
11374 /* Print "NAME: FORMAT", wrapping when output text would make the line
11375 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
11376 but this function is also used for registers which should be printed
11377 aligned. Fortunately registers output uses fixed fields width (such
11378 as %11d) for the alignment.
11379
11380 Line breaks should not depend on the particular values although that
11381 may happen in some cases of the core items. */
11382
11383 static unsigned int
11384 __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,...)11385 print_core_item (unsigned int colno, char sep, unsigned int wrap,
11386 size_t name_width, const char *name, const char *format, ...)
11387 {
11388 size_t len = strlen (name);
11389 if (name_width < len)
11390 name_width = len;
11391
11392 char *out;
11393 va_list ap;
11394 va_start (ap, format);
11395 int out_len = vasprintf (&out, format, ap);
11396 va_end (ap);
11397 if (out_len == -1)
11398 error (EXIT_FAILURE, 0, _("memory exhausted"));
11399
11400 size_t n = name_width + sizeof ": " - 1 + out_len;
11401
11402 if (colno == 0)
11403 {
11404 printf ("%*s", ITEM_INDENT, "");
11405 colno = ITEM_INDENT + n;
11406 }
11407 else if (colno + 2 + n < wrap)
11408 {
11409 printf ("%c ", sep);
11410 colno += 2 + n;
11411 }
11412 else
11413 {
11414 printf ("\n%*s", ITEM_INDENT, "");
11415 colno = ITEM_INDENT + n;
11416 }
11417
11418 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
11419
11420 free (out);
11421
11422 return colno;
11423 }
11424
11425 static const void *
convert(Elf * core,Elf_Type type,uint_fast16_t count,void * value,const void * data,size_t size)11426 convert (Elf *core, Elf_Type type, uint_fast16_t count,
11427 void *value, const void *data, size_t size)
11428 {
11429 Elf_Data valuedata =
11430 {
11431 .d_type = type,
11432 .d_buf = value,
11433 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
11434 .d_version = EV_CURRENT,
11435 };
11436 Elf_Data indata =
11437 {
11438 .d_type = type,
11439 .d_buf = (void *) data,
11440 .d_size = valuedata.d_size,
11441 .d_version = EV_CURRENT,
11442 };
11443
11444 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
11445 ? elf32_xlatetom : elf64_xlatetom)
11446 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
11447 if (d == NULL)
11448 error (EXIT_FAILURE, 0,
11449 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
11450
11451 return data + indata.d_size;
11452 }
11453
11454 typedef uint8_t GElf_Byte;
11455
11456 static unsigned int
handle_core_item(Elf * core,const Ebl_Core_Item * item,const void * desc,unsigned int colno,size_t * repeated_size)11457 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
11458 unsigned int colno, size_t *repeated_size)
11459 {
11460 uint_fast16_t count = item->count ?: 1;
11461 /* Ebl_Core_Item count is always a small number.
11462 Make sure the backend didn't put in some large bogus value. */
11463 assert (count < 128);
11464
11465 #define TYPES \
11466 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
11467 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
11468 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
11469 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
11470 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
11471 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
11472
11473 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
11474 typedef union { TYPES; } value_t;
11475 void *data = alloca (count * sizeof (value_t));
11476 #undef DO_TYPE
11477
11478 #define DO_TYPE(NAME, Name, hex, dec) \
11479 GElf_##Name *value_##Name __attribute__((unused)) = data
11480 TYPES;
11481 #undef DO_TYPE
11482
11483 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
11484 size_t convsize = size;
11485 if (repeated_size != NULL)
11486 {
11487 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
11488 {
11489 data = alloca (*repeated_size);
11490 count *= *repeated_size / size;
11491 convsize = count * size;
11492 *repeated_size -= convsize;
11493 }
11494 else if (item->count != 0 || item->format != '\n')
11495 *repeated_size -= size;
11496 }
11497
11498 convert (core, item->type, count, data, desc + item->offset, convsize);
11499
11500 Elf_Type type = item->type;
11501 if (type == ELF_T_ADDR)
11502 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
11503
11504 switch (item->format)
11505 {
11506 case 'd':
11507 assert (count == 1);
11508 switch (type)
11509 {
11510 #define DO_TYPE(NAME, Name, hex, dec) \
11511 case ELF_T_##NAME: \
11512 colno = print_core_item (colno, ',', WRAP_COLUMN, \
11513 0, item->name, dec, value_##Name[0]); \
11514 break
11515 TYPES;
11516 #undef DO_TYPE
11517 default:
11518 abort ();
11519 }
11520 break;
11521
11522 case 'x':
11523 assert (count == 1);
11524 switch (type)
11525 {
11526 #define DO_TYPE(NAME, Name, hex, dec) \
11527 case ELF_T_##NAME: \
11528 colno = print_core_item (colno, ',', WRAP_COLUMN, \
11529 0, item->name, hex, value_##Name[0]); \
11530 break
11531 TYPES;
11532 #undef DO_TYPE
11533 default:
11534 abort ();
11535 }
11536 break;
11537
11538 case 'b':
11539 case 'B':
11540 assert (size % sizeof (unsigned int) == 0);
11541 unsigned int nbits = count * size * 8;
11542 unsigned int pop = 0;
11543 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
11544 pop += __builtin_popcount (*i);
11545 bool negate = pop > nbits / 2;
11546 const unsigned int bias = item->format == 'b';
11547
11548 {
11549 char printed[(negate ? nbits - pop : pop) * 16 + 1];
11550 char *p = printed;
11551 *p = '\0';
11552
11553 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
11554 {
11555 assert (size == sizeof (unsigned int) * 2);
11556 for (unsigned int *i = data;
11557 (void *) i < data + count * size; i += 2)
11558 {
11559 unsigned int w = i[1];
11560 i[1] = i[0];
11561 i[0] = w;
11562 }
11563 }
11564
11565 unsigned int lastbit = 0;
11566 unsigned int run = 0;
11567 for (const unsigned int *i = data;
11568 (void *) i < data + count * size; ++i)
11569 {
11570 unsigned int bit = ((void *) i - data) * 8;
11571 unsigned int w = negate ? ~*i : *i;
11572 while (w != 0)
11573 {
11574 /* Note that a right shift equal to (or greater than)
11575 the number of bits of w is undefined behaviour. In
11576 particular when the least significant bit is bit 32
11577 (w = 0x8000000) then w >>= n is undefined. So
11578 explicitly handle that case separately. */
11579 unsigned int n = ffs (w);
11580 if (n < sizeof (w) * 8)
11581 w >>= n;
11582 else
11583 w = 0;
11584 bit += n;
11585
11586 if (lastbit != 0 && lastbit + 1 == bit)
11587 ++run;
11588 else
11589 {
11590 if (lastbit == 0)
11591 p += sprintf (p, "%u", bit - bias);
11592 else if (run == 0)
11593 p += sprintf (p, ",%u", bit - bias);
11594 else
11595 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
11596 run = 0;
11597 }
11598
11599 lastbit = bit;
11600 }
11601 }
11602 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
11603 p += sprintf (p, "-%u", lastbit - bias);
11604
11605 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11606 negate ? "~<%s>" : "<%s>", printed);
11607 }
11608 break;
11609
11610 case 'T':
11611 case (char) ('T'|0x80):
11612 assert (count == 2);
11613 Dwarf_Word sec;
11614 Dwarf_Word usec;
11615 switch (type)
11616 {
11617 #define DO_TYPE(NAME, Name, hex, dec) \
11618 case ELF_T_##NAME: \
11619 sec = value_##Name[0]; \
11620 usec = value_##Name[1]; \
11621 break
11622 TYPES;
11623 #undef DO_TYPE
11624 default:
11625 abort ();
11626 }
11627 if (unlikely (item->format == (char) ('T'|0x80)))
11628 {
11629 /* This is a hack for an ill-considered 64-bit ABI where
11630 tv_usec is actually a 32-bit field with 32 bits of padding
11631 rounding out struct timeval. We've already converted it as
11632 a 64-bit field. For little-endian, this just means the
11633 high half is the padding; it's presumably zero, but should
11634 be ignored anyway. For big-endian, it means the 32-bit
11635 field went into the high half of USEC. */
11636 GElf_Ehdr ehdr_mem;
11637 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
11638 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
11639 usec >>= 32;
11640 else
11641 usec &= UINT32_MAX;
11642 }
11643 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11644 "%" PRIu64 ".%.6" PRIu64, sec, usec);
11645 break;
11646
11647 case 'c':
11648 assert (count == 1);
11649 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11650 "%c", value_Byte[0]);
11651 break;
11652
11653 case 's':
11654 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11655 "%.*s", (int) count, value_Byte);
11656 break;
11657
11658 case '\n':
11659 /* This is a list of strings separated by '\n'. */
11660 assert (item->count == 0);
11661 assert (repeated_size != NULL);
11662 assert (item->name == NULL);
11663 if (unlikely (item->offset >= *repeated_size))
11664 break;
11665
11666 const char *s = desc + item->offset;
11667 size = *repeated_size - item->offset;
11668 *repeated_size = 0;
11669 while (size > 0)
11670 {
11671 const char *eol = memchr (s, '\n', size);
11672 int len = size;
11673 if (eol != NULL)
11674 len = eol - s;
11675 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
11676 if (eol == NULL)
11677 break;
11678 size -= eol + 1 - s;
11679 s = eol + 1;
11680 }
11681
11682 colno = WRAP_COLUMN;
11683 break;
11684
11685 case 'h':
11686 break;
11687
11688 default:
11689 error (0, 0, "XXX not handling format '%c' for %s",
11690 item->format, item->name);
11691 break;
11692 }
11693
11694 #undef TYPES
11695
11696 return colno;
11697 }
11698
11699
11700 /* Sort items by group, and by layout offset within each group. */
11701 static int
compare_core_items(const void * a,const void * b)11702 compare_core_items (const void *a, const void *b)
11703 {
11704 const Ebl_Core_Item *const *p1 = a;
11705 const Ebl_Core_Item *const *p2 = b;
11706 const Ebl_Core_Item *item1 = *p1;
11707 const Ebl_Core_Item *item2 = *p2;
11708
11709 return ((item1->group == item2->group ? 0
11710 : strcmp (item1->group, item2->group))
11711 ?: (int) item1->offset - (int) item2->offset);
11712 }
11713
11714 /* Sort item groups by layout offset of the first item in the group. */
11715 static int
compare_core_item_groups(const void * a,const void * b)11716 compare_core_item_groups (const void *a, const void *b)
11717 {
11718 const Ebl_Core_Item *const *const *p1 = a;
11719 const Ebl_Core_Item *const *const *p2 = b;
11720 const Ebl_Core_Item *const *group1 = *p1;
11721 const Ebl_Core_Item *const *group2 = *p2;
11722 const Ebl_Core_Item *item1 = *group1;
11723 const Ebl_Core_Item *item2 = *group2;
11724
11725 return (int) item1->offset - (int) item2->offset;
11726 }
11727
11728 static unsigned int
handle_core_items(Elf * core,const void * desc,size_t descsz,const Ebl_Core_Item * items,size_t nitems)11729 handle_core_items (Elf *core, const void *desc, size_t descsz,
11730 const Ebl_Core_Item *items, size_t nitems)
11731 {
11732 if (nitems == 0)
11733 return 0;
11734 unsigned int colno = 0;
11735
11736 /* FORMAT '\n' makes sense to be present only as a single item as it
11737 processes all the data of a note. FORMATs 'b' and 'B' have a special case
11738 if present as a single item but they can be also processed with other
11739 items below. */
11740 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
11741 || items[0].format == 'B'))
11742 {
11743 assert (items[0].offset == 0);
11744 size_t size = descsz;
11745 colno = handle_core_item (core, items, desc, colno, &size);
11746 /* If SIZE is not zero here there is some remaining data. But we do not
11747 know how to process it anyway. */
11748 return colno;
11749 }
11750 for (size_t i = 0; i < nitems; ++i)
11751 assert (items[i].format != '\n');
11752
11753 /* Sort to collect the groups together. */
11754 const Ebl_Core_Item *sorted_items[nitems];
11755 for (size_t i = 0; i < nitems; ++i)
11756 sorted_items[i] = &items[i];
11757 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
11758
11759 /* Collect the unique groups and sort them. */
11760 const Ebl_Core_Item **groups[nitems];
11761 groups[0] = &sorted_items[0];
11762 size_t ngroups = 1;
11763 for (size_t i = 1; i < nitems; ++i)
11764 if (sorted_items[i]->group != sorted_items[i - 1]->group
11765 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
11766 groups[ngroups++] = &sorted_items[i];
11767 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
11768
11769 /* Write out all the groups. */
11770 const void *last = desc;
11771 do
11772 {
11773 for (size_t i = 0; i < ngroups; ++i)
11774 {
11775 for (const Ebl_Core_Item **item = groups[i];
11776 (item < &sorted_items[nitems]
11777 && ((*item)->group == groups[i][0]->group
11778 || !strcmp ((*item)->group, groups[i][0]->group)));
11779 ++item)
11780 colno = handle_core_item (core, *item, desc, colno, NULL);
11781
11782 /* Force a line break at the end of the group. */
11783 colno = WRAP_COLUMN;
11784 }
11785
11786 if (descsz == 0)
11787 break;
11788
11789 /* This set of items consumed a certain amount of the note's data.
11790 If there is more data there, we have another unit of the same size.
11791 Loop to print that out too. */
11792 const Ebl_Core_Item *item = &items[nitems - 1];
11793 size_t eltsz = item->offset + gelf_fsize (core, item->type,
11794 item->count ?: 1, EV_CURRENT);
11795
11796 int reps = -1;
11797 do
11798 {
11799 ++reps;
11800 desc += eltsz;
11801 descsz -= eltsz;
11802 }
11803 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
11804
11805 if (reps == 1)
11806 {
11807 /* For just one repeat, print it unabridged twice. */
11808 desc -= eltsz;
11809 descsz += eltsz;
11810 }
11811 else if (reps > 1)
11812 printf (gettext ("\n%*s... <repeats %u more times> ..."),
11813 ITEM_INDENT, "", reps);
11814
11815 last = desc;
11816 }
11817 while (descsz > 0);
11818
11819 return colno;
11820 }
11821
11822 static unsigned int
handle_bit_registers(const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)11823 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
11824 unsigned int colno)
11825 {
11826 desc += regloc->offset;
11827
11828 abort (); /* XXX */
11829 return colno;
11830 }
11831
11832
11833 static unsigned int
handle_core_register(Ebl * ebl,Elf * core,int maxregname,const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)11834 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
11835 const Ebl_Register_Location *regloc, const void *desc,
11836 unsigned int colno)
11837 {
11838 if (regloc->bits % 8 != 0)
11839 return handle_bit_registers (regloc, desc, colno);
11840
11841 desc += regloc->offset;
11842
11843 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
11844 {
11845 char name[REGNAMESZ];
11846 int bits;
11847 int type;
11848 register_info (ebl, reg, regloc, name, &bits, &type);
11849
11850 #define TYPES \
11851 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
11852 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
11853 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
11854 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
11855
11856 #define BITS(bits, xtype, sfmt, ufmt) \
11857 uint##bits##_t b##bits; int##bits##_t b##bits##s
11858 union { TYPES; uint64_t b128[2]; } value;
11859 #undef BITS
11860
11861 switch (type)
11862 {
11863 case DW_ATE_unsigned:
11864 case DW_ATE_signed:
11865 case DW_ATE_address:
11866 switch (bits)
11867 {
11868 #define BITS(bits, xtype, sfmt, ufmt) \
11869 case bits: \
11870 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
11871 if (type == DW_ATE_signed) \
11872 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
11873 maxregname, name, \
11874 sfmt, value.b##bits##s); \
11875 else \
11876 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
11877 maxregname, name, \
11878 ufmt, value.b##bits); \
11879 break
11880
11881 TYPES;
11882
11883 case 128:
11884 assert (type == DW_ATE_unsigned);
11885 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
11886 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
11887 colno = print_core_item (colno, ' ', WRAP_COLUMN,
11888 maxregname, name,
11889 "0x%.16" PRIx64 "%.16" PRIx64,
11890 value.b128[!be], value.b128[be]);
11891 break;
11892
11893 default:
11894 abort ();
11895 #undef BITS
11896 }
11897 break;
11898
11899 default:
11900 /* Print each byte in hex, the whole thing in native byte order. */
11901 assert (bits % 8 == 0);
11902 const uint8_t *bytes = desc;
11903 desc += bits / 8;
11904 char hex[bits / 4 + 1];
11905 hex[bits / 4] = '\0';
11906 int incr = 1;
11907 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
11908 {
11909 bytes += bits / 8 - 1;
11910 incr = -1;
11911 }
11912 size_t idx = 0;
11913 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
11914 {
11915 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
11916 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
11917 }
11918 colno = print_core_item (colno, ' ', WRAP_COLUMN,
11919 maxregname, name, "0x%s", hex);
11920 break;
11921 }
11922 desc += regloc->pad;
11923
11924 #undef TYPES
11925 }
11926
11927 return colno;
11928 }
11929
11930
11931 struct register_info
11932 {
11933 const Ebl_Register_Location *regloc;
11934 const char *set;
11935 char name[REGNAMESZ];
11936 int regno;
11937 int bits;
11938 int type;
11939 };
11940
11941 static int
register_bitpos(const struct register_info * r)11942 register_bitpos (const struct register_info *r)
11943 {
11944 return (r->regloc->offset * 8
11945 + ((r->regno - r->regloc->regno)
11946 * (r->regloc->bits + r->regloc->pad * 8)));
11947 }
11948
11949 static int
compare_sets_by_info(const struct register_info * r1,const struct register_info * r2)11950 compare_sets_by_info (const struct register_info *r1,
11951 const struct register_info *r2)
11952 {
11953 return ((int) r2->bits - (int) r1->bits
11954 ?: register_bitpos (r1) - register_bitpos (r2));
11955 }
11956
11957 /* Sort registers by set, and by size and layout offset within each set. */
11958 static int
compare_registers(const void * a,const void * b)11959 compare_registers (const void *a, const void *b)
11960 {
11961 const struct register_info *r1 = a;
11962 const struct register_info *r2 = b;
11963
11964 /* Unused elements sort last. */
11965 if (r1->regloc == NULL)
11966 return r2->regloc == NULL ? 0 : 1;
11967 if (r2->regloc == NULL)
11968 return -1;
11969
11970 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
11971 ?: compare_sets_by_info (r1, r2));
11972 }
11973
11974 /* Sort register sets by layout offset of the first register in the set. */
11975 static int
compare_register_sets(const void * a,const void * b)11976 compare_register_sets (const void *a, const void *b)
11977 {
11978 const struct register_info *const *p1 = a;
11979 const struct register_info *const *p2 = b;
11980 return compare_sets_by_info (*p1, *p2);
11981 }
11982
11983 static unsigned int
handle_core_registers(Ebl * ebl,Elf * core,const void * desc,const Ebl_Register_Location * reglocs,size_t nregloc)11984 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
11985 const Ebl_Register_Location *reglocs, size_t nregloc)
11986 {
11987 if (nregloc == 0)
11988 return 0;
11989
11990 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
11991 if (maxnreg <= 0)
11992 {
11993 for (size_t i = 0; i < nregloc; ++i)
11994 if (maxnreg < reglocs[i].regno + reglocs[i].count)
11995 maxnreg = reglocs[i].regno + reglocs[i].count;
11996 assert (maxnreg > 0);
11997 }
11998
11999 struct register_info regs[maxnreg];
12000 memset (regs, 0, sizeof regs);
12001
12002 /* Sort to collect the sets together. */
12003 int maxreg = 0;
12004 for (size_t i = 0; i < nregloc; ++i)
12005 for (int reg = reglocs[i].regno;
12006 reg < reglocs[i].regno + reglocs[i].count;
12007 ++reg)
12008 {
12009 assert (reg < maxnreg);
12010 if (reg > maxreg)
12011 maxreg = reg;
12012 struct register_info *info = ®s[reg];
12013 info->regloc = ®locs[i];
12014 info->regno = reg;
12015 info->set = register_info (ebl, reg, ®locs[i],
12016 info->name, &info->bits, &info->type);
12017 }
12018 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
12019
12020 /* Collect the unique sets and sort them. */
12021 inline bool same_set (const struct register_info *a,
12022 const struct register_info *b)
12023 {
12024 return (a < ®s[maxnreg] && a->regloc != NULL
12025 && b < ®s[maxnreg] && b->regloc != NULL
12026 && a->bits == b->bits
12027 && (a->set == b->set || !strcmp (a->set, b->set)));
12028 }
12029 struct register_info *sets[maxreg + 1];
12030 sets[0] = ®s[0];
12031 size_t nsets = 1;
12032 for (int i = 1; i <= maxreg; ++i)
12033 if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1]))
12034 sets[nsets++] = ®s[i];
12035 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
12036
12037 /* Write out all the sets. */
12038 unsigned int colno = 0;
12039 for (size_t i = 0; i < nsets; ++i)
12040 {
12041 /* Find the longest name of a register in this set. */
12042 size_t maxname = 0;
12043 const struct register_info *end;
12044 for (end = sets[i]; same_set (sets[i], end); ++end)
12045 {
12046 size_t len = strlen (end->name);
12047 if (len > maxname)
12048 maxname = len;
12049 }
12050
12051 for (const struct register_info *reg = sets[i];
12052 reg < end;
12053 reg += reg->regloc->count ?: 1)
12054 colno = handle_core_register (ebl, core, maxname,
12055 reg->regloc, desc, colno);
12056
12057 /* Force a line break at the end of the group. */
12058 colno = WRAP_COLUMN;
12059 }
12060
12061 return colno;
12062 }
12063
12064 static void
handle_auxv_note(Ebl * ebl,Elf * core,GElf_Word descsz,GElf_Off desc_pos)12065 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12066 {
12067 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
12068 if (data == NULL)
12069 elf_error:
12070 error (EXIT_FAILURE, 0,
12071 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12072
12073 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
12074 for (size_t i = 0; i < nauxv; ++i)
12075 {
12076 GElf_auxv_t av_mem;
12077 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
12078 if (av == NULL)
12079 goto elf_error;
12080
12081 const char *name;
12082 const char *fmt;
12083 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
12084 {
12085 /* Unknown type. */
12086 if (av->a_un.a_val == 0)
12087 printf (" %" PRIu64 "\n", av->a_type);
12088 else
12089 printf (" %" PRIu64 ": %#" PRIx64 "\n",
12090 av->a_type, av->a_un.a_val);
12091 }
12092 else
12093 switch (fmt[0])
12094 {
12095 case '\0': /* Normally zero. */
12096 if (av->a_un.a_val == 0)
12097 {
12098 printf (" %s\n", name);
12099 break;
12100 }
12101 FALLTHROUGH;
12102 case 'x': /* hex */
12103 case 'p': /* address */
12104 case 's': /* address of string */
12105 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
12106 break;
12107 case 'u':
12108 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
12109 break;
12110 case 'd':
12111 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
12112 break;
12113
12114 case 'b':
12115 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
12116 GElf_Xword bit = 1;
12117 const char *pfx = "<";
12118 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
12119 {
12120 if (av->a_un.a_val & bit)
12121 {
12122 printf ("%s%s", pfx, p);
12123 pfx = " ";
12124 }
12125 bit <<= 1;
12126 }
12127 printf (">\n");
12128 break;
12129
12130 default:
12131 abort ();
12132 }
12133 }
12134 }
12135
12136 static bool
buf_has_data(unsigned char const * ptr,unsigned char const * end,size_t sz)12137 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
12138 {
12139 return ptr < end && (size_t) (end - ptr) >= sz;
12140 }
12141
12142 static bool
buf_read_int(Elf * core,unsigned char const ** ptrp,unsigned char const * end,int * retp)12143 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12144 int *retp)
12145 {
12146 if (! buf_has_data (*ptrp, end, 4))
12147 return false;
12148
12149 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
12150 return true;
12151 }
12152
12153 static bool
buf_read_ulong(Elf * core,unsigned char const ** ptrp,unsigned char const * end,uint64_t * retp)12154 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12155 uint64_t *retp)
12156 {
12157 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12158 if (! buf_has_data (*ptrp, end, sz))
12159 return false;
12160
12161 union
12162 {
12163 uint64_t u64;
12164 uint32_t u32;
12165 } u;
12166
12167 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
12168
12169 if (sz == 4)
12170 *retp = u.u32;
12171 else
12172 *retp = u.u64;
12173 return true;
12174 }
12175
12176 static void
handle_siginfo_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12177 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12178 {
12179 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12180 if (data == NULL)
12181 error (EXIT_FAILURE, 0,
12182 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12183
12184 unsigned char const *ptr = data->d_buf;
12185 unsigned char const *const end = data->d_buf + data->d_size;
12186
12187 /* Siginfo head is three ints: signal number, error number, origin
12188 code. */
12189 int si_signo, si_errno, si_code;
12190 if (! buf_read_int (core, &ptr, end, &si_signo)
12191 || ! buf_read_int (core, &ptr, end, &si_errno)
12192 || ! buf_read_int (core, &ptr, end, &si_code))
12193 {
12194 fail:
12195 printf (" Not enough data in NT_SIGINFO note.\n");
12196 return;
12197 }
12198
12199 /* Next is a pointer-aligned union of structures. On 64-bit
12200 machines, that implies a word of padding. */
12201 if (gelf_getclass (core) == ELFCLASS64)
12202 ptr += 4;
12203
12204 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
12205 si_signo, si_errno, si_code);
12206
12207 if (si_code > 0)
12208 switch (si_signo)
12209 {
12210 case CORE_SIGILL:
12211 case CORE_SIGFPE:
12212 case CORE_SIGSEGV:
12213 case CORE_SIGBUS:
12214 {
12215 uint64_t addr;
12216 if (! buf_read_ulong (core, &ptr, end, &addr))
12217 goto fail;
12218 printf (" fault address: %#" PRIx64 "\n", addr);
12219 break;
12220 }
12221 default:
12222 ;
12223 }
12224 else if (si_code == CORE_SI_USER)
12225 {
12226 int pid, uid;
12227 if (! buf_read_int (core, &ptr, end, &pid)
12228 || ! buf_read_int (core, &ptr, end, &uid))
12229 goto fail;
12230 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
12231 }
12232 }
12233
12234 static void
handle_file_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12235 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12236 {
12237 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12238 if (data == NULL)
12239 error (EXIT_FAILURE, 0,
12240 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12241
12242 unsigned char const *ptr = data->d_buf;
12243 unsigned char const *const end = data->d_buf + data->d_size;
12244
12245 uint64_t count, page_size;
12246 if (! buf_read_ulong (core, &ptr, end, &count)
12247 || ! buf_read_ulong (core, &ptr, end, &page_size))
12248 {
12249 fail:
12250 printf (" Not enough data in NT_FILE note.\n");
12251 return;
12252 }
12253
12254 size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12255 uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
12256 if (count > maxcount)
12257 goto fail;
12258
12259 /* Where file names are stored. */
12260 unsigned char const *const fstart = ptr + 3 * count * addrsize;
12261 char const *fptr = (char *) fstart;
12262
12263 printf (" %" PRId64 " files:\n", count);
12264 for (uint64_t i = 0; i < count; ++i)
12265 {
12266 uint64_t mstart, mend, moffset;
12267 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
12268 || ! buf_read_ulong (core, &ptr, fstart, &mend)
12269 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
12270 goto fail;
12271
12272 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
12273 if (fnext == NULL)
12274 goto fail;
12275
12276 int ct = printf (" %08" PRIx64 "-%08" PRIx64
12277 " %08" PRIx64 " %" PRId64,
12278 mstart, mend, moffset * page_size, mend - mstart);
12279 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
12280
12281 fptr = fnext + 1;
12282 }
12283 }
12284
12285 static void
handle_core_note(Ebl * ebl,const GElf_Nhdr * nhdr,const char * name,const void * desc)12286 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
12287 const char *name, const void *desc)
12288 {
12289 GElf_Word regs_offset;
12290 size_t nregloc;
12291 const Ebl_Register_Location *reglocs;
12292 size_t nitems;
12293 const Ebl_Core_Item *items;
12294
12295 if (! ebl_core_note (ebl, nhdr, name, desc,
12296 ®s_offset, &nregloc, ®locs, &nitems, &items))
12297 return;
12298
12299 /* Pass 0 for DESCSZ when there are registers in the note,
12300 so that the ITEMS array does not describe the whole thing.
12301 For non-register notes, the actual descsz might be a multiple
12302 of the unit size, not just exactly the unit size. */
12303 unsigned int colno = handle_core_items (ebl->elf, desc,
12304 nregloc == 0 ? nhdr->n_descsz : 0,
12305 items, nitems);
12306 if (colno != 0)
12307 putchar_unlocked ('\n');
12308
12309 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
12310 reglocs, nregloc);
12311 if (colno != 0)
12312 putchar_unlocked ('\n');
12313 }
12314
12315 static void
handle_notes_data(Ebl * ebl,const GElf_Ehdr * ehdr,GElf_Off start,Elf_Data * data)12316 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
12317 GElf_Off start, Elf_Data *data)
12318 {
12319 fputs_unlocked (gettext (" Owner Data size Type\n"), stdout);
12320
12321 if (data == NULL)
12322 goto bad_note;
12323
12324 size_t offset = 0;
12325 GElf_Nhdr nhdr;
12326 size_t name_offset;
12327 size_t desc_offset;
12328 while (offset < data->d_size
12329 && (offset = gelf_getnote (data, offset,
12330 &nhdr, &name_offset, &desc_offset)) > 0)
12331 {
12332 const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
12333 const char *desc = data->d_buf + desc_offset;
12334
12335 /* GNU Build Attributes are weird, they store most of their data
12336 into the owner name field. Extract just the owner name
12337 prefix here, then use the rest later as data. */
12338 bool is_gnu_build_attr
12339 = strncmp (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX,
12340 strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0;
12341 const char *print_name = (is_gnu_build_attr
12342 ? ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX : name);
12343 size_t print_namesz = (is_gnu_build_attr
12344 ? strlen (print_name) : nhdr.n_namesz);
12345
12346 char buf[100];
12347 char buf2[100];
12348 printf (gettext (" %-13.*s %9" PRId32 " %s\n"),
12349 (int) print_namesz, print_name, nhdr.n_descsz,
12350 ehdr->e_type == ET_CORE
12351 ? ebl_core_note_type_name (ebl, nhdr.n_type,
12352 buf, sizeof (buf))
12353 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
12354 nhdr.n_descsz,
12355 buf2, sizeof (buf2)));
12356
12357 /* Filter out invalid entries. */
12358 if (memchr (name, '\0', nhdr.n_namesz) != NULL
12359 /* XXX For now help broken Linux kernels. */
12360 || 1)
12361 {
12362 if (ehdr->e_type == ET_CORE)
12363 {
12364 if (nhdr.n_type == NT_AUXV
12365 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
12366 || (nhdr.n_namesz == 5 && name[4] == '\0'))
12367 && !memcmp (name, "CORE", 4))
12368 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
12369 start + desc_offset);
12370 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
12371 switch (nhdr.n_type)
12372 {
12373 case NT_SIGINFO:
12374 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
12375 start + desc_offset);
12376 break;
12377
12378 case NT_FILE:
12379 handle_file_note (ebl->elf, nhdr.n_descsz,
12380 start + desc_offset);
12381 break;
12382
12383 default:
12384 handle_core_note (ebl, &nhdr, name, desc);
12385 }
12386 else
12387 handle_core_note (ebl, &nhdr, name, desc);
12388 }
12389 else
12390 ebl_object_note (ebl, nhdr.n_namesz, name, nhdr.n_type,
12391 nhdr.n_descsz, desc);
12392 }
12393 }
12394
12395 if (offset == data->d_size)
12396 return;
12397
12398 bad_note:
12399 error (0, 0,
12400 gettext ("cannot get content of note: %s"),
12401 data != NULL ? "garbage data" : elf_errmsg (-1));
12402 }
12403
12404 static void
handle_notes(Ebl * ebl,GElf_Ehdr * ehdr)12405 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
12406 {
12407 /* If we have section headers, just look for SHT_NOTE sections.
12408 In a debuginfo file, the program headers are not reliable. */
12409 if (shnum != 0)
12410 {
12411 /* Get the section header string table index. */
12412 size_t shstrndx;
12413 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
12414 error (EXIT_FAILURE, 0,
12415 gettext ("cannot get section header string table index"));
12416
12417 Elf_Scn *scn = NULL;
12418 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12419 {
12420 GElf_Shdr shdr_mem;
12421 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
12422
12423 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
12424 /* Not what we are looking for. */
12425 continue;
12426
12427 if (notes_section != NULL)
12428 {
12429 char *sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
12430 if (sname == NULL || strcmp (sname, notes_section) != 0)
12431 continue;
12432 }
12433
12434 printf (gettext ("\
12435 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12436 elf_ndxscn (scn),
12437 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
12438 shdr->sh_size, shdr->sh_offset);
12439
12440 handle_notes_data (ebl, ehdr, shdr->sh_offset,
12441 elf_getdata (scn, NULL));
12442 }
12443 return;
12444 }
12445
12446 /* We have to look through the program header to find the note
12447 sections. There can be more than one. */
12448 for (size_t cnt = 0; cnt < phnum; ++cnt)
12449 {
12450 GElf_Phdr mem;
12451 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
12452
12453 if (phdr == NULL || phdr->p_type != PT_NOTE)
12454 /* Not what we are looking for. */
12455 continue;
12456
12457 printf (gettext ("\
12458 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12459 phdr->p_filesz, phdr->p_offset);
12460
12461 handle_notes_data (ebl, ehdr, phdr->p_offset,
12462 elf_getdata_rawchunk (ebl->elf,
12463 phdr->p_offset, phdr->p_filesz,
12464 (phdr->p_align == 8
12465 ? ELF_T_NHDR8 : ELF_T_NHDR)));
12466 }
12467 }
12468
12469
12470 static void
hex_dump(const uint8_t * data,size_t len)12471 hex_dump (const uint8_t *data, size_t len)
12472 {
12473 size_t pos = 0;
12474 while (pos < len)
12475 {
12476 printf (" 0x%08zx ", pos);
12477
12478 const size_t chunk = MIN (len - pos, 16);
12479
12480 for (size_t i = 0; i < chunk; ++i)
12481 if (i % 4 == 3)
12482 printf ("%02x ", data[pos + i]);
12483 else
12484 printf ("%02x", data[pos + i]);
12485
12486 if (chunk < 16)
12487 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
12488
12489 for (size_t i = 0; i < chunk; ++i)
12490 {
12491 unsigned char b = data[pos + i];
12492 printf ("%c", isprint (b) ? b : '.');
12493 }
12494
12495 putchar ('\n');
12496 pos += chunk;
12497 }
12498 }
12499
12500 static void
dump_data_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12501 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12502 {
12503 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12504 printf (gettext ("\nSection [%zu] '%s' has no data to dump.\n"),
12505 elf_ndxscn (scn), name);
12506 else
12507 {
12508 if (print_decompress)
12509 {
12510 /* We try to decompress the section, but keep the old shdr around
12511 so we can show both the original shdr size and the uncompressed
12512 data size. */
12513 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12514 {
12515 if (elf_compress (scn, 0, 0) < 0)
12516 printf ("WARNING: %s [%zd]\n",
12517 gettext ("Couldn't uncompress section"),
12518 elf_ndxscn (scn));
12519 }
12520 else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12521 {
12522 if (elf_compress_gnu (scn, 0, 0) < 0)
12523 printf ("WARNING: %s [%zd]\n",
12524 gettext ("Couldn't uncompress section"),
12525 elf_ndxscn (scn));
12526 }
12527 }
12528
12529 Elf_Data *data = elf_rawdata (scn, NULL);
12530 if (data == NULL)
12531 error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
12532 elf_ndxscn (scn), name, elf_errmsg (-1));
12533 else
12534 {
12535 if (data->d_size == shdr->sh_size)
12536 printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
12537 " bytes at offset %#0" PRIx64 ":\n"),
12538 elf_ndxscn (scn), name,
12539 shdr->sh_size, shdr->sh_offset);
12540 else
12541 printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
12542 " bytes (%zd uncompressed) at offset %#0"
12543 PRIx64 ":\n"),
12544 elf_ndxscn (scn), name,
12545 shdr->sh_size, data->d_size, shdr->sh_offset);
12546 hex_dump (data->d_buf, data->d_size);
12547 }
12548 }
12549 }
12550
12551 static void
print_string_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12552 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12553 {
12554 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12555 printf (gettext ("\nSection [%zu] '%s' has no strings to dump.\n"),
12556 elf_ndxscn (scn), name);
12557 else
12558 {
12559 if (print_decompress)
12560 {
12561 /* We try to decompress the section, but keep the old shdr around
12562 so we can show both the original shdr size and the uncompressed
12563 data size. */
12564 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12565 {
12566 if (elf_compress (scn, 0, 0) < 0)
12567 printf ("WARNING: %s [%zd]\n",
12568 gettext ("Couldn't uncompress section"),
12569 elf_ndxscn (scn));
12570 }
12571 else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12572 {
12573 if (elf_compress_gnu (scn, 0, 0) < 0)
12574 printf ("WARNING: %s [%zd]\n",
12575 gettext ("Couldn't uncompress section"),
12576 elf_ndxscn (scn));
12577 }
12578 }
12579
12580 Elf_Data *data = elf_rawdata (scn, NULL);
12581 if (data == NULL)
12582 error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
12583 elf_ndxscn (scn), name, elf_errmsg (-1));
12584 else
12585 {
12586 if (data->d_size == shdr->sh_size)
12587 printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
12588 " bytes at offset %#0" PRIx64 ":\n"),
12589 elf_ndxscn (scn), name,
12590 shdr->sh_size, shdr->sh_offset);
12591 else
12592 printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
12593 " bytes (%zd uncompressed) at offset %#0"
12594 PRIx64 ":\n"),
12595 elf_ndxscn (scn), name,
12596 shdr->sh_size, data->d_size, shdr->sh_offset);
12597
12598 const char *start = data->d_buf;
12599 const char *const limit = start + data->d_size;
12600 do
12601 {
12602 const char *end = memchr (start, '\0', limit - start);
12603 const size_t pos = start - (const char *) data->d_buf;
12604 if (unlikely (end == NULL))
12605 {
12606 printf (" [%6zx]- %.*s\n",
12607 pos, (int) (limit - start), start);
12608 break;
12609 }
12610 printf (" [%6zx] %s\n", pos, start);
12611 start = end + 1;
12612 } while (start < limit);
12613 }
12614 }
12615 }
12616
12617 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))12618 for_each_section_argument (Elf *elf, const struct section_argument *list,
12619 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
12620 const char *name))
12621 {
12622 /* Get the section header string table index. */
12623 size_t shstrndx;
12624 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
12625 error (EXIT_FAILURE, 0,
12626 gettext ("cannot get section header string table index"));
12627
12628 for (const struct section_argument *a = list; a != NULL; a = a->next)
12629 {
12630 Elf_Scn *scn;
12631 GElf_Shdr shdr_mem;
12632 const char *name = NULL;
12633
12634 char *endp = NULL;
12635 unsigned long int shndx = strtoul (a->arg, &endp, 0);
12636 if (endp != a->arg && *endp == '\0')
12637 {
12638 scn = elf_getscn (elf, shndx);
12639 if (scn == NULL)
12640 {
12641 error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
12642 continue;
12643 }
12644
12645 if (gelf_getshdr (scn, &shdr_mem) == NULL)
12646 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
12647 elf_errmsg (-1));
12648 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12649 (*dump) (scn, &shdr_mem, name);
12650 }
12651 else
12652 {
12653 /* Need to look up the section by name. */
12654 scn = NULL;
12655 bool found = false;
12656 while ((scn = elf_nextscn (elf, scn)) != NULL)
12657 {
12658 if (gelf_getshdr (scn, &shdr_mem) == NULL)
12659 continue;
12660 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12661 if (name == NULL)
12662 continue;
12663 if (!strcmp (name, a->arg))
12664 {
12665 found = true;
12666 (*dump) (scn, &shdr_mem, name);
12667 }
12668 }
12669
12670 if (unlikely (!found) && !a->implicit)
12671 error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
12672 }
12673 }
12674 }
12675
12676 static void
dump_data(Ebl * ebl)12677 dump_data (Ebl *ebl)
12678 {
12679 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
12680 }
12681
12682 static void
dump_strings(Ebl * ebl)12683 dump_strings (Ebl *ebl)
12684 {
12685 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
12686 }
12687
12688 static void
print_strings(Ebl * ebl)12689 print_strings (Ebl *ebl)
12690 {
12691 /* Get the section header string table index. */
12692 size_t shstrndx;
12693 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
12694 error (EXIT_FAILURE, 0,
12695 gettext ("cannot get section header string table index"));
12696
12697 Elf_Scn *scn;
12698 GElf_Shdr shdr_mem;
12699 const char *name;
12700 scn = NULL;
12701 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12702 {
12703 if (gelf_getshdr (scn, &shdr_mem) == NULL)
12704 continue;
12705
12706 if (shdr_mem.sh_type != SHT_PROGBITS
12707 || !(shdr_mem.sh_flags & SHF_STRINGS))
12708 continue;
12709
12710 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
12711 if (name == NULL)
12712 continue;
12713
12714 print_string_section (scn, &shdr_mem, name);
12715 }
12716 }
12717
12718 static void
dump_archive_index(Elf * elf,const char * fname)12719 dump_archive_index (Elf *elf, const char *fname)
12720 {
12721 size_t narsym;
12722 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
12723 if (arsym == NULL)
12724 {
12725 int result = elf_errno ();
12726 if (unlikely (result != ELF_E_NO_INDEX))
12727 error (EXIT_FAILURE, 0,
12728 gettext ("cannot get symbol index of archive '%s': %s"),
12729 fname, elf_errmsg (result));
12730 else
12731 printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
12732 return;
12733 }
12734
12735 printf (gettext ("\nIndex of archive '%s' has %zu entries:\n"),
12736 fname, narsym);
12737
12738 size_t as_off = 0;
12739 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
12740 {
12741 if (s->as_off != as_off)
12742 {
12743 as_off = s->as_off;
12744
12745 Elf *subelf = NULL;
12746 if (unlikely (elf_rand (elf, as_off) == 0)
12747 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
12748 == NULL))
12749 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
12750 while (1)
12751 #endif
12752 error (EXIT_FAILURE, 0,
12753 gettext ("cannot extract member at offset %zu in '%s': %s"),
12754 as_off, fname, elf_errmsg (-1));
12755
12756 const Elf_Arhdr *h = elf_getarhdr (subelf);
12757
12758 printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
12759
12760 elf_end (subelf);
12761 }
12762
12763 printf ("\t%s\n", s->as_name);
12764 }
12765 }
12766
12767 #include "debugpred.h"
12768