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 <locale.h>
34 #include <stdarg.h>
35 #include <stdbool.h>
36 #include <stdio.h>
37 #include <stdio_ext.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <strings.h>
41 #include <time.h>
42 #include <unistd.h>
43 #include <sys/stat.h>
44 #include <signal.h>
45
46 #include <libeu.h>
47 #include <system.h>
48 #include <printversion.h>
49 #include "../libelf/libelfP.h"
50 #include "../libelf/common.h"
51 #include "../libebl/libeblP.h"
52 #include "../libdwelf/libdwelf.h"
53 #include "../libdw/libdwP.h"
54 #include "../libdwfl/libdwflP.h"
55 #include "../libdw/memory-access.h"
56
57 #include "../libdw/known-dwarf.h"
58
59 #ifdef __linux__
60 #define CORE_SIGILL SIGILL
61 #define CORE_SIGBUS SIGBUS
62 #define CORE_SIGFPE SIGFPE
63 #define CORE_SIGSEGV SIGSEGV
64 #define CORE_SI_USER SI_USER
65 #else
66 /* We want the linux version of those as that is what shows up in the core files. */
67 #define CORE_SIGILL 4 /* Illegal instruction (ANSI). */
68 #define CORE_SIGBUS 7 /* BUS error (4.2 BSD). */
69 #define CORE_SIGFPE 8 /* Floating-point exception (ANSI). */
70 #define CORE_SIGSEGV 11 /* Segmentation violation (ANSI). */
71 #define CORE_SI_USER 0 /* Sent by kill, sigsend. */
72 #endif
73
74 /* Name and version of program. */
75 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
76
77 /* Bug report address. */
78 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
79
80 /* argp key value for --elf-section, non-ascii. */
81 #define ELF_INPUT_SECTION 256
82
83 /* argp key value for --dwarf-skeleton, non-ascii. */
84 #define DWARF_SKELETON 257
85
86 /* argp key value for --dyn-syms, non-ascii. */
87 #define PRINT_DYNSYM_TABLE 258
88
89 /* Terrible hack for hooking unrelated skeleton/split compile units,
90 see __libdw_link_skel_split in print_debug. */
91 static bool do_not_close_dwfl = false;
92
93 /* Definitions of arguments for argp functions. */
94 static const struct argp_option options[] =
95 {
96 { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 },
97 { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL,
98 N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF "
99 "input data"), 0 },
100 { "dwarf-skeleton", DWARF_SKELETON, "FILE", 0,
101 N_("Used with -w to find the skeleton Compile Units in FILE associated "
102 "with the Split Compile units in a .dwo input file"), 0 },
103 { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
104 { "all", 'a', NULL, 0,
105 N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
106 { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
107 { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
108 { "histogram", 'I', NULL, 0,
109 N_("Display histogram of bucket list lengths"), 0 },
110 { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
111 { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
112 { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
113 { "section-groups", 'g', NULL, 0, N_("Display the section groups"), 0 },
114 { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
115 { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
116 { "symbols", 's', "SECTION", OPTION_ARG_OPTIONAL,
117 N_("Display the symbol table sections"), 0 },
118 { "syms", 's', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 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 { "use-dynamic", 'D', NULL, 0,
141 N_("Use the dynamic segment when possible for displaying info"), 0 },
142
143 { NULL, 0, NULL, 0, N_("Output control:"), 0 },
144 { "numeric-addresses", 'N', NULL, 0,
145 N_("Do not find symbol names for addresses in DWARF data"), 0 },
146 { "unresolved-address-offsets", 'U', NULL, 0,
147 N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
148 { "wide", 'W', NULL, 0,
149 N_("Ignored for compatibility (lines always wide)"), 0 },
150 { "decompress", 'z', NULL, 0,
151 N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 },
152 { NULL, 0, NULL, 0, NULL, 0 }
153 };
154
155 /* Short description of program. */
156 static const char doc[] = N_("\
157 Print information from ELF file in human-readable form.");
158
159 /* Strings for arguments in help texts. */
160 static const char args_doc[] = N_("FILE...");
161
162 /* Prototype for option handler. */
163 static error_t parse_opt (int key, char *arg, struct argp_state *state);
164
165 /* Data structure to communicate with argp functions. */
166 static struct argp argp =
167 {
168 options, parse_opt, args_doc, doc, NULL, NULL, NULL
169 };
170
171 /* If non-null, the section from which we should read to (compressed) ELF. */
172 static const char *elf_input_section = NULL;
173
174 /* If non-null, the file that contains the skeleton CUs. */
175 static const char *dwarf_skeleton = NULL;
176
177 /* Flags set by the option controlling the output. */
178
179 /* True if dynamic segment should be printed. */
180 static bool print_dynamic_table;
181
182 /* True if the file header should be printed. */
183 static bool print_file_header;
184
185 /* True if the program headers should be printed. */
186 static bool print_program_header;
187
188 /* True if relocations should be printed. */
189 static bool print_relocations;
190
191 /* True if the section headers should be printed. */
192 static bool print_section_header;
193
194 /* True if the symbol table should be printed. */
195 static bool print_symbol_table;
196
197 /* True if (only) the dynsym table should be printed. */
198 static bool print_dynsym_table;
199
200 /* True if reconstruct dynamic symbol table from the PT_DYNAMIC segment. */
201 static bool use_dynamic_segment;
202
203 /* A specific section name, or NULL to print all symbol tables. */
204 static char *symbol_table_section;
205
206 /* A specific section name, or NULL to print all ELF notes. */
207 static char *notes_section;
208
209 /* True if the version information should be printed. */
210 static bool print_version_info;
211
212 /* True if section groups should be printed. */
213 static bool print_section_groups;
214
215 /* True if bucket list length histogram should be printed. */
216 static bool print_histogram;
217
218 /* True if the architecture specific data should be printed. */
219 static bool print_arch;
220
221 /* True if note section content should be printed. */
222 static bool print_notes;
223
224 /* True if SHF_STRINGS section content should be printed. */
225 static bool print_string_sections;
226
227 /* True if archive index should be printed. */
228 static bool print_archive_index;
229
230 /* True if any of the control options except print_archive_index is set. */
231 static bool any_control_option;
232
233 /* True if we should print addresses from DWARF in symbolic form. */
234 static bool print_address_names = true;
235
236 /* True if we should print raw values instead of relativized addresses. */
237 static bool print_unresolved_addresses = false;
238
239 /* True if we should print the .debug_aranges section using libdw. */
240 static bool decodedaranges = false;
241
242 /* True if we should print the .debug_aranges section using libdw. */
243 static bool decodedline = false;
244
245 /* True if we want to show more information about compressed sections. */
246 static bool print_decompress = false;
247
248 /* True if we want to show split compile units for debug_info skeletons. */
249 static bool show_split_units = false;
250
251 /* Select printing of debugging sections. */
252 static enum section_e
253 {
254 section_abbrev = 1, /* .debug_abbrev */
255 section_aranges = 2, /* .debug_aranges */
256 section_frame = 4, /* .debug_frame or .eh_frame & al. */
257 section_info = 8, /* .debug_info, (implies .debug_types) */
258 section_line = 16, /* .debug_line */
259 section_loc = 32, /* .debug_loc */
260 section_pubnames = 64, /* .debug_pubnames */
261 section_str = 128, /* .debug_str */
262 section_macinfo = 256, /* .debug_macinfo */
263 section_ranges = 512, /* .debug_ranges */
264 section_exception = 1024, /* .eh_frame & al. */
265 section_gdb_index = 2048, /* .gdb_index */
266 section_macro = 4096, /* .debug_macro */
267 section_addr = 8192, /* .debug_addr */
268 section_types = 16384, /* .debug_types (implied by .debug_info) */
269 section_all = (section_abbrev | section_aranges | section_frame
270 | section_info | section_line | section_loc
271 | section_pubnames | section_str | section_macinfo
272 | section_ranges | section_exception | section_gdb_index
273 | section_macro | section_addr | section_types)
274 } print_debug_sections, implicit_debug_sections;
275
276 /* Select hex dumping of sections. */
277 static struct section_argument *dump_data_sections;
278 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
279
280 /* Select string dumping of sections. */
281 static struct section_argument *string_sections;
282 static struct section_argument **string_sections_tail = &string_sections;
283
284 struct section_argument
285 {
286 struct section_argument *next;
287 const char *arg;
288 bool implicit;
289 };
290
291 /* Numbers of sections and program headers in the file. */
292 static size_t shnum;
293 static size_t phnum;
294
295
296 /* Declarations of local functions. */
297 static void process_file (int fd, const char *fname, bool only_one);
298 static void process_elf_file (Dwfl_Module *dwflmod, int fd);
299 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
300 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
301 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
302 static void print_scngrp (Ebl *ebl);
303 static void print_dynamic (Ebl *ebl);
304 static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
305 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
306 GElf_Shdr *shdr);
307 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
308 GElf_Shdr *shdr);
309 static void print_symtab (Ebl *ebl, int type);
310 static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
311 static void print_verinfo (Ebl *ebl);
312 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
313 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
314 static void handle_versym (Ebl *ebl, Elf_Scn *scn,
315 GElf_Shdr *shdr);
316 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
317 static void handle_hash (Ebl *ebl);
318 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
319 static void print_liblist (Ebl *ebl);
320 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
321 static void dump_data (Ebl *ebl);
322 static void dump_strings (Ebl *ebl);
323 static void print_strings (Ebl *ebl);
324 static void dump_archive_index (Elf *, const char *);
325
326 enum dyn_idx
327 {
328 i_strsz,
329 i_verneed,
330 i_verdef,
331 i_versym,
332 i_symtab,
333 i_strtab,
334 i_hash,
335 i_gnu_hash,
336 i_max
337 };
338
339 /* Declarations of local functions for use-dynamic. */
340 static Elf_Data *get_dynscn_strtab (Elf *elf, GElf_Phdr *phdr);
341 static void get_dynscn_addrs (Elf *elf, GElf_Phdr *phdr, GElf_Addr addrs[i_max]);
342 static void find_offsets (Elf *elf, GElf_Addr main_bias, size_t n,
343 GElf_Addr addrs[n], GElf_Off offs[n]);
344
345 /* Looked up once with gettext in main. */
346 static char *yes_str;
347 static char *no_str;
348
349 static void
cleanup_list(struct section_argument * list)350 cleanup_list (struct section_argument *list)
351 {
352 while (list != NULL)
353 {
354 struct section_argument *a = list;
355 list = a->next;
356 free (a);
357 }
358 }
359
360 int
main(int argc,char * argv[])361 main (int argc, char *argv[])
362 {
363 /* We use no threads here which can interfere with handling a stream. */
364 (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
365
366 /* Set locale. */
367 setlocale (LC_ALL, "");
368
369 /* Initialize the message catalog. */
370 textdomain (PACKAGE_TARNAME);
371
372 /* Look up once. */
373 yes_str = _("yes");
374 no_str = _("no");
375
376 /* Parse and process arguments. */
377 int remaining;
378 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
379
380 /* Before we start tell the ELF library which version we are using. */
381 elf_version (EV_CURRENT);
382
383 /* Now process all the files given at the command line. */
384 bool only_one = remaining + 1 == argc;
385 do
386 {
387 /* Open the file. */
388 int fd = open (argv[remaining], O_RDONLY);
389 if (fd == -1)
390 {
391 error (0, errno, _("cannot open input file '%s'"), argv[remaining]);
392 continue;
393 }
394
395 process_file (fd, argv[remaining], only_one);
396
397 close (fd);
398 }
399 while (++remaining < argc);
400
401 cleanup_list (dump_data_sections);
402 cleanup_list (string_sections);
403
404 return error_message_count != 0;
405 }
406
407 static void
add_dump_section(const char * name,int key,bool implicit)408 add_dump_section (const char *name,
409 int key,
410 bool implicit)
411 {
412 struct section_argument *a = xmalloc (sizeof *a);
413 a->arg = name;
414 a->next = NULL;
415 a->implicit = implicit;
416 struct section_argument ***tailp
417 = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
418 **tailp = a;
419 *tailp = &a->next;
420 }
421
422 /* Handle program arguments. */
423 static error_t
parse_opt(int key,char * arg,struct argp_state * state)424 parse_opt (int key, char *arg,
425 struct argp_state *state __attribute__ ((unused)))
426 {
427 switch (key)
428 {
429 case 'a':
430 print_file_header = true;
431 print_program_header = true;
432 print_relocations = true;
433 print_section_header = true;
434 print_symbol_table = true;
435 print_version_info = true;
436 print_dynamic_table = true;
437 print_section_groups = true;
438 print_histogram = true;
439 print_arch = true;
440 print_notes = true;
441 implicit_debug_sections |= section_exception;
442 add_dump_section (".strtab", key, true);
443 add_dump_section (".dynstr", key, true);
444 add_dump_section (".comment", key, true);
445 any_control_option = true;
446 break;
447 case 'A':
448 print_arch = true;
449 any_control_option = true;
450 break;
451 case 'd':
452 print_dynamic_table = true;
453 any_control_option = true;
454 break;
455 case 'D':
456 use_dynamic_segment = true;
457 break;
458 case 'e':
459 print_debug_sections |= section_exception;
460 any_control_option = true;
461 break;
462 case 'g':
463 print_section_groups = true;
464 any_control_option = true;
465 break;
466 case 'h':
467 print_file_header = true;
468 any_control_option = true;
469 break;
470 case 'I':
471 print_histogram = true;
472 any_control_option = true;
473 break;
474 case 'l':
475 print_program_header = true;
476 any_control_option = true;
477 break;
478 case 'n':
479 print_notes = true;
480 any_control_option = true;
481 notes_section = arg;
482 break;
483 case 'r':
484 print_relocations = true;
485 any_control_option = true;
486 break;
487 case 'S':
488 print_section_header = true;
489 any_control_option = true;
490 break;
491 case 's':
492 print_symbol_table = true;
493 any_control_option = true;
494 symbol_table_section = arg;
495 break;
496 case PRINT_DYNSYM_TABLE:
497 print_dynsym_table = true;
498 any_control_option = true;
499 break;
500 case 'V':
501 print_version_info = true;
502 any_control_option = true;
503 break;
504 case 'c':
505 print_archive_index = true;
506 break;
507 case 'w':
508 if (arg == NULL)
509 {
510 print_debug_sections = section_all;
511 implicit_debug_sections = section_info;
512 show_split_units = true;
513 }
514 else if (strcmp (arg, "abbrev") == 0)
515 print_debug_sections |= section_abbrev;
516 else if (strcmp (arg, "addr") == 0)
517 {
518 print_debug_sections |= section_addr;
519 implicit_debug_sections |= section_info;
520 }
521 else if (strcmp (arg, "aranges") == 0)
522 print_debug_sections |= section_aranges;
523 else if (strcmp (arg, "decodedaranges") == 0)
524 {
525 print_debug_sections |= section_aranges;
526 decodedaranges = true;
527 }
528 else if (strcmp (arg, "ranges") == 0)
529 {
530 print_debug_sections |= section_ranges;
531 implicit_debug_sections |= section_info;
532 }
533 else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
534 print_debug_sections |= section_frame;
535 else if (strcmp (arg, "info") == 0)
536 {
537 print_debug_sections |= section_info;
538 print_debug_sections |= section_types;
539 }
540 else if (strcmp (arg, "info+") == 0)
541 {
542 print_debug_sections |= section_info;
543 print_debug_sections |= section_types;
544 show_split_units = true;
545 }
546 else if (strcmp (arg, "loc") == 0)
547 {
548 print_debug_sections |= section_loc;
549 implicit_debug_sections |= section_info;
550 }
551 else if (strcmp (arg, "line") == 0)
552 print_debug_sections |= section_line;
553 else if (strcmp (arg, "decodedline") == 0)
554 {
555 print_debug_sections |= section_line;
556 decodedline = true;
557 }
558 else if (strcmp (arg, "pubnames") == 0)
559 print_debug_sections |= section_pubnames;
560 else if (strcmp (arg, "str") == 0)
561 {
562 print_debug_sections |= section_str;
563 /* For mapping string offset tables to CUs. */
564 implicit_debug_sections |= section_info;
565 }
566 else if (strcmp (arg, "macinfo") == 0)
567 print_debug_sections |= section_macinfo;
568 else if (strcmp (arg, "macro") == 0)
569 print_debug_sections |= section_macro;
570 else if (strcmp (arg, "exception") == 0)
571 print_debug_sections |= section_exception;
572 else if (strcmp (arg, "gdb_index") == 0)
573 print_debug_sections |= section_gdb_index;
574 else
575 {
576 fprintf (stderr, _("Unknown DWARF debug section `%s'.\n"),
577 arg);
578 argp_help (&argp, stderr, ARGP_HELP_SEE,
579 program_invocation_short_name);
580 exit (1);
581 }
582 any_control_option = true;
583 break;
584 case 'p':
585 any_control_option = true;
586 if (arg == NULL)
587 {
588 print_string_sections = true;
589 break;
590 }
591 FALLTHROUGH;
592 case 'x':
593 add_dump_section (arg, key, false);
594 any_control_option = true;
595 break;
596 case 'N':
597 print_address_names = false;
598 break;
599 case 'U':
600 print_unresolved_addresses = true;
601 break;
602 case ARGP_KEY_NO_ARGS:
603 fputs (_("Missing file name.\n"), stderr);
604 goto do_argp_help;
605 case ARGP_KEY_FINI:
606 if (! any_control_option && ! print_archive_index)
607 {
608 fputs (_("No operation specified.\n"), stderr);
609 do_argp_help:
610 argp_help (&argp, stderr, ARGP_HELP_SEE,
611 program_invocation_short_name);
612 exit (EXIT_FAILURE);
613 }
614 break;
615 case 'W': /* Ignored. */
616 break;
617 case 'z':
618 print_decompress = true;
619 break;
620 case ELF_INPUT_SECTION:
621 if (arg == NULL)
622 elf_input_section = ".gnu_debugdata";
623 else
624 elf_input_section = arg;
625 break;
626 case DWARF_SKELETON:
627 dwarf_skeleton = arg;
628 break;
629 default:
630 return ARGP_ERR_UNKNOWN;
631 }
632 return 0;
633 }
634
635
636 /* Create a file descriptor to read the data from the
637 elf_input_section given a file descriptor to an ELF file. */
638 static int
open_input_section(int fd)639 open_input_section (int fd)
640 {
641 size_t shnums;
642 size_t cnt;
643 size_t shstrndx;
644 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
645 if (elf == NULL)
646 {
647 error (0, 0, _("cannot generate Elf descriptor: %s"),
648 elf_errmsg (-1));
649 return -1;
650 }
651
652 if (elf_getshdrnum (elf, &shnums) < 0)
653 {
654 error (0, 0, _("cannot determine number of sections: %s"),
655 elf_errmsg (-1));
656 open_error:
657 elf_end (elf);
658 return -1;
659 }
660
661 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
662 {
663 error (0, 0, _("cannot get section header string table index"));
664 goto open_error;
665 }
666
667 for (cnt = 0; cnt < shnums; ++cnt)
668 {
669 Elf_Scn *scn = elf_getscn (elf, cnt);
670 if (scn == NULL)
671 {
672 error (0, 0, _("cannot get section: %s"),
673 elf_errmsg (-1));
674 goto open_error;
675 }
676
677 GElf_Shdr shdr_mem;
678 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
679 if (unlikely (shdr == NULL))
680 {
681 error (0, 0, _("cannot get section header: %s"),
682 elf_errmsg (-1));
683 goto open_error;
684 }
685
686 const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
687 if (sname == NULL)
688 {
689 error (0, 0, _("cannot get section name"));
690 goto open_error;
691 }
692
693 if (strcmp (sname, elf_input_section) == 0)
694 {
695 Elf_Data *data = elf_rawdata (scn, NULL);
696 if (data == NULL)
697 {
698 error (0, 0, _("cannot get %s content: %s"),
699 sname, elf_errmsg (-1));
700 goto open_error;
701 }
702
703 /* Create (and immediately unlink) a temporary file to store
704 section data in to create a file descriptor for it. */
705 const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
706 static const char suffix[] = "/readelfXXXXXX";
707 int tmplen = strlen (tmpdir) + sizeof (suffix);
708 char *tempname = alloca (tmplen);
709 sprintf (tempname, "%s%s", tmpdir, suffix);
710
711 int sfd = mkstemp (tempname);
712 if (sfd == -1)
713 {
714 error (0, 0, _("cannot create temp file '%s'"),
715 tempname);
716 goto open_error;
717 }
718 unlink (tempname);
719
720 ssize_t size = data->d_size;
721 if (write_retry (sfd, data->d_buf, size) != size)
722 {
723 error (0, 0, _("cannot write section data"));
724 goto open_error;
725 }
726
727 if (elf_end (elf) != 0)
728 {
729 error (0, 0, _("error while closing Elf descriptor: %s"),
730 elf_errmsg (-1));
731 return -1;
732 }
733
734 if (lseek (sfd, 0, SEEK_SET) == -1)
735 {
736 error (0, 0, _("error while rewinding file descriptor"));
737 return -1;
738 }
739
740 return sfd;
741 }
742 }
743
744 /* Named section not found. */
745 if (elf_end (elf) != 0)
746 error (0, 0, _("error while closing Elf descriptor: %s"),
747 elf_errmsg (-1));
748 return -1;
749 }
750
751 /* Check if the file is an archive, and if so dump its index. */
752 static void
check_archive_index(int fd,const char * fname,bool only_one)753 check_archive_index (int fd, const char *fname, bool only_one)
754 {
755 /* Create an `Elf' descriptor. */
756 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
757 if (elf == NULL)
758 error (0, 0, _("cannot generate Elf descriptor: %s"),
759 elf_errmsg (-1));
760 else
761 {
762 if (elf_kind (elf) == ELF_K_AR)
763 {
764 if (!only_one)
765 printf ("\n%s:\n\n", fname);
766 dump_archive_index (elf, fname);
767 }
768 else
769 error (0, 0,
770 _("'%s' is not an archive, cannot print archive index"),
771 fname);
772
773 /* Now we can close the descriptor. */
774 if (elf_end (elf) != 0)
775 error (0, 0, _("error while closing Elf descriptor: %s"),
776 elf_errmsg (-1));
777 }
778 }
779
780 /* Trivial callback used for checking if we opened an archive. */
781 static int
count_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)782 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
783 void **userdata __attribute__ ((unused)),
784 const char *name __attribute__ ((unused)),
785 Dwarf_Addr base __attribute__ ((unused)),
786 void *arg)
787 {
788 if (*(bool *) arg)
789 return DWARF_CB_ABORT;
790 *(bool *) arg = true;
791 return DWARF_CB_OK;
792 }
793
794 struct process_dwflmod_args
795 {
796 int fd;
797 bool only_one;
798 };
799
800 static int
process_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)801 process_dwflmod (Dwfl_Module *dwflmod,
802 void **userdata __attribute__ ((unused)),
803 const char *name __attribute__ ((unused)),
804 Dwarf_Addr base __attribute__ ((unused)),
805 void *arg)
806 {
807 const struct process_dwflmod_args *a = arg;
808
809 /* Print the file name. */
810 if (!a->only_one)
811 {
812 const char *fname;
813 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
814
815 printf ("\n%s:\n\n", fname);
816 }
817
818 process_elf_file (dwflmod, a->fd);
819
820 return DWARF_CB_OK;
821 }
822
823 /* Stub libdwfl callback, only the ELF handle already open is ever used.
824 Only used for finding the alternate debug file if the Dwarf comes from
825 the main file. We are not interested in separate debuginfo. */
826 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)827 find_no_debuginfo (Dwfl_Module *mod,
828 void **userdata,
829 const char *modname,
830 Dwarf_Addr base,
831 const char *file_name,
832 const char *debuglink_file,
833 GElf_Word debuglink_crc,
834 char **debuginfo_file_name)
835 {
836 Dwarf_Addr dwbias;
837 dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
838
839 /* We are only interested if the Dwarf has been setup on the main
840 elf file but is only missing the alternate debug link. If dwbias
841 hasn't even been setup, this is searching for separate debuginfo
842 for the main elf. We don't care in that case. */
843 if (dwbias == (Dwarf_Addr) -1)
844 return -1;
845
846 return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
847 file_name, debuglink_file,
848 debuglink_crc, debuginfo_file_name);
849 }
850
851 static Dwfl *
create_dwfl(int fd,const char * fname)852 create_dwfl (int fd, const char *fname)
853 {
854 /* Duplicate an fd for dwfl_report_offline to swallow. */
855 int dwfl_fd = dup (fd);
856 if (unlikely (dwfl_fd < 0))
857 error_exit (errno, "dup");
858
859 /* Use libdwfl in a trivial way to open the libdw handle for us.
860 This takes care of applying relocations to DWARF data in ET_REL files. */
861 static const Dwfl_Callbacks callbacks =
862 {
863 .section_address = dwfl_offline_section_address,
864 .find_debuginfo = find_no_debuginfo
865 };
866 Dwfl *dwfl = dwfl_begin (&callbacks);
867 if (likely (dwfl != NULL))
868 /* Let 0 be the logical address of the file (or first in archive). */
869 dwfl->offline_next_address = 0;
870 if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
871 {
872 struct stat st;
873 if (fstat (dwfl_fd, &st) != 0)
874 error (0, errno, _("cannot stat input file"));
875 else if (unlikely (st.st_size == 0))
876 error (0, 0, _("input file is empty"));
877 else
878 error (0, 0, _("failed reading '%s': %s"),
879 fname, dwfl_errmsg (-1));
880 close (dwfl_fd); /* Consumed on success, not on failure. */
881 dwfl = NULL;
882 }
883 else
884 dwfl_report_end (dwfl, NULL, NULL);
885
886 return dwfl;
887 }
888
889 /* Process one input file. */
890 static void
process_file(int fd,const char * fname,bool only_one)891 process_file (int fd, const char *fname, bool only_one)
892 {
893 if (print_archive_index)
894 check_archive_index (fd, fname, only_one);
895
896 if (!any_control_option)
897 return;
898
899 if (elf_input_section != NULL)
900 {
901 /* Replace fname and fd with section content. */
902 char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
903 sprintf (fnname, "%s:%s", fname, elf_input_section);
904 fd = open_input_section (fd);
905 if (fd == -1)
906 {
907 error (0, 0, _("No such section '%s' in '%s'"),
908 elf_input_section, fname);
909 return;
910 }
911 fname = fnname;
912 }
913
914 Dwfl *dwfl = create_dwfl (fd, fname);
915 if (dwfl != NULL)
916 {
917 if (only_one)
918 {
919 /* Clear ONLY_ONE if we have multiple modules, from an archive. */
920 bool seen = false;
921 only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
922 }
923
924 /* Process the one or more modules gleaned from this file. */
925 struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
926 dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
927 }
928 /* Terrible hack for hooking unrelated skeleton/split compile units,
929 see __libdw_link_skel_split in print_debug. */
930 if (! do_not_close_dwfl)
931 dwfl_end (dwfl);
932
933 /* Need to close the replaced fd if we created it. Caller takes
934 care of original. */
935 if (elf_input_section != NULL)
936 close (fd);
937 }
938
939 /* Check whether there are any compressed sections in the ELF file. */
940 static bool
elf_contains_chdrs(Elf * elf)941 elf_contains_chdrs (Elf *elf)
942 {
943 Elf_Scn *scn = NULL;
944 while ((scn = elf_nextscn (elf, scn)) != NULL)
945 {
946 GElf_Shdr shdr_mem;
947 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
948 if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
949 return true;
950 }
951 return false;
952 }
953
954 /* Process one ELF file. */
955 static void
process_elf_file(Dwfl_Module * dwflmod,int fd)956 process_elf_file (Dwfl_Module *dwflmod, int fd)
957 {
958 GElf_Addr dwflbias;
959 Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
960
961 GElf_Ehdr ehdr_mem;
962 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
963
964 if (ehdr == NULL)
965 {
966 error (0, 0, _("cannot read ELF header: %s"), elf_errmsg (-1));
967 return;
968 }
969
970 Ebl *ebl = ebl_openbackend (elf);
971 if (unlikely (ebl == NULL))
972 {
973 ebl_error:
974 error (0, errno, _("cannot create EBL handle"));
975 return;
976 }
977
978 /* Determine the number of sections. */
979 if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
980 error_exit (0, _("cannot determine number of sections: %s"),
981 elf_errmsg (-1));
982
983 /* Determine the number of phdrs. */
984 if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
985 error_exit (0, _("cannot determine number of program headers: %s"),
986 elf_errmsg (-1));
987
988 /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
989 may have applied relocation to some sections. If there are any
990 compressed sections, any pass (or libdw/libdwfl) might have
991 uncompressed them. So we need to get a fresh Elf handle on the
992 file to display those. */
993 bool print_unchanged = ((print_section_header
994 || print_relocations
995 || dump_data_sections != NULL
996 || print_notes)
997 && (ehdr->e_type == ET_REL
998 || elf_contains_chdrs (ebl->elf)));
999
1000 Elf *pure_elf = NULL;
1001 Ebl *pure_ebl = ebl;
1002 if (print_unchanged)
1003 {
1004 /* Read the file afresh. */
1005 off_t aroff = elf_getaroff (elf);
1006 pure_elf = dwelf_elf_begin (fd);
1007 if (aroff > 0)
1008 {
1009 /* Archive member. */
1010 (void) elf_rand (pure_elf, aroff);
1011 Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
1012 elf_end (pure_elf);
1013 pure_elf = armem;
1014 }
1015 if (pure_elf == NULL)
1016 {
1017 error (0, 0, _("cannot read ELF: %s"), elf_errmsg (-1));
1018 return;
1019 }
1020 pure_ebl = ebl_openbackend (pure_elf);
1021 if (pure_ebl == NULL)
1022 goto ebl_error;
1023 }
1024
1025 if (print_file_header)
1026 print_ehdr (ebl, ehdr);
1027 if (print_section_header)
1028 print_shdr (pure_ebl, ehdr);
1029 if (print_program_header)
1030 print_phdr (ebl, ehdr);
1031 if (print_section_groups)
1032 print_scngrp (ebl);
1033 if (print_dynamic_table)
1034 print_dynamic (ebl);
1035 if (print_relocations)
1036 print_relocs (pure_ebl, ehdr);
1037 if (print_histogram)
1038 handle_hash (ebl);
1039 if (print_symbol_table || print_dynsym_table)
1040 print_symtab (ebl, SHT_DYNSYM);
1041 if (print_version_info)
1042 print_verinfo (ebl);
1043 if (print_symbol_table)
1044 print_symtab (ebl, SHT_SYMTAB);
1045 if (print_arch)
1046 print_liblist (ebl);
1047 if (print_arch)
1048 print_attributes (ebl, ehdr);
1049 if (dump_data_sections != NULL)
1050 dump_data (pure_ebl);
1051 if (string_sections != NULL)
1052 dump_strings (ebl);
1053 if ((print_debug_sections | implicit_debug_sections) != 0)
1054 print_debug (dwflmod, ebl, ehdr);
1055 if (print_notes)
1056 handle_notes (pure_ebl, ehdr);
1057 if (print_string_sections)
1058 print_strings (ebl);
1059
1060 ebl_closebackend (ebl);
1061
1062 if (pure_ebl != ebl)
1063 {
1064 ebl_closebackend (pure_ebl);
1065 elf_end (pure_elf);
1066 }
1067 }
1068
1069
1070 /* Print file type. */
1071 static void
print_file_type(unsigned short int e_type)1072 print_file_type (unsigned short int e_type)
1073 {
1074 if (likely (e_type <= ET_CORE))
1075 {
1076 static const char *const knowntypes[] =
1077 {
1078 N_("NONE (None)"),
1079 N_("REL (Relocatable file)"),
1080 N_("EXEC (Executable file)"),
1081 N_("DYN (Shared object file)"),
1082 N_("CORE (Core file)")
1083 };
1084 puts (_(knowntypes[e_type]));
1085 }
1086 else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
1087 printf (_("OS Specific: (%x)\n"), e_type);
1088 else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
1089 printf (_("Processor Specific: (%x)\n"), e_type);
1090 else
1091 puts ("???");
1092 }
1093
1094
1095 /* Print ELF header. */
1096 static void
print_ehdr(Ebl * ebl,GElf_Ehdr * ehdr)1097 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
1098 {
1099 fputs_unlocked (_("ELF Header:\n Magic: "), stdout);
1100 for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
1101 printf (" %02hhx", ehdr->e_ident[cnt]);
1102
1103 printf (_("\n Class: %s\n"),
1104 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
1105 : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
1106 : "\?\?\?");
1107
1108 printf (_(" Data: %s\n"),
1109 ehdr->e_ident[EI_DATA] == ELFDATA2LSB
1110 ? "2's complement, little endian"
1111 : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
1112 ? "2's complement, big endian" : "\?\?\?");
1113
1114 printf (_(" Ident Version: %hhd %s\n"),
1115 ehdr->e_ident[EI_VERSION],
1116 ehdr->e_ident[EI_VERSION] == EV_CURRENT ? _("(current)")
1117 : "(\?\?\?)");
1118
1119 char buf[512];
1120 printf (_(" OS/ABI: %s\n"),
1121 ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
1122
1123 printf (_(" ABI Version: %hhd\n"),
1124 ehdr->e_ident[EI_ABIVERSION]);
1125
1126 fputs_unlocked (_(" Type: "), stdout);
1127 print_file_type (ehdr->e_type);
1128
1129 const char *machine = dwelf_elf_e_machine_string (ehdr->e_machine);
1130 if (machine != NULL)
1131 printf (_(" Machine: %s\n"), machine);
1132 else
1133 printf (_(" Machine: <unknown>: 0x%x\n"),
1134 ehdr->e_machine);
1135
1136 printf (_(" Version: %d %s\n"),
1137 ehdr->e_version,
1138 ehdr->e_version == EV_CURRENT ? _("(current)") : "(\?\?\?)");
1139
1140 printf (_(" Entry point address: %#" PRIx64 "\n"),
1141 ehdr->e_entry);
1142
1143 printf (_(" Start of program headers: %" PRId64 " %s\n"),
1144 ehdr->e_phoff, _("(bytes into file)"));
1145
1146 printf (_(" Start of section headers: %" PRId64 " %s\n"),
1147 ehdr->e_shoff, _("(bytes into file)"));
1148
1149 printf (_(" Flags: %s\n"),
1150 ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
1151
1152 printf (_(" Size of this header: %" PRId16 " %s\n"),
1153 ehdr->e_ehsize, _("(bytes)"));
1154
1155 printf (_(" Size of program header entries: %" PRId16 " %s\n"),
1156 ehdr->e_phentsize, _("(bytes)"));
1157
1158 printf (_(" Number of program headers entries: %" PRId16),
1159 ehdr->e_phnum);
1160 if (ehdr->e_phnum == PN_XNUM)
1161 {
1162 GElf_Shdr shdr_mem;
1163 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1164 if (shdr != NULL)
1165 printf (_(" (%" PRIu32 " in [0].sh_info)"),
1166 (uint32_t) shdr->sh_info);
1167 else
1168 fputs_unlocked (_(" ([0] not available)"), stdout);
1169 }
1170 fputc_unlocked ('\n', stdout);
1171
1172 printf (_(" Size of section header entries: %" PRId16 " %s\n"),
1173 ehdr->e_shentsize, _("(bytes)"));
1174
1175 printf (_(" Number of section headers entries: %" PRId16),
1176 ehdr->e_shnum);
1177 if (ehdr->e_shnum == 0)
1178 {
1179 GElf_Shdr shdr_mem;
1180 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1181 if (shdr != NULL)
1182 printf (_(" (%" PRIu32 " in [0].sh_size)"),
1183 (uint32_t) shdr->sh_size);
1184 else
1185 fputs_unlocked (_(" ([0] not available)"), stdout);
1186 }
1187 fputc_unlocked ('\n', stdout);
1188
1189 if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1190 {
1191 GElf_Shdr shdr_mem;
1192 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1193 if (shdr != NULL)
1194 /* We managed to get the zeroth section. */
1195 snprintf (buf, sizeof (buf), _(" (%" PRIu32 " in [0].sh_link)"),
1196 (uint32_t) shdr->sh_link);
1197 else
1198 {
1199 strncpy (buf, _(" ([0] not available)"), sizeof (buf) - 1);
1200 buf[sizeof (buf) - 1] = '\0';
1201 }
1202
1203 printf (_(" Section header string table index: XINDEX%s\n\n"),
1204 buf);
1205 }
1206 else
1207 printf (_(" Section header string table index: %" PRId16 "\n\n"),
1208 ehdr->e_shstrndx);
1209 }
1210
1211
1212 static const char *
get_visibility_type(int value)1213 get_visibility_type (int value)
1214 {
1215 switch (value)
1216 {
1217 case STV_DEFAULT:
1218 return "DEFAULT";
1219 case STV_INTERNAL:
1220 return "INTERNAL";
1221 case STV_HIDDEN:
1222 return "HIDDEN";
1223 case STV_PROTECTED:
1224 return "PROTECTED";
1225 default:
1226 return "???";
1227 }
1228 }
1229
1230 static const char *
elf_ch_type_name(unsigned int code)1231 elf_ch_type_name (unsigned int code)
1232 {
1233 if (code == 0)
1234 return "NONE";
1235
1236 if (code == ELFCOMPRESS_ZLIB)
1237 return "ZLIB";
1238
1239 return "UNKNOWN";
1240 }
1241
1242 /* Print the section headers. */
1243 static void
print_shdr(Ebl * ebl,GElf_Ehdr * ehdr)1244 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1245 {
1246 size_t cnt;
1247 size_t shstrndx;
1248
1249 if (! print_file_header)
1250 {
1251 size_t sections;
1252 if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0))
1253 error_exit (0, _("cannot get number of sections: %s"),
1254 elf_errmsg (-1));
1255
1256 printf (_("\
1257 There are %zd section headers, starting at offset %#" PRIx64 ":\n\
1258 \n"),
1259 sections, ehdr->e_shoff);
1260 }
1261
1262 /* Get the section header string table index. */
1263 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1264 error_exit (0, _("cannot get section header string table index: %s"),
1265 elf_errmsg (-1));
1266
1267 puts (_("Section Headers:"));
1268
1269 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1270 puts (_("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1271 else
1272 puts (_("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1273
1274 if (print_decompress)
1275 {
1276 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1277 puts (_(" [Compression Size Al]"));
1278 else
1279 puts (_(" [Compression Size Al]"));
1280 }
1281
1282 for (cnt = 0; cnt < shnum; ++cnt)
1283 {
1284 Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1285
1286 if (unlikely (scn == NULL))
1287 error_exit (0, _("cannot get section: %s"),
1288 elf_errmsg (-1));
1289
1290 /* Get the section header. */
1291 GElf_Shdr shdr_mem;
1292 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1293 if (unlikely (shdr == NULL))
1294 error_exit (0, _("cannot get section header: %s"),
1295 elf_errmsg (-1));
1296
1297 char flagbuf[20];
1298 char *cp = flagbuf;
1299 if (shdr->sh_flags & SHF_WRITE)
1300 *cp++ = 'W';
1301 if (shdr->sh_flags & SHF_ALLOC)
1302 *cp++ = 'A';
1303 if (shdr->sh_flags & SHF_EXECINSTR)
1304 *cp++ = 'X';
1305 if (shdr->sh_flags & SHF_MERGE)
1306 *cp++ = 'M';
1307 if (shdr->sh_flags & SHF_STRINGS)
1308 *cp++ = 'S';
1309 if (shdr->sh_flags & SHF_INFO_LINK)
1310 *cp++ = 'I';
1311 if (shdr->sh_flags & SHF_LINK_ORDER)
1312 *cp++ = 'L';
1313 if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1314 *cp++ = 'N';
1315 if (shdr->sh_flags & SHF_GROUP)
1316 *cp++ = 'G';
1317 if (shdr->sh_flags & SHF_TLS)
1318 *cp++ = 'T';
1319 if (shdr->sh_flags & SHF_COMPRESSED)
1320 *cp++ = 'C';
1321 if (shdr->sh_flags & SHF_ORDERED)
1322 *cp++ = 'O';
1323 if (shdr->sh_flags & SHF_EXCLUDE)
1324 *cp++ = 'E';
1325 if (shdr->sh_flags & SHF_GNU_RETAIN)
1326 *cp++ = 'R';
1327 *cp = '\0';
1328
1329 const char *sname;
1330 char buf[128];
1331 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>";
1332 printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1333 " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1334 " %2" PRId64 "\n",
1335 cnt, sname,
1336 ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1337 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1338 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1339 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1340 shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1341 shdr->sh_addralign);
1342
1343 if (print_decompress)
1344 {
1345 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1346 {
1347 GElf_Chdr chdr;
1348 if (gelf_getchdr (scn, &chdr) != NULL)
1349 printf (" [ELF %s (%" PRId32 ") %0*" PRIx64
1350 " %2" PRId64 "]\n",
1351 elf_ch_type_name (chdr.ch_type),
1352 chdr.ch_type,
1353 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8,
1354 chdr.ch_size, chdr.ch_addralign);
1355 else
1356 error (0, 0,
1357 _("bad compression header for section %zd: %s"),
1358 elf_ndxscn (scn), elf_errmsg (-1));
1359 }
1360 else if (startswith (sname, ".zdebug"))
1361 {
1362 ssize_t size;
1363 if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0)
1364 printf (" [GNU ZLIB %0*zx ]\n",
1365 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size);
1366 else
1367 error (0, 0,
1368 _("bad gnu compressed size for section %zd: %s"),
1369 elf_ndxscn (scn), elf_errmsg (-1));
1370 }
1371 }
1372 }
1373
1374 fputc_unlocked ('\n', stdout);
1375 }
1376
1377
1378 /* Print the program header. */
1379 static void
print_phdr(Ebl * ebl,GElf_Ehdr * ehdr)1380 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1381 {
1382 if (phnum == 0)
1383 /* No program header, this is OK in relocatable objects. */
1384 return;
1385
1386 puts (_("Program Headers:"));
1387 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1388 puts (_("\
1389 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1390 else
1391 puts (_("\
1392 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1393
1394 /* Process all program headers. */
1395 bool has_relro = false;
1396 GElf_Addr relro_from = 0;
1397 GElf_Addr relro_to = 0;
1398 for (size_t cnt = 0; cnt < phnum; ++cnt)
1399 {
1400 char buf[128];
1401 GElf_Phdr mem;
1402 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1403
1404 /* If for some reason the header cannot be returned show this. */
1405 if (unlikely (phdr == NULL))
1406 {
1407 puts (" ???");
1408 continue;
1409 }
1410
1411 printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1412 " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1413 ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1414 phdr->p_offset,
1415 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1416 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1417 phdr->p_filesz,
1418 phdr->p_memsz,
1419 phdr->p_flags & PF_R ? 'R' : ' ',
1420 phdr->p_flags & PF_W ? 'W' : ' ',
1421 phdr->p_flags & PF_X ? 'E' : ' ',
1422 phdr->p_align);
1423
1424 if (phdr->p_type == PT_INTERP)
1425 {
1426 /* If we are sure the file offset is valid then we can show
1427 the user the name of the interpreter. We check whether
1428 there is a section at the file offset. Normally there
1429 would be a section called ".interp". But in separate
1430 .debug files it is a NOBITS section (and so doesn't match
1431 with gelf_offscn). Which probably means the offset is
1432 not valid another reason could be because the ELF file
1433 just doesn't contain any section headers, in that case
1434 just play it safe and don't display anything. */
1435
1436 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1437 GElf_Shdr shdr_mem;
1438 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1439
1440 size_t maxsize;
1441 char *filedata = elf_rawfile (ebl->elf, &maxsize);
1442
1443 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
1444 && filedata != NULL && phdr->p_offset < maxsize
1445 && phdr->p_filesz <= maxsize - phdr->p_offset
1446 && memchr (filedata + phdr->p_offset, '\0',
1447 phdr->p_filesz) != NULL)
1448 printf (_("\t[Requesting program interpreter: %s]\n"),
1449 filedata + phdr->p_offset);
1450 }
1451 else if (phdr->p_type == PT_GNU_RELRO)
1452 {
1453 has_relro = true;
1454 relro_from = phdr->p_vaddr;
1455 relro_to = relro_from + phdr->p_memsz;
1456 }
1457 }
1458
1459 size_t sections;
1460 if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0))
1461 error_exit (0, _("cannot get number of sections: %s"),
1462 elf_errmsg (-1));
1463
1464 if (sections == 0)
1465 /* No sections in the file. Punt. */
1466 return;
1467
1468 /* Get the section header string table index. */
1469 size_t shstrndx;
1470 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1471 error_exit (0, _("cannot get section header string table index"));
1472
1473 puts (_("\n Section to Segment mapping:\n Segment Sections..."));
1474
1475 for (size_t cnt = 0; cnt < phnum; ++cnt)
1476 {
1477 /* Print the segment number. */
1478 printf (" %2.2zu ", cnt);
1479
1480 GElf_Phdr phdr_mem;
1481 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1482 /* This must not happen. */
1483 if (unlikely (phdr == NULL))
1484 error_exit (0, _("cannot get program header: %s"),
1485 elf_errmsg (-1));
1486
1487 /* Iterate over the sections. */
1488 bool in_relro = false;
1489 bool in_ro = false;
1490 for (size_t inner = 1; inner < shnum; ++inner)
1491 {
1492 Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1493 /* This should not happen. */
1494 if (unlikely (scn == NULL))
1495 error_exit (0, _("cannot get section: %s"),
1496 elf_errmsg (-1));
1497
1498 /* Get the section header. */
1499 GElf_Shdr shdr_mem;
1500 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1501 if (unlikely (shdr == NULL))
1502 error_exit (0, _("cannot get section header: %s"),
1503 elf_errmsg (-1));
1504
1505 if (shdr->sh_size > 0
1506 /* Compare allocated sections by VMA, unallocated
1507 sections by file offset. */
1508 && (shdr->sh_flags & SHF_ALLOC
1509 ? (shdr->sh_addr >= phdr->p_vaddr
1510 && (shdr->sh_addr + shdr->sh_size
1511 <= phdr->p_vaddr + phdr->p_memsz))
1512 : (shdr->sh_offset >= phdr->p_offset
1513 && (shdr->sh_offset + shdr->sh_size
1514 <= phdr->p_offset + phdr->p_filesz))))
1515 {
1516 if (has_relro && !in_relro
1517 && shdr->sh_addr >= relro_from
1518 && shdr->sh_addr + shdr->sh_size <= relro_to)
1519 {
1520 fputs_unlocked (" [RELRO:", stdout);
1521 in_relro = true;
1522 }
1523 else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1524 {
1525 fputs_unlocked ("]", stdout);
1526 in_relro = false;
1527 }
1528 else if (has_relro && in_relro
1529 && shdr->sh_addr + shdr->sh_size > relro_to)
1530 fputs_unlocked ("] <RELRO:", stdout);
1531 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1532 {
1533 if (!in_ro)
1534 {
1535 fputs_unlocked (" [RO:", stdout);
1536 in_ro = true;
1537 }
1538 }
1539 else
1540 {
1541 /* Determine the segment this section is part of. */
1542 size_t cnt2;
1543 GElf_Phdr phdr2_mem;
1544 GElf_Phdr *phdr2 = NULL;
1545 for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1546 {
1547 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1548
1549 if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1550 && shdr->sh_addr >= phdr2->p_vaddr
1551 && (shdr->sh_addr + shdr->sh_size
1552 <= phdr2->p_vaddr + phdr2->p_memsz))
1553 break;
1554 }
1555
1556 if (cnt2 < phnum)
1557 {
1558 if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1559 {
1560 fputs_unlocked (" [RO:", stdout);
1561 in_ro = true;
1562 }
1563 else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1564 {
1565 fputs_unlocked ("]", stdout);
1566 in_ro = false;
1567 }
1568 }
1569 }
1570
1571 printf (" %s",
1572 elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1573
1574 /* Signal that this section is only partially covered. */
1575 if (has_relro && in_relro
1576 && shdr->sh_addr + shdr->sh_size > relro_to)
1577 {
1578 fputs_unlocked (">", stdout);
1579 in_relro = false;
1580 }
1581 }
1582 }
1583 if (in_relro || in_ro)
1584 fputs_unlocked ("]", stdout);
1585
1586 /* Finish the line. */
1587 fputc_unlocked ('\n', stdout);
1588 }
1589 }
1590
1591
1592 static const char *
section_name(Ebl * ebl,GElf_Shdr * shdr)1593 section_name (Ebl *ebl, GElf_Shdr *shdr)
1594 {
1595 size_t shstrndx;
1596 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
1597 return "???";
1598 return elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "???";
1599 }
1600
1601
1602 static void
handle_scngrp(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1603 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1604 {
1605 /* Get the data of the section. */
1606 Elf_Data *data = elf_getdata (scn, NULL);
1607
1608 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1609 GElf_Shdr symshdr_mem;
1610 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1611 Elf_Data *symdata = elf_getdata (symscn, NULL);
1612
1613 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1614 || symdata == NULL)
1615 return;
1616
1617 /* Get the section header string table index. */
1618 size_t shstrndx;
1619 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1620 error_exit (0, _("cannot get section header string table index"));
1621
1622 Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1623
1624 GElf_Sym sym_mem;
1625 GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1626
1627 printf ((grpref[0] & GRP_COMDAT)
1628 ? ngettext ("\
1629 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1630 "\
1631 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1632 data->d_size / sizeof (Elf32_Word) - 1)
1633 : ngettext ("\
1634 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1635 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1636 data->d_size / sizeof (Elf32_Word) - 1),
1637 elf_ndxscn (scn),
1638 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1639 (sym == NULL ? NULL
1640 : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1641 ?: _("<INVALID SYMBOL>"),
1642 data->d_size / sizeof (Elf32_Word) - 1);
1643
1644 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1645 {
1646 GElf_Shdr grpshdr_mem;
1647 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1648 &grpshdr_mem);
1649
1650 const char *str;
1651 printf (" [%2u] %s\n",
1652 grpref[cnt],
1653 grpshdr != NULL
1654 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1655 ? str : _("<INVALID SECTION>"));
1656 }
1657 }
1658
1659
1660 static void
print_scngrp(Ebl * ebl)1661 print_scngrp (Ebl *ebl)
1662 {
1663 /* Find all relocation sections and handle them. */
1664 Elf_Scn *scn = NULL;
1665
1666 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1667 {
1668 /* Handle the section if it is a symbol table. */
1669 GElf_Shdr shdr_mem;
1670 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1671
1672 if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1673 {
1674 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1675 {
1676 if (elf_compress (scn, 0, 0) < 0)
1677 printf ("WARNING: %s [%zd]\n",
1678 _("Couldn't uncompress section"),
1679 elf_ndxscn (scn));
1680 shdr = gelf_getshdr (scn, &shdr_mem);
1681 if (unlikely (shdr == NULL))
1682 error_exit (0, _("cannot get section [%zd] header: %s"),
1683 elf_ndxscn (scn),
1684 elf_errmsg (-1));
1685 }
1686 handle_scngrp (ebl, scn, shdr);
1687 }
1688 }
1689 }
1690
1691
1692 static const struct flags
1693 {
1694 int mask;
1695 const char *str;
1696 } dt_flags[] =
1697 {
1698 { DF_ORIGIN, "ORIGIN" },
1699 { DF_SYMBOLIC, "SYMBOLIC" },
1700 { DF_TEXTREL, "TEXTREL" },
1701 { DF_BIND_NOW, "BIND_NOW" },
1702 { DF_STATIC_TLS, "STATIC_TLS" }
1703 };
1704 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1705
1706 static const struct flags dt_flags_1[] =
1707 {
1708 { DF_1_NOW, "NOW" },
1709 { DF_1_GLOBAL, "GLOBAL" },
1710 { DF_1_GROUP, "GROUP" },
1711 { DF_1_NODELETE, "NODELETE" },
1712 { DF_1_LOADFLTR, "LOADFLTR" },
1713 { DF_1_INITFIRST, "INITFIRST" },
1714 { DF_1_NOOPEN, "NOOPEN" },
1715 { DF_1_ORIGIN, "ORIGIN" },
1716 { DF_1_DIRECT, "DIRECT" },
1717 { DF_1_TRANS, "TRANS" },
1718 { DF_1_INTERPOSE, "INTERPOSE" },
1719 { DF_1_NODEFLIB, "NODEFLIB" },
1720 { DF_1_NODUMP, "NODUMP" },
1721 { DF_1_CONFALT, "CONFALT" },
1722 { DF_1_ENDFILTEE, "ENDFILTEE" },
1723 { DF_1_DISPRELDNE, "DISPRELDNE" },
1724 { DF_1_DISPRELPND, "DISPRELPND" },
1725 };
1726 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1727
1728 static const struct flags dt_feature_1[] =
1729 {
1730 { DTF_1_PARINIT, "PARINIT" },
1731 { DTF_1_CONFEXP, "CONFEXP" }
1732 };
1733 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1734 / sizeof (dt_feature_1[0]));
1735
1736 static const struct flags dt_posflag_1[] =
1737 {
1738 { DF_P1_LAZYLOAD, "LAZYLOAD" },
1739 { DF_P1_GROUPPERM, "GROUPPERM" }
1740 };
1741 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1742 / sizeof (dt_posflag_1[0]));
1743
1744
1745 static void
print_flags(int class,GElf_Xword d_val,const struct flags * flags,int nflags)1746 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1747 int nflags)
1748 {
1749 bool first = true;
1750 int cnt;
1751
1752 for (cnt = 0; cnt < nflags; ++cnt)
1753 if (d_val & flags[cnt].mask)
1754 {
1755 if (!first)
1756 putchar_unlocked (' ');
1757 fputs_unlocked (flags[cnt].str, stdout);
1758 d_val &= ~flags[cnt].mask;
1759 first = false;
1760 }
1761
1762 if (d_val != 0)
1763 {
1764 if (!first)
1765 putchar_unlocked (' ');
1766 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1767 }
1768
1769 putchar_unlocked ('\n');
1770 }
1771
1772
1773 static void
print_dt_flags(int class,GElf_Xword d_val)1774 print_dt_flags (int class, GElf_Xword d_val)
1775 {
1776 print_flags (class, d_val, dt_flags, ndt_flags);
1777 }
1778
1779
1780 static void
print_dt_flags_1(int class,GElf_Xword d_val)1781 print_dt_flags_1 (int class, GElf_Xword d_val)
1782 {
1783 print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1784 }
1785
1786
1787 static void
print_dt_feature_1(int class,GElf_Xword d_val)1788 print_dt_feature_1 (int class, GElf_Xword d_val)
1789 {
1790 print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1791 }
1792
1793
1794 static void
print_dt_posflag_1(int class,GElf_Xword d_val)1795 print_dt_posflag_1 (int class, GElf_Xword d_val)
1796 {
1797 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1798 }
1799
1800
1801 static size_t
get_dyn_ents(Elf_Data * dyn_data)1802 get_dyn_ents (Elf_Data * dyn_data)
1803 {
1804 GElf_Dyn *dyn;
1805 GElf_Dyn dyn_mem;
1806 size_t dyn_idx = 0;
1807 do
1808 {
1809 dyn = gelf_getdyn(dyn_data, dyn_idx, &dyn_mem);
1810 if (dyn != NULL)
1811 ++dyn_idx;
1812 }
1813 while (dyn != NULL && dyn->d_tag != DT_NULL);
1814
1815 return dyn_idx;
1816 }
1817
1818
1819 static void
handle_dynamic(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,GElf_Phdr * phdr)1820 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr)
1821 {
1822 int class = gelf_getclass (ebl->elf);
1823 GElf_Shdr glink_mem;
1824 GElf_Shdr *glink;
1825 Elf_Data *data;
1826 size_t cnt;
1827 size_t shstrndx;
1828 size_t dyn_ents;
1829
1830 /* Get the data of the section. */
1831 if (use_dynamic_segment)
1832 data = elf_getdata_rawchunk(ebl->elf, phdr->p_offset,
1833 phdr->p_filesz, ELF_T_DYN);
1834 else
1835 data = elf_getdata (scn, NULL);
1836
1837 if (data == NULL)
1838 return;
1839
1840 /* Get the dynamic section entry number */
1841 dyn_ents = get_dyn_ents (data);
1842
1843 if (!use_dynamic_segment)
1844 {
1845 /* Get the section header string table index. */
1846 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1847 error_exit (0, _("cannot get section header string table index"));
1848
1849 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1850 if (glink == NULL)
1851 error_exit (0, _("invalid sh_link value in section %zu"),
1852 elf_ndxscn (scn));
1853
1854 printf (ngettext ("\
1855 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1856 "\
1857 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1858 dyn_ents),
1859 (unsigned long int) dyn_ents,
1860 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1861 shdr->sh_offset,
1862 (int) shdr->sh_link,
1863 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1864 }
1865 else
1866 {
1867 printf (ngettext ("\
1868 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 "\n",
1869 "\
1870 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 "\n",
1871 dyn_ents),
1872 (unsigned long int) dyn_ents,
1873 class == ELFCLASS32 ? 10 : 18, phdr->p_paddr,
1874 phdr->p_offset);
1875 }
1876
1877 fputs_unlocked (_(" Type Value\n"), stdout);
1878
1879 /* if --use-dynamic option is enabled,
1880 use the string table to get the related library info. */
1881 Elf_Data *strtab_data = NULL;
1882 if (use_dynamic_segment)
1883 {
1884 strtab_data = get_dynscn_strtab(ebl->elf, phdr);
1885 if (strtab_data == NULL)
1886 error_exit (0, _("cannot get string table by using dynamic segment"));
1887 }
1888
1889 for (cnt = 0; cnt < dyn_ents; ++cnt)
1890 {
1891 GElf_Dyn dynmem;
1892 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1893 if (dyn == NULL)
1894 break;
1895
1896 char buf[64];
1897 printf (" %-17s ",
1898 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1899
1900 char *name = NULL;
1901 if (dyn->d_tag == DT_NEEDED
1902 || dyn->d_tag == DT_SONAME
1903 || dyn->d_tag == DT_RPATH
1904 || dyn->d_tag == DT_RUNPATH)
1905 {
1906 if (! use_dynamic_segment)
1907 name = elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val);
1908 else if (dyn->d_un.d_val < strtab_data->d_size
1909 && memrchr (strtab_data->d_buf + dyn->d_un.d_val, '\0',
1910 strtab_data->d_size - 1 - dyn->d_un.d_val) != NULL)
1911 name = ((char *) strtab_data->d_buf) + dyn->d_un.d_val;
1912 }
1913
1914 switch (dyn->d_tag)
1915 {
1916 case DT_NULL:
1917 case DT_DEBUG:
1918 case DT_BIND_NOW:
1919 case DT_TEXTREL:
1920 /* No further output. */
1921 fputc_unlocked ('\n', stdout);
1922 break;
1923
1924 case DT_NEEDED:
1925 printf (_("Shared library: [%s]\n"), name);
1926 break;
1927
1928 case DT_SONAME:
1929 printf (_("Library soname: [%s]\n"), name);
1930 break;
1931
1932 case DT_RPATH:
1933 printf (_("Library rpath: [%s]\n"), name);
1934 break;
1935
1936 case DT_RUNPATH:
1937 printf (_("Library runpath: [%s]\n"), name);
1938 break;
1939
1940 case DT_PLTRELSZ:
1941 case DT_RELASZ:
1942 case DT_STRSZ:
1943 case DT_RELSZ:
1944 case DT_RELAENT:
1945 case DT_SYMENT:
1946 case DT_RELENT:
1947 case DT_PLTPADSZ:
1948 case DT_MOVEENT:
1949 case DT_MOVESZ:
1950 case DT_INIT_ARRAYSZ:
1951 case DT_FINI_ARRAYSZ:
1952 case DT_SYMINSZ:
1953 case DT_SYMINENT:
1954 case DT_GNU_CONFLICTSZ:
1955 case DT_GNU_LIBLISTSZ:
1956 printf (_("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1957 break;
1958
1959 case DT_VERDEFNUM:
1960 case DT_VERNEEDNUM:
1961 case DT_RELACOUNT:
1962 case DT_RELCOUNT:
1963 printf ("%" PRId64 "\n", dyn->d_un.d_val);
1964 break;
1965
1966 case DT_PLTREL:;
1967 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1968 NULL, 0);
1969 puts (tagname ?: "???");
1970 break;
1971
1972 case DT_FLAGS:
1973 print_dt_flags (class, dyn->d_un.d_val);
1974 break;
1975
1976 case DT_FLAGS_1:
1977 print_dt_flags_1 (class, dyn->d_un.d_val);
1978 break;
1979
1980 case DT_FEATURE_1:
1981 print_dt_feature_1 (class, dyn->d_un.d_val);
1982 break;
1983
1984 case DT_POSFLAG_1:
1985 print_dt_posflag_1 (class, dyn->d_un.d_val);
1986 break;
1987
1988 default:
1989 printf ("%#0*" PRIx64 "\n",
1990 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1991 break;
1992 }
1993 }
1994 }
1995
1996
1997 /* Print the dynamic segment. */
1998 static void
print_dynamic(Ebl * ebl)1999 print_dynamic (Ebl *ebl)
2000 {
2001 for (size_t i = 0; i < phnum; ++i)
2002 {
2003 GElf_Phdr phdr_mem;
2004 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
2005
2006 if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
2007 {
2008 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
2009 GElf_Shdr shdr_mem;
2010 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2011 if ((use_dynamic_segment && phdr != NULL)
2012 || (shdr != NULL && shdr->sh_type == SHT_DYNAMIC))
2013 handle_dynamic (ebl, scn, shdr, phdr);
2014 break;
2015 }
2016 }
2017 }
2018
2019
2020 /* Print relocations. */
2021 static void
print_relocs(Ebl * ebl,GElf_Ehdr * ehdr)2022 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
2023 {
2024 /* Find all relocation sections and handle them. */
2025 Elf_Scn *scn = NULL;
2026
2027 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2028 {
2029 /* Handle the section if it is a symbol table. */
2030 GElf_Shdr shdr_mem;
2031 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2032
2033 if (likely (shdr != NULL))
2034 {
2035 if (shdr->sh_type == SHT_REL)
2036 handle_relocs_rel (ebl, ehdr, scn, shdr);
2037 else if (shdr->sh_type == SHT_RELA)
2038 handle_relocs_rela (ebl, ehdr, scn, shdr);
2039 }
2040 }
2041 }
2042
2043
2044 /* Handle a relocation section. */
2045 static void
handle_relocs_rel(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)2046 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2047 {
2048 int class = gelf_getclass (ebl->elf);
2049 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
2050 int nentries = shdr->sh_size / sh_entsize;
2051
2052 /* Get the data of the section. */
2053 Elf_Data *data = elf_getdata (scn, NULL);
2054 if (data == NULL)
2055 return;
2056
2057 /* Get the symbol table information. */
2058 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2059 GElf_Shdr symshdr_mem;
2060 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2061 Elf_Data *symdata = elf_getdata (symscn, NULL);
2062
2063 /* Get the section header of the section the relocations are for. */
2064 GElf_Shdr destshdr_mem;
2065 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2066 &destshdr_mem);
2067
2068 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2069 {
2070 printf (_("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2071 shdr->sh_offset);
2072 return;
2073 }
2074
2075 /* Search for the optional extended section index table. */
2076 Elf_Data *xndxdata = NULL;
2077 int xndxscnidx = elf_scnshndx (scn);
2078 if (unlikely (xndxscnidx > 0))
2079 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2080
2081 /* Get the section header string table index. */
2082 size_t shstrndx;
2083 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2084 error_exit (0, _("cannot get section header string table index"));
2085
2086 if (shdr->sh_info != 0)
2087 printf (ngettext ("\
2088 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2089 "\
2090 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2091 nentries),
2092 elf_ndxscn (scn),
2093 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2094 (unsigned int) shdr->sh_info,
2095 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2096 shdr->sh_offset,
2097 nentries);
2098 else
2099 /* The .rel.dyn section does not refer to a specific section but
2100 instead of section index zero. Do not try to print a section
2101 name. */
2102 printf (ngettext ("\
2103 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2104 "\
2105 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2106 nentries),
2107 (unsigned int) elf_ndxscn (scn),
2108 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2109 shdr->sh_offset,
2110 nentries);
2111 fputs_unlocked (class == ELFCLASS32
2112 ? _("\
2113 Offset Type Value Name\n")
2114 : _("\
2115 Offset Type Value Name\n"),
2116 stdout);
2117
2118 int is_statically_linked = 0;
2119 for (int cnt = 0; cnt < nentries; ++cnt)
2120 {
2121 GElf_Rel relmem;
2122 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
2123 if (likely (rel != NULL))
2124 {
2125 char buf[128];
2126 GElf_Sym symmem;
2127 Elf32_Word xndx;
2128 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2129 GELF_R_SYM (rel->r_info),
2130 &symmem, &xndx);
2131 if (unlikely (sym == NULL))
2132 {
2133 /* As a special case we have to handle relocations in static
2134 executables. This only happens for IRELATIVE relocations
2135 (so far). There is no symbol table. */
2136 if (is_statically_linked == 0)
2137 {
2138 /* Find the program header and look for a PT_INTERP entry. */
2139 is_statically_linked = -1;
2140 if (ehdr->e_type == ET_EXEC)
2141 {
2142 is_statically_linked = 1;
2143
2144 for (size_t inner = 0; inner < phnum; ++inner)
2145 {
2146 GElf_Phdr phdr_mem;
2147 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2148 &phdr_mem);
2149 if (phdr != NULL && phdr->p_type == PT_INTERP)
2150 {
2151 is_statically_linked = -1;
2152 break;
2153 }
2154 }
2155 }
2156 }
2157
2158 if (is_statically_linked > 0 && shdr->sh_link == 0)
2159 printf ("\
2160 %#0*" PRIx64 " %-20s %*s %s\n",
2161 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2162 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2163 /* Avoid the leading R_ which isn't carrying any
2164 information. */
2165 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2166 buf, sizeof (buf)) + 2
2167 : _("<INVALID RELOC>"),
2168 class == ELFCLASS32 ? 10 : 18, "",
2169 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2170 else
2171 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
2172 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2173 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2174 /* Avoid the leading R_ which isn't carrying any
2175 information. */
2176 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2177 buf, sizeof (buf)) + 2
2178 : _("<INVALID RELOC>"),
2179 _("INVALID SYMBOL"),
2180 (long int) GELF_R_SYM (rel->r_info));
2181 }
2182 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2183 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
2184 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2185 likely (ebl_reloc_type_check (ebl,
2186 GELF_R_TYPE (rel->r_info)))
2187 /* Avoid the leading R_ which isn't carrying any
2188 information. */
2189 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2190 buf, sizeof (buf)) + 2
2191 : _("<INVALID RELOC>"),
2192 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2193 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2194 else
2195 {
2196 /* This is a relocation against a STT_SECTION symbol. */
2197 GElf_Shdr secshdr_mem;
2198 GElf_Shdr *secshdr;
2199 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2200 sym->st_shndx == SHN_XINDEX
2201 ? xndx : sym->st_shndx),
2202 &secshdr_mem);
2203
2204 if (unlikely (secshdr == NULL))
2205 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
2206 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2207 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2208 /* Avoid the leading R_ which isn't carrying any
2209 information. */
2210 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2211 buf, sizeof (buf)) + 2
2212 : _("<INVALID RELOC>"),
2213 _("INVALID SECTION"),
2214 (long int) (sym->st_shndx == SHN_XINDEX
2215 ? xndx : sym->st_shndx));
2216 else
2217 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
2218 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2219 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2220 /* Avoid the leading R_ which isn't carrying any
2221 information. */
2222 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2223 buf, sizeof (buf)) + 2
2224 : _("<INVALID RELOC>"),
2225 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2226 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2227 }
2228 }
2229 }
2230 }
2231
2232
2233 /* Handle a relocation section. */
2234 static void
handle_relocs_rela(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)2235 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2236 {
2237 int class = gelf_getclass (ebl->elf);
2238 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
2239 int nentries = shdr->sh_size / sh_entsize;
2240
2241 /* Get the data of the section. */
2242 Elf_Data *data = elf_getdata (scn, NULL);
2243 if (data == NULL)
2244 return;
2245
2246 /* Get the symbol table information. */
2247 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2248 GElf_Shdr symshdr_mem;
2249 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2250 Elf_Data *symdata = elf_getdata (symscn, NULL);
2251
2252 /* Get the section header of the section the relocations are for. */
2253 GElf_Shdr destshdr_mem;
2254 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2255 &destshdr_mem);
2256
2257 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2258 {
2259 printf (_("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2260 shdr->sh_offset);
2261 return;
2262 }
2263
2264 /* Search for the optional extended section index table. */
2265 Elf_Data *xndxdata = NULL;
2266 int xndxscnidx = elf_scnshndx (scn);
2267 if (unlikely (xndxscnidx > 0))
2268 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2269
2270 /* Get the section header string table index. */
2271 size_t shstrndx;
2272 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2273 error_exit (0, _("cannot get section header string table index"));
2274
2275 if (shdr->sh_info != 0)
2276 printf (ngettext ("\
2277 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2278 "\
2279 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2280 nentries),
2281 elf_ndxscn (scn),
2282 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2283 (unsigned int) shdr->sh_info,
2284 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2285 shdr->sh_offset,
2286 nentries);
2287 else
2288 /* The .rela.dyn section does not refer to a specific section but
2289 instead of section index zero. Do not try to print a section
2290 name. */
2291 printf (ngettext ("\
2292 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2293 "\
2294 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2295 nentries),
2296 (unsigned int) elf_ndxscn (scn),
2297 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2298 shdr->sh_offset,
2299 nentries);
2300 fputs_unlocked (class == ELFCLASS32
2301 ? _("\
2302 Offset Type Value Addend Name\n")
2303 : _("\
2304 Offset Type Value Addend Name\n"),
2305 stdout);
2306
2307 int is_statically_linked = 0;
2308 for (int cnt = 0; cnt < nentries; ++cnt)
2309 {
2310 GElf_Rela relmem;
2311 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2312 if (likely (rel != NULL))
2313 {
2314 char buf[64];
2315 GElf_Sym symmem;
2316 Elf32_Word xndx;
2317 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2318 GELF_R_SYM (rel->r_info),
2319 &symmem, &xndx);
2320
2321 if (unlikely (sym == NULL))
2322 {
2323 /* As a special case we have to handle relocations in static
2324 executables. This only happens for IRELATIVE relocations
2325 (so far). There is no symbol table. */
2326 if (is_statically_linked == 0)
2327 {
2328 /* Find the program header and look for a PT_INTERP entry. */
2329 is_statically_linked = -1;
2330 if (ehdr->e_type == ET_EXEC)
2331 {
2332 is_statically_linked = 1;
2333
2334 for (size_t inner = 0; inner < phnum; ++inner)
2335 {
2336 GElf_Phdr phdr_mem;
2337 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2338 &phdr_mem);
2339 if (phdr != NULL && phdr->p_type == PT_INTERP)
2340 {
2341 is_statically_linked = -1;
2342 break;
2343 }
2344 }
2345 }
2346 }
2347
2348 if (is_statically_linked > 0 && shdr->sh_link == 0)
2349 printf ("\
2350 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
2351 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2352 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2353 /* Avoid the leading R_ which isn't carrying any
2354 information. */
2355 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2356 buf, sizeof (buf)) + 2
2357 : _("<INVALID RELOC>"),
2358 class == ELFCLASS32 ? 10 : 18, "",
2359 rel->r_addend,
2360 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2361 else
2362 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2363 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2364 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2365 /* Avoid the leading R_ which isn't carrying any
2366 information. */
2367 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2368 buf, sizeof (buf)) + 2
2369 : _("<INVALID RELOC>"),
2370 _("INVALID SYMBOL"),
2371 (long int) GELF_R_SYM (rel->r_info));
2372 }
2373 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2374 printf ("\
2375 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2376 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2377 likely (ebl_reloc_type_check (ebl,
2378 GELF_R_TYPE (rel->r_info)))
2379 /* Avoid the leading R_ which isn't carrying any
2380 information. */
2381 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2382 buf, sizeof (buf)) + 2
2383 : _("<INVALID RELOC>"),
2384 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2385 rel->r_addend,
2386 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2387 else
2388 {
2389 /* This is a relocation against a STT_SECTION symbol. */
2390 GElf_Shdr secshdr_mem;
2391 GElf_Shdr *secshdr;
2392 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2393 sym->st_shndx == SHN_XINDEX
2394 ? xndx : sym->st_shndx),
2395 &secshdr_mem);
2396
2397 if (unlikely (secshdr == NULL))
2398 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2399 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2400 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2401 /* Avoid the leading R_ which isn't carrying any
2402 information. */
2403 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2404 buf, sizeof (buf)) + 2
2405 : _("<INVALID RELOC>"),
2406 _("INVALID SECTION"),
2407 (long int) (sym->st_shndx == SHN_XINDEX
2408 ? xndx : sym->st_shndx));
2409 else
2410 printf ("\
2411 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2412 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2413 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2414 /* Avoid the leading R_ which isn't carrying any
2415 information. */
2416 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2417 buf, sizeof (buf)) + 2
2418 : _("<INVALID RELOC>"),
2419 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2420 rel->r_addend,
2421 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2422 }
2423 }
2424 }
2425 }
2426
2427
2428 /* Print the program header. */
2429 static void
print_symtab(Ebl * ebl,int type)2430 print_symtab (Ebl *ebl, int type)
2431 {
2432 /* Find the symbol table(s). For this we have to search through the
2433 section table. */
2434 Elf_Scn *scn = NULL;
2435
2436 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2437 {
2438 /* Handle the section if it is a symbol table. */
2439 GElf_Shdr shdr_mem;
2440 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2441
2442 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2443 {
2444 if (symbol_table_section != NULL)
2445 {
2446 /* Get the section header string table index. */
2447 size_t shstrndx;
2448 const char *sname;
2449 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2450 error_exit (0,
2451 _("cannot get section header string table index"));
2452 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
2453 if (sname == NULL || strcmp (sname, symbol_table_section) != 0)
2454 continue;
2455 }
2456
2457 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
2458 {
2459 if (elf_compress (scn, 0, 0) < 0)
2460 printf ("WARNING: %s [%zd]\n",
2461 _("Couldn't uncompress section"),
2462 elf_ndxscn (scn));
2463 shdr = gelf_getshdr (scn, &shdr_mem);
2464 if (unlikely (shdr == NULL))
2465 error_exit (0,
2466 _("cannot get section [%zd] header: %s"),
2467 elf_ndxscn (scn), elf_errmsg (-1));
2468 }
2469 handle_symtab (ebl, scn, shdr);
2470 }
2471 }
2472 }
2473
2474
2475 static void
handle_symtab(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2476 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2477 {
2478 Elf_Data *versym_data = NULL;
2479 Elf_Data *verneed_data = NULL;
2480 Elf_Data *verdef_data = NULL;
2481 Elf_Data *xndx_data = NULL;
2482 int class = gelf_getclass (ebl->elf);
2483 Elf32_Word verneed_stridx = 0;
2484 Elf32_Word verdef_stridx = 0;
2485
2486 /* Get the data of the section. */
2487 Elf_Data *data = elf_getdata (scn, NULL);
2488 if (data == NULL)
2489 return;
2490
2491 /* Find out whether we have other sections we might need. */
2492 Elf_Scn *runscn = NULL;
2493 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2494 {
2495 GElf_Shdr runshdr_mem;
2496 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2497
2498 if (likely (runshdr != NULL))
2499 {
2500 if (runshdr->sh_type == SHT_GNU_versym
2501 && runshdr->sh_link == elf_ndxscn (scn))
2502 /* Bingo, found the version information. Now get the data. */
2503 versym_data = elf_getdata (runscn, NULL);
2504 else if (runshdr->sh_type == SHT_GNU_verneed)
2505 {
2506 /* This is the information about the needed versions. */
2507 verneed_data = elf_getdata (runscn, NULL);
2508 verneed_stridx = runshdr->sh_link;
2509 }
2510 else if (runshdr->sh_type == SHT_GNU_verdef)
2511 {
2512 /* This is the information about the defined versions. */
2513 verdef_data = elf_getdata (runscn, NULL);
2514 verdef_stridx = runshdr->sh_link;
2515 }
2516 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2517 && runshdr->sh_link == elf_ndxscn (scn))
2518 /* Extended section index. */
2519 xndx_data = elf_getdata (runscn, NULL);
2520 }
2521 }
2522
2523 /* Get the section header string table index. */
2524 size_t shstrndx;
2525 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2526 error_exit (0, _("cannot get section header string table index"));
2527
2528 GElf_Shdr glink_mem;
2529 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2530 &glink_mem);
2531 if (glink == NULL)
2532 error_exit (0, _("invalid sh_link value in section %zu"),
2533 elf_ndxscn (scn));
2534
2535 /* Now we can compute the number of entries in the section. */
2536 unsigned int nsyms = data->d_size / (class == ELFCLASS32
2537 ? sizeof (Elf32_Sym)
2538 : sizeof (Elf64_Sym));
2539
2540 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2541 "\nSymbol table [%2u] '%s' contains %u entries:\n",
2542 nsyms),
2543 (unsigned int) elf_ndxscn (scn),
2544 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2545 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
2546 " %lu local symbols String table: [%2u] '%s'\n",
2547 shdr->sh_info),
2548 (unsigned long int) shdr->sh_info,
2549 (unsigned int) shdr->sh_link,
2550 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2551
2552 fputs_unlocked (class == ELFCLASS32
2553 ? _("\
2554 Num: Value Size Type Bind Vis Ndx Name\n")
2555 : _("\
2556 Num: Value Size Type Bind Vis Ndx Name\n"),
2557 stdout);
2558
2559 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2560 {
2561 char typebuf[64];
2562 char bindbuf[64];
2563 char scnbuf[64];
2564 Elf32_Word xndx;
2565 GElf_Sym sym_mem;
2566 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2567
2568 if (unlikely (sym == NULL))
2569 continue;
2570
2571 /* Determine the real section index. */
2572 if (likely (sym->st_shndx != SHN_XINDEX))
2573 xndx = sym->st_shndx;
2574
2575 printf (_("\
2576 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2577 cnt,
2578 class == ELFCLASS32 ? 8 : 16,
2579 sym->st_value,
2580 sym->st_size,
2581 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2582 typebuf, sizeof (typebuf)),
2583 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2584 bindbuf, sizeof (bindbuf)),
2585 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2586 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2587 sizeof (scnbuf), NULL, shnum),
2588 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2589
2590 if (versym_data != NULL)
2591 {
2592 /* Get the version information. */
2593 GElf_Versym versym_mem;
2594 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2595
2596 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2597 {
2598 bool is_nobits = false;
2599 bool check_def = xndx != SHN_UNDEF;
2600
2601 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2602 {
2603 GElf_Shdr symshdr_mem;
2604 GElf_Shdr *symshdr =
2605 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2606
2607 is_nobits = (symshdr != NULL
2608 && symshdr->sh_type == SHT_NOBITS);
2609 }
2610
2611 if (is_nobits || ! check_def)
2612 {
2613 /* We must test both. */
2614 GElf_Vernaux vernaux_mem;
2615 GElf_Vernaux *vernaux = NULL;
2616 size_t vn_offset = 0;
2617
2618 GElf_Verneed verneed_mem;
2619 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2620 &verneed_mem);
2621 while (verneed != NULL)
2622 {
2623 size_t vna_offset = vn_offset;
2624
2625 vernaux = gelf_getvernaux (verneed_data,
2626 vna_offset += verneed->vn_aux,
2627 &vernaux_mem);
2628 while (vernaux != NULL
2629 && vernaux->vna_other != *versym
2630 && vernaux->vna_next != 0
2631 && (verneed_data->d_size - vna_offset
2632 >= vernaux->vna_next))
2633 {
2634 /* Update the offset. */
2635 vna_offset += vernaux->vna_next;
2636
2637 vernaux = (vernaux->vna_next == 0
2638 ? NULL
2639 : gelf_getvernaux (verneed_data,
2640 vna_offset,
2641 &vernaux_mem));
2642 }
2643
2644 /* Check whether we found the version. */
2645 if (vernaux != NULL && vernaux->vna_other == *versym)
2646 /* Found it. */
2647 break;
2648
2649 if (verneed_data->d_size - vn_offset < verneed->vn_next)
2650 break;
2651
2652 vn_offset += verneed->vn_next;
2653 verneed = (verneed->vn_next == 0
2654 ? NULL
2655 : gelf_getverneed (verneed_data, vn_offset,
2656 &verneed_mem));
2657 }
2658
2659 if (vernaux != NULL && vernaux->vna_other == *versym)
2660 {
2661 printf ("@%s (%u)",
2662 elf_strptr (ebl->elf, verneed_stridx,
2663 vernaux->vna_name),
2664 (unsigned int) vernaux->vna_other);
2665 check_def = 0;
2666 }
2667 else if (unlikely (! is_nobits))
2668 error (0, 0, _("bad dynamic symbol"));
2669 else
2670 check_def = 1;
2671 }
2672
2673 if (check_def && *versym != 0x8001)
2674 {
2675 /* We must test both. */
2676 size_t vd_offset = 0;
2677
2678 GElf_Verdef verdef_mem;
2679 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2680 &verdef_mem);
2681 while (verdef != NULL)
2682 {
2683 if (verdef->vd_ndx == (*versym & 0x7fff))
2684 /* Found the definition. */
2685 break;
2686
2687 if (verdef_data->d_size - vd_offset < verdef->vd_next)
2688 break;
2689
2690 vd_offset += verdef->vd_next;
2691 verdef = (verdef->vd_next == 0
2692 ? NULL
2693 : gelf_getverdef (verdef_data, vd_offset,
2694 &verdef_mem));
2695 }
2696
2697 if (verdef != NULL)
2698 {
2699 GElf_Verdaux verdaux_mem;
2700 GElf_Verdaux *verdaux
2701 = gelf_getverdaux (verdef_data,
2702 vd_offset + verdef->vd_aux,
2703 &verdaux_mem);
2704
2705 if (verdaux != NULL)
2706 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2707 elf_strptr (ebl->elf, verdef_stridx,
2708 verdaux->vda_name));
2709 }
2710 }
2711 }
2712 }
2713
2714 putchar_unlocked ('\n');
2715 }
2716 }
2717
2718
2719 /* Print version information. */
2720 static void
print_verinfo(Ebl * ebl)2721 print_verinfo (Ebl *ebl)
2722 {
2723 /* Find the version information sections. For this we have to
2724 search through the section table. */
2725 Elf_Scn *scn = NULL;
2726
2727 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2728 {
2729 /* Handle the section if it is part of the versioning handling. */
2730 GElf_Shdr shdr_mem;
2731 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2732
2733 if (likely (shdr != NULL))
2734 {
2735 if (shdr->sh_type == SHT_GNU_verneed)
2736 handle_verneed (ebl, scn, shdr);
2737 else if (shdr->sh_type == SHT_GNU_verdef)
2738 handle_verdef (ebl, scn, shdr);
2739 else if (shdr->sh_type == SHT_GNU_versym)
2740 handle_versym (ebl, scn, shdr);
2741 }
2742 }
2743 }
2744
2745
2746 static const char *
get_ver_flags(unsigned int flags)2747 get_ver_flags (unsigned int flags)
2748 {
2749 static char buf[32];
2750 char *endp;
2751
2752 if (flags == 0)
2753 return _("none");
2754
2755 if (flags & VER_FLG_BASE)
2756 endp = stpcpy (buf, "BASE ");
2757 else
2758 endp = buf;
2759
2760 if (flags & VER_FLG_WEAK)
2761 {
2762 if (endp != buf)
2763 endp = stpcpy (endp, "| ");
2764
2765 endp = stpcpy (endp, "WEAK ");
2766 }
2767
2768 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2769 {
2770 strncpy (endp, _("| <unknown>"), buf + sizeof (buf) - endp);
2771 buf[sizeof (buf) - 1] = '\0';
2772 }
2773
2774 return buf;
2775 }
2776
2777
2778 static void
handle_verneed(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2779 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2780 {
2781 int class = gelf_getclass (ebl->elf);
2782
2783 /* Get the data of the section. */
2784 Elf_Data *data = elf_getdata (scn, NULL);
2785 if (data == NULL)
2786 return;
2787
2788 /* Get the section header string table index. */
2789 size_t shstrndx;
2790 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2791 error_exit (0, _("cannot get section header string table index"));
2792
2793 GElf_Shdr glink_mem;
2794 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2795 &glink_mem);
2796 if (glink == NULL)
2797 error_exit (0, _("invalid sh_link value in section %zu"),
2798 elf_ndxscn (scn));
2799
2800 printf (ngettext ("\
2801 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2802 "\
2803 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2804 shdr->sh_info),
2805 (unsigned int) elf_ndxscn (scn),
2806 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2807 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2808 shdr->sh_offset,
2809 (unsigned int) shdr->sh_link,
2810 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2811
2812 unsigned int offset = 0;
2813 for (int cnt = shdr->sh_info; --cnt >= 0; )
2814 {
2815 /* Get the data at the next offset. */
2816 GElf_Verneed needmem;
2817 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2818 if (unlikely (need == NULL))
2819 break;
2820
2821 printf (_(" %#06x: Version: %hu File: %s Cnt: %hu\n"),
2822 offset, (unsigned short int) need->vn_version,
2823 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2824 (unsigned short int) need->vn_cnt);
2825
2826 unsigned int auxoffset = offset + need->vn_aux;
2827 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2828 {
2829 GElf_Vernaux auxmem;
2830 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2831 if (unlikely (aux == NULL))
2832 break;
2833
2834 printf (_(" %#06x: Name: %s Flags: %s Version: %hu\n"),
2835 auxoffset,
2836 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2837 get_ver_flags (aux->vna_flags),
2838 (unsigned short int) aux->vna_other);
2839
2840 if (aux->vna_next == 0)
2841 break;
2842
2843 auxoffset += aux->vna_next;
2844 }
2845
2846 /* Find the next offset. */
2847 if (need->vn_next == 0)
2848 break;
2849
2850 offset += need->vn_next;
2851 }
2852 }
2853
2854
2855 static void
handle_verdef(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2856 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2857 {
2858 /* Get the data of the section. */
2859 Elf_Data *data = elf_getdata (scn, NULL);
2860 if (data == NULL)
2861 return;
2862
2863 /* Get the section header string table index. */
2864 size_t shstrndx;
2865 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2866 error_exit (0, _("cannot get section header string table index"));
2867
2868 GElf_Shdr glink_mem;
2869 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2870 &glink_mem);
2871 if (glink == NULL)
2872 error_exit (0, _("invalid sh_link value in section %zu"),
2873 elf_ndxscn (scn));
2874
2875 int class = gelf_getclass (ebl->elf);
2876 printf (ngettext ("\
2877 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2878 "\
2879 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2880 shdr->sh_info),
2881 (unsigned int) elf_ndxscn (scn),
2882 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2883 shdr->sh_info,
2884 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2885 shdr->sh_offset,
2886 (unsigned int) shdr->sh_link,
2887 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2888
2889 unsigned int offset = 0;
2890 for (int cnt = shdr->sh_info; --cnt >= 0; )
2891 {
2892 /* Get the data at the next offset. */
2893 GElf_Verdef defmem;
2894 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2895 if (unlikely (def == NULL))
2896 break;
2897
2898 unsigned int auxoffset = offset + def->vd_aux;
2899 GElf_Verdaux auxmem;
2900 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2901 if (unlikely (aux == NULL))
2902 break;
2903
2904 printf (_("\
2905 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
2906 offset, def->vd_version,
2907 get_ver_flags (def->vd_flags),
2908 def->vd_ndx,
2909 def->vd_cnt,
2910 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2911
2912 auxoffset += aux->vda_next;
2913 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2914 {
2915 aux = gelf_getverdaux (data, auxoffset, &auxmem);
2916 if (unlikely (aux == NULL))
2917 break;
2918
2919 printf (_(" %#06x: Parent %d: %s\n"),
2920 auxoffset, cnt2,
2921 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2922
2923 if (aux->vda_next == 0)
2924 break;
2925
2926 auxoffset += aux->vda_next;
2927 }
2928
2929 /* Find the next offset. */
2930 if (def->vd_next == 0)
2931 break;
2932 offset += def->vd_next;
2933 }
2934 }
2935
2936
2937 static void
handle_versym(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2938 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2939 {
2940 int class = gelf_getclass (ebl->elf);
2941 const char **vername;
2942 const char **filename;
2943
2944 /* Get the data of the section. */
2945 Elf_Data *data = elf_getdata (scn, NULL);
2946 if (data == NULL)
2947 return;
2948
2949 /* Get the section header string table index. */
2950 size_t shstrndx;
2951 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2952 error_exit (0, _("cannot get section header string table index"));
2953
2954 /* We have to find the version definition section and extract the
2955 version names. */
2956 Elf_Scn *defscn = NULL;
2957 Elf_Scn *needscn = NULL;
2958
2959 Elf_Scn *verscn = NULL;
2960 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2961 {
2962 GElf_Shdr vershdr_mem;
2963 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2964
2965 if (likely (vershdr != NULL))
2966 {
2967 if (vershdr->sh_type == SHT_GNU_verdef)
2968 defscn = verscn;
2969 else if (vershdr->sh_type == SHT_GNU_verneed)
2970 needscn = verscn;
2971 }
2972 }
2973
2974 size_t nvername;
2975 if (defscn != NULL || needscn != NULL)
2976 {
2977 /* We have a version information (better should have). Now get
2978 the version names. First find the maximum version number. */
2979 nvername = 0;
2980 if (defscn != NULL)
2981 {
2982 /* Run through the version definitions and find the highest
2983 index. */
2984 unsigned int offset = 0;
2985 Elf_Data *defdata;
2986 GElf_Shdr defshdrmem;
2987 GElf_Shdr *defshdr;
2988
2989 defdata = elf_getdata (defscn, NULL);
2990 if (unlikely (defdata == NULL))
2991 return;
2992
2993 defshdr = gelf_getshdr (defscn, &defshdrmem);
2994 if (unlikely (defshdr == NULL))
2995 return;
2996
2997 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2998 {
2999 GElf_Verdef defmem;
3000 GElf_Verdef *def;
3001
3002 /* Get the data at the next offset. */
3003 def = gelf_getverdef (defdata, offset, &defmem);
3004 if (unlikely (def == NULL))
3005 break;
3006
3007 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
3008
3009 if (def->vd_next == 0)
3010 break;
3011 offset += def->vd_next;
3012 }
3013 }
3014 if (needscn != NULL)
3015 {
3016 unsigned int offset = 0;
3017 Elf_Data *needdata;
3018 GElf_Shdr needshdrmem;
3019 GElf_Shdr *needshdr;
3020
3021 needdata = elf_getdata (needscn, NULL);
3022 if (unlikely (needdata == NULL))
3023 return;
3024
3025 needshdr = gelf_getshdr (needscn, &needshdrmem);
3026 if (unlikely (needshdr == NULL))
3027 return;
3028
3029 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
3030 {
3031 GElf_Verneed needmem;
3032 GElf_Verneed *need;
3033 unsigned int auxoffset;
3034 int cnt2;
3035
3036 /* Get the data at the next offset. */
3037 need = gelf_getverneed (needdata, offset, &needmem);
3038 if (unlikely (need == NULL))
3039 break;
3040
3041 /* Run through the auxiliary entries. */
3042 auxoffset = offset + need->vn_aux;
3043 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
3044 {
3045 GElf_Vernaux auxmem;
3046 GElf_Vernaux *aux;
3047
3048 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
3049 if (unlikely (aux == NULL))
3050 break;
3051
3052 nvername = MAX (nvername,
3053 (size_t) (aux->vna_other & 0x7fff));
3054
3055 if (aux->vna_next == 0)
3056 break;
3057 auxoffset += aux->vna_next;
3058 }
3059
3060 if (need->vn_next == 0)
3061 break;
3062 offset += need->vn_next;
3063 }
3064 }
3065
3066 /* This is the number of versions we know about. */
3067 ++nvername;
3068
3069 /* Allocate the array. */
3070 vername = (const char **) alloca (nvername * sizeof (const char *));
3071 memset(vername, 0, nvername * sizeof (const char *));
3072 filename = (const char **) alloca (nvername * sizeof (const char *));
3073 memset(filename, 0, nvername * sizeof (const char *));
3074
3075 /* Run through the data structures again and collect the strings. */
3076 if (defscn != NULL)
3077 {
3078 /* Run through the version definitions and find the highest
3079 index. */
3080 unsigned int offset = 0;
3081 Elf_Data *defdata;
3082 GElf_Shdr defshdrmem;
3083 GElf_Shdr *defshdr;
3084
3085 defdata = elf_getdata (defscn, NULL);
3086 if (unlikely (defdata == NULL))
3087 return;
3088
3089 defshdr = gelf_getshdr (defscn, &defshdrmem);
3090 if (unlikely (defshdr == NULL))
3091 return;
3092
3093 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
3094 {
3095
3096 /* Get the data at the next offset. */
3097 GElf_Verdef defmem;
3098 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
3099 if (unlikely (def == NULL))
3100 break;
3101
3102 GElf_Verdaux auxmem;
3103 GElf_Verdaux *aux = gelf_getverdaux (defdata,
3104 offset + def->vd_aux,
3105 &auxmem);
3106 if (unlikely (aux == NULL))
3107 break;
3108
3109 vername[def->vd_ndx & 0x7fff]
3110 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
3111 filename[def->vd_ndx & 0x7fff] = NULL;
3112
3113 if (def->vd_next == 0)
3114 break;
3115 offset += def->vd_next;
3116 }
3117 }
3118 if (needscn != NULL)
3119 {
3120 unsigned int offset = 0;
3121
3122 Elf_Data *needdata = elf_getdata (needscn, NULL);
3123 GElf_Shdr needshdrmem;
3124 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
3125 if (unlikely (needdata == NULL || needshdr == NULL))
3126 return;
3127
3128 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
3129 {
3130 /* Get the data at the next offset. */
3131 GElf_Verneed needmem;
3132 GElf_Verneed *need = gelf_getverneed (needdata, offset,
3133 &needmem);
3134 if (unlikely (need == NULL))
3135 break;
3136
3137 /* Run through the auxiliary entries. */
3138 unsigned int auxoffset = offset + need->vn_aux;
3139 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
3140 {
3141 GElf_Vernaux auxmem;
3142 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
3143 &auxmem);
3144 if (unlikely (aux == NULL))
3145 break;
3146
3147 vername[aux->vna_other & 0x7fff]
3148 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
3149 filename[aux->vna_other & 0x7fff]
3150 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
3151
3152 if (aux->vna_next == 0)
3153 break;
3154 auxoffset += aux->vna_next;
3155 }
3156
3157 if (need->vn_next == 0)
3158 break;
3159 offset += need->vn_next;
3160 }
3161 }
3162 }
3163 else
3164 {
3165 vername = NULL;
3166 nvername = 1;
3167 filename = NULL;
3168 }
3169
3170 GElf_Shdr glink_mem;
3171 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
3172 &glink_mem);
3173 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
3174 if (glink == NULL)
3175 error_exit (0, _("invalid sh_link value in section %zu"),
3176 elf_ndxscn (scn));
3177
3178 /* Print the header. */
3179 printf (ngettext ("\
3180 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
3181 "\
3182 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
3183 shdr->sh_size / sh_entsize),
3184 (unsigned int) elf_ndxscn (scn),
3185 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3186 (int) (shdr->sh_size / sh_entsize),
3187 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
3188 shdr->sh_offset,
3189 (unsigned int) shdr->sh_link,
3190 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3191
3192 /* Now we can finally look at the actual contents of this section. */
3193 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
3194 {
3195 if (cnt % 2 == 0)
3196 printf ("\n %4d:", cnt);
3197
3198 GElf_Versym symmem;
3199 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
3200 if (sym == NULL)
3201 break;
3202
3203 switch (*sym)
3204 {
3205 ssize_t n;
3206 case 0:
3207 fputs_unlocked (_(" 0 *local* "),
3208 stdout);
3209 break;
3210
3211 case 1:
3212 fputs_unlocked (_(" 1 *global* "),
3213 stdout);
3214 break;
3215
3216 default:
3217 n = printf ("%4d%c%s",
3218 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
3219 (vername != NULL
3220 && (unsigned int) (*sym & 0x7fff) < nvername)
3221 ? vername[*sym & 0x7fff] : "???");
3222 if ((unsigned int) (*sym & 0x7fff) < nvername
3223 && filename != NULL && filename[*sym & 0x7fff] != NULL)
3224 n += printf ("(%s)", filename[*sym & 0x7fff]);
3225 printf ("%*s", MAX (0, 33 - (int) n), " ");
3226 break;
3227 }
3228 }
3229 putchar_unlocked ('\n');
3230 }
3231
3232
3233 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)3234 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
3235 uint_fast32_t maxlength, Elf32_Word nbucket,
3236 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
3237 {
3238 uint32_t *counts = xcalloc (maxlength + 1, sizeof (uint32_t));
3239
3240 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3241 ++counts[lengths[cnt]];
3242
3243 GElf_Shdr glink_mem;
3244 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
3245 shdr->sh_link),
3246 &glink_mem);
3247 if (glink == NULL)
3248 {
3249 error (0, 0, _("invalid sh_link value in section %zu"),
3250 elf_ndxscn (scn));
3251 return;
3252 }
3253
3254 printf (ngettext ("\
3255 \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",
3256 "\
3257 \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",
3258 nbucket),
3259 (unsigned int) elf_ndxscn (scn),
3260 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3261 (int) nbucket,
3262 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
3263 shdr->sh_addr,
3264 shdr->sh_offset,
3265 (unsigned int) shdr->sh_link,
3266 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3267
3268 if (extrastr != NULL)
3269 fputs (extrastr, stdout);
3270
3271 if (likely (nbucket > 0))
3272 {
3273 uint64_t success = 0;
3274
3275 /* xgettext:no-c-format */
3276 fputs_unlocked (_("\
3277 Length Number % of total Coverage\n"), stdout);
3278 printf (_(" 0 %6" PRIu32 " %5.1f%%\n"),
3279 counts[0], (counts[0] * 100.0) / nbucket);
3280
3281 uint64_t nzero_counts = 0;
3282 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3283 {
3284 nzero_counts += counts[cnt] * cnt;
3285 printf (_("\
3286 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
3287 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
3288 (nzero_counts * 100.0) / nsyms);
3289 }
3290
3291 Elf32_Word acc = 0;
3292 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3293 {
3294 acc += cnt;
3295 success += counts[cnt] * acc;
3296 }
3297
3298 printf (_("\
3299 Average number of tests: successful lookup: %f\n\
3300 unsuccessful lookup: %f\n"),
3301 (double) success / (double) nzero_counts,
3302 (double) nzero_counts / (double) nbucket);
3303 }
3304
3305 free (counts);
3306 }
3307
3308
3309 /* This function handles the traditional System V-style hash table format. */
3310 static void
handle_sysv_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3311 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3312 {
3313 Elf_Data *data = elf_getdata (scn, NULL);
3314 if (unlikely (data == NULL))
3315 {
3316 error (0, 0, _("cannot get data for section %d: %s"),
3317 (int) elf_ndxscn (scn), elf_errmsg (-1));
3318 return;
3319 }
3320
3321 if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
3322 {
3323 invalid_data:
3324 error (0, 0, _("invalid data in sysv.hash section %d"),
3325 (int) elf_ndxscn (scn));
3326 return;
3327 }
3328
3329 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3330 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
3331
3332 uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
3333 if (used_buf > data->d_size)
3334 goto invalid_data;
3335
3336 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
3337 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
3338
3339 uint32_t *lengths = xcalloc (nbucket, sizeof (uint32_t));
3340
3341 uint_fast32_t maxlength = 0;
3342 uint_fast32_t nsyms = 0;
3343 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3344 {
3345 Elf32_Word inner = bucket[cnt];
3346 Elf32_Word chain_len = 0;
3347 while (inner > 0 && inner < nchain)
3348 {
3349 ++nsyms;
3350 ++chain_len;
3351 if (chain_len > nchain)
3352 {
3353 error (0, 0, _("invalid chain in sysv.hash section %d"),
3354 (int) elf_ndxscn (scn));
3355 free (lengths);
3356 return;
3357 }
3358 if (maxlength < ++lengths[cnt])
3359 ++maxlength;
3360
3361 inner = chain[inner];
3362 }
3363 }
3364
3365 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3366 lengths, NULL);
3367
3368 free (lengths);
3369 }
3370
3371
3372 /* This function handles the incorrect, System V-style hash table
3373 format some 64-bit architectures use. */
3374 static void
handle_sysv_hash64(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3375 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3376 {
3377 Elf_Data *data = elf_getdata (scn, NULL);
3378 if (unlikely (data == NULL))
3379 {
3380 error (0, 0, _("cannot get data for section %d: %s"),
3381 (int) elf_ndxscn (scn), elf_errmsg (-1));
3382 return;
3383 }
3384
3385 if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3386 {
3387 invalid_data:
3388 error (0, 0, _("invalid data in sysv.hash64 section %d"),
3389 (int) elf_ndxscn (scn));
3390 return;
3391 }
3392
3393 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3394 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3395
3396 uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
3397 if (maxwords < 2
3398 || maxwords - 2 < nbucket
3399 || maxwords - 2 - nbucket < nchain)
3400 goto invalid_data;
3401
3402 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3403 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3404
3405 uint32_t *lengths = xcalloc (nbucket, sizeof (uint32_t));
3406
3407 uint_fast32_t maxlength = 0;
3408 uint_fast32_t nsyms = 0;
3409 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3410 {
3411 Elf64_Xword inner = bucket[cnt];
3412 Elf64_Xword chain_len = 0;
3413 while (inner > 0 && inner < nchain)
3414 {
3415 ++nsyms;
3416 ++chain_len;
3417 if (chain_len > nchain)
3418 {
3419 error (0, 0, _("invalid chain in sysv.hash64 section %d"),
3420 (int) elf_ndxscn (scn));
3421 free (lengths);
3422 return;
3423 }
3424 if (maxlength < ++lengths[cnt])
3425 ++maxlength;
3426
3427 inner = chain[inner];
3428 }
3429 }
3430
3431 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3432 lengths, NULL);
3433
3434 free (lengths);
3435 }
3436
3437
3438 /* This function handles the GNU-style hash table format. */
3439 static void
handle_gnu_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3440 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3441 {
3442 uint32_t *lengths = NULL;
3443 Elf_Data *data = elf_getdata (scn, NULL);
3444 if (unlikely (data == NULL))
3445 {
3446 error (0, 0, _("cannot get data for section %d: %s"),
3447 (int) elf_ndxscn (scn), elf_errmsg (-1));
3448 return;
3449 }
3450
3451 if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3452 {
3453 invalid_data:
3454 free (lengths);
3455 error (0, 0, _("invalid data in gnu.hash section %d"),
3456 (int) elf_ndxscn (scn));
3457 return;
3458 }
3459
3460 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3461 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3462
3463 /* Next comes the size of the bitmap. It's measured in words for
3464 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3465 64 bit archs. There is always a bloom filter present, so zero is
3466 an invalid value. */
3467 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3468 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3469 bitmask_words *= 2;
3470
3471 if (bitmask_words == 0)
3472 goto invalid_data;
3473
3474 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3475
3476 /* Is there still room for the sym chain?
3477 Use uint64_t calculation to prevent 32bit overflow. */
3478 uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3479 uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3480 if (used_buf > data->d_size)
3481 goto invalid_data;
3482
3483 lengths = xcalloc (nbucket, sizeof (uint32_t));
3484
3485 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3486 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3487 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3488 + nbucket];
3489
3490 /* Compute distribution of chain lengths. */
3491 uint_fast32_t maxlength = 0;
3492 uint_fast32_t nsyms = 0;
3493 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3494 if (bucket[cnt] != 0)
3495 {
3496 Elf32_Word inner = bucket[cnt] - symbias;
3497 do
3498 {
3499 ++nsyms;
3500 if (maxlength < ++lengths[cnt])
3501 ++maxlength;
3502 if (inner >= max_nsyms)
3503 goto invalid_data;
3504 }
3505 while ((chain[inner++] & 1) == 0);
3506 }
3507
3508 /* Count bits in bitmask. */
3509 uint_fast32_t nbits = 0;
3510 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3511 {
3512 uint_fast32_t word = bitmask[cnt];
3513
3514 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3515 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3516 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3517 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3518 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3519 }
3520
3521 char *str = xasprintf (_("\
3522 Symbol Bias: %u\n\
3523 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3524 (unsigned int) symbias,
3525 bitmask_words * sizeof (Elf32_Word),
3526 ((nbits * 100 + 50)
3527 / (uint_fast32_t) (bitmask_words
3528 * sizeof (Elf32_Word) * 8)),
3529 (unsigned int) shift);
3530
3531 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3532 lengths, str);
3533
3534 free (str);
3535 free (lengths);
3536 }
3537
3538
3539 /* Find the symbol table(s). For this we have to search through the
3540 section table. */
3541 static void
handle_hash(Ebl * ebl)3542 handle_hash (Ebl *ebl)
3543 {
3544 /* Get the section header string table index. */
3545 size_t shstrndx;
3546 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3547 error_exit (0, _("cannot get section header string table index"));
3548
3549 Elf_Scn *scn = NULL;
3550 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3551 {
3552 /* Handle the section if it is a symbol table. */
3553 GElf_Shdr shdr_mem;
3554 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3555
3556 if (likely (shdr != NULL))
3557 {
3558 if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH)
3559 && (shdr->sh_flags & SHF_COMPRESSED) != 0)
3560 {
3561 if (elf_compress (scn, 0, 0) < 0)
3562 printf ("WARNING: %s [%zd]\n",
3563 _("Couldn't uncompress section"),
3564 elf_ndxscn (scn));
3565 shdr = gelf_getshdr (scn, &shdr_mem);
3566 if (unlikely (shdr == NULL))
3567 error_exit (0, _("cannot get section [%zd] header: %s"),
3568 elf_ndxscn (scn), elf_errmsg (-1));
3569 }
3570
3571 if (shdr->sh_type == SHT_HASH)
3572 {
3573 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3574 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3575 else
3576 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3577 }
3578 else if (shdr->sh_type == SHT_GNU_HASH)
3579 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3580 }
3581 }
3582 }
3583
3584
3585 static void
print_liblist(Ebl * ebl)3586 print_liblist (Ebl *ebl)
3587 {
3588 /* Find the library list sections. For this we have to search
3589 through the section table. */
3590 Elf_Scn *scn = NULL;
3591
3592 /* Get the section header string table index. */
3593 size_t shstrndx;
3594 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3595 error_exit (0, _("cannot get section header string table index"));
3596
3597 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3598 {
3599 GElf_Shdr shdr_mem;
3600 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3601
3602 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3603 {
3604 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3605 int nentries = shdr->sh_size / sh_entsize;
3606 printf (ngettext ("\
3607 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3608 "\
3609 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3610 nentries),
3611 elf_ndxscn (scn),
3612 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3613 shdr->sh_offset,
3614 nentries);
3615
3616 Elf_Data *data = elf_getdata (scn, NULL);
3617 if (data == NULL)
3618 return;
3619
3620 puts (_("\
3621 Library Time Stamp Checksum Version Flags"));
3622
3623 for (int cnt = 0; cnt < nentries; ++cnt)
3624 {
3625 GElf_Lib lib_mem;
3626 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3627 if (unlikely (lib == NULL))
3628 continue;
3629
3630 time_t t = (time_t) lib->l_time_stamp;
3631 struct tm *tm = gmtime (&t);
3632 if (unlikely (tm == NULL))
3633 continue;
3634
3635 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3636 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3637 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3638 tm->tm_hour, tm->tm_min, tm->tm_sec,
3639 (unsigned int) lib->l_checksum,
3640 (unsigned int) lib->l_version,
3641 (unsigned int) lib->l_flags);
3642 }
3643 }
3644 }
3645 }
3646
3647 static inline size_t
left(Elf_Data * data,const unsigned char * p)3648 left (Elf_Data *data,
3649 const unsigned char *p)
3650 {
3651 return (const unsigned char *) data->d_buf + data->d_size - p;
3652 }
3653
3654 static void
print_attributes(Ebl * ebl,const GElf_Ehdr * ehdr)3655 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3656 {
3657 /* Find the object attributes sections. For this we have to search
3658 through the section table. */
3659 Elf_Scn *scn = NULL;
3660
3661 /* Get the section header string table index. */
3662 size_t shstrndx;
3663 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3664 error_exit (0, _("cannot get section header string table index"));
3665
3666 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3667 {
3668 GElf_Shdr shdr_mem;
3669 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3670
3671 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3672 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3673 || ehdr->e_machine != EM_ARM)
3674 && (shdr->sh_type != SHT_CSKY_ATTRIBUTES
3675 || ehdr->e_machine != EM_CSKY)
3676 && (shdr->sh_type != SHT_RISCV_ATTRIBUTES
3677 || ehdr->e_machine != EM_RISCV)))
3678 continue;
3679
3680 printf (_("\
3681 \nObject attributes section [%2zu] '%s' of %" PRIu64
3682 " bytes at offset %#0" PRIx64 ":\n"),
3683 elf_ndxscn (scn),
3684 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3685 shdr->sh_size, shdr->sh_offset);
3686
3687 Elf_Data *data = elf_rawdata (scn, NULL);
3688 if (unlikely (data == NULL || data->d_size == 0))
3689 return;
3690
3691 const unsigned char *p = data->d_buf;
3692
3693 /* There is only one 'version', A. */
3694 if (unlikely (*p++ != 'A'))
3695 return;
3696
3697 fputs_unlocked (_(" Owner Size\n"), stdout);
3698
3699 /* Loop over the sections. */
3700 while (left (data, p) >= 4)
3701 {
3702 /* Section length. */
3703 uint32_t len;
3704 memcpy (&len, p, sizeof len);
3705
3706 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3707 CONVERT (len);
3708
3709 if (unlikely (len > left (data, p)))
3710 break;
3711
3712 /* Section vendor name. */
3713 const unsigned char *name = p + sizeof len;
3714 p += len;
3715
3716 unsigned const char *q = memchr (name, '\0', len);
3717 if (unlikely (q == NULL))
3718 break;
3719 ++q;
3720
3721 printf (_(" %-13s %4" PRIu32 "\n"), name, len);
3722
3723 bool gnu_vendor = (q - name == sizeof "gnu"
3724 && !memcmp (name, "gnu", sizeof "gnu"));
3725
3726 /* Loop over subsections. */
3727 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3728 || gnu_vendor)
3729 while (q < p)
3730 {
3731 const unsigned char *const sub = q;
3732
3733 unsigned int subsection_tag;
3734 get_uleb128 (subsection_tag, q, p);
3735 if (unlikely (q >= p))
3736 break;
3737
3738 uint32_t subsection_len;
3739 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3740 break;
3741
3742 memcpy (&subsection_len, q, sizeof subsection_len);
3743
3744 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3745 CONVERT (subsection_len);
3746
3747 /* Don't overflow, ptrdiff_t might be 32bits, but signed. */
3748 if (unlikely (subsection_len == 0
3749 || subsection_len >= (uint32_t) PTRDIFF_MAX
3750 || p - sub < (ptrdiff_t) subsection_len))
3751 break;
3752
3753 const unsigned char *r = q + sizeof subsection_len;
3754 q = sub + subsection_len;
3755
3756 switch (subsection_tag)
3757 {
3758 default:
3759 /* Unknown subsection, print and skip. */
3760 printf (_(" %-4u %12" PRIu32 "\n"),
3761 subsection_tag, subsection_len);
3762 break;
3763
3764 case 1: /* Tag_File */
3765 printf (_(" File: %11" PRIu32 "\n"),
3766 subsection_len);
3767
3768 while (r < q)
3769 {
3770 unsigned int tag;
3771 get_uleb128 (tag, r, q);
3772 if (unlikely (r >= q))
3773 break;
3774
3775 /* GNU style tags have either a uleb128 value,
3776 when lowest bit is not set, or a string
3777 when the lowest bit is set.
3778 "compatibility" (32) is special. It has
3779 both a string and a uleb128 value. For
3780 non-gnu we assume 6 till 31 only take ints.
3781 XXX see arm backend, do we need a separate
3782 hook? */
3783 uint64_t value = 0;
3784 const char *string = NULL;
3785 if (tag == 32 || (tag & 1) == 0
3786 || (! gnu_vendor && (tag > 5 && tag < 32)))
3787 {
3788 get_uleb128 (value, r, q);
3789 if (r > q)
3790 break;
3791 }
3792 if (tag == 32
3793 || ((tag & 1) != 0
3794 && (gnu_vendor
3795 || (! gnu_vendor && tag > 32)))
3796 || (! gnu_vendor && tag > 3 && tag < 6))
3797 {
3798 string = (const char *) r;
3799 r = memchr (r, '\0', q - r);
3800 if (r == NULL)
3801 break;
3802 ++r;
3803 }
3804
3805 const char *tag_name = NULL;
3806 const char *value_name = NULL;
3807 ebl_check_object_attribute (ebl, (const char *) name,
3808 tag, value,
3809 &tag_name, &value_name);
3810
3811 if (tag_name != NULL)
3812 {
3813 if (tag == 32)
3814 printf (_(" %s: %" PRId64 ", %s\n"),
3815 tag_name, value, string);
3816 else if (string == NULL && value_name == NULL)
3817 printf (_(" %s: %" PRId64 "\n"),
3818 tag_name, value);
3819 else
3820 printf (_(" %s: %s\n"),
3821 tag_name, string ?: value_name);
3822 }
3823 else
3824 {
3825 /* For "gnu" vendor 32 "compatibility" has
3826 already been handled above. */
3827 assert (tag != 32
3828 || strcmp ((const char *) name, "gnu"));
3829 if (string == NULL)
3830 printf (_(" %u: %" PRId64 "\n"),
3831 tag, value);
3832 else
3833 printf (_(" %u: %s\n"),
3834 tag, string);
3835 }
3836 }
3837 }
3838 }
3839 }
3840 }
3841 }
3842
3843
3844 void
print_dwarf_addr(Dwfl_Module * dwflmod,int address_size,Dwarf_Addr address,Dwarf_Addr raw)3845 print_dwarf_addr (Dwfl_Module *dwflmod,
3846 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3847 {
3848 /* See if there is a name we can give for this address. */
3849 GElf_Sym sym;
3850 GElf_Off off = 0;
3851 const char *name = (print_address_names && ! print_unresolved_addresses)
3852 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3853 : NULL;
3854
3855 const char *scn;
3856 if (print_unresolved_addresses)
3857 {
3858 address = raw;
3859 scn = NULL;
3860 }
3861 else
3862 {
3863 /* Relativize the address. */
3864 int n = dwfl_module_relocations (dwflmod);
3865 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3866
3867 /* In an ET_REL file there is a section name to refer to. */
3868 scn = (i < 0 ? NULL
3869 : dwfl_module_relocation_info (dwflmod, i, NULL));
3870 }
3871
3872 if ((name != NULL
3873 ? (off != 0
3874 ? (scn != NULL
3875 ? (address_size == 0
3876 ? printf ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">",
3877 scn, address, name, off)
3878 : printf ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">",
3879 scn, 2 + address_size * 2, address,
3880 name, off))
3881 : (address_size == 0
3882 ? printf ("%#" PRIx64 " <%s+%#" PRIx64 ">",
3883 address, name, off)
3884 : printf ("%#0*" PRIx64 " <%s+%#" PRIx64 ">",
3885 2 + address_size * 2, address,
3886 name, off)))
3887 : (scn != NULL
3888 ? (address_size == 0
3889 ? printf ("%s+%#" PRIx64 " <%s>", scn, address, name)
3890 : printf ("%s+%#0*" PRIx64 " <%s>",
3891 scn, 2 + address_size * 2, address, name))
3892 : (address_size == 0
3893 ? printf ("%#" PRIx64 " <%s>", address, name)
3894 : printf ("%#0*" PRIx64 " <%s>",
3895 2 + address_size * 2, address, name))))
3896 : (scn != NULL
3897 ? (address_size == 0
3898 ? printf ("%s+%#" PRIx64, scn, address)
3899 : printf ("%s+%#0*" PRIx64, scn, 2 + address_size * 2, address))
3900 : (address_size == 0
3901 ? printf ("%#" PRIx64, address)
3902 : printf ("%#0*" PRIx64, 2 + address_size * 2, address)))) < 0)
3903 error_exit (0, _("sprintf failure"));
3904 }
3905
3906
3907 static const char *
dwarf_tag_string(unsigned int tag)3908 dwarf_tag_string (unsigned int tag)
3909 {
3910 switch (tag)
3911 {
3912 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3913 DWARF_ALL_KNOWN_DW_TAG
3914 #undef DWARF_ONE_KNOWN_DW_TAG
3915 default:
3916 return NULL;
3917 }
3918 }
3919
3920
3921 static const char *
dwarf_attr_string(unsigned int attrnum)3922 dwarf_attr_string (unsigned int attrnum)
3923 {
3924 switch (attrnum)
3925 {
3926 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3927 DWARF_ALL_KNOWN_DW_AT
3928 #undef DWARF_ONE_KNOWN_DW_AT
3929 default:
3930 return NULL;
3931 }
3932 }
3933
3934
3935 static const char *
dwarf_form_string(unsigned int form)3936 dwarf_form_string (unsigned int form)
3937 {
3938 switch (form)
3939 {
3940 #define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3941 DWARF_ALL_KNOWN_DW_FORM
3942 #undef DWARF_ONE_KNOWN_DW_FORM
3943 default:
3944 return NULL;
3945 }
3946 }
3947
3948
3949 static const char *
dwarf_lang_string(unsigned int lang)3950 dwarf_lang_string (unsigned int lang)
3951 {
3952 switch (lang)
3953 {
3954 #define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
3955 DWARF_ALL_KNOWN_DW_LANG
3956 #undef DWARF_ONE_KNOWN_DW_LANG
3957 default:
3958 return NULL;
3959 }
3960 }
3961
3962
3963 static const char *
dwarf_inline_string(unsigned int code)3964 dwarf_inline_string (unsigned int code)
3965 {
3966 static const char *const known[] =
3967 {
3968 #define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3969 DWARF_ALL_KNOWN_DW_INL
3970 #undef DWARF_ONE_KNOWN_DW_INL
3971 };
3972
3973 if (likely (code < sizeof (known) / sizeof (known[0])))
3974 return known[code];
3975
3976 return NULL;
3977 }
3978
3979
3980 static const char *
dwarf_encoding_string(unsigned int code)3981 dwarf_encoding_string (unsigned int code)
3982 {
3983 static const char *const known[] =
3984 {
3985 #define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3986 DWARF_ALL_KNOWN_DW_ATE
3987 #undef DWARF_ONE_KNOWN_DW_ATE
3988 };
3989
3990 if (likely (code < sizeof (known) / sizeof (known[0])))
3991 return known[code];
3992
3993 return NULL;
3994 }
3995
3996
3997 static const char *
dwarf_access_string(unsigned int code)3998 dwarf_access_string (unsigned int code)
3999 {
4000 static const char *const known[] =
4001 {
4002 #define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
4003 DWARF_ALL_KNOWN_DW_ACCESS
4004 #undef DWARF_ONE_KNOWN_DW_ACCESS
4005 };
4006
4007 if (likely (code < sizeof (known) / sizeof (known[0])))
4008 return known[code];
4009
4010 return NULL;
4011 }
4012
4013
4014 static const char *
dwarf_defaulted_string(unsigned int code)4015 dwarf_defaulted_string (unsigned int code)
4016 {
4017 static const char *const known[] =
4018 {
4019 #define DWARF_ONE_KNOWN_DW_DEFAULTED(NAME, CODE) [CODE] = #NAME,
4020 DWARF_ALL_KNOWN_DW_DEFAULTED
4021 #undef DWARF_ONE_KNOWN_DW_DEFAULTED
4022 };
4023
4024 if (likely (code < sizeof (known) / sizeof (known[0])))
4025 return known[code];
4026
4027 return NULL;
4028 }
4029
4030
4031 static const char *
dwarf_visibility_string(unsigned int code)4032 dwarf_visibility_string (unsigned int code)
4033 {
4034 static const char *const known[] =
4035 {
4036 #define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
4037 DWARF_ALL_KNOWN_DW_VIS
4038 #undef DWARF_ONE_KNOWN_DW_VIS
4039 };
4040
4041 if (likely (code < sizeof (known) / sizeof (known[0])))
4042 return known[code];
4043
4044 return NULL;
4045 }
4046
4047
4048 static const char *
dwarf_virtuality_string(unsigned int code)4049 dwarf_virtuality_string (unsigned int code)
4050 {
4051 static const char *const known[] =
4052 {
4053 #define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
4054 DWARF_ALL_KNOWN_DW_VIRTUALITY
4055 #undef DWARF_ONE_KNOWN_DW_VIRTUALITY
4056 };
4057
4058 if (likely (code < sizeof (known) / sizeof (known[0])))
4059 return known[code];
4060
4061 return NULL;
4062 }
4063
4064
4065 static const char *
dwarf_identifier_case_string(unsigned int code)4066 dwarf_identifier_case_string (unsigned int code)
4067 {
4068 static const char *const known[] =
4069 {
4070 #define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
4071 DWARF_ALL_KNOWN_DW_ID
4072 #undef DWARF_ONE_KNOWN_DW_ID
4073 };
4074
4075 if (likely (code < sizeof (known) / sizeof (known[0])))
4076 return known[code];
4077
4078 return NULL;
4079 }
4080
4081
4082 static const char *
dwarf_calling_convention_string(unsigned int code)4083 dwarf_calling_convention_string (unsigned int code)
4084 {
4085 static const char *const known[] =
4086 {
4087 #define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
4088 DWARF_ALL_KNOWN_DW_CC
4089 #undef DWARF_ONE_KNOWN_DW_CC
4090 };
4091
4092 if (likely (code < sizeof (known) / sizeof (known[0])))
4093 return known[code];
4094
4095 return NULL;
4096 }
4097
4098
4099 static const char *
dwarf_ordering_string(unsigned int code)4100 dwarf_ordering_string (unsigned int code)
4101 {
4102 static const char *const known[] =
4103 {
4104 #define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
4105 DWARF_ALL_KNOWN_DW_ORD
4106 #undef DWARF_ONE_KNOWN_DW_ORD
4107 };
4108
4109 if (likely (code < sizeof (known) / sizeof (known[0])))
4110 return known[code];
4111
4112 return NULL;
4113 }
4114
4115
4116 static const char *
dwarf_discr_list_string(unsigned int code)4117 dwarf_discr_list_string (unsigned int code)
4118 {
4119 static const char *const known[] =
4120 {
4121 #define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
4122 DWARF_ALL_KNOWN_DW_DSC
4123 #undef DWARF_ONE_KNOWN_DW_DSC
4124 };
4125
4126 if (likely (code < sizeof (known) / sizeof (known[0])))
4127 return known[code];
4128
4129 return NULL;
4130 }
4131
4132
4133 static const char *
dwarf_locexpr_opcode_string(unsigned int code)4134 dwarf_locexpr_opcode_string (unsigned int code)
4135 {
4136 static const char *const known[] =
4137 {
4138 /* Normally we can't afford building huge table of 64K entries,
4139 most of them zero, just because there are a couple defined
4140 values at the far end. In case of opcodes, it's OK. */
4141 #define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
4142 DWARF_ALL_KNOWN_DW_OP
4143 #undef DWARF_ONE_KNOWN_DW_OP
4144 };
4145
4146 if (likely (code < sizeof (known) / sizeof (known[0])))
4147 return known[code];
4148
4149 return NULL;
4150 }
4151
4152
4153 static const char *
dwarf_unit_string(unsigned int type)4154 dwarf_unit_string (unsigned int type)
4155 {
4156 switch (type)
4157 {
4158 #define DWARF_ONE_KNOWN_DW_UT(NAME, CODE) case CODE: return #NAME;
4159 DWARF_ALL_KNOWN_DW_UT
4160 #undef DWARF_ONE_KNOWN_DW_UT
4161 default:
4162 return NULL;
4163 }
4164 }
4165
4166
4167 static const char *
dwarf_range_list_encoding_string(unsigned int kind)4168 dwarf_range_list_encoding_string (unsigned int kind)
4169 {
4170 switch (kind)
4171 {
4172 #define DWARF_ONE_KNOWN_DW_RLE(NAME, CODE) case CODE: return #NAME;
4173 DWARF_ALL_KNOWN_DW_RLE
4174 #undef DWARF_ONE_KNOWN_DW_RLE
4175 default:
4176 return NULL;
4177 }
4178 }
4179
4180
4181 static const char *
dwarf_loc_list_encoding_string(unsigned int kind)4182 dwarf_loc_list_encoding_string (unsigned int kind)
4183 {
4184 switch (kind)
4185 {
4186 #define DWARF_ONE_KNOWN_DW_LLE(NAME, CODE) case CODE: return #NAME;
4187 DWARF_ALL_KNOWN_DW_LLE
4188 #undef DWARF_ONE_KNOWN_DW_LLE
4189 /* DW_LLE_GNU_view_pair is special/incompatible with default codes. */
4190 case DW_LLE_GNU_view_pair: return "GNU_view_pair";
4191 default:
4192 return NULL;
4193 }
4194 }
4195
4196
4197 static const char *
dwarf_line_content_description_string(unsigned int kind)4198 dwarf_line_content_description_string (unsigned int kind)
4199 {
4200 switch (kind)
4201 {
4202 #define DWARF_ONE_KNOWN_DW_LNCT(NAME, CODE) case CODE: return #NAME;
4203 DWARF_ALL_KNOWN_DW_LNCT
4204 #undef DWARF_ONE_KNOWN_DW_LNCT
4205 default:
4206 return NULL;
4207 }
4208 }
4209
4210
4211 /* Used by all dwarf_foo_name functions. */
4212 static const char *
string_or_unknown(const char * known,unsigned int code,unsigned int lo_user,unsigned int hi_user,bool print_unknown_num)4213 string_or_unknown (const char *known, unsigned int code,
4214 unsigned int lo_user, unsigned int hi_user,
4215 bool print_unknown_num)
4216 {
4217 static char unknown_buf[20];
4218
4219 if (likely (known != NULL))
4220 return known;
4221
4222 if (lo_user != 0 && code >= lo_user && code <= hi_user)
4223 {
4224 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
4225 code - lo_user);
4226 return unknown_buf;
4227 }
4228
4229 if (print_unknown_num)
4230 {
4231 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
4232 return unknown_buf;
4233 }
4234
4235 return "???";
4236 }
4237
4238
4239 static const char *
dwarf_tag_name(unsigned int tag)4240 dwarf_tag_name (unsigned int tag)
4241 {
4242 const char *ret = dwarf_tag_string (tag);
4243 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
4244 }
4245
4246 static const char *
dwarf_attr_name(unsigned int attr)4247 dwarf_attr_name (unsigned int attr)
4248 {
4249 const char *ret = dwarf_attr_string (attr);
4250 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
4251 }
4252
4253
4254 static const char *
dwarf_form_name(unsigned int form)4255 dwarf_form_name (unsigned int form)
4256 {
4257 const char *ret = dwarf_form_string (form);
4258 return string_or_unknown (ret, form, 0, 0, true);
4259 }
4260
4261
4262 static const char *
dwarf_lang_name(unsigned int lang)4263 dwarf_lang_name (unsigned int lang)
4264 {
4265 const char *ret = dwarf_lang_string (lang);
4266 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
4267 }
4268
4269
4270 static const char *
dwarf_inline_name(unsigned int code)4271 dwarf_inline_name (unsigned int code)
4272 {
4273 const char *ret = dwarf_inline_string (code);
4274 return string_or_unknown (ret, code, 0, 0, false);
4275 }
4276
4277
4278 static const char *
dwarf_encoding_name(unsigned int code)4279 dwarf_encoding_name (unsigned int code)
4280 {
4281 const char *ret = dwarf_encoding_string (code);
4282 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
4283 }
4284
4285
4286 static const char *
dwarf_access_name(unsigned int code)4287 dwarf_access_name (unsigned int code)
4288 {
4289 const char *ret = dwarf_access_string (code);
4290 return string_or_unknown (ret, code, 0, 0, false);
4291 }
4292
4293
4294 static const char *
dwarf_defaulted_name(unsigned int code)4295 dwarf_defaulted_name (unsigned int code)
4296 {
4297 const char *ret = dwarf_defaulted_string (code);
4298 return string_or_unknown (ret, code, 0, 0, false);
4299 }
4300
4301
4302 static const char *
dwarf_visibility_name(unsigned int code)4303 dwarf_visibility_name (unsigned int code)
4304 {
4305 const char *ret = dwarf_visibility_string (code);
4306 return string_or_unknown (ret, code, 0, 0, false);
4307 }
4308
4309
4310 static const char *
dwarf_virtuality_name(unsigned int code)4311 dwarf_virtuality_name (unsigned int code)
4312 {
4313 const char *ret = dwarf_virtuality_string (code);
4314 return string_or_unknown (ret, code, 0, 0, false);
4315 }
4316
4317
4318 static const char *
dwarf_identifier_case_name(unsigned int code)4319 dwarf_identifier_case_name (unsigned int code)
4320 {
4321 const char *ret = dwarf_identifier_case_string (code);
4322 return string_or_unknown (ret, code, 0, 0, false);
4323 }
4324
4325
4326 static const char *
dwarf_calling_convention_name(unsigned int code)4327 dwarf_calling_convention_name (unsigned int code)
4328 {
4329 const char *ret = dwarf_calling_convention_string (code);
4330 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
4331 }
4332
4333
4334 static const char *
dwarf_ordering_name(unsigned int code)4335 dwarf_ordering_name (unsigned int code)
4336 {
4337 const char *ret = dwarf_ordering_string (code);
4338 return string_or_unknown (ret, code, 0, 0, false);
4339 }
4340
4341
4342 static const char *
dwarf_discr_list_name(unsigned int code)4343 dwarf_discr_list_name (unsigned int code)
4344 {
4345 const char *ret = dwarf_discr_list_string (code);
4346 return string_or_unknown (ret, code, 0, 0, false);
4347 }
4348
4349
4350 static const char *
dwarf_unit_name(unsigned int type)4351 dwarf_unit_name (unsigned int type)
4352 {
4353 const char *ret = dwarf_unit_string (type);
4354 return string_or_unknown (ret, type, DW_UT_lo_user, DW_UT_hi_user, true);
4355 }
4356
4357
4358 static const char *
dwarf_range_list_encoding_name(unsigned int kind)4359 dwarf_range_list_encoding_name (unsigned int kind)
4360 {
4361 const char *ret = dwarf_range_list_encoding_string (kind);
4362 return string_or_unknown (ret, kind, 0, 0, false);
4363 }
4364
4365
4366 static const char *
dwarf_loc_list_encoding_name(unsigned int kind)4367 dwarf_loc_list_encoding_name (unsigned int kind)
4368 {
4369 const char *ret = dwarf_loc_list_encoding_string (kind);
4370 return string_or_unknown (ret, kind, 0, 0, false);
4371 }
4372
4373
4374 static const char *
dwarf_line_content_description_name(unsigned int kind)4375 dwarf_line_content_description_name (unsigned int kind)
4376 {
4377 const char *ret = dwarf_line_content_description_string (kind);
4378 return string_or_unknown (ret, kind, DW_LNCT_lo_user, DW_LNCT_hi_user,
4379 false);
4380 }
4381
4382
4383 static void
print_block(size_t n,const void * block)4384 print_block (size_t n, const void *block)
4385 {
4386 if (n == 0)
4387 puts (_("empty block"));
4388 else
4389 {
4390 printf (_("%zu byte block:"), n);
4391 const unsigned char *data = block;
4392 do
4393 printf (" %02x", *data++);
4394 while (--n > 0);
4395 putchar ('\n');
4396 }
4397 }
4398
4399 static void
print_bytes(size_t n,const unsigned char * bytes)4400 print_bytes (size_t n, const unsigned char *bytes)
4401 {
4402 while (n-- > 0)
4403 {
4404 printf ("%02x", *bytes++);
4405 if (n > 0)
4406 printf (" ");
4407 }
4408 }
4409
4410 static int
get_indexed_addr(Dwarf_CU * cu,Dwarf_Word idx,Dwarf_Addr * addr)4411 get_indexed_addr (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
4412 {
4413 if (cu == NULL)
4414 return -1;
4415
4416 Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
4417 if (debug_addr == NULL)
4418 return -1;
4419
4420 Dwarf_Off base = __libdw_cu_addr_base (cu);
4421 Dwarf_Word off = idx * cu->address_size;
4422 if (base > debug_addr->d_size
4423 || off > debug_addr->d_size - base
4424 || cu->address_size > debug_addr->d_size - base - off)
4425 return -1;
4426
4427 const unsigned char *addrp = debug_addr->d_buf + base + off;
4428 if (cu->address_size == 4)
4429 *addr = read_4ubyte_unaligned (cu->dbg, addrp);
4430 else
4431 *addr = read_8ubyte_unaligned (cu->dbg, addrp);
4432
4433 return 0;
4434 }
4435
4436 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)4437 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
4438 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
4439 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
4440 {
4441 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
4442
4443 if (len == 0)
4444 {
4445 printf ("%*s(empty)\n", indent, "");
4446 return;
4447 }
4448
4449 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
4450 #define CONSUME(n) NEED (n); else len -= (n)
4451
4452 Dwarf_Word offset = 0;
4453 while (len-- > 0)
4454 {
4455 uint_fast8_t op = *data++;
4456
4457 const char *op_name = dwarf_locexpr_opcode_string (op);
4458 if (unlikely (op_name == NULL))
4459 {
4460 static char buf[20];
4461 if (op >= DW_OP_lo_user)
4462 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
4463 else
4464 snprintf (buf, sizeof buf, "??? (%#x)", op);
4465 op_name = buf;
4466 }
4467
4468 switch (op)
4469 {
4470 case DW_OP_addr:;
4471 /* Address operand. */
4472 Dwarf_Word addr;
4473 NEED (addrsize);
4474 if (addrsize == 4)
4475 addr = read_4ubyte_unaligned (dbg, data);
4476 else if (addrsize == 8)
4477 addr = read_8ubyte_unaligned (dbg, data);
4478 else
4479 goto invalid;
4480 data += addrsize;
4481 CONSUME (addrsize);
4482
4483 printf ("%*s[%2" PRIuMAX "] %s ",
4484 indent, "", (uintmax_t) offset, op_name);
4485 print_dwarf_addr (dwflmod, 0, addr, addr);
4486 printf ("\n");
4487
4488 offset += 1 + addrsize;
4489 break;
4490
4491 case DW_OP_call_ref:
4492 case DW_OP_GNU_variable_value:
4493 /* Offset operand. */
4494 if (ref_size != 4 && ref_size != 8)
4495 goto invalid; /* Cannot be used in CFA. */
4496 NEED (ref_size);
4497 if (ref_size == 4)
4498 addr = read_4ubyte_unaligned (dbg, data);
4499 else
4500 addr = read_8ubyte_unaligned (dbg, data);
4501 data += ref_size;
4502 CONSUME (ref_size);
4503 /* addr is a DIE offset, so format it as one. */
4504 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4505 indent, "", (uintmax_t) offset,
4506 op_name, (uintmax_t) addr);
4507 offset += 1 + ref_size;
4508 break;
4509
4510 case DW_OP_deref_size:
4511 case DW_OP_xderef_size:
4512 case DW_OP_pick:
4513 case DW_OP_const1u:
4514 // XXX value might be modified by relocation
4515 NEED (1);
4516 printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 "\n",
4517 indent, "", (uintmax_t) offset,
4518 op_name, *((uint8_t *) data));
4519 ++data;
4520 --len;
4521 offset += 2;
4522 break;
4523
4524 case DW_OP_const2u:
4525 NEED (2);
4526 // XXX value might be modified by relocation
4527 printf ("%*s[%2" PRIuMAX "] %s %" PRIu16 "\n",
4528 indent, "", (uintmax_t) offset,
4529 op_name, read_2ubyte_unaligned (dbg, data));
4530 CONSUME (2);
4531 data += 2;
4532 offset += 3;
4533 break;
4534
4535 case DW_OP_const4u:
4536 NEED (4);
4537 // XXX value might be modified by relocation
4538 printf ("%*s[%2" PRIuMAX "] %s %" PRIu32 "\n",
4539 indent, "", (uintmax_t) offset,
4540 op_name, read_4ubyte_unaligned (dbg, data));
4541 CONSUME (4);
4542 data += 4;
4543 offset += 5;
4544 break;
4545
4546 case DW_OP_const8u:
4547 NEED (8);
4548 // XXX value might be modified by relocation
4549 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4550 indent, "", (uintmax_t) offset,
4551 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4552 CONSUME (8);
4553 data += 8;
4554 offset += 9;
4555 break;
4556
4557 case DW_OP_const1s:
4558 NEED (1);
4559 // XXX value might be modified by relocation
4560 printf ("%*s[%2" PRIuMAX "] %s %" PRId8 "\n",
4561 indent, "", (uintmax_t) offset,
4562 op_name, *((int8_t *) data));
4563 ++data;
4564 --len;
4565 offset += 2;
4566 break;
4567
4568 case DW_OP_const2s:
4569 NEED (2);
4570 // XXX value might be modified by relocation
4571 printf ("%*s[%2" PRIuMAX "] %s %" PRId16 "\n",
4572 indent, "", (uintmax_t) offset,
4573 op_name, read_2sbyte_unaligned (dbg, data));
4574 CONSUME (2);
4575 data += 2;
4576 offset += 3;
4577 break;
4578
4579 case DW_OP_const4s:
4580 NEED (4);
4581 // XXX value might be modified by relocation
4582 printf ("%*s[%2" PRIuMAX "] %s %" PRId32 "\n",
4583 indent, "", (uintmax_t) offset,
4584 op_name, read_4sbyte_unaligned (dbg, data));
4585 CONSUME (4);
4586 data += 4;
4587 offset += 5;
4588 break;
4589
4590 case DW_OP_const8s:
4591 NEED (8);
4592 // XXX value might be modified by relocation
4593 printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4594 indent, "", (uintmax_t) offset,
4595 op_name, read_8sbyte_unaligned (dbg, data));
4596 CONSUME (8);
4597 data += 8;
4598 offset += 9;
4599 break;
4600
4601 case DW_OP_piece:
4602 case DW_OP_regx:
4603 case DW_OP_plus_uconst:
4604 case DW_OP_constu:;
4605 const unsigned char *start = data;
4606 uint64_t uleb;
4607 NEED (1);
4608 get_uleb128 (uleb, data, data + len);
4609 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4610 indent, "", (uintmax_t) offset, op_name, uleb);
4611 CONSUME (data - start);
4612 offset += 1 + (data - start);
4613 break;
4614
4615 case DW_OP_addrx:
4616 case DW_OP_GNU_addr_index:
4617 case DW_OP_constx:
4618 case DW_OP_GNU_const_index:;
4619 start = data;
4620 NEED (1);
4621 get_uleb128 (uleb, data, data + len);
4622 printf ("%*s[%2" PRIuMAX "] %s [%" PRIu64 "] ",
4623 indent, "", (uintmax_t) offset, op_name, uleb);
4624 CONSUME (data - start);
4625 offset += 1 + (data - start);
4626 if (get_indexed_addr (cu, uleb, &addr) != 0)
4627 printf ("???\n");
4628 else
4629 {
4630 print_dwarf_addr (dwflmod, 0, addr, addr);
4631 printf ("\n");
4632 }
4633 break;
4634
4635 case DW_OP_bit_piece:
4636 start = data;
4637 uint64_t uleb2;
4638 NEED (1);
4639 get_uleb128 (uleb, data, data + len);
4640 NEED (1);
4641 get_uleb128 (uleb2, data, data + len);
4642 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4643 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4644 CONSUME (data - start);
4645 offset += 1 + (data - start);
4646 break;
4647
4648 case DW_OP_fbreg:
4649 case DW_OP_breg0 ... DW_OP_breg31:
4650 case DW_OP_consts:
4651 start = data;
4652 int64_t sleb;
4653 NEED (1);
4654 get_sleb128 (sleb, data, data + len);
4655 printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4656 indent, "", (uintmax_t) offset, op_name, sleb);
4657 CONSUME (data - start);
4658 offset += 1 + (data - start);
4659 break;
4660
4661 case DW_OP_bregx:
4662 start = data;
4663 NEED (1);
4664 get_uleb128 (uleb, data, data + len);
4665 NEED (1);
4666 get_sleb128 (sleb, data, data + len);
4667 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4668 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4669 CONSUME (data - start);
4670 offset += 1 + (data - start);
4671 break;
4672
4673 case DW_OP_call2:
4674 NEED (2);
4675 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx16 "]\n",
4676 indent, "", (uintmax_t) offset, op_name,
4677 read_2ubyte_unaligned (dbg, data));
4678 CONSUME (2);
4679 data += 2;
4680 offset += 3;
4681 break;
4682
4683 case DW_OP_call4:
4684 NEED (4);
4685 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx32 "]\n",
4686 indent, "", (uintmax_t) offset, op_name,
4687 read_4ubyte_unaligned (dbg, data));
4688 CONSUME (4);
4689 data += 4;
4690 offset += 5;
4691 break;
4692
4693 case DW_OP_skip:
4694 case DW_OP_bra:
4695 NEED (2);
4696 printf ("%*s[%2" PRIuMAX "] %s %" PRIuMAX "\n",
4697 indent, "", (uintmax_t) offset, op_name,
4698 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4699 CONSUME (2);
4700 data += 2;
4701 offset += 3;
4702 break;
4703
4704 case DW_OP_implicit_value:
4705 start = data;
4706 NEED (1);
4707 get_uleb128 (uleb, data, data + len);
4708 printf ("%*s[%2" PRIuMAX "] %s: ",
4709 indent, "", (uintmax_t) offset, op_name);
4710 NEED (uleb);
4711 print_block (uleb, data);
4712 data += uleb;
4713 CONSUME (data - start);
4714 offset += 1 + (data - start);
4715 break;
4716
4717 case DW_OP_implicit_pointer:
4718 case DW_OP_GNU_implicit_pointer:
4719 /* DIE offset operand. */
4720 start = data;
4721 NEED (ref_size);
4722 if (ref_size != 4 && ref_size != 8)
4723 goto invalid; /* Cannot be used in CFA. */
4724 if (ref_size == 4)
4725 addr = read_4ubyte_unaligned (dbg, data);
4726 else
4727 addr = read_8ubyte_unaligned (dbg, data);
4728 data += ref_size;
4729 /* Byte offset operand. */
4730 NEED (1);
4731 get_sleb128 (sleb, data, data + len);
4732
4733 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4734 indent, "", (intmax_t) offset,
4735 op_name, (uintmax_t) addr, sleb);
4736 CONSUME (data - start);
4737 offset += 1 + (data - start);
4738 break;
4739
4740 case DW_OP_entry_value:
4741 case DW_OP_GNU_entry_value:
4742 /* Size plus expression block. */
4743 start = data;
4744 NEED (1);
4745 get_uleb128 (uleb, data, data + len);
4746 printf ("%*s[%2" PRIuMAX "] %s:\n",
4747 indent, "", (uintmax_t) offset, op_name);
4748 NEED (uleb);
4749 print_ops (dwflmod, dbg, indent + 5, indent + 5, vers,
4750 addrsize, offset_size, cu, uleb, data);
4751 data += uleb;
4752 CONSUME (data - start);
4753 offset += 1 + (data - start);
4754 break;
4755
4756 case DW_OP_const_type:
4757 case DW_OP_GNU_const_type:
4758 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4759 unsigned size plus block. */
4760 start = data;
4761 NEED (1);
4762 get_uleb128 (uleb, data, data + len);
4763 if (! print_unresolved_addresses && cu != NULL)
4764 uleb += cu->start;
4765 NEED (1);
4766 uint8_t usize = *(uint8_t *) data++;
4767 NEED (usize);
4768 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] ",
4769 indent, "", (uintmax_t) offset, op_name, uleb);
4770 print_block (usize, data);
4771 data += usize;
4772 CONSUME (data - start);
4773 offset += 1 + (data - start);
4774 break;
4775
4776 case DW_OP_regval_type:
4777 case DW_OP_GNU_regval_type:
4778 /* uleb128 register number, uleb128 CU relative
4779 DW_TAG_base_type DIE offset. */
4780 start = data;
4781 NEED (1);
4782 get_uleb128 (uleb, data, data + len);
4783 NEED (1);
4784 get_uleb128 (uleb2, data, data + len);
4785 if (! print_unresolved_addresses && cu != NULL)
4786 uleb2 += cu->start;
4787 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4788 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4789 CONSUME (data - start);
4790 offset += 1 + (data - start);
4791 break;
4792
4793 case DW_OP_deref_type:
4794 case DW_OP_GNU_deref_type:
4795 /* 1-byte unsigned size of value, uleb128 CU relative
4796 DW_TAG_base_type DIE offset. */
4797 start = data;
4798 NEED (1);
4799 usize = *(uint8_t *) data++;
4800 NEED (1);
4801 get_uleb128 (uleb, data, data + len);
4802 if (! print_unresolved_addresses && cu != NULL)
4803 uleb += cu->start;
4804 printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4805 indent, "", (uintmax_t) offset,
4806 op_name, usize, uleb);
4807 CONSUME (data - start);
4808 offset += 1 + (data - start);
4809 break;
4810
4811 case DW_OP_xderef_type:
4812 /* 1-byte unsigned size of value, uleb128 base_type DIE offset. */
4813 start = data;
4814 NEED (1);
4815 usize = *(uint8_t *) data++;
4816 NEED (1);
4817 get_uleb128 (uleb, data, data + len);
4818 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4819 indent, "", (uintmax_t) offset,
4820 op_name, usize, uleb);
4821 CONSUME (data - start);
4822 offset += 1 + (data - start);
4823 break;
4824
4825 case DW_OP_convert:
4826 case DW_OP_GNU_convert:
4827 case DW_OP_reinterpret:
4828 case DW_OP_GNU_reinterpret:
4829 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4830 for conversion to untyped. */
4831 start = data;
4832 NEED (1);
4833 get_uleb128 (uleb, data, data + len);
4834 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4835 uleb += cu->start;
4836 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4837 indent, "", (uintmax_t) offset, op_name, uleb);
4838 CONSUME (data - start);
4839 offset += 1 + (data - start);
4840 break;
4841
4842 case DW_OP_GNU_parameter_ref:
4843 /* 4 byte CU relative reference to the abstract optimized away
4844 DW_TAG_formal_parameter. */
4845 NEED (4);
4846 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4847 if (! print_unresolved_addresses && cu != NULL)
4848 param_off += cu->start;
4849 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4850 indent, "", (uintmax_t) offset, op_name, param_off);
4851 CONSUME (4);
4852 data += 4;
4853 offset += 5;
4854 break;
4855
4856 default:
4857 /* No Operand. */
4858 printf ("%*s[%2" PRIuMAX "] %s\n",
4859 indent, "", (uintmax_t) offset, op_name);
4860 ++offset;
4861 break;
4862 }
4863
4864 indent = indentrest;
4865 continue;
4866
4867 invalid:
4868 printf (_("%*s[%2" PRIuMAX "] %s <TRUNCATED>\n"),
4869 indent, "", (uintmax_t) offset, op_name);
4870 break;
4871 }
4872 }
4873
4874
4875 /* Turn the addresses into file offsets by using the phdrs. */
4876 static void
find_offsets(Elf * elf,GElf_Addr main_bias,size_t n,GElf_Addr addrs[n],GElf_Off offs[n])4877 find_offsets(Elf *elf, GElf_Addr main_bias, size_t n,
4878 GElf_Addr addrs[n], GElf_Off offs[n])
4879 {
4880 size_t unsolved = n;
4881 for (size_t i = 0; i < phnum; ++i) {
4882 GElf_Phdr phdr_mem;
4883 GElf_Phdr *phdr = gelf_getphdr(elf, i, &phdr_mem);
4884 if (phdr != NULL && phdr->p_type == PT_LOAD && phdr->p_memsz > 0)
4885 for (size_t j = 0; j < n; ++j)
4886 if (offs[j] == 0 && addrs[j] >= phdr->p_vaddr + main_bias &&
4887 addrs[j] - (phdr->p_vaddr + main_bias) < phdr->p_filesz) {
4888 offs[j] = addrs[j] - (phdr->p_vaddr + main_bias) + phdr->p_offset;
4889 if (--unsolved == 0)
4890 break;
4891 }
4892 }
4893 }
4894
4895 /* The dynamic segment (type PT_DYNAMIC), contains the .dynamic section.
4896 And .dynamic section contains an array of the dynamic structures.
4897 We use the array to get:
4898 DT_STRTAB: the address of the string table
4899 DT_SYMTAB: the address of the symbol table
4900 DT_STRSZ: the size, in bytes, of the string table
4901 ... */
4902 static void
get_dynscn_addrs(Elf * elf,GElf_Phdr * phdr,GElf_Addr addrs[i_max])4903 get_dynscn_addrs(Elf *elf, GElf_Phdr *phdr, GElf_Addr addrs[i_max])
4904 {
4905 Elf_Data *data = elf_getdata_rawchunk(
4906 elf, phdr->p_offset, phdr->p_filesz, ELF_T_DYN);
4907
4908 int dyn_idx = 0;
4909 for (;; ++dyn_idx) {
4910 GElf_Dyn dyn_mem;
4911 GElf_Dyn *dyn = gelf_getdyn(data, dyn_idx, &dyn_mem);
4912 /* DT_NULL Marks end of dynamic section. */
4913 if (dyn->d_tag == DT_NULL)
4914 break;
4915
4916 switch (dyn->d_tag) {
4917 case DT_SYMTAB:
4918 addrs[i_symtab] = dyn->d_un.d_ptr;
4919 break;
4920
4921 case DT_HASH:
4922 addrs[i_hash] = dyn->d_un.d_ptr;
4923 break;
4924
4925 case DT_GNU_HASH:
4926 addrs[i_gnu_hash] = dyn->d_un.d_ptr;
4927 break;
4928
4929 case DT_STRTAB:
4930 addrs[i_strtab] = dyn->d_un.d_ptr;
4931 break;
4932
4933 case DT_VERSYM:
4934 addrs[i_versym] = dyn->d_un.d_ptr;
4935 break;
4936
4937 case DT_VERDEF:
4938 addrs[i_verdef] = dyn->d_un.d_ptr;
4939 break;
4940
4941 case DT_VERNEED:
4942 addrs[i_verneed] = dyn->d_un.d_ptr;
4943 break;
4944
4945 case DT_STRSZ:
4946 addrs[i_strsz] = dyn->d_un.d_val;
4947 break;
4948 }
4949 }
4950 }
4951
4952
4953 /* Use dynamic segment to get data for the string table section. */
4954 static Elf_Data *
get_dynscn_strtab(Elf * elf,GElf_Phdr * phdr)4955 get_dynscn_strtab(Elf *elf, GElf_Phdr *phdr)
4956 {
4957 Elf_Data *strtab_data;
4958 GElf_Addr addrs[i_max] = {0,};
4959 GElf_Off offs[i_max] = {0,};
4960 get_dynscn_addrs(elf, phdr, addrs);
4961 find_offsets(elf, 0, i_max, addrs, offs);
4962 strtab_data = elf_getdata_rawchunk(
4963 elf, offs[i_strtab], addrs[i_strsz], ELF_T_BYTE);
4964 return strtab_data;
4965 }
4966
4967
4968 struct listptr
4969 {
4970 Dwarf_Off offset:(64 - 3);
4971 bool addr64:1;
4972 bool dwarf64:1;
4973 bool warned:1;
4974 struct Dwarf_CU *cu;
4975 unsigned int attr;
4976 };
4977
4978 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4979 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4980
4981 static Dwarf_Addr
cudie_base(Dwarf_Die * cudie)4982 cudie_base (Dwarf_Die *cudie)
4983 {
4984 Dwarf_Addr base;
4985 /* Find the base address of the compilation unit. It will normally
4986 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4987 address could be overridden by DW_AT_entry_pc. It's been
4988 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4989 compilation units with discontinuous ranges. */
4990 if (unlikely (dwarf_lowpc (cudie, &base) != 0))
4991 {
4992 Dwarf_Attribute attr_mem;
4993 if (dwarf_formaddr (dwarf_attr (cudie, DW_AT_entry_pc, &attr_mem),
4994 &base) != 0)
4995 base = 0;
4996 }
4997 return base;
4998 }
4999
5000 static Dwarf_Addr
listptr_base(struct listptr * p)5001 listptr_base (struct listptr *p)
5002 {
5003 Dwarf_Die cu = CUDIE (p->cu);
5004 return cudie_base (&cu);
5005 }
5006
5007 /* To store the name used in compare_listptr */
5008 static const char *sort_listptr_name;
5009
5010 static int
compare_listptr(const void * a,const void * b)5011 compare_listptr (const void *a, const void *b)
5012 {
5013 const char *name = sort_listptr_name;
5014 struct listptr *p1 = (void *) a;
5015 struct listptr *p2 = (void *) b;
5016
5017 if (p1->offset < p2->offset)
5018 return -1;
5019 if (p1->offset > p2->offset)
5020 return 1;
5021
5022 if (!p1->warned && !p2->warned)
5023 {
5024 if (p1->addr64 != p2->addr64)
5025 {
5026 p1->warned = p2->warned = true;
5027 error (0, 0,
5028 _("%s %#" PRIx64 " used with different address sizes"),
5029 name, (uint64_t) p1->offset);
5030 }
5031 if (p1->dwarf64 != p2->dwarf64)
5032 {
5033 p1->warned = p2->warned = true;
5034 error (0, 0,
5035 _("%s %#" PRIx64 " used with different offset sizes"),
5036 name, (uint64_t) p1->offset);
5037 }
5038 if (listptr_base (p1) != listptr_base (p2))
5039 {
5040 p1->warned = p2->warned = true;
5041 error (0, 0,
5042 _("%s %#" PRIx64 " used with different base addresses"),
5043 name, (uint64_t) p1->offset);
5044 }
5045 if (p1->attr != p2 ->attr)
5046 {
5047 p1->warned = p2->warned = true;
5048 error (0, 0,
5049 _("%s %#" PRIx64
5050 " used with different attribute %s and %s"),
5051 name, (uint64_t) p1->offset, dwarf_attr_name (p1->attr),
5052 dwarf_attr_name (p2->attr));
5053 }
5054 }
5055
5056 return 0;
5057 }
5058
5059 struct listptr_table
5060 {
5061 size_t n;
5062 size_t alloc;
5063 struct listptr *table;
5064 };
5065
5066 static struct listptr_table known_locsptr;
5067 static struct listptr_table known_loclistsptr;
5068 static struct listptr_table known_rangelistptr;
5069 static struct listptr_table known_rnglistptr;
5070 static struct listptr_table known_addrbases;
5071 static struct listptr_table known_stroffbases;
5072
5073 static void
reset_listptr(struct listptr_table * table)5074 reset_listptr (struct listptr_table *table)
5075 {
5076 free (table->table);
5077 table->table = NULL;
5078 table->n = table->alloc = 0;
5079 }
5080
5081 /* Returns false if offset doesn't fit. See struct listptr. */
5082 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)5083 notice_listptr (enum section_e section, struct listptr_table *table,
5084 uint_fast8_t address_size, uint_fast8_t offset_size,
5085 struct Dwarf_CU *cu, Dwarf_Off offset, unsigned int attr)
5086 {
5087 if (print_debug_sections & section)
5088 {
5089 if (table->n == table->alloc)
5090 {
5091 if (table->alloc == 0)
5092 table->alloc = 128;
5093 else
5094 table->alloc *= 2;
5095 table->table = xrealloc (table->table,
5096 table->alloc * sizeof table->table[0]);
5097 }
5098
5099 struct listptr *p = &table->table[table->n++];
5100
5101 *p = (struct listptr)
5102 {
5103 .addr64 = address_size == 8,
5104 .dwarf64 = offset_size == 8,
5105 .offset = offset,
5106 .cu = cu,
5107 .attr = attr
5108 };
5109
5110 if (p->offset != offset)
5111 {
5112 table->n--;
5113 return false;
5114 }
5115 }
5116 return true;
5117 }
5118
5119 static void
sort_listptr(struct listptr_table * table,const char * name)5120 sort_listptr (struct listptr_table *table, const char *name)
5121 {
5122 if (table->n > 0)
5123 {
5124 sort_listptr_name = name;
5125 qsort (table->table, table->n, sizeof table->table[0],
5126 &compare_listptr);
5127 }
5128 }
5129
5130 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)5131 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
5132 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
5133 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
5134 unsigned char **readp, unsigned char *endp,
5135 unsigned int *attr)
5136 {
5137 if (table->n == 0)
5138 return false;
5139
5140 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
5141 ++*idxp;
5142
5143 struct listptr *p = &table->table[*idxp];
5144
5145 if (*idxp == table->n
5146 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
5147 {
5148 *readp = endp;
5149 printf (_(" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
5150 offset);
5151 return true;
5152 }
5153
5154 if (p->offset != (Dwarf_Off) offset)
5155 {
5156 *readp += p->offset - offset;
5157 printf (_(" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
5158 offset, (Dwarf_Off) p->offset - offset);
5159 return true;
5160 }
5161
5162 if (address_sizep != NULL)
5163 *address_sizep = listptr_address_size (p);
5164 if (offset_sizep != NULL)
5165 *offset_sizep = listptr_offset_size (p);
5166 if (base != NULL)
5167 *base = listptr_base (p);
5168 if (cu != NULL)
5169 *cu = p->cu;
5170 if (attr != NULL)
5171 *attr = p->attr;
5172
5173 return false;
5174 }
5175
5176 static Dwarf_Off
next_listptr_offset(struct listptr_table * table,size_t * idxp,Dwarf_Off off)5177 next_listptr_offset (struct listptr_table *table, size_t *idxp, Dwarf_Off off)
5178 {
5179 /* Note that multiple attributes could in theory point to the same loclist
5180 offset, so make sure we pick one that is bigger than the current one.
5181 The table is sorted on offset. */
5182 if (*idxp < table->n)
5183 {
5184 while (++*idxp < table->n)
5185 {
5186 Dwarf_Off next = table->table[*idxp].offset;
5187 if (next > off)
5188 return next;
5189 }
5190 }
5191 return 0;
5192 }
5193
5194 /* Returns the listptr associated with the given index, or NULL. */
5195 static struct listptr *
get_listptr(struct listptr_table * table,size_t idx)5196 get_listptr (struct listptr_table *table, size_t idx)
5197 {
5198 if (idx >= table->n)
5199 return NULL;
5200 return &table->table[idx];
5201 }
5202
5203 /* Returns the next index, base address and CU associated with the
5204 list unit offsets. If there is none false is returned, otherwise
5205 true. Assumes the table has been sorted. */
5206 static bool
listptr_cu(struct listptr_table * table,size_t * idxp,Dwarf_Off start,Dwarf_Off end,Dwarf_Addr * base,struct Dwarf_CU ** cu)5207 listptr_cu (struct listptr_table *table, size_t *idxp,
5208 Dwarf_Off start, Dwarf_Off end,
5209 Dwarf_Addr *base, struct Dwarf_CU **cu)
5210 {
5211 while (*idxp < table->n
5212 && table->table[*idxp].offset < start)
5213 ++*idxp;
5214
5215 if (*idxp < table->n
5216 && table->table[*idxp].offset >= start
5217 && table->table[*idxp].offset < end)
5218 {
5219 struct listptr *p = &table->table[*idxp];
5220 *base = listptr_base (p);
5221 *cu = p->cu;
5222 return true;
5223 }
5224
5225 return false;
5226 }
5227
5228 /* Returns the next index with the current CU for the given attribute.
5229 If there is none false is returned, otherwise true. Assumes the
5230 table has been sorted. */
5231 static bool
listptr_attr(struct listptr_table * table,size_t idxp,Dwarf_Off offset,unsigned int attr)5232 listptr_attr (struct listptr_table *table, size_t idxp,
5233 Dwarf_Off offset, unsigned int attr)
5234 {
5235 struct listptr *listptr;
5236 do
5237 {
5238 listptr = get_listptr (table, idxp);
5239 if (listptr == NULL)
5240 return false;
5241
5242 if (listptr->offset == offset && listptr->attr == attr)
5243 return true;
5244
5245 idxp++;
5246 }
5247 while (listptr->offset <= offset);
5248
5249 return false;
5250 }
5251
5252 static void
print_debug_abbrev_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5253 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5254 Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
5255 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5256 {
5257 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
5258 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
5259
5260 printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
5261 " [ Code]\n"),
5262 elf_ndxscn (scn), section_name (ebl, shdr),
5263 (uint64_t) shdr->sh_offset);
5264
5265 Dwarf_Off offset = 0;
5266 while (offset < sh_size)
5267 {
5268 printf (_("\nAbbreviation section at offset %" PRIu64 ":\n"),
5269 offset);
5270
5271 while (1)
5272 {
5273 size_t length;
5274 Dwarf_Abbrev abbrev;
5275
5276 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
5277 if (res != 0)
5278 {
5279 if (unlikely (res < 0))
5280 {
5281 printf (_("\
5282 *** error while reading abbreviation: %s\n"),
5283 dwarf_errmsg (-1));
5284 return;
5285 }
5286
5287 /* This is the NUL byte at the end of the section. */
5288 ++offset;
5289 break;
5290 }
5291
5292 /* We know these calls can never fail. */
5293 unsigned int code = dwarf_getabbrevcode (&abbrev);
5294 unsigned int tag = dwarf_getabbrevtag (&abbrev);
5295 int has_children = dwarf_abbrevhaschildren (&abbrev);
5296
5297 printf (_(" [%5u] offset: %" PRId64
5298 ", children: %s, tag: %s\n"),
5299 code, (int64_t) offset,
5300 has_children ? yes_str : no_str,
5301 dwarf_tag_name (tag));
5302
5303 size_t cnt = 0;
5304 unsigned int name;
5305 unsigned int form;
5306 Dwarf_Sword data;
5307 Dwarf_Off enoffset;
5308 while (dwarf_getabbrevattr_data (&abbrev, cnt, &name, &form,
5309 &data, &enoffset) == 0)
5310 {
5311 printf (" attr: %s, form: %s",
5312 dwarf_attr_name (name), dwarf_form_name (form));
5313 if (form == DW_FORM_implicit_const)
5314 printf (" (%" PRId64 ")", data);
5315 printf (", offset: %#" PRIx64 "\n", (uint64_t) enoffset);
5316 ++cnt;
5317 }
5318
5319 offset += length;
5320 }
5321 }
5322 }
5323
5324
5325 static void
print_debug_addr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5326 print_debug_addr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5327 Ebl *ebl, GElf_Ehdr *ehdr,
5328 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5329 {
5330 printf (_("\
5331 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5332 elf_ndxscn (scn), section_name (ebl, shdr),
5333 (uint64_t) shdr->sh_offset);
5334
5335 if (shdr->sh_size == 0)
5336 return;
5337
5338 /* We like to get the section from libdw to make sure they are relocated. */
5339 Elf_Data *data = (dbg->sectiondata[IDX_debug_addr]
5340 ?: elf_rawdata (scn, NULL));
5341 if (unlikely (data == NULL))
5342 {
5343 error (0, 0, _("cannot get .debug_addr section data: %s"),
5344 elf_errmsg (-1));
5345 return;
5346 }
5347
5348 size_t idx = 0;
5349 sort_listptr (&known_addrbases, "addr_base");
5350
5351 const unsigned char *start = (const unsigned char *) data->d_buf;
5352 const unsigned char *readp = start;
5353 const unsigned char *readendp = ((const unsigned char *) data->d_buf
5354 + data->d_size);
5355
5356 while (readp < readendp)
5357 {
5358 /* We cannot really know whether or not there is an header. The
5359 DebugFission extension to DWARF4 doesn't add one. The DWARF5
5360 .debug_addr variant does. Whether or not we have an header,
5361 DW_AT_[GNU_]addr_base points at "index 0". So if the current
5362 offset equals the CU addr_base then we can just start
5363 printing addresses. If there is no CU with an exact match
5364 then we'll try to parse the header first. */
5365 Dwarf_Off off = (Dwarf_Off) (readp
5366 - (const unsigned char *) data->d_buf);
5367
5368 printf ("Table at offset %" PRIx64 " ", off);
5369
5370 struct listptr *listptr = get_listptr (&known_addrbases, idx++);
5371 const unsigned char *next_unitp;
5372
5373 uint64_t unit_length;
5374 uint16_t version;
5375 uint8_t address_size;
5376 uint8_t segment_size;
5377 if (listptr == NULL)
5378 {
5379 error (0, 0, "Warning: No CU references .debug_addr after %" PRIx64,
5380 off);
5381
5382 /* We will have to assume it is just addresses to the end... */
5383 address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5384 next_unitp = readendp;
5385 printf ("Unknown CU:\n");
5386 }
5387 else
5388 {
5389 Dwarf_Die cudie;
5390 if (dwarf_cu_die (listptr->cu, &cudie,
5391 NULL, NULL, NULL, NULL,
5392 NULL, NULL) == NULL)
5393 printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
5394 else
5395 printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
5396
5397 if (listptr->offset == off)
5398 {
5399 address_size = listptr_address_size (listptr);
5400 segment_size = 0;
5401 version = 4;
5402
5403 /* The addresses start here, but where do they end? */
5404 listptr = get_listptr (&known_addrbases, idx);
5405 if (listptr == NULL)
5406 next_unitp = readendp;
5407 else if (listptr->cu->version < 5)
5408 {
5409 next_unitp = start + listptr->offset;
5410 if (listptr->offset < off || listptr->offset > data->d_size)
5411 {
5412 error (0, 0,
5413 "Warning: Bad address base for next unit at %"
5414 PRIx64, off);
5415 next_unitp = readendp;
5416 }
5417 }
5418 else
5419 {
5420 /* Tricky, we don't have a header for this unit, but
5421 there is one for the next. We will have to
5422 "guess" how big it is and subtract it from the
5423 offset (because that points after the header). */
5424 unsigned int offset_size = listptr_offset_size (listptr);
5425 Dwarf_Off next_off = (listptr->offset
5426 - (offset_size == 4 ? 4 : 12) /* len */
5427 - 2 /* version */
5428 - 1 /* address size */
5429 - 1); /* segment selector size */
5430 next_unitp = start + next_off;
5431 if (next_off < off || next_off > data->d_size)
5432 {
5433 error (0, 0,
5434 "Warning: Couldn't calculate .debug_addr "
5435 " unit length at %" PRIx64, off);
5436 next_unitp = readendp;
5437 }
5438 }
5439 unit_length = (uint64_t) (next_unitp - readp);
5440
5441 /* Pretend we have a header. */
5442 printf ("\n");
5443 printf (_(" Length: %8" PRIu64 "\n"),
5444 unit_length);
5445 printf (_(" DWARF version: %8" PRIu16 "\n"), version);
5446 printf (_(" Address size: %8" PRIu64 "\n"),
5447 (uint64_t) address_size);
5448 printf (_(" Segment size: %8" PRIu64 "\n"),
5449 (uint64_t) segment_size);
5450 printf ("\n");
5451 }
5452 else
5453 {
5454 /* OK, we have to parse an header first. */
5455 unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5456 if (unlikely (unit_length == 0xffffffff))
5457 {
5458 if (unlikely (readp > readendp - 8))
5459 {
5460 invalid_data:
5461 error (0, 0, "Invalid data");
5462 return;
5463 }
5464 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5465 }
5466 printf ("\n");
5467 printf (_(" Length: %8" PRIu64 "\n"),
5468 unit_length);
5469
5470 /* We need at least 2-bytes (version) + 1-byte
5471 (addr_size) + 1-byte (segment_size) = 4 bytes to
5472 complete the header. And this unit cannot go beyond
5473 the section data. */
5474 if (readp > readendp - 4
5475 || unit_length < 4
5476 || unit_length > (uint64_t) (readendp - readp))
5477 goto invalid_data;
5478
5479 next_unitp = readp + unit_length;
5480
5481 version = read_2ubyte_unaligned_inc (dbg, readp);
5482 printf (_(" DWARF version: %8" PRIu16 "\n"), version);
5483
5484 if (version != 5)
5485 {
5486 error (0, 0, _("Unknown version"));
5487 goto next_unit;
5488 }
5489
5490 address_size = *readp++;
5491 printf (_(" Address size: %8" PRIu64 "\n"),
5492 (uint64_t) address_size);
5493
5494 if (address_size != 4 && address_size != 8)
5495 {
5496 error (0, 0, _("unsupported address size"));
5497 goto next_unit;
5498 }
5499
5500 segment_size = *readp++;
5501 printf (_(" Segment size: %8" PRIu64 "\n"),
5502 (uint64_t) segment_size);
5503 printf ("\n");
5504
5505 if (segment_size != 0)
5506 {
5507 error (0, 0, _("unsupported segment size"));
5508 goto next_unit;
5509 }
5510
5511 if (listptr->offset != (Dwarf_Off) (readp - start))
5512 {
5513 error (0, 0, "Address index doesn't start after header");
5514 goto next_unit;
5515 }
5516 }
5517 }
5518
5519 int digits = 1;
5520 size_t addresses = (next_unitp - readp) / address_size;
5521 while (addresses >= 10)
5522 {
5523 ++digits;
5524 addresses /= 10;
5525 }
5526
5527 unsigned int uidx = 0;
5528 size_t index_offset = readp - (const unsigned char *) data->d_buf;
5529 printf (" Addresses start at offset 0x%zx:\n", index_offset);
5530 while (readp <= next_unitp - address_size)
5531 {
5532 Dwarf_Addr addr = read_addr_unaligned_inc (address_size, dbg,
5533 readp);
5534 printf (" [%*u] ", digits, uidx++);
5535 print_dwarf_addr (dwflmod, address_size, addr, addr);
5536 printf ("\n");
5537 }
5538 printf ("\n");
5539
5540 if (readp != next_unitp)
5541 error (0, 0, "extra %zd bytes at end of unit",
5542 (size_t) (next_unitp - readp));
5543
5544 next_unit:
5545 readp = next_unitp;
5546 }
5547 }
5548
5549 /* Print content of DWARF .debug_aranges section. We fortunately do
5550 not have to know a bit about the structure of the section, libdwarf
5551 takes care of it. */
5552 static void
print_decoded_aranges_section(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5553 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5554 GElf_Shdr *shdr, Dwarf *dbg)
5555 {
5556 Dwarf_Aranges *aranges;
5557 size_t cnt;
5558 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
5559 {
5560 error (0, 0, _("cannot get .debug_aranges content: %s"),
5561 dwarf_errmsg (-1));
5562 return;
5563 }
5564
5565 GElf_Shdr glink_mem;
5566 GElf_Shdr *glink;
5567 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
5568 if (glink == NULL)
5569 {
5570 error (0, 0, _("invalid sh_link value in section %zu"),
5571 elf_ndxscn (scn));
5572 return;
5573 }
5574
5575 printf (ngettext ("\
5576 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
5577 "\
5578 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
5579 cnt),
5580 elf_ndxscn (scn), section_name (ebl, shdr),
5581 (uint64_t) shdr->sh_offset, cnt);
5582
5583 /* Compute floor(log16(cnt)). */
5584 size_t tmp = cnt;
5585 int digits = 1;
5586 while (tmp >= 16)
5587 {
5588 ++digits;
5589 tmp >>= 4;
5590 }
5591
5592 for (size_t n = 0; n < cnt; ++n)
5593 {
5594 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
5595 if (unlikely (runp == NULL))
5596 {
5597 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
5598 return;
5599 }
5600
5601 Dwarf_Addr start;
5602 Dwarf_Word length;
5603 Dwarf_Off offset;
5604
5605 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
5606 printf (_(" [%*zu] ???\n"), digits, n);
5607 else
5608 printf (_(" [%*zu] start: %0#*" PRIx64
5609 ", length: %5" PRIu64 ", CU DIE offset: %6"
5610 PRId64 "\n"),
5611 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
5612 (uint64_t) start, (uint64_t) length, (int64_t) offset);
5613 }
5614 }
5615
5616
5617 /* Print content of DWARF .debug_aranges section. */
5618 static void
print_debug_aranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5619 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5620 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5621 GElf_Shdr *shdr, Dwarf *dbg)
5622 {
5623 if (decodedaranges)
5624 {
5625 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
5626 return;
5627 }
5628
5629 Elf_Data *data = (dbg->sectiondata[IDX_debug_aranges]
5630 ?: elf_rawdata (scn, NULL));
5631
5632 if (unlikely (data == NULL))
5633 {
5634 error (0, 0, _("cannot get .debug_aranges content: %s"),
5635 elf_errmsg (-1));
5636 return;
5637 }
5638
5639 printf (_("\
5640 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5641 elf_ndxscn (scn), section_name (ebl, shdr),
5642 (uint64_t) shdr->sh_offset);
5643
5644 const unsigned char *readp = data->d_buf;
5645 const unsigned char *readendp = readp + data->d_size;
5646
5647 while (readp < readendp)
5648 {
5649 const unsigned char *hdrstart = readp;
5650 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
5651
5652 printf (_("\nTable at offset %zu:\n"), start_offset);
5653 if (readp + 4 > readendp)
5654 {
5655 invalid_data:
5656 error (0, 0, _("invalid data in section [%zu] '%s'"),
5657 elf_ndxscn (scn), section_name (ebl, shdr));
5658 return;
5659 }
5660
5661 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
5662 unsigned int length_bytes = 4;
5663 if (length == DWARF3_LENGTH_64_BIT)
5664 {
5665 if (readp + 8 > readendp)
5666 goto invalid_data;
5667 length = read_8ubyte_unaligned_inc (dbg, readp);
5668 length_bytes = 8;
5669 }
5670
5671 const unsigned char *nexthdr = readp + length;
5672 printf (_("\n Length: %6" PRIu64 "\n"),
5673 (uint64_t) length);
5674
5675 if (unlikely (length > (size_t) (readendp - readp)))
5676 goto invalid_data;
5677
5678 if (length == 0)
5679 continue;
5680
5681 if (readp + 2 > readendp)
5682 goto invalid_data;
5683 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5684 printf (_(" DWARF version: %6" PRIuFAST16 "\n"),
5685 version);
5686 if (version != 2)
5687 {
5688 error (0, 0, _("unsupported aranges version"));
5689 goto next_table;
5690 }
5691
5692 Dwarf_Word offset;
5693 if (readp + length_bytes > readendp)
5694 goto invalid_data;
5695 if (length_bytes == 8)
5696 offset = read_8ubyte_unaligned_inc (dbg, readp);
5697 else
5698 offset = read_4ubyte_unaligned_inc (dbg, readp);
5699 printf (_(" CU offset: %6" PRIx64 "\n"),
5700 (uint64_t) offset);
5701
5702 if (readp + 1 > readendp)
5703 goto invalid_data;
5704 unsigned int address_size = *readp++;
5705 printf (_(" Address size: %6" PRIu64 "\n"),
5706 (uint64_t) address_size);
5707 if (address_size != 4 && address_size != 8)
5708 {
5709 error (0, 0, _("unsupported address size"));
5710 goto next_table;
5711 }
5712
5713 if (readp + 1 > readendp)
5714 goto invalid_data;
5715 unsigned int segment_size = *readp++;
5716 printf (_(" Segment size: %6" PRIu64 "\n\n"),
5717 (uint64_t) segment_size);
5718 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5719 {
5720 error (0, 0, _("unsupported segment size"));
5721 goto next_table;
5722 }
5723
5724 /* Round the address to the next multiple of 2*address_size. */
5725 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
5726 % (2 * address_size));
5727
5728 while (readp < nexthdr)
5729 {
5730 Dwarf_Word range_address;
5731 Dwarf_Word range_length;
5732 Dwarf_Word segment = 0;
5733 if (readp + 2 * address_size + segment_size > readendp)
5734 goto invalid_data;
5735 if (address_size == 4)
5736 {
5737 range_address = read_4ubyte_unaligned_inc (dbg, readp);
5738 range_length = read_4ubyte_unaligned_inc (dbg, readp);
5739 }
5740 else
5741 {
5742 range_address = read_8ubyte_unaligned_inc (dbg, readp);
5743 range_length = read_8ubyte_unaligned_inc (dbg, readp);
5744 }
5745
5746 if (segment_size == 4)
5747 segment = read_4ubyte_unaligned_inc (dbg, readp);
5748 else if (segment_size == 8)
5749 segment = read_8ubyte_unaligned_inc (dbg, readp);
5750
5751 if (range_address == 0 && range_length == 0 && segment == 0)
5752 break;
5753
5754 printf (" ");
5755 print_dwarf_addr (dwflmod, address_size, range_address,
5756 range_address);
5757 printf ("..");
5758 print_dwarf_addr (dwflmod, address_size,
5759 range_address + range_length - 1,
5760 range_length);
5761 if (segment_size != 0)
5762 printf (" (%" PRIx64 ")\n", (uint64_t) segment);
5763 else
5764 printf ("\n");
5765 }
5766
5767 next_table:
5768 if (readp != nexthdr)
5769 {
5770 size_t padding = nexthdr - readp;
5771 printf (_(" %zu padding bytes\n"), padding);
5772 readp = nexthdr;
5773 }
5774 }
5775 }
5776
5777
5778 static bool is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu);
5779
5780 /* Returns true and sets cu and cu_base if the given Dwarf is a split
5781 DWARF (.dwo) file. */
5782 static bool
split_dwarf_cu_base(Dwarf * dbg,Dwarf_CU ** cu,Dwarf_Addr * cu_base)5783 split_dwarf_cu_base (Dwarf *dbg, Dwarf_CU **cu, Dwarf_Addr *cu_base)
5784 {
5785 uint64_t id;
5786 if (is_split_dwarf (dbg, &id, cu))
5787 {
5788 Dwarf_Die cudie;
5789 if (dwarf_cu_info (*cu, NULL, NULL, &cudie, NULL, NULL, NULL, NULL) == 0)
5790 {
5791 *cu_base = cudie_base (&cudie);
5792 return true;
5793 }
5794 }
5795 return false;
5796 }
5797
5798 /* Print content of DWARF .debug_rnglists section. */
5799 static void
print_debug_rnglists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5800 print_debug_rnglists_section (Dwfl_Module *dwflmod,
5801 Ebl *ebl,
5802 GElf_Ehdr *ehdr __attribute__ ((unused)),
5803 Elf_Scn *scn, GElf_Shdr *shdr,
5804 Dwarf *dbg __attribute__((unused)))
5805 {
5806 printf (_("\
5807 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5808 elf_ndxscn (scn), section_name (ebl, shdr),
5809 (uint64_t) shdr->sh_offset);
5810
5811 Elf_Data *data =(dbg->sectiondata[IDX_debug_rnglists]
5812 ?: elf_rawdata (scn, NULL));
5813 if (unlikely (data == NULL))
5814 {
5815 error (0, 0, _("cannot get .debug_rnglists content: %s"),
5816 elf_errmsg (-1));
5817 return;
5818 }
5819
5820 /* For the listptr to get the base address/CU. */
5821 sort_listptr (&known_rnglistptr, "rnglistptr");
5822 size_t listptr_idx = 0;
5823
5824 const unsigned char *readp = data->d_buf;
5825 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5826 + data->d_size);
5827 while (readp < dataend)
5828 {
5829 if (unlikely (readp > dataend - 4))
5830 {
5831 invalid_data:
5832 error (0, 0, _("invalid data in section [%zu] '%s'"),
5833 elf_ndxscn (scn), section_name (ebl, shdr));
5834 return;
5835 }
5836
5837 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5838 printf (_("Table at Offset 0x%" PRIx64 ":\n\n"),
5839 (uint64_t) offset);
5840
5841 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5842 unsigned int offset_size = 4;
5843 if (unlikely (unit_length == 0xffffffff))
5844 {
5845 if (unlikely (readp > dataend - 8))
5846 goto invalid_data;
5847
5848 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5849 offset_size = 8;
5850 }
5851 printf (_(" Length: %8" PRIu64 "\n"), unit_length);
5852
5853 /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
5854 bytes to complete the header. And this unit cannot go beyond
5855 the section data. */
5856 if (readp > dataend - 8
5857 || unit_length < 8
5858 || unit_length > (uint64_t) (dataend - readp))
5859 goto invalid_data;
5860
5861 const unsigned char *nexthdr = readp + unit_length;
5862
5863 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5864 printf (_(" DWARF version: %8" PRIu16 "\n"), version);
5865
5866 if (version != 5)
5867 {
5868 error (0, 0, _("Unknown version"));
5869 goto next_table;
5870 }
5871
5872 uint8_t address_size = *readp++;
5873 printf (_(" Address size: %8" PRIu64 "\n"),
5874 (uint64_t) address_size);
5875
5876 if (address_size != 4 && address_size != 8)
5877 {
5878 error (0, 0, _("unsupported address size"));
5879 goto next_table;
5880 }
5881
5882 uint8_t segment_size = *readp++;
5883 printf (_(" Segment size: %8" PRIu64 "\n"),
5884 (uint64_t) segment_size);
5885
5886 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5887 {
5888 error (0, 0, _("unsupported segment size"));
5889 goto next_table;
5890 }
5891
5892 uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
5893 printf (_(" Offset entries: %8" PRIu64 "\n"),
5894 (uint64_t) offset_entry_count);
5895
5896 /* We need the CU that uses this unit to get the initial base address. */
5897 Dwarf_Addr cu_base = 0;
5898 struct Dwarf_CU *cu = NULL;
5899 if (listptr_cu (&known_rnglistptr, &listptr_idx,
5900 (Dwarf_Off) offset,
5901 (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
5902 &cu_base, &cu)
5903 || split_dwarf_cu_base (dbg, &cu, &cu_base))
5904 {
5905 Dwarf_Die cudie;
5906 if (dwarf_cu_die (cu, &cudie,
5907 NULL, NULL, NULL, NULL,
5908 NULL, NULL) == NULL)
5909 printf (_(" Unknown CU base: "));
5910 else
5911 printf (_(" CU [%6" PRIx64 "] base: "),
5912 dwarf_dieoffset (&cudie));
5913 print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
5914 printf ("\n");
5915 }
5916 else
5917 printf (_(" Not associated with a CU.\n"));
5918
5919 printf ("\n");
5920
5921 const unsigned char *offset_array_start = readp;
5922 if (offset_entry_count > 0)
5923 {
5924 uint64_t max_entries = (unit_length - 8) / offset_size;
5925 if (offset_entry_count > max_entries)
5926 {
5927 error (0, 0,
5928 _("too many offset entries for unit length"));
5929 offset_entry_count = max_entries;
5930 }
5931
5932 printf (_(" Offsets starting at 0x%" PRIx64 ":\n"),
5933 (uint64_t) (offset_array_start
5934 - (unsigned char *) data->d_buf));
5935 for (uint32_t idx = 0; idx < offset_entry_count; idx++)
5936 {
5937 printf (" [%6" PRIu32 "] ", idx);
5938 if (offset_size == 4)
5939 {
5940 uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
5941 printf ("0x%" PRIx32 "\n", off);
5942 }
5943 else
5944 {
5945 uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
5946 printf ("0x%" PRIx64 "\n", off);
5947 }
5948 }
5949 printf ("\n");
5950 }
5951
5952 Dwarf_Addr base = cu_base;
5953 bool start_of_list = true;
5954 while (readp < nexthdr)
5955 {
5956 uint8_t kind = *readp++;
5957 uint64_t op1, op2;
5958
5959 /* Skip padding. */
5960 if (start_of_list && kind == DW_RLE_end_of_list)
5961 continue;
5962
5963 if (start_of_list)
5964 {
5965 base = cu_base;
5966 printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
5967 (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
5968 (uint64_t) (readp - offset_array_start - 1));
5969 start_of_list = false;
5970 }
5971
5972 printf (" %s", dwarf_range_list_encoding_name (kind));
5973 switch (kind)
5974 {
5975 case DW_RLE_end_of_list:
5976 start_of_list = true;
5977 printf ("\n\n");
5978 break;
5979
5980 case DW_RLE_base_addressx:
5981 if ((uint64_t) (nexthdr - readp) < 1)
5982 {
5983 invalid_range:
5984 error (0, 0, _("invalid range list data"));
5985 goto next_table;
5986 }
5987 get_uleb128 (op1, readp, nexthdr);
5988 printf (" %" PRIx64 "\n", op1);
5989 if (! print_unresolved_addresses)
5990 {
5991 Dwarf_Addr addr;
5992 if (get_indexed_addr (cu, op1, &addr) != 0)
5993 printf (" ???\n");
5994 else
5995 {
5996 printf (" ");
5997 print_dwarf_addr (dwflmod, address_size, addr, addr);
5998 printf ("\n");
5999 }
6000 }
6001 break;
6002
6003 case DW_RLE_startx_endx:
6004 if ((uint64_t) (nexthdr - readp) < 1)
6005 goto invalid_range;
6006 get_uleb128 (op1, readp, nexthdr);
6007 if ((uint64_t) (nexthdr - readp) < 1)
6008 goto invalid_range;
6009 get_uleb128 (op2, readp, nexthdr);
6010 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
6011 if (! print_unresolved_addresses)
6012 {
6013 Dwarf_Addr addr1;
6014 Dwarf_Addr addr2;
6015 if (get_indexed_addr (cu, op1, &addr1) != 0
6016 || get_indexed_addr (cu, op2, &addr2) != 0)
6017 {
6018 printf (" ???..\n");
6019 printf (" ???\n");
6020 }
6021 else
6022 {
6023 printf (" ");
6024 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
6025 printf ("..\n ");
6026 print_dwarf_addr (dwflmod, address_size,
6027 addr2 - 1, addr2);
6028 printf ("\n");
6029 }
6030 }
6031 break;
6032
6033 case DW_RLE_startx_length:
6034 if ((uint64_t) (nexthdr - readp) < 1)
6035 goto invalid_range;
6036 get_uleb128 (op1, readp, nexthdr);
6037 if ((uint64_t) (nexthdr - readp) < 1)
6038 goto invalid_range;
6039 get_uleb128 (op2, readp, nexthdr);
6040 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
6041 if (! print_unresolved_addresses)
6042 {
6043 Dwarf_Addr addr1;
6044 Dwarf_Addr addr2;
6045 if (get_indexed_addr (cu, op1, &addr1) != 0)
6046 {
6047 printf (" ???..\n");
6048 printf (" ???\n");
6049 }
6050 else
6051 {
6052 addr2 = addr1 + op2;
6053 printf (" ");
6054 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
6055 printf ("..\n ");
6056 print_dwarf_addr (dwflmod, address_size,
6057 addr2 - 1, addr2);
6058 printf ("\n");
6059 }
6060 }
6061 break;
6062
6063 case DW_RLE_offset_pair:
6064 if ((uint64_t) (nexthdr - readp) < 1)
6065 goto invalid_range;
6066 get_uleb128 (op1, readp, nexthdr);
6067 if ((uint64_t) (nexthdr - readp) < 1)
6068 goto invalid_range;
6069 get_uleb128 (op2, readp, nexthdr);
6070 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
6071 if (! print_unresolved_addresses)
6072 {
6073 op1 += base;
6074 op2 += base;
6075 printf (" ");
6076 print_dwarf_addr (dwflmod, address_size, op1, op1);
6077 printf ("..\n ");
6078 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
6079 printf ("\n");
6080 }
6081 break;
6082
6083 case DW_RLE_base_address:
6084 if (address_size == 4)
6085 {
6086 if ((uint64_t) (nexthdr - readp) < 4)
6087 goto invalid_range;
6088 op1 = read_4ubyte_unaligned_inc (dbg, readp);
6089 }
6090 else
6091 {
6092 if ((uint64_t) (nexthdr - readp) < 8)
6093 goto invalid_range;
6094 op1 = read_8ubyte_unaligned_inc (dbg, readp);
6095 }
6096 base = op1;
6097 printf (" 0x%" PRIx64 "\n", base);
6098 if (! print_unresolved_addresses)
6099 {
6100 printf (" ");
6101 print_dwarf_addr (dwflmod, address_size, base, base);
6102 printf ("\n");
6103 }
6104 break;
6105
6106 case DW_RLE_start_end:
6107 if (address_size == 4)
6108 {
6109 if ((uint64_t) (nexthdr - readp) < 8)
6110 goto invalid_range;
6111 op1 = read_4ubyte_unaligned_inc (dbg, readp);
6112 op2 = read_4ubyte_unaligned_inc (dbg, readp);
6113 }
6114 else
6115 {
6116 if ((uint64_t) (nexthdr - readp) < 16)
6117 goto invalid_range;
6118 op1 = read_8ubyte_unaligned_inc (dbg, readp);
6119 op2 = read_8ubyte_unaligned_inc (dbg, readp);
6120 }
6121 printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
6122 if (! print_unresolved_addresses)
6123 {
6124 printf (" ");
6125 print_dwarf_addr (dwflmod, address_size, op1, op1);
6126 printf ("..\n ");
6127 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
6128 printf ("\n");
6129 }
6130 break;
6131
6132 case DW_RLE_start_length:
6133 if (address_size == 4)
6134 {
6135 if ((uint64_t) (nexthdr - readp) < 4)
6136 goto invalid_range;
6137 op1 = read_4ubyte_unaligned_inc (dbg, readp);
6138 }
6139 else
6140 {
6141 if ((uint64_t) (nexthdr - readp) < 8)
6142 goto invalid_range;
6143 op1 = read_8ubyte_unaligned_inc (dbg, readp);
6144 }
6145 if ((uint64_t) (nexthdr - readp) < 1)
6146 goto invalid_range;
6147 get_uleb128 (op2, readp, nexthdr);
6148 printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
6149 if (! print_unresolved_addresses)
6150 {
6151 op2 = op1 + op2;
6152 printf (" ");
6153 print_dwarf_addr (dwflmod, address_size, op1, op1);
6154 printf ("..\n ");
6155 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
6156 printf ("\n");
6157 }
6158 break;
6159
6160 default:
6161 goto invalid_range;
6162 }
6163 }
6164
6165 next_table:
6166 if (readp != nexthdr)
6167 {
6168 size_t padding = nexthdr - readp;
6169 printf (_(" %zu padding bytes\n\n"), padding);
6170 readp = nexthdr;
6171 }
6172 }
6173 }
6174
6175 /* Print content of DWARF .debug_ranges section. */
6176 static void
print_debug_ranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6177 print_debug_ranges_section (Dwfl_Module *dwflmod,
6178 Ebl *ebl, GElf_Ehdr *ehdr,
6179 Elf_Scn *scn, GElf_Shdr *shdr,
6180 Dwarf *dbg)
6181 {
6182 Elf_Data *data = (dbg->sectiondata[IDX_debug_ranges]
6183 ?: elf_rawdata (scn, NULL));
6184 if (unlikely (data == NULL))
6185 {
6186 error (0, 0, _("cannot get .debug_ranges content: %s"),
6187 elf_errmsg (-1));
6188 return;
6189 }
6190
6191 printf (_("\
6192 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6193 elf_ndxscn (scn), section_name (ebl, shdr),
6194 (uint64_t) shdr->sh_offset);
6195
6196 sort_listptr (&known_rangelistptr, "rangelistptr");
6197 size_t listptr_idx = 0;
6198
6199 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6200
6201 bool first = true;
6202 Dwarf_Addr base = 0;
6203 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6204 unsigned char *readp = data->d_buf;
6205 Dwarf_CU *last_cu = NULL;
6206 while (readp < endp)
6207 {
6208 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6209 Dwarf_CU *cu = last_cu;
6210
6211 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
6212 &address_size, NULL, &base, &cu,
6213 offset, &readp, endp, NULL))
6214 continue;
6215
6216 if (last_cu != cu)
6217 {
6218 Dwarf_Die cudie;
6219 if (dwarf_cu_die (cu, &cudie,
6220 NULL, NULL, NULL, NULL,
6221 NULL, NULL) == NULL)
6222 printf (_("\n Unknown CU base: "));
6223 else
6224 printf (_("\n CU [%6" PRIx64 "] base: "),
6225 dwarf_dieoffset (&cudie));
6226 print_dwarf_addr (dwflmod, address_size, base, base);
6227 printf ("\n");
6228 }
6229 last_cu = cu;
6230
6231 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6232 {
6233 printf (_(" [%6tx] <INVALID DATA>\n"), offset);
6234 break;
6235 }
6236
6237 Dwarf_Addr begin;
6238 Dwarf_Addr end;
6239 if (address_size == 8)
6240 {
6241 begin = read_8ubyte_unaligned_inc (dbg, readp);
6242 end = read_8ubyte_unaligned_inc (dbg, readp);
6243 }
6244 else
6245 {
6246 begin = read_4ubyte_unaligned_inc (dbg, readp);
6247 end = read_4ubyte_unaligned_inc (dbg, readp);
6248 if (begin == (Dwarf_Addr) (uint32_t) -1)
6249 begin = (Dwarf_Addr) -1l;
6250 }
6251
6252 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
6253 {
6254 if (first)
6255 printf (" [%6tx] ", offset);
6256 else
6257 printf (" ");
6258 puts (_("base address"));
6259 printf (" ");
6260 print_dwarf_addr (dwflmod, address_size, end, end);
6261 printf ("\n");
6262 base = end;
6263 first = false;
6264 }
6265 else if (begin == 0 && end == 0) /* End of list entry. */
6266 {
6267 if (first)
6268 printf (_(" [%6tx] empty list\n"), offset);
6269 first = true;
6270 }
6271 else
6272 {
6273 /* We have an address range entry. */
6274 if (first) /* First address range entry in a list. */
6275 printf (" [%6tx] ", offset);
6276 else
6277 printf (" ");
6278
6279 printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
6280 if (! print_unresolved_addresses)
6281 {
6282 printf (" ");
6283 print_dwarf_addr (dwflmod, address_size, base + begin,
6284 base + begin);
6285 printf ("..\n ");
6286 print_dwarf_addr (dwflmod, address_size,
6287 base + end - 1, base + end);
6288 printf ("\n");
6289 }
6290
6291 first = false;
6292 }
6293 }
6294 }
6295
6296 #define REGNAMESZ 16
6297 static const char *
register_info(Ebl * ebl,unsigned int regno,const Ebl_Register_Location * loc,char name[REGNAMESZ],int * bits,int * type)6298 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
6299 char name[REGNAMESZ], int *bits, int *type)
6300 {
6301 const char *set;
6302 const char *pfx;
6303 int ignore;
6304 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
6305 bits ?: &ignore, type ?: &ignore);
6306 if (n <= 0)
6307 {
6308 if (loc != NULL)
6309 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
6310 else
6311 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
6312 if (bits != NULL)
6313 *bits = loc != NULL ? loc->bits : 0;
6314 if (type != NULL)
6315 *type = DW_ATE_unsigned;
6316 set = "??? unrecognized";
6317 }
6318 else
6319 {
6320 if (bits != NULL && *bits <= 0)
6321 *bits = loc != NULL ? loc->bits : 0;
6322 if (type != NULL && *type == DW_ATE_void)
6323 *type = DW_ATE_unsigned;
6324
6325 }
6326 return set;
6327 }
6328
6329 static const unsigned char *
read_encoded(unsigned int encoding,const unsigned char * readp,const unsigned char * const endp,uint64_t * res,Dwarf * dbg)6330 read_encoded (unsigned int encoding, const unsigned char *readp,
6331 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
6332 {
6333 if ((encoding & 0xf) == DW_EH_PE_absptr)
6334 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
6335 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
6336
6337 switch (encoding & 0xf)
6338 {
6339 case DW_EH_PE_uleb128:
6340 get_uleb128 (*res, readp, endp);
6341 break;
6342 case DW_EH_PE_sleb128:
6343 get_sleb128 (*res, readp, endp);
6344 break;
6345 case DW_EH_PE_udata2:
6346 if (readp + 2 > endp)
6347 goto invalid;
6348 *res = read_2ubyte_unaligned_inc (dbg, readp);
6349 break;
6350 case DW_EH_PE_udata4:
6351 if (readp + 4 > endp)
6352 goto invalid;
6353 *res = read_4ubyte_unaligned_inc (dbg, readp);
6354 break;
6355 case DW_EH_PE_udata8:
6356 if (readp + 8 > endp)
6357 goto invalid;
6358 *res = read_8ubyte_unaligned_inc (dbg, readp);
6359 break;
6360 case DW_EH_PE_sdata2:
6361 if (readp + 2 > endp)
6362 goto invalid;
6363 *res = read_2sbyte_unaligned_inc (dbg, readp);
6364 break;
6365 case DW_EH_PE_sdata4:
6366 if (readp + 4 > endp)
6367 goto invalid;
6368 *res = read_4sbyte_unaligned_inc (dbg, readp);
6369 break;
6370 case DW_EH_PE_sdata8:
6371 if (readp + 8 > endp)
6372 goto invalid;
6373 *res = read_8sbyte_unaligned_inc (dbg, readp);
6374 break;
6375 default:
6376 invalid:
6377 error (1, 0,
6378 _("invalid encoding"));
6379 }
6380
6381 return readp;
6382 }
6383
6384 static const char *
regname(Ebl * ebl,unsigned int regno,char * regnamebuf)6385 regname (Ebl *ebl, unsigned int regno, char *regnamebuf)
6386 {
6387 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
6388
6389 return regnamebuf;
6390 }
6391
6392 static void
print_cfa_program(const unsigned char * readp,const unsigned char * const endp,Dwarf_Word vma_base,unsigned int code_align,int data_align,unsigned int version,unsigned int ptr_size,unsigned int encoding,Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Dwarf * dbg)6393 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
6394 Dwarf_Word vma_base, unsigned int code_align,
6395 int data_align,
6396 unsigned int version, unsigned int ptr_size,
6397 unsigned int encoding,
6398 Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, Dwarf *dbg)
6399 {
6400 char regnamebuf[REGNAMESZ];
6401
6402 puts ("\n Program:");
6403 Dwarf_Word pc = vma_base;
6404 while (readp < endp)
6405 {
6406 unsigned int opcode = *readp++;
6407
6408 if (opcode < DW_CFA_advance_loc)
6409 /* Extended opcode. */
6410 switch (opcode)
6411 {
6412 uint64_t op1;
6413 int64_t sop1;
6414 uint64_t op2;
6415 int64_t sop2;
6416
6417 case DW_CFA_nop:
6418 puts (" nop");
6419 break;
6420 case DW_CFA_set_loc:
6421 if ((uint64_t) (endp - readp) < 1)
6422 goto invalid;
6423 readp = read_encoded (encoding, readp, endp, &op1, dbg);
6424 printf (" set_loc %#" PRIx64 " to %#" PRIx64 "\n",
6425 op1, pc = vma_base + op1);
6426 break;
6427 case DW_CFA_advance_loc1:
6428 if ((uint64_t) (endp - readp) < 1)
6429 goto invalid;
6430 printf (" advance_loc1 %u to %#" PRIx64 "\n",
6431 *readp, pc += *readp * code_align);
6432 ++readp;
6433 break;
6434 case DW_CFA_advance_loc2:
6435 if ((uint64_t) (endp - readp) < 2)
6436 goto invalid;
6437 op1 = read_2ubyte_unaligned_inc (dbg, readp);
6438 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
6439 op1, pc += op1 * code_align);
6440 break;
6441 case DW_CFA_advance_loc4:
6442 if ((uint64_t) (endp - readp) < 4)
6443 goto invalid;
6444 op1 = read_4ubyte_unaligned_inc (dbg, readp);
6445 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
6446 op1, pc += op1 * code_align);
6447 break;
6448 case DW_CFA_offset_extended:
6449 if ((uint64_t) (endp - readp) < 1)
6450 goto invalid;
6451 get_uleb128 (op1, readp, endp);
6452 if ((uint64_t) (endp - readp) < 1)
6453 goto invalid;
6454 get_uleb128 (op2, readp, endp);
6455 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
6456 "\n",
6457 op1, regname (ebl, op1, regnamebuf), op2 * data_align);
6458 break;
6459 case DW_CFA_restore_extended:
6460 if ((uint64_t) (endp - readp) < 1)
6461 goto invalid;
6462 get_uleb128 (op1, readp, endp);
6463 printf (" restore_extended r%" PRIu64 " (%s)\n",
6464 op1, regname (ebl, op1, regnamebuf));
6465 break;
6466 case DW_CFA_undefined:
6467 if ((uint64_t) (endp - readp) < 1)
6468 goto invalid;
6469 get_uleb128 (op1, readp, endp);
6470 printf (" undefined r%" PRIu64 " (%s)\n", op1,
6471 regname (ebl, op1, regnamebuf));
6472 break;
6473 case DW_CFA_same_value:
6474 if ((uint64_t) (endp - readp) < 1)
6475 goto invalid;
6476 get_uleb128 (op1, readp, endp);
6477 printf (" same_value r%" PRIu64 " (%s)\n", op1,
6478 regname (ebl, op1, regnamebuf));
6479 break;
6480 case DW_CFA_register:
6481 if ((uint64_t) (endp - readp) < 1)
6482 goto invalid;
6483 get_uleb128 (op1, readp, endp);
6484 if ((uint64_t) (endp - readp) < 1)
6485 goto invalid;
6486 get_uleb128 (op2, readp, endp);
6487 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
6488 op1, regname (ebl, op1, regnamebuf), op2,
6489 regname (ebl, op2, regnamebuf));
6490 break;
6491 case DW_CFA_remember_state:
6492 puts (" remember_state");
6493 break;
6494 case DW_CFA_restore_state:
6495 puts (" restore_state");
6496 break;
6497 case DW_CFA_def_cfa:
6498 if ((uint64_t) (endp - readp) < 1)
6499 goto invalid;
6500 get_uleb128 (op1, readp, endp);
6501 if ((uint64_t) (endp - readp) < 1)
6502 goto invalid;
6503 get_uleb128 (op2, readp, endp);
6504 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
6505 op1, regname (ebl, op1, regnamebuf), op2);
6506 break;
6507 case DW_CFA_def_cfa_register:
6508 if ((uint64_t) (endp - readp) < 1)
6509 goto invalid;
6510 get_uleb128 (op1, readp, endp);
6511 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
6512 op1, regname (ebl, op1, regnamebuf));
6513 break;
6514 case DW_CFA_def_cfa_offset:
6515 if ((uint64_t) (endp - readp) < 1)
6516 goto invalid;
6517 get_uleb128 (op1, readp, endp);
6518 printf (" def_cfa_offset %" PRIu64 "\n", op1);
6519 break;
6520 case DW_CFA_def_cfa_expression:
6521 if ((uint64_t) (endp - readp) < 1)
6522 goto invalid;
6523 get_uleb128 (op1, readp, endp); /* Length of DW_FORM_block. */
6524 printf (" def_cfa_expression %" PRIu64 "\n", op1);
6525 if ((uint64_t) (endp - readp) < op1)
6526 {
6527 invalid:
6528 fputs (_(" <INVALID DATA>\n"), stdout);
6529 return;
6530 }
6531 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6532 op1, readp);
6533 readp += op1;
6534 break;
6535 case DW_CFA_expression:
6536 if ((uint64_t) (endp - readp) < 1)
6537 goto invalid;
6538 get_uleb128 (op1, readp, endp);
6539 if ((uint64_t) (endp - readp) < 1)
6540 goto invalid;
6541 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
6542 printf (" expression r%" PRIu64 " (%s) \n",
6543 op1, regname (ebl, op1, regnamebuf));
6544 if ((uint64_t) (endp - readp) < op2)
6545 goto invalid;
6546 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6547 op2, readp);
6548 readp += op2;
6549 break;
6550 case DW_CFA_offset_extended_sf:
6551 if ((uint64_t) (endp - readp) < 1)
6552 goto invalid;
6553 get_uleb128 (op1, readp, endp);
6554 if ((uint64_t) (endp - readp) < 1)
6555 goto invalid;
6556 get_sleb128 (sop2, readp, endp);
6557 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
6558 PRId64 "\n",
6559 op1, regname (ebl, op1, regnamebuf), sop2 * data_align);
6560 break;
6561 case DW_CFA_def_cfa_sf:
6562 if ((uint64_t) (endp - readp) < 1)
6563 goto invalid;
6564 get_uleb128 (op1, readp, endp);
6565 if ((uint64_t) (endp - readp) < 1)
6566 goto invalid;
6567 get_sleb128 (sop2, readp, endp);
6568 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
6569 op1, regname (ebl, op1, regnamebuf), sop2 * data_align);
6570 break;
6571 case DW_CFA_def_cfa_offset_sf:
6572 if ((uint64_t) (endp - readp) < 1)
6573 goto invalid;
6574 get_sleb128 (sop1, readp, endp);
6575 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
6576 break;
6577 case DW_CFA_val_offset:
6578 if ((uint64_t) (endp - readp) < 1)
6579 goto invalid;
6580 get_uleb128 (op1, readp, endp);
6581 if ((uint64_t) (endp - readp) < 1)
6582 goto invalid;
6583 get_uleb128 (op2, readp, endp);
6584 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
6585 op1, op2 * data_align);
6586 break;
6587 case DW_CFA_val_offset_sf:
6588 if ((uint64_t) (endp - readp) < 1)
6589 goto invalid;
6590 get_uleb128 (op1, readp, endp);
6591 if ((uint64_t) (endp - readp) < 1)
6592 goto invalid;
6593 get_sleb128 (sop2, readp, endp);
6594 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
6595 op1, sop2 * data_align);
6596 break;
6597 case DW_CFA_val_expression:
6598 if ((uint64_t) (endp - readp) < 1)
6599 goto invalid;
6600 get_uleb128 (op1, readp, endp);
6601 if ((uint64_t) (endp - readp) < 1)
6602 goto invalid;
6603 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
6604 printf (" val_expression r%" PRIu64 " (%s)\n",
6605 op1, regname (ebl, op1, regnamebuf));
6606 if ((uint64_t) (endp - readp) < op2)
6607 goto invalid;
6608 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
6609 NULL, op2, readp);
6610 readp += op2;
6611 break;
6612 case DW_CFA_MIPS_advance_loc8:
6613 if ((uint64_t) (endp - readp) < 8)
6614 goto invalid;
6615 op1 = read_8ubyte_unaligned_inc (dbg, readp);
6616 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
6617 op1, pc += op1 * code_align);
6618 break;
6619 case DW_CFA_GNU_window_save: /* DW_CFA_AARCH64_negate_ra_state */
6620 if (ehdr->e_machine == EM_AARCH64)
6621 puts (" AARCH64_negate_ra_state");
6622 else
6623 puts (" GNU_window_save");
6624 break;
6625 case DW_CFA_GNU_args_size:
6626 if ((uint64_t) (endp - readp) < 1)
6627 goto invalid;
6628 get_uleb128 (op1, readp, endp);
6629 printf (" args_size %" PRIu64 "\n", op1);
6630 break;
6631 default:
6632 printf (" ??? (%u)\n", opcode);
6633 break;
6634 }
6635 else if (opcode < DW_CFA_offset)
6636 printf (" advance_loc %u to %#" PRIx64 "\n",
6637 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
6638 else if (opcode < DW_CFA_restore)
6639 {
6640 uint64_t offset;
6641 if ((uint64_t) (endp - readp) < 1)
6642 goto invalid;
6643 get_uleb128 (offset, readp, endp);
6644 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
6645 opcode & 0x3f, regname (ebl, opcode & 0x3f, regnamebuf),
6646 offset * data_align);
6647 }
6648 else
6649 printf (" restore r%u (%s)\n",
6650 opcode & 0x3f, regname (ebl, opcode & 0x3f, regnamebuf));
6651 }
6652 }
6653
6654
6655 static unsigned int
encoded_ptr_size(int encoding,unsigned int ptr_size)6656 encoded_ptr_size (int encoding, unsigned int ptr_size)
6657 {
6658 switch (encoding & 7)
6659 {
6660 case DW_EH_PE_udata4:
6661 return 4;
6662 case DW_EH_PE_udata8:
6663 return 8;
6664 case 0:
6665 return ptr_size;
6666 }
6667
6668 fprintf (stderr, "Unsupported pointer encoding: %#x, "
6669 "assuming pointer size of %d.\n", encoding, ptr_size);
6670 return ptr_size;
6671 }
6672
6673
6674 static unsigned int
print_encoding(unsigned int val)6675 print_encoding (unsigned int val)
6676 {
6677 switch (val & 0xf)
6678 {
6679 case DW_EH_PE_absptr:
6680 fputs ("absptr", stdout);
6681 break;
6682 case DW_EH_PE_uleb128:
6683 fputs ("uleb128", stdout);
6684 break;
6685 case DW_EH_PE_udata2:
6686 fputs ("udata2", stdout);
6687 break;
6688 case DW_EH_PE_udata4:
6689 fputs ("udata4", stdout);
6690 break;
6691 case DW_EH_PE_udata8:
6692 fputs ("udata8", stdout);
6693 break;
6694 case DW_EH_PE_sleb128:
6695 fputs ("sleb128", stdout);
6696 break;
6697 case DW_EH_PE_sdata2:
6698 fputs ("sdata2", stdout);
6699 break;
6700 case DW_EH_PE_sdata4:
6701 fputs ("sdata4", stdout);
6702 break;
6703 case DW_EH_PE_sdata8:
6704 fputs ("sdata8", stdout);
6705 break;
6706 default:
6707 /* We did not use any of the bits after all. */
6708 return val;
6709 }
6710
6711 return val & ~0xf;
6712 }
6713
6714
6715 static unsigned int
print_relinfo(unsigned int val)6716 print_relinfo (unsigned int val)
6717 {
6718 switch (val & 0x70)
6719 {
6720 case DW_EH_PE_pcrel:
6721 fputs ("pcrel", stdout);
6722 break;
6723 case DW_EH_PE_textrel:
6724 fputs ("textrel", stdout);
6725 break;
6726 case DW_EH_PE_datarel:
6727 fputs ("datarel", stdout);
6728 break;
6729 case DW_EH_PE_funcrel:
6730 fputs ("funcrel", stdout);
6731 break;
6732 case DW_EH_PE_aligned:
6733 fputs ("aligned", stdout);
6734 break;
6735 default:
6736 return val;
6737 }
6738
6739 return val & ~0x70;
6740 }
6741
6742
6743 static void
print_encoding_base(const char * pfx,unsigned int fde_encoding)6744 print_encoding_base (const char *pfx, unsigned int fde_encoding)
6745 {
6746 printf ("(%s", pfx);
6747
6748 if (fde_encoding == DW_EH_PE_omit)
6749 puts ("omit)");
6750 else
6751 {
6752 unsigned int w = fde_encoding;
6753
6754 w = print_encoding (w);
6755
6756 if (w & 0x70)
6757 {
6758 if (w != fde_encoding)
6759 fputc_unlocked (' ', stdout);
6760
6761 w = print_relinfo (w);
6762 }
6763
6764 if (w != 0)
6765 printf ("%s%x", w != fde_encoding ? " " : "", w);
6766
6767 puts (")");
6768 }
6769 }
6770
6771
6772 static void
print_debug_frame_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6773 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6774 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6775 {
6776 size_t shstrndx;
6777 /* We know this call will succeed since it did in the caller. */
6778 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
6779 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
6780
6781 /* Needed if we find PC-relative addresses. */
6782 GElf_Addr bias;
6783 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
6784 {
6785 error (0, 0, _("cannot get ELF: %s"), dwfl_errmsg (-1));
6786 return;
6787 }
6788
6789 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
6790 Elf_Data *data = (is_eh_frame
6791 ? elf_rawdata (scn, NULL)
6792 : (dbg->sectiondata[IDX_debug_frame]
6793 ?: elf_rawdata (scn, NULL)));
6794
6795 if (unlikely (data == NULL))
6796 {
6797 error (0, 0, _("cannot get %s content: %s"),
6798 scnname, elf_errmsg (-1));
6799 return;
6800 }
6801
6802 if (is_eh_frame)
6803 printf (_("\
6804 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6805 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6806 else
6807 printf (_("\
6808 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6809 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6810
6811 struct cieinfo
6812 {
6813 ptrdiff_t cie_offset;
6814 const char *augmentation;
6815 unsigned int code_alignment_factor;
6816 unsigned int data_alignment_factor;
6817 uint8_t address_size;
6818 uint8_t fde_encoding;
6819 uint8_t lsda_encoding;
6820 struct cieinfo *next;
6821 } *cies = NULL;
6822
6823 const unsigned char *readp = data->d_buf;
6824 const unsigned char *const dataend = ((unsigned char *) data->d_buf
6825 + data->d_size);
6826 while (readp < dataend)
6827 {
6828 if (unlikely (readp + 4 > dataend))
6829 {
6830 invalid_data:
6831 error (0, 0, _("invalid data in section [%zu] '%s'"),
6832 elf_ndxscn (scn), scnname);
6833 return;
6834 }
6835
6836 /* At the beginning there must be a CIE. There can be multiple,
6837 hence we test tis in a loop. */
6838 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6839
6840 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
6841 unsigned int length = 4;
6842 if (unlikely (unit_length == 0xffffffff))
6843 {
6844 if (unlikely (readp + 8 > dataend))
6845 goto invalid_data;
6846
6847 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
6848 length = 8;
6849 }
6850
6851 if (unlikely (unit_length == 0))
6852 {
6853 printf (_("\n [%6tx] Zero terminator\n"), offset);
6854 continue;
6855 }
6856
6857 Dwarf_Word maxsize = dataend - readp;
6858 if (unlikely (unit_length > maxsize))
6859 goto invalid_data;
6860
6861 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6862
6863 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
6864 const unsigned char *const cieend = readp + unit_length;
6865 if (unlikely (cieend > dataend))
6866 goto invalid_data;
6867
6868 Dwarf_Off cie_id;
6869 if (length == 4)
6870 {
6871 if (unlikely (cieend - readp < 4))
6872 goto invalid_data;
6873 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
6874 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
6875 cie_id = DW_CIE_ID_64;
6876 }
6877 else
6878 {
6879 if (unlikely (cieend - readp < 8))
6880 goto invalid_data;
6881 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
6882 }
6883
6884 uint_fast8_t version = 2;
6885 unsigned int code_alignment_factor;
6886 int data_alignment_factor;
6887 unsigned int fde_encoding = 0;
6888 unsigned int lsda_encoding = 0;
6889 Dwarf_Word initial_location = 0;
6890 Dwarf_Word vma_base = 0;
6891
6892 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
6893 {
6894 if (unlikely (cieend - readp < 2))
6895 goto invalid_data;
6896 version = *readp++;
6897 const char *const augmentation = (const char *) readp;
6898 readp = memchr (readp, '\0', cieend - readp);
6899 if (unlikely (readp == NULL))
6900 goto invalid_data;
6901 ++readp;
6902
6903 uint_fast8_t segment_size = 0;
6904 if (version >= 4)
6905 {
6906 if (cieend - readp < 5)
6907 goto invalid_data;
6908 ptr_size = *readp++;
6909 segment_size = *readp++;
6910 }
6911
6912 if (cieend - readp < 1)
6913 goto invalid_data;
6914 get_uleb128 (code_alignment_factor, readp, cieend);
6915 if (cieend - readp < 1)
6916 goto invalid_data;
6917 get_sleb128 (data_alignment_factor, readp, cieend);
6918
6919 /* In some variant for unwind data there is another field. */
6920 if (strcmp (augmentation, "eh") == 0)
6921 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6922
6923 unsigned int return_address_register;
6924 if (cieend - readp < 1)
6925 goto invalid_data;
6926 if (unlikely (version == 1))
6927 return_address_register = *readp++;
6928 else
6929 get_uleb128 (return_address_register, readp, cieend);
6930
6931 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
6932 " CIE_id: %" PRIu64 "\n"
6933 " version: %u\n"
6934 " augmentation: \"%s\"\n",
6935 offset, (uint64_t) unit_length, (uint64_t) cie_id,
6936 version, augmentation);
6937 if (version >= 4)
6938 printf (" address_size: %u\n"
6939 " segment_size: %u\n",
6940 ptr_size, segment_size);
6941 printf (" code_alignment_factor: %u\n"
6942 " data_alignment_factor: %d\n"
6943 " return_address_register: %u\n",
6944 code_alignment_factor,
6945 data_alignment_factor, return_address_register);
6946
6947 if (augmentation[0] == 'z')
6948 {
6949 unsigned int augmentationlen;
6950 get_uleb128 (augmentationlen, readp, cieend);
6951
6952 if (augmentationlen > (size_t) (cieend - readp))
6953 {
6954 error (0, 0, _("invalid augmentation length"));
6955 readp = cieend;
6956 continue;
6957 }
6958
6959 const char *hdr = "Augmentation data:";
6960 const char *cp = augmentation + 1;
6961 while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
6962 {
6963 printf (" %-26s%#x ", hdr, *readp);
6964 hdr = "";
6965
6966 if (*cp == 'R')
6967 {
6968 fde_encoding = *readp++;
6969 print_encoding_base (_("FDE address encoding: "),
6970 fde_encoding);
6971 }
6972 else if (*cp == 'L')
6973 {
6974 lsda_encoding = *readp++;
6975 print_encoding_base (_("LSDA pointer encoding: "),
6976 lsda_encoding);
6977 }
6978 else if (*cp == 'P')
6979 {
6980 /* Personality. This field usually has a relocation
6981 attached pointing to __gcc_personality_v0. */
6982 const unsigned char *startp = readp;
6983 unsigned int encoding = *readp++;
6984 uint64_t val = 0;
6985 readp = read_encoded (encoding, readp,
6986 readp - 1 + augmentationlen,
6987 &val, dbg);
6988
6989 while (++startp < readp)
6990 printf ("%#x ", *startp);
6991
6992 putchar ('(');
6993 print_encoding (encoding);
6994 putchar (' ');
6995 switch (encoding & 0xf)
6996 {
6997 case DW_EH_PE_sleb128:
6998 case DW_EH_PE_sdata2:
6999 case DW_EH_PE_sdata4:
7000 printf ("%" PRId64 ")\n", val);
7001 break;
7002 default:
7003 printf ("%#" PRIx64 ")\n", val);
7004 break;
7005 }
7006 }
7007 else
7008 printf ("(%x)\n", *readp++);
7009
7010 ++cp;
7011 }
7012 }
7013
7014 if (likely (ptr_size == 4 || ptr_size == 8))
7015 {
7016 struct cieinfo *newp = alloca (sizeof (*newp));
7017 newp->cie_offset = offset;
7018 newp->augmentation = augmentation;
7019 newp->fde_encoding = fde_encoding;
7020 newp->lsda_encoding = lsda_encoding;
7021 newp->address_size = ptr_size;
7022 newp->code_alignment_factor = code_alignment_factor;
7023 newp->data_alignment_factor = data_alignment_factor;
7024 newp->next = cies;
7025 cies = newp;
7026 }
7027 }
7028 else
7029 {
7030 struct cieinfo *cie = cies;
7031 while (cie != NULL)
7032 if (is_eh_frame
7033 ? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
7034 : cie_id == (Dwarf_Off) cie->cie_offset)
7035 break;
7036 else
7037 cie = cie->next;
7038 if (unlikely (cie == NULL))
7039 {
7040 puts ("invalid CIE reference in FDE");
7041 return;
7042 }
7043
7044 /* Initialize from CIE data. */
7045 fde_encoding = cie->fde_encoding;
7046 lsda_encoding = cie->lsda_encoding;
7047 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
7048 code_alignment_factor = cie->code_alignment_factor;
7049 data_alignment_factor = cie->data_alignment_factor;
7050
7051 const unsigned char *base = readp;
7052 // XXX There are sometimes relocations for this value
7053 initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
7054 Dwarf_Word address_range
7055 = read_addr_unaligned_inc (ptr_size, dbg, readp);
7056
7057 /* pcrel for an FDE address is relative to the runtime
7058 address of the start_address field itself. Sign extend
7059 if necessary to make sure the calculation is done on the
7060 full 64 bit address even when initial_location only holds
7061 the lower 32 bits. */
7062 Dwarf_Addr pc_start = initial_location;
7063 if (ptr_size == 4)
7064 pc_start = (uint64_t) (int32_t) pc_start;
7065 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
7066 pc_start += ((uint64_t) shdr->sh_addr
7067 + (base - (const unsigned char *) data->d_buf)
7068 - bias);
7069
7070 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
7071 " CIE_pointer: %" PRIu64 "\n"
7072 " initial_location: ",
7073 offset, (uint64_t) unit_length,
7074 cie->cie_offset, (uint64_t) cie_id);
7075 print_dwarf_addr (dwflmod, cie->address_size,
7076 pc_start, initial_location);
7077 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
7078 {
7079 vma_base = (((uint64_t) shdr->sh_offset
7080 + (base - (const unsigned char *) data->d_buf)
7081 + (uint64_t) initial_location)
7082 & (ptr_size == 4
7083 ? UINT64_C (0xffffffff)
7084 : UINT64_C (0xffffffffffffffff)));
7085 printf (_(" (offset: %#" PRIx64 ")"),
7086 (uint64_t) vma_base);
7087 }
7088
7089 printf ("\n address_range: %#" PRIx64,
7090 (uint64_t) address_range);
7091 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
7092 printf (_(" (end offset: %#" PRIx64 ")"),
7093 ((uint64_t) vma_base + (uint64_t) address_range)
7094 & (ptr_size == 4
7095 ? UINT64_C (0xffffffff)
7096 : UINT64_C (0xffffffffffffffff)));
7097 putchar ('\n');
7098
7099 if (cie->augmentation[0] == 'z')
7100 {
7101 unsigned int augmentationlen;
7102 if (cieend - readp < 1)
7103 goto invalid_data;
7104 get_uleb128 (augmentationlen, readp, cieend);
7105
7106 if (augmentationlen > (size_t) (cieend - readp))
7107 {
7108 error (0, 0, _("invalid augmentation length"));
7109 readp = cieend;
7110 continue;
7111 }
7112
7113 if (augmentationlen > 0)
7114 {
7115 const char *hdr = "Augmentation data:";
7116 const char *cp = cie->augmentation + 1;
7117 unsigned int u = 0;
7118 while (*cp != '\0'
7119 && cp < cie->augmentation + augmentationlen + 1)
7120 {
7121 if (*cp == 'L')
7122 {
7123 uint64_t lsda_pointer;
7124 const unsigned char *p
7125 = read_encoded (lsda_encoding, &readp[u],
7126 &readp[augmentationlen],
7127 &lsda_pointer, dbg);
7128 u = p - readp;
7129 printf (_("\
7130 %-26sLSDA pointer: %#" PRIx64 "\n"),
7131 hdr, lsda_pointer);
7132 hdr = "";
7133 }
7134 ++cp;
7135 }
7136
7137 while (u < augmentationlen)
7138 {
7139 printf (" %-26s%#x\n", hdr, readp[u++]);
7140 hdr = "";
7141 }
7142 }
7143
7144 readp += augmentationlen;
7145 }
7146 }
7147
7148 /* Handle the initialization instructions. */
7149 if (ptr_size != 4 && ptr_size !=8)
7150 printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
7151 else
7152 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
7153 data_alignment_factor, version, ptr_size,
7154 fde_encoding, dwflmod, ebl, ehdr, dbg);
7155 readp = cieend;
7156 }
7157 }
7158
7159
7160 /* Returns the signedness (or false if it cannot be determined) and
7161 the byte size (or zero if it cannot be gotten) of the given DIE
7162 DW_AT_type attribute. Uses dwarf_peel_type and dwarf_aggregate_size. */
7163 static void
die_type_sign_bytes(Dwarf_Die * die,bool * is_signed,int * bytes)7164 die_type_sign_bytes (Dwarf_Die *die, bool *is_signed, int *bytes)
7165 {
7166 Dwarf_Attribute attr;
7167 Dwarf_Die type;
7168
7169 *bytes = 0;
7170 *is_signed = false;
7171
7172 if (dwarf_peel_type (dwarf_formref_die (dwarf_attr_integrate (die,
7173 DW_AT_type,
7174 &attr), &type),
7175 &type) == 0)
7176 {
7177 Dwarf_Word val;
7178 *is_signed = (dwarf_formudata (dwarf_attr (&type, DW_AT_encoding,
7179 &attr), &val) == 0
7180 && (val == DW_ATE_signed || val == DW_ATE_signed_char));
7181
7182 if (dwarf_aggregate_size (&type, &val) == 0)
7183 *bytes = val;
7184 }
7185 }
7186
7187 struct attrcb_args
7188 {
7189 Dwfl_Module *dwflmod;
7190 Dwarf *dbg;
7191 Dwarf_Die *dies;
7192 int level;
7193 bool silent;
7194 bool is_split;
7195 unsigned int version;
7196 unsigned int addrsize;
7197 unsigned int offset_size;
7198 struct Dwarf_CU *cu;
7199 };
7200
7201
7202 static int
attr_callback(Dwarf_Attribute * attrp,void * arg)7203 attr_callback (Dwarf_Attribute *attrp, void *arg)
7204 {
7205 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
7206 const int level = cbargs->level;
7207 Dwarf_Die *die = &cbargs->dies[level];
7208 bool is_split = cbargs->is_split;
7209
7210 unsigned int attr = dwarf_whatattr (attrp);
7211 if (unlikely (attr == 0))
7212 {
7213 if (!cbargs->silent)
7214 error (0, 0, _("DIE [%" PRIx64 "] "
7215 "cannot get attribute code: %s"),
7216 dwarf_dieoffset (die), dwarf_errmsg (-1));
7217 return DWARF_CB_ABORT;
7218 }
7219
7220 unsigned int form = dwarf_whatform (attrp);
7221 if (unlikely (form == 0))
7222 {
7223 if (!cbargs->silent)
7224 error (0, 0, _("DIE [%" PRIx64 "] "
7225 "cannot get attribute form: %s"),
7226 dwarf_dieoffset (die), dwarf_errmsg (-1));
7227 return DWARF_CB_ABORT;
7228 }
7229
7230 switch (form)
7231 {
7232 case DW_FORM_addr:
7233 case DW_FORM_addrx:
7234 case DW_FORM_addrx1:
7235 case DW_FORM_addrx2:
7236 case DW_FORM_addrx3:
7237 case DW_FORM_addrx4:
7238 case DW_FORM_GNU_addr_index:
7239 if (!cbargs->silent)
7240 {
7241 Dwarf_Addr addr;
7242 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
7243 {
7244 attrval_out:
7245 if (!cbargs->silent)
7246 error (0, 0, _("DIE [%" PRIx64 "] "
7247 "cannot get attribute '%s' (%s) value: "
7248 "%s"),
7249 dwarf_dieoffset (die),
7250 dwarf_attr_name (attr),
7251 dwarf_form_name (form),
7252 dwarf_errmsg (-1));
7253 /* Don't ABORT, it might be other attributes can be resolved. */
7254 return DWARF_CB_OK;
7255 }
7256 if (form != DW_FORM_addr )
7257 {
7258 Dwarf_Word word;
7259 if (dwarf_formudata (attrp, &word) != 0)
7260 goto attrval_out;
7261 printf (" %*s%-20s (%s) [%" PRIx64 "] ",
7262 (int) (level * 2), "", dwarf_attr_name (attr),
7263 dwarf_form_name (form), word);
7264 }
7265 else
7266 printf (" %*s%-20s (%s) ",
7267 (int) (level * 2), "", dwarf_attr_name (attr),
7268 dwarf_form_name (form));
7269 print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr, addr);
7270 printf ("\n");
7271 }
7272 break;
7273
7274 case DW_FORM_indirect:
7275 case DW_FORM_strp:
7276 case DW_FORM_line_strp:
7277 case DW_FORM_strx:
7278 case DW_FORM_strx1:
7279 case DW_FORM_strx2:
7280 case DW_FORM_strx3:
7281 case DW_FORM_strx4:
7282 case DW_FORM_string:
7283 case DW_FORM_GNU_strp_alt:
7284 case DW_FORM_GNU_str_index:
7285 if (cbargs->silent)
7286 break;
7287 const char *str = dwarf_formstring (attrp);
7288 if (unlikely (str == NULL))
7289 goto attrval_out;
7290 printf (" %*s%-20s (%s) \"%s\"\n",
7291 (int) (level * 2), "", dwarf_attr_name (attr),
7292 dwarf_form_name (form), str);
7293 break;
7294
7295 case DW_FORM_ref_addr:
7296 case DW_FORM_ref_udata:
7297 case DW_FORM_ref8:
7298 case DW_FORM_ref4:
7299 case DW_FORM_ref2:
7300 case DW_FORM_ref1:
7301 case DW_FORM_GNU_ref_alt:
7302 case DW_FORM_ref_sup4:
7303 case DW_FORM_ref_sup8:
7304 if (cbargs->silent)
7305 break;
7306 Dwarf_Die ref;
7307 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
7308 goto attrval_out;
7309
7310 printf (" %*s%-20s (%s) ",
7311 (int) (level * 2), "", dwarf_attr_name (attr),
7312 dwarf_form_name (form));
7313 if (is_split)
7314 printf ("{%6" PRIxMAX "}\n", (uintmax_t) dwarf_dieoffset (&ref));
7315 else
7316 printf ("[%6" PRIxMAX "]\n", (uintmax_t) dwarf_dieoffset (&ref));
7317 break;
7318
7319 case DW_FORM_ref_sig8:
7320 if (cbargs->silent)
7321 break;
7322 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
7323 (int) (level * 2), "", dwarf_attr_name (attr),
7324 dwarf_form_name (form),
7325 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
7326 break;
7327
7328 case DW_FORM_sec_offset:
7329 case DW_FORM_rnglistx:
7330 case DW_FORM_loclistx:
7331 case DW_FORM_implicit_const:
7332 case DW_FORM_udata:
7333 case DW_FORM_sdata:
7334 case DW_FORM_data8: /* Note no data16 here, we see that as block. */
7335 case DW_FORM_data4:
7336 case DW_FORM_data2:
7337 case DW_FORM_data1:;
7338 Dwarf_Word num;
7339 if (unlikely (dwarf_formudata (attrp, &num) != 0))
7340 goto attrval_out;
7341
7342 const char *valuestr = NULL;
7343 bool as_hex_id = false;
7344 switch (attr)
7345 {
7346 /* This case can take either a constant or a loclistptr. */
7347 case DW_AT_data_member_location:
7348 if (form != DW_FORM_sec_offset
7349 && (cbargs->version >= 4
7350 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
7351 {
7352 if (!cbargs->silent)
7353 printf (" %*s%-20s (%s) %" PRIuMAX "\n",
7354 (int) (level * 2), "", dwarf_attr_name (attr),
7355 dwarf_form_name (form), (uintmax_t) num);
7356 return DWARF_CB_OK;
7357 }
7358 FALLTHROUGH;
7359
7360 /* These cases always take a loclist[ptr] and no constant. */
7361 case DW_AT_location:
7362 case DW_AT_data_location:
7363 case DW_AT_vtable_elem_location:
7364 case DW_AT_string_length:
7365 case DW_AT_use_location:
7366 case DW_AT_frame_base:
7367 case DW_AT_return_addr:
7368 case DW_AT_static_link:
7369 case DW_AT_segment:
7370 case DW_AT_GNU_call_site_value:
7371 case DW_AT_GNU_call_site_data_value:
7372 case DW_AT_GNU_call_site_target:
7373 case DW_AT_GNU_call_site_target_clobbered:
7374 case DW_AT_GNU_locviews:
7375 {
7376 bool nlpt;
7377 if (cbargs->cu->version < 5)
7378 {
7379 if (! cbargs->is_split)
7380 {
7381 nlpt = notice_listptr (section_loc, &known_locsptr,
7382 cbargs->addrsize,
7383 cbargs->offset_size,
7384 cbargs->cu, num, attr);
7385 }
7386 else
7387 nlpt = true;
7388 }
7389 else
7390 {
7391 /* Only register for a real section offset. Otherwise
7392 it is a DW_FORM_loclistx which is just an index
7393 number and we should already have registered the
7394 section offset for the index when we saw the
7395 DW_AT_loclists_base CU attribute. */
7396 if (form == DW_FORM_sec_offset)
7397 nlpt = notice_listptr (section_loc, &known_loclistsptr,
7398 cbargs->addrsize, cbargs->offset_size,
7399 cbargs->cu, num, attr);
7400 else
7401 nlpt = true;
7402
7403 }
7404
7405 if (!cbargs->silent)
7406 {
7407 if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7408 printf (" %*s%-20s (%s) location list [%6"
7409 PRIxMAX "]%s\n",
7410 (int) (level * 2), "", dwarf_attr_name (attr),
7411 dwarf_form_name (form), (uintmax_t) num,
7412 nlpt ? "" : " <WARNING offset too big>");
7413 else
7414 printf (" %*s%-20s (%s) location index [%6"
7415 PRIxMAX "]\n",
7416 (int) (level * 2), "", dwarf_attr_name (attr),
7417 dwarf_form_name (form), (uintmax_t) num);
7418 }
7419 }
7420 return DWARF_CB_OK;
7421
7422 case DW_AT_loclists_base:
7423 {
7424 bool nlpt = notice_listptr (section_loc, &known_loclistsptr,
7425 cbargs->addrsize, cbargs->offset_size,
7426 cbargs->cu, num, attr);
7427
7428 if (!cbargs->silent)
7429 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
7430 (int) (level * 2), "", dwarf_attr_name (attr),
7431 dwarf_form_name (form), (uintmax_t) num,
7432 nlpt ? "" : " <WARNING offset too big>");
7433 }
7434 return DWARF_CB_OK;
7435
7436 case DW_AT_ranges:
7437 case DW_AT_start_scope:
7438 {
7439 bool nlpt;
7440 if (cbargs->cu->version < 5)
7441 nlpt = notice_listptr (section_ranges, &known_rangelistptr,
7442 cbargs->addrsize, cbargs->offset_size,
7443 cbargs->cu, num, attr);
7444 else
7445 {
7446 /* Only register for a real section offset. Otherwise
7447 it is a DW_FORM_rangelistx which is just an index
7448 number and we should already have registered the
7449 section offset for the index when we saw the
7450 DW_AT_rnglists_base CU attribute. */
7451 if (form == DW_FORM_sec_offset)
7452 nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7453 cbargs->addrsize, cbargs->offset_size,
7454 cbargs->cu, num, attr);
7455 else
7456 nlpt = true;
7457 }
7458
7459 if (!cbargs->silent)
7460 {
7461 if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7462 printf (" %*s%-20s (%s) range list [%6"
7463 PRIxMAX "]%s\n",
7464 (int) (level * 2), "", dwarf_attr_name (attr),
7465 dwarf_form_name (form), (uintmax_t) num,
7466 nlpt ? "" : " <WARNING offset too big>");
7467 else
7468 printf (" %*s%-20s (%s) range index [%6"
7469 PRIxMAX "]\n",
7470 (int) (level * 2), "", dwarf_attr_name (attr),
7471 dwarf_form_name (form), (uintmax_t) num);
7472 }
7473 }
7474 return DWARF_CB_OK;
7475
7476 case DW_AT_rnglists_base:
7477 {
7478 bool nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7479 cbargs->addrsize, cbargs->offset_size,
7480 cbargs->cu, num, attr);
7481 if (!cbargs->silent)
7482 printf (" %*s%-20s (%s) range list [%6"
7483 PRIxMAX "]%s\n",
7484 (int) (level * 2), "", dwarf_attr_name (attr),
7485 dwarf_form_name (form), (uintmax_t) num,
7486 nlpt ? "" : " <WARNING offset too big>");
7487 }
7488 return DWARF_CB_OK;
7489
7490 case DW_AT_addr_base:
7491 case DW_AT_GNU_addr_base:
7492 {
7493 bool addrbase = notice_listptr (section_addr, &known_addrbases,
7494 cbargs->addrsize,
7495 cbargs->offset_size,
7496 cbargs->cu, num, attr);
7497 if (!cbargs->silent)
7498 printf (" %*s%-20s (%s) address base [%6"
7499 PRIxMAX "]%s\n",
7500 (int) (level * 2), "", dwarf_attr_name (attr),
7501 dwarf_form_name (form), (uintmax_t) num,
7502 addrbase ? "" : " <WARNING offset too big>");
7503 }
7504 return DWARF_CB_OK;
7505
7506 case DW_AT_str_offsets_base:
7507 {
7508 bool stroffbase = notice_listptr (section_str, &known_stroffbases,
7509 cbargs->addrsize,
7510 cbargs->offset_size,
7511 cbargs->cu, num, attr);
7512 if (!cbargs->silent)
7513 printf (" %*s%-20s (%s) str offsets base [%6"
7514 PRIxMAX "]%s\n",
7515 (int) (level * 2), "", dwarf_attr_name (attr),
7516 dwarf_form_name (form), (uintmax_t) num,
7517 stroffbase ? "" : " <WARNING offset too big>");
7518 }
7519 return DWARF_CB_OK;
7520
7521 case DW_AT_language:
7522 valuestr = dwarf_lang_name (num);
7523 break;
7524 case DW_AT_encoding:
7525 valuestr = dwarf_encoding_name (num);
7526 break;
7527 case DW_AT_accessibility:
7528 valuestr = dwarf_access_name (num);
7529 break;
7530 case DW_AT_defaulted:
7531 valuestr = dwarf_defaulted_name (num);
7532 break;
7533 case DW_AT_visibility:
7534 valuestr = dwarf_visibility_name (num);
7535 break;
7536 case DW_AT_virtuality:
7537 valuestr = dwarf_virtuality_name (num);
7538 break;
7539 case DW_AT_identifier_case:
7540 valuestr = dwarf_identifier_case_name (num);
7541 break;
7542 case DW_AT_calling_convention:
7543 valuestr = dwarf_calling_convention_name (num);
7544 break;
7545 case DW_AT_inline:
7546 valuestr = dwarf_inline_name (num);
7547 break;
7548 case DW_AT_ordering:
7549 valuestr = dwarf_ordering_name (num);
7550 break;
7551 case DW_AT_decl_file:
7552 case DW_AT_call_file:
7553 {
7554 if (cbargs->silent)
7555 break;
7556
7557 /* Try to get the actual file, the current interface only
7558 gives us full paths, but we only want to show the file
7559 name for now. */
7560 Dwarf_Die cudie;
7561 if (dwarf_cu_die (cbargs->cu, &cudie,
7562 NULL, NULL, NULL, NULL, NULL, NULL) != NULL)
7563 {
7564 Dwarf_Files *files;
7565 size_t nfiles;
7566 if (dwarf_getsrcfiles (&cudie, &files, &nfiles) == 0)
7567 {
7568 valuestr = dwarf_filesrc (files, num, NULL, NULL);
7569 if (valuestr != NULL)
7570 {
7571 char *filename = strrchr (valuestr, '/');
7572 if (filename != NULL)
7573 valuestr = filename + 1;
7574 }
7575 else
7576 error (0, 0, _("invalid file (%" PRId64 "): %s"),
7577 num, dwarf_errmsg (-1));
7578 }
7579 else
7580 error (0, 0, _("no srcfiles for CU [%" PRIx64 "]"),
7581 dwarf_dieoffset (&cudie));
7582 }
7583 else
7584 error (0, 0, _("couldn't get DWARF CU: %s"),
7585 dwarf_errmsg (-1));
7586 if (valuestr == NULL)
7587 valuestr = "???";
7588 }
7589 break;
7590 case DW_AT_GNU_dwo_id:
7591 as_hex_id = true;
7592 break;
7593
7594 default:
7595 /* Nothing. */
7596 break;
7597 }
7598
7599 if (cbargs->silent)
7600 break;
7601
7602 /* When highpc is in constant form it is relative to lowpc.
7603 In that case also show the address. */
7604 Dwarf_Addr highpc;
7605 if (attr == DW_AT_high_pc && dwarf_highpc (die, &highpc) == 0)
7606 {
7607 printf (" %*s%-20s (%s) %" PRIuMAX " (",
7608 (int) (level * 2), "", dwarf_attr_name (attr),
7609 dwarf_form_name (form), (uintmax_t) num);
7610 print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, highpc, highpc);
7611 printf (")\n");
7612 }
7613 else
7614 {
7615 if (as_hex_id)
7616 {
7617 printf (" %*s%-20s (%s) 0x%.16" PRIx64 "\n",
7618 (int) (level * 2), "", dwarf_attr_name (attr),
7619 dwarf_form_name (form), num);
7620 }
7621 else
7622 {
7623 Dwarf_Sword snum = 0;
7624 bool is_signed;
7625 int bytes = 0;
7626 if (attr == DW_AT_const_value)
7627 die_type_sign_bytes (die, &is_signed, &bytes);
7628 else
7629 is_signed = (form == DW_FORM_sdata
7630 || form == DW_FORM_implicit_const);
7631
7632 if (is_signed)
7633 if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
7634 goto attrval_out;
7635
7636 if (valuestr == NULL)
7637 {
7638 printf (" %*s%-20s (%s) ",
7639 (int) (level * 2), "", dwarf_attr_name (attr),
7640 dwarf_form_name (form));
7641 }
7642 else
7643 {
7644 printf (" %*s%-20s (%s) %s (",
7645 (int) (level * 2), "", dwarf_attr_name (attr),
7646 dwarf_form_name (form), valuestr);
7647 }
7648
7649 switch (bytes)
7650 {
7651 case 1:
7652 if (is_signed)
7653 printf ("%" PRId8, (int8_t) snum);
7654 else
7655 printf ("%" PRIu8, (uint8_t) num);
7656 break;
7657
7658 case 2:
7659 if (is_signed)
7660 printf ("%" PRId16, (int16_t) snum);
7661 else
7662 printf ("%" PRIu16, (uint16_t) num);
7663 break;
7664
7665 case 4:
7666 if (is_signed)
7667 printf ("%" PRId32, (int32_t) snum);
7668 else
7669 printf ("%" PRIu32, (uint32_t) num);
7670 break;
7671
7672 case 8:
7673 if (is_signed)
7674 printf ("%" PRId64, (int64_t) snum);
7675 else
7676 printf ("%" PRIu64, (uint64_t) num);
7677 break;
7678
7679 default:
7680 if (is_signed)
7681 printf ("%" PRIdMAX, (intmax_t) snum);
7682 else
7683 printf ("%" PRIuMAX, (uintmax_t) num);
7684 break;
7685 }
7686
7687 /* Make clear if we switched from a signed encoding to
7688 an unsigned value. */
7689 if (attr == DW_AT_const_value
7690 && (form == DW_FORM_sdata || form == DW_FORM_implicit_const)
7691 && !is_signed)
7692 printf (" (%" PRIdMAX ")", (intmax_t) num);
7693
7694 if (valuestr == NULL)
7695 printf ("\n");
7696 else
7697 printf (")\n");
7698 }
7699 }
7700 break;
7701
7702 case DW_FORM_flag:
7703 if (cbargs->silent)
7704 break;
7705 bool flag;
7706 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
7707 goto attrval_out;
7708
7709 printf (" %*s%-20s (%s) %s\n",
7710 (int) (level * 2), "", dwarf_attr_name (attr),
7711 dwarf_form_name (form), flag ? yes_str : no_str);
7712 break;
7713
7714 case DW_FORM_flag_present:
7715 if (cbargs->silent)
7716 break;
7717 printf (" %*s%-20s (%s) %s\n",
7718 (int) (level * 2), "", dwarf_attr_name (attr),
7719 dwarf_form_name (form), yes_str);
7720 break;
7721
7722 case DW_FORM_exprloc:
7723 case DW_FORM_block4:
7724 case DW_FORM_block2:
7725 case DW_FORM_block1:
7726 case DW_FORM_block:
7727 case DW_FORM_data16: /* DWARF5 calls this a constant class. */
7728 if (cbargs->silent)
7729 break;
7730 Dwarf_Block block;
7731 if (unlikely (dwarf_formblock (attrp, &block) != 0))
7732 goto attrval_out;
7733
7734 printf (" %*s%-20s (%s) ",
7735 (int) (level * 2), "", dwarf_attr_name (attr),
7736 dwarf_form_name (form));
7737
7738 switch (attr)
7739 {
7740 default:
7741 if (form != DW_FORM_exprloc)
7742 {
7743 print_block (block.length, block.data);
7744 break;
7745 }
7746 FALLTHROUGH;
7747
7748 case DW_AT_location:
7749 case DW_AT_data_location:
7750 case DW_AT_data_member_location:
7751 case DW_AT_vtable_elem_location:
7752 case DW_AT_string_length:
7753 case DW_AT_use_location:
7754 case DW_AT_frame_base:
7755 case DW_AT_return_addr:
7756 case DW_AT_static_link:
7757 case DW_AT_allocated:
7758 case DW_AT_associated:
7759 case DW_AT_bit_size:
7760 case DW_AT_bit_offset:
7761 case DW_AT_bit_stride:
7762 case DW_AT_byte_size:
7763 case DW_AT_byte_stride:
7764 case DW_AT_count:
7765 case DW_AT_lower_bound:
7766 case DW_AT_upper_bound:
7767 case DW_AT_GNU_call_site_value:
7768 case DW_AT_GNU_call_site_data_value:
7769 case DW_AT_GNU_call_site_target:
7770 case DW_AT_GNU_call_site_target_clobbered:
7771 if (form == DW_FORM_exprloc
7772 || (form != DW_FORM_data16
7773 && attrp->cu->version < 4)) /* blocks were expressions. */
7774 {
7775 putchar ('\n');
7776 print_ops (cbargs->dwflmod, cbargs->dbg,
7777 12 + level * 2, 12 + level * 2,
7778 cbargs->version, cbargs->addrsize, cbargs->offset_size,
7779 attrp->cu, block.length, block.data);
7780 }
7781 else
7782 print_block (block.length, block.data);
7783 break;
7784
7785 case DW_AT_discr_list:
7786 if (block.length == 0)
7787 puts ("<default>");
7788 else if (form != DW_FORM_data16)
7789 {
7790 const unsigned char *readp = block.data;
7791 const unsigned char *readendp = readp + block.length;
7792
7793 /* See if we are dealing with a signed or unsigned
7794 values. If the parent of this variant DIE is a
7795 variant_part then it will either have a discriminant
7796 which points to the member which type is the
7797 discriminant type. Or the variant_part itself has a
7798 type representing the discriminant. */
7799 bool is_signed = false;
7800 if (level > 0)
7801 {
7802 Dwarf_Die *parent = &cbargs->dies[level - 1];
7803 if (dwarf_tag (die) == DW_TAG_variant
7804 && dwarf_tag (parent) == DW_TAG_variant_part)
7805 {
7806 Dwarf_Die member;
7807 Dwarf_Attribute discr_attr;
7808 int bytes;
7809 if (dwarf_formref_die (dwarf_attr (parent,
7810 DW_AT_discr,
7811 &discr_attr),
7812 &member) != NULL)
7813 die_type_sign_bytes (&member, &is_signed, &bytes);
7814 else
7815 die_type_sign_bytes (parent, &is_signed, &bytes);
7816 }
7817 }
7818 while (readp < readendp)
7819 {
7820 int d = (int) *readp++;
7821 printf ("%s ", dwarf_discr_list_name (d));
7822 if (readp >= readendp)
7823 goto attrval_out;
7824
7825 Dwarf_Word val;
7826 Dwarf_Sword sval;
7827 if (d == DW_DSC_label)
7828 {
7829 if (is_signed)
7830 {
7831 get_sleb128 (sval, readp, readendp);
7832 printf ("%" PRId64 "", sval);
7833 }
7834 else
7835 {
7836 get_uleb128 (val, readp, readendp);
7837 printf ("%" PRIu64 "", val);
7838 }
7839 }
7840 else if (d == DW_DSC_range)
7841 {
7842 if (is_signed)
7843 {
7844 get_sleb128 (sval, readp, readendp);
7845 printf ("%" PRId64 "..", sval);
7846 if (readp >= readendp)
7847 goto attrval_out;
7848 get_sleb128 (sval, readp, readendp);
7849 printf ("%" PRId64 "", sval);
7850 }
7851 else
7852 {
7853 get_uleb128 (val, readp, readendp);
7854 printf ("%" PRIu64 "..", val);
7855 if (readp >= readendp)
7856 goto attrval_out;
7857 get_uleb128 (val, readp, readendp);
7858 printf ("%" PRIu64 "", val);
7859 }
7860 }
7861 else
7862 {
7863 print_block (readendp - readp, readp);
7864 break;
7865 }
7866 if (readp < readendp)
7867 printf (", ");
7868 }
7869 putchar ('\n');
7870 }
7871 else
7872 print_block (block.length, block.data);
7873 break;
7874 }
7875 break;
7876
7877 default:
7878 if (cbargs->silent)
7879 break;
7880 printf (" %*s%-20s (%s) ???\n",
7881 (int) (level * 2), "", dwarf_attr_name (attr),
7882 dwarf_form_name (form));
7883 break;
7884 }
7885
7886 return DWARF_CB_OK;
7887 }
7888
7889 static void
print_debug_units(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg,bool debug_types)7890 print_debug_units (Dwfl_Module *dwflmod,
7891 Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
7892 Elf_Scn *scn, GElf_Shdr *shdr,
7893 Dwarf *dbg, bool debug_types)
7894 {
7895 const bool silent = !(print_debug_sections & section_info) && !debug_types;
7896 const char *secname = section_name (ebl, shdr);
7897
7898 if (!silent)
7899 printf (_("\
7900 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
7901 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
7902
7903 /* If the section is empty we don't have to do anything. */
7904 if (!silent && shdr->sh_size == 0)
7905 return;
7906
7907 int maxdies = 20;
7908 Dwarf_Die *dies = xmalloc (maxdies * sizeof (Dwarf_Die));
7909
7910 /* New compilation unit. */
7911 Dwarf_Half version;
7912
7913 Dwarf_Die result;
7914 Dwarf_Off abbroffset;
7915 uint8_t addrsize;
7916 uint8_t offsize;
7917 uint64_t unit_id;
7918 Dwarf_Off subdie_off;
7919
7920 int unit_res;
7921 Dwarf_CU *cu;
7922 Dwarf_CU cu_mem;
7923 uint8_t unit_type;
7924 Dwarf_Die cudie;
7925
7926 /* We cheat a little because we want to see only the CUs from .debug_info
7927 or .debug_types. We know the Dwarf_CU struct layout. Set it up at
7928 the end of .debug_info if we want .debug_types only. Check the returned
7929 Dwarf_CU is still in the expected section. */
7930 if (debug_types)
7931 {
7932 cu_mem.dbg = dbg;
7933 cu_mem.end = dbg->sectiondata[IDX_debug_info]->d_size;
7934 cu_mem.sec_idx = IDX_debug_info;
7935 cu = &cu_mem;
7936 }
7937 else
7938 cu = NULL;
7939
7940 next_cu:
7941 unit_res = dwarf_get_units (dbg, cu, &cu, &version, &unit_type,
7942 &cudie, NULL);
7943 if (unit_res == 1)
7944 goto do_return;
7945
7946 if (unit_res == -1)
7947 {
7948 if (!silent)
7949 error (0, 0, _("cannot get next unit: %s"), dwarf_errmsg (-1));
7950 goto do_return;
7951 }
7952
7953 if (cu->sec_idx != (size_t) (debug_types ? IDX_debug_types : IDX_debug_info))
7954 goto do_return;
7955
7956 dwarf_cu_die (cu, &result, NULL, &abbroffset, &addrsize, &offsize,
7957 &unit_id, &subdie_off);
7958
7959 if (!silent)
7960 {
7961 Dwarf_Off offset = cu->start;
7962 if (debug_types && version < 5)
7963 {
7964 Dwarf_Die typedie;
7965 Dwarf_Off dieoffset;
7966 dieoffset = dwarf_dieoffset (dwarf_offdie_types (dbg, cu->start
7967 + subdie_off,
7968 &typedie));
7969 printf (_(" Type unit at offset %" PRIu64 ":\n"
7970 " Version: %" PRIu16
7971 ", Abbreviation section offset: %" PRIu64
7972 ", Address size: %" PRIu8
7973 ", Offset size: %" PRIu8
7974 "\n Type signature: %#" PRIx64
7975 ", Type offset: %#" PRIx64 " [%" PRIx64 "]\n"),
7976 (uint64_t) offset, version, abbroffset, addrsize, offsize,
7977 unit_id, (uint64_t) subdie_off, dieoffset);
7978 }
7979 else
7980 {
7981 printf (_(" Compilation unit at offset %" PRIu64 ":\n"
7982 " Version: %" PRIu16
7983 ", Abbreviation section offset: %" PRIu64
7984 ", Address size: %" PRIu8
7985 ", Offset size: %" PRIu8 "\n"),
7986 (uint64_t) offset, version, abbroffset, addrsize, offsize);
7987
7988 if (version >= 5 || (unit_type != DW_UT_compile
7989 && unit_type != DW_UT_partial))
7990 {
7991 printf (_(" Unit type: %s (%" PRIu8 ")"),
7992 dwarf_unit_name (unit_type), unit_type);
7993 if (unit_type == DW_UT_type
7994 || unit_type == DW_UT_skeleton
7995 || unit_type == DW_UT_split_compile
7996 || unit_type == DW_UT_split_type)
7997 printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7998 if (unit_type == DW_UT_type
7999 || unit_type == DW_UT_split_type)
8000 {
8001 Dwarf_Die typedie;
8002 Dwarf_Off dieoffset;
8003 dwarf_cu_info (cu, NULL, NULL, NULL, &typedie,
8004 NULL, NULL, NULL);
8005 dieoffset = dwarf_dieoffset (&typedie);
8006 printf (", Unit DIE off: %#" PRIx64 " [%" PRIx64 "]",
8007 subdie_off, dieoffset);
8008 }
8009 printf ("\n");
8010 }
8011 }
8012 }
8013
8014 if (version < 2 || version > 5
8015 || unit_type < DW_UT_compile || unit_type > DW_UT_split_type)
8016 {
8017 if (!silent)
8018 error (0, 0, _("unknown version (%d) or unit type (%d)"),
8019 version, unit_type);
8020 goto next_cu;
8021 }
8022
8023 struct attrcb_args args =
8024 {
8025 .dwflmod = dwflmod,
8026 .silent = silent,
8027 .version = version,
8028 .addrsize = addrsize,
8029 .offset_size = offsize
8030 };
8031
8032 bool is_split = false;
8033 int level = 0;
8034 dies[0] = cudie;
8035 args.cu = dies[0].cu;
8036 args.dbg = dbg;
8037 args.is_split = is_split;
8038
8039 /* We might return here again for the split CU subdie. */
8040 do_cu:
8041 do
8042 {
8043 Dwarf_Off offset = dwarf_dieoffset (&dies[level]);
8044 if (unlikely (offset == (Dwarf_Off) -1))
8045 {
8046 if (!silent)
8047 error (0, 0, _("cannot get DIE offset: %s"),
8048 dwarf_errmsg (-1));
8049 goto do_return;
8050 }
8051
8052 int tag = dwarf_tag (&dies[level]);
8053 if (unlikely (tag == DW_TAG_invalid))
8054 {
8055 if (!silent)
8056 error (0, 0, _("cannot get tag of DIE at offset [%" PRIx64
8057 "] in section '%s': %s"),
8058 (uint64_t) offset, secname, dwarf_errmsg (-1));
8059 goto do_return;
8060 }
8061
8062 if (!silent)
8063 {
8064 unsigned int code = dwarf_getabbrevcode (dies[level].abbrev);
8065 if (is_split)
8066 printf (" {%6" PRIx64 "} ", (uint64_t) offset);
8067 else
8068 printf (" [%6" PRIx64 "] ", (uint64_t) offset);
8069 printf ("%*s%-20s abbrev: %u\n", (int) (level * 2), "",
8070 dwarf_tag_name (tag), code);
8071 }
8072
8073 /* Print the attribute values. */
8074 args.level = level;
8075 args.dies = dies;
8076 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
8077
8078 /* Make room for the next level's DIE. */
8079 if (level + 1 == maxdies)
8080 dies = xrealloc (dies, (maxdies += 10) * sizeof (Dwarf_Die));
8081
8082 int res = dwarf_child (&dies[level], &dies[level + 1]);
8083 if (res > 0)
8084 {
8085 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
8086 if (level-- == 0)
8087 break;
8088
8089 if (unlikely (res == -1))
8090 {
8091 if (!silent)
8092 error (0, 0, _("cannot get next DIE: %s\n"),
8093 dwarf_errmsg (-1));
8094 goto do_return;
8095 }
8096 }
8097 else if (unlikely (res < 0))
8098 {
8099 if (!silent)
8100 error (0, 0, _("cannot get next DIE: %s"),
8101 dwarf_errmsg (-1));
8102 goto do_return;
8103 }
8104 else
8105 ++level;
8106 }
8107 while (level >= 0);
8108
8109 /* We might want to show the split compile unit if this was a skeleton.
8110 We need to scan it if we are requesting printing .debug_ranges for
8111 DWARF4 since GNU DebugFission uses "offsets" into the main ranges
8112 section. */
8113 if (unit_type == DW_UT_skeleton
8114 && ((!silent && show_split_units)
8115 || (version < 5 && (print_debug_sections & section_ranges) != 0)))
8116 {
8117 Dwarf_Die subdie;
8118 if (dwarf_cu_info (cu, NULL, NULL, NULL, &subdie, NULL, NULL, NULL) != 0
8119 || dwarf_tag (&subdie) == DW_TAG_invalid)
8120 {
8121 if (!silent)
8122 {
8123 Dwarf_Attribute dwo_at;
8124 const char *dwo_name =
8125 (dwarf_formstring (dwarf_attr (&cudie, DW_AT_dwo_name,
8126 &dwo_at))
8127 ?: (dwarf_formstring (dwarf_attr (&cudie, DW_AT_GNU_dwo_name,
8128 &dwo_at))
8129 ?: "<unknown>"));
8130 fprintf (stderr,
8131 "Could not find split unit '%s', id: %" PRIx64 "\n",
8132 dwo_name, unit_id);
8133 }
8134 }
8135 else
8136 {
8137 Dwarf_CU *split_cu = subdie.cu;
8138 dwarf_cu_die (split_cu, &result, NULL, &abbroffset,
8139 &addrsize, &offsize, &unit_id, &subdie_off);
8140 Dwarf_Off offset = cu->start;
8141
8142 if (!silent)
8143 {
8144 printf (_(" Split compilation unit at offset %"
8145 PRIu64 ":\n"
8146 " Version: %" PRIu16
8147 ", Abbreviation section offset: %" PRIu64
8148 ", Address size: %" PRIu8
8149 ", Offset size: %" PRIu8 "\n"),
8150 (uint64_t) offset, version, abbroffset,
8151 addrsize, offsize);
8152 printf (_(" Unit type: %s (%" PRIu8 ")"),
8153 dwarf_unit_name (unit_type), unit_type);
8154 printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
8155 printf ("\n");
8156 }
8157
8158 unit_type = DW_UT_split_compile;
8159 is_split = true;
8160 level = 0;
8161 dies[0] = subdie;
8162 args.cu = dies[0].cu;
8163 args.dbg = split_cu->dbg;
8164 args.is_split = is_split;
8165 goto do_cu;
8166 }
8167 }
8168
8169 /* And again... */
8170 goto next_cu;
8171
8172 do_return:
8173 free (dies);
8174 }
8175
8176 static void
print_debug_info_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8177 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8178 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8179 {
8180 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
8181 }
8182
8183 static void
print_debug_types_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8184 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8185 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8186 {
8187 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
8188 }
8189
8190
8191 static void
print_decoded_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8192 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
8193 GElf_Ehdr *ehdr __attribute__ ((unused)),
8194 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8195 {
8196 printf (_("\
8197 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
8198 elf_ndxscn (scn), section_name (ebl, shdr),
8199 (uint64_t) shdr->sh_offset);
8200
8201 size_t address_size
8202 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
8203
8204 Dwarf_Lines *lines;
8205 size_t nlines;
8206 Dwarf_Off off, next_off = 0;
8207 Dwarf_CU *cu = NULL;
8208 while (dwarf_next_lines (dbg, off = next_off, &next_off, &cu, NULL, NULL,
8209 &lines, &nlines) == 0)
8210 {
8211 Dwarf_Die cudie;
8212 if (cu != NULL && dwarf_cu_info (cu, NULL, NULL, &cudie,
8213 NULL, NULL, NULL, NULL) == 0)
8214 printf (" CU [%" PRIx64 "] %s\n",
8215 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8216 else
8217 {
8218 /* DWARF5 lines can be independent of any CU, but they probably
8219 are used by some CU. Determine the CU this block is for. */
8220 Dwarf_Off cuoffset;
8221 Dwarf_Off ncuoffset = 0;
8222 size_t hsize;
8223 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
8224 NULL, NULL, NULL) == 0)
8225 {
8226 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
8227 continue;
8228 Dwarf_Attribute stmt_list;
8229 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
8230 continue;
8231 Dwarf_Word lineoff;
8232 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
8233 continue;
8234 if (lineoff == off)
8235 {
8236 /* Found the CU. */
8237 cu = cudie.cu;
8238 break;
8239 }
8240 }
8241
8242 if (cu != NULL)
8243 printf (" CU [%" PRIx64 "] %s\n",
8244 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8245 else
8246 printf (" No CU\n");
8247 }
8248
8249 printf (" line:col SBPE* disc isa op address"
8250 " (Statement Block Prologue Epilogue *End)\n");
8251 const char *last_file = "";
8252 for (size_t n = 0; n < nlines; n++)
8253 {
8254 Dwarf_Line *line = dwarf_onesrcline (lines, n);
8255 if (line == NULL)
8256 {
8257 printf (" dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
8258 continue;
8259 }
8260 Dwarf_Word mtime, length;
8261 const char *file = dwarf_linesrc (line, &mtime, &length);
8262 if (file == NULL)
8263 {
8264 printf (" <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
8265 last_file = "";
8266 }
8267 else if (strcmp (last_file, file) != 0)
8268 {
8269 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
8270 file, mtime, length);
8271 last_file = file;
8272 }
8273
8274 int lineno, colno;
8275 bool statement, endseq, block, prologue_end, epilogue_begin;
8276 unsigned int lineop, isa, disc;
8277 Dwarf_Addr address;
8278 dwarf_lineaddr (line, &address);
8279 dwarf_lineno (line, &lineno);
8280 dwarf_linecol (line, &colno);
8281 dwarf_lineop_index (line, &lineop);
8282 dwarf_linebeginstatement (line, &statement);
8283 dwarf_lineendsequence (line, &endseq);
8284 dwarf_lineblock (line, &block);
8285 dwarf_lineprologueend (line, &prologue_end);
8286 dwarf_lineepiloguebegin (line, &epilogue_begin);
8287 dwarf_lineisa (line, &isa);
8288 dwarf_linediscriminator (line, &disc);
8289
8290 /* End sequence is special, it is one byte past. */
8291 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d ",
8292 lineno, colno,
8293 (statement ? 'S' : ' '),
8294 (block ? 'B' : ' '),
8295 (prologue_end ? 'P' : ' '),
8296 (epilogue_begin ? 'E' : ' '),
8297 (endseq ? '*' : ' '),
8298 disc, isa, lineop);
8299 print_dwarf_addr (dwflmod, address_size,
8300 address - (endseq ? 1 : 0), address);
8301 printf ("\n");
8302
8303 if (endseq)
8304 printf("\n");
8305 }
8306 }
8307 }
8308
8309
8310 /* Print the value of a form.
8311 Returns new value of readp, or readendp on failure. */
8312 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)8313 print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
8314 const unsigned char *readendp, unsigned int offset_len,
8315 Dwarf_Off str_offsets_base)
8316 {
8317 Dwarf_Word val;
8318 unsigned char *endp;
8319 Elf_Data *data;
8320 char *str;
8321 switch (form)
8322 {
8323 case DW_FORM_data1:
8324 if (readendp - readp < 1)
8325 {
8326 invalid_data:
8327 error (0, 0, "invalid data");
8328 return readendp;
8329 }
8330 val = *readp++;
8331 printf (" %" PRIx8, (unsigned int) val);
8332 break;
8333
8334 case DW_FORM_data2:
8335 if (readendp - readp < 2)
8336 goto invalid_data;
8337 val = read_2ubyte_unaligned_inc (dbg, readp);
8338 printf(" %" PRIx16, (unsigned int) val);
8339 break;
8340
8341 case DW_FORM_data4:
8342 if (readendp - readp < 4)
8343 goto invalid_data;
8344 val = read_4ubyte_unaligned_inc (dbg, readp);
8345 printf (" %" PRIx32, (unsigned int) val);
8346 break;
8347
8348 case DW_FORM_data8:
8349 if (readendp - readp < 8)
8350 goto invalid_data;
8351 val = read_8ubyte_unaligned_inc (dbg, readp);
8352 printf (" %" PRIx64, val);
8353 break;
8354
8355 case DW_FORM_sdata:
8356 if (readendp - readp < 1)
8357 goto invalid_data;
8358 get_sleb128 (val, readp, readendp);
8359 printf (" %" PRIx64, val);
8360 break;
8361
8362 case DW_FORM_udata:
8363 if (readendp - readp < 1)
8364 goto invalid_data;
8365 get_uleb128 (val, readp, readendp);
8366 printf (" %" PRIx64, val);
8367 break;
8368
8369 case DW_FORM_block:
8370 if (readendp - readp < 1)
8371 goto invalid_data;
8372 get_uleb128 (val, readp, readendp);
8373 if ((size_t) (readendp - readp) < val)
8374 goto invalid_data;
8375 print_bytes (val, readp);
8376 readp += val;
8377 break;
8378
8379 case DW_FORM_block1:
8380 if (readendp - readp < 1)
8381 goto invalid_data;
8382 val = *readp++;
8383 if ((size_t) (readendp - readp) < val)
8384 goto invalid_data;
8385 print_bytes (val, readp);
8386 readp += val;
8387 break;
8388
8389 case DW_FORM_block2:
8390 if (readendp - readp < 2)
8391 goto invalid_data;
8392 val = read_2ubyte_unaligned_inc (dbg, readp);
8393 if ((size_t) (readendp - readp) < val)
8394 goto invalid_data;
8395 print_bytes (val, readp);
8396 readp += val;
8397 break;
8398
8399 case DW_FORM_block4:
8400 if (readendp - readp < 4)
8401 goto invalid_data;
8402 val = read_4ubyte_unaligned_inc (dbg, readp);
8403 if ((size_t) (readendp - readp) < val)
8404 goto invalid_data;
8405 print_bytes (val, readp);
8406 readp += val;
8407 break;
8408
8409 case DW_FORM_data16:
8410 if (readendp - readp < 16)
8411 goto invalid_data;
8412 print_bytes (16, readp);
8413 readp += 16;
8414 break;
8415
8416 case DW_FORM_flag:
8417 if (readendp - readp < 1)
8418 goto invalid_data;
8419 val = *readp++;
8420 printf ("%s", val != 0 ? yes_str : no_str);
8421 break;
8422
8423 case DW_FORM_string:
8424 endp = memchr (readp, '\0', readendp - readp);
8425 if (endp == NULL)
8426 goto invalid_data;
8427 printf ("%s", readp);
8428 readp = endp + 1;
8429 break;
8430
8431 case DW_FORM_strp:
8432 case DW_FORM_line_strp:
8433 case DW_FORM_strp_sup:
8434 if ((size_t) (readendp - readp) < offset_len)
8435 goto invalid_data;
8436 if (offset_len == 8)
8437 val = read_8ubyte_unaligned_inc (dbg, readp);
8438 else
8439 val = read_4ubyte_unaligned_inc (dbg, readp);
8440 if (form == DW_FORM_strp)
8441 data = dbg->sectiondata[IDX_debug_str];
8442 else if (form == DW_FORM_line_strp)
8443 data = dbg->sectiondata[IDX_debug_line_str];
8444 else /* form == DW_FORM_strp_sup */
8445 {
8446 Dwarf *alt = dwarf_getalt (dbg);
8447 data = alt != NULL ? alt->sectiondata[IDX_debug_str] : NULL;
8448 }
8449 if (data == NULL || val >= data->d_size
8450 || memchr (data->d_buf + val, '\0', data->d_size - val) == NULL)
8451 str = "???";
8452 else
8453 str = (char *) data->d_buf + val;
8454 printf ("%s (%" PRIu64 ")", str, val);
8455 break;
8456
8457 case DW_FORM_sec_offset:
8458 if ((size_t) (readendp - readp) < offset_len)
8459 goto invalid_data;
8460 if (offset_len == 8)
8461 val = read_8ubyte_unaligned_inc (dbg, readp);
8462 else
8463 val = read_4ubyte_unaligned_inc (dbg, readp);
8464 printf ("[%" PRIx64 "]", val);
8465 break;
8466
8467 case DW_FORM_strx:
8468 case DW_FORM_GNU_str_index:
8469 if (readendp - readp < 1)
8470 goto invalid_data;
8471 get_uleb128 (val, readp, readendp);
8472 strx_val:
8473 data = dbg->sectiondata[IDX_debug_str_offsets];
8474 if (data == NULL
8475 || data->d_size - str_offsets_base < val)
8476 str = "???";
8477 else
8478 {
8479 const unsigned char *strreadp = data->d_buf + str_offsets_base + val;
8480 const unsigned char *strreadendp = data->d_buf + data->d_size;
8481 if ((size_t) (strreadendp - strreadp) < offset_len)
8482 str = "???";
8483 else
8484 {
8485 Dwarf_Off idx;
8486 if (offset_len == 8)
8487 idx = read_8ubyte_unaligned (dbg, strreadp);
8488 else
8489 idx = read_4ubyte_unaligned (dbg, strreadp);
8490
8491 data = dbg->sectiondata[IDX_debug_str];
8492 if (data == NULL || idx >= data->d_size
8493 || memchr (data->d_buf + idx, '\0',
8494 data->d_size - idx) == NULL)
8495 str = "???";
8496 else
8497 str = (char *) data->d_buf + idx;
8498 }
8499 }
8500 printf ("%s (%" PRIu64 ")", str, val);
8501 break;
8502
8503 case DW_FORM_strx1:
8504 if (readendp - readp < 1)
8505 goto invalid_data;
8506 val = *readp++;
8507 goto strx_val;
8508
8509 case DW_FORM_strx2:
8510 if (readendp - readp < 2)
8511 goto invalid_data;
8512 val = read_2ubyte_unaligned_inc (dbg, readp);
8513 goto strx_val;
8514
8515 case DW_FORM_strx3:
8516 if (readendp - readp < 3)
8517 goto invalid_data;
8518 val = read_3ubyte_unaligned_inc (dbg, readp);
8519 goto strx_val;
8520
8521 case DW_FORM_strx4:
8522 if (readendp - readp < 4)
8523 goto invalid_data;
8524 val = read_4ubyte_unaligned_inc (dbg, readp);
8525 goto strx_val;
8526
8527 default:
8528 error (0, 0, _("unknown form: %s"), dwarf_form_name (form));
8529 return readendp;
8530 }
8531
8532 return readp;
8533 }
8534
8535 /* Only used via run_advance_pc() macro */
8536 static inline void
run_advance_pc(unsigned int op_advance,unsigned int minimum_instr_len,unsigned int max_ops_per_instr,unsigned int * op_addr_advance,Dwarf_Word * address,unsigned int * op_index)8537 run_advance_pc (unsigned int op_advance,
8538 unsigned int minimum_instr_len,
8539 unsigned int max_ops_per_instr,
8540 unsigned int *op_addr_advance,
8541 Dwarf_Word *address,
8542 unsigned int *op_index)
8543 {
8544 const unsigned int advanced_op_index = (*op_index) + op_advance;
8545
8546 *op_addr_advance = minimum_instr_len * (advanced_op_index
8547 / max_ops_per_instr);
8548 *address = *address + *op_addr_advance;
8549 *op_index = advanced_op_index % max_ops_per_instr;
8550 }
8551
8552 static void
print_debug_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8553 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8554 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8555 {
8556 if (decodedline)
8557 {
8558 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
8559 return;
8560 }
8561
8562 printf (_("\
8563 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
8564 elf_ndxscn (scn), section_name (ebl, shdr),
8565 (uint64_t) shdr->sh_offset);
8566
8567 if (shdr->sh_size == 0)
8568 return;
8569
8570 /* There is no functionality in libdw to read the information in the
8571 way it is represented here. Hardcode the decoder. */
8572 Elf_Data *data = (dbg->sectiondata[IDX_debug_line]
8573 ?: elf_rawdata (scn, NULL));
8574 if (unlikely (data == NULL))
8575 {
8576 error (0, 0, _("cannot get line data section data: %s"),
8577 elf_errmsg (-1));
8578 return;
8579 }
8580
8581 const unsigned char *linep = (const unsigned char *) data->d_buf;
8582 const unsigned char *lineendp;
8583
8584 while (linep
8585 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
8586 {
8587 size_t start_offset = linep - (const unsigned char *) data->d_buf;
8588
8589 printf (_("\nTable at offset %zu:\n"), start_offset);
8590
8591 if (unlikely (linep + 4 > lineendp))
8592 goto invalid_data;
8593 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
8594 unsigned int length = 4;
8595 if (unlikely (unit_length == 0xffffffff))
8596 {
8597 if (unlikely (linep + 8 > lineendp))
8598 {
8599 invalid_data:
8600 error (0, 0, _("invalid data in section [%zu] '%s'"),
8601 elf_ndxscn (scn), section_name (ebl, shdr));
8602 return;
8603 }
8604 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
8605 length = 8;
8606 }
8607
8608 /* Check whether we have enough room in the section. */
8609 if (unlikely (unit_length > (size_t) (lineendp - linep)))
8610 goto invalid_data;
8611 lineendp = linep + unit_length;
8612
8613 /* The next element of the header is the version identifier. */
8614 if ((size_t) (lineendp - linep) < 2)
8615 goto invalid_data;
8616 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
8617
8618 size_t address_size
8619 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
8620 unsigned char segment_selector_size = 0;
8621 if (version > 4)
8622 {
8623 if ((size_t) (lineendp - linep) < 2)
8624 goto invalid_data;
8625 address_size = *linep++;
8626 segment_selector_size = *linep++;
8627 }
8628
8629 /* Next comes the header length. */
8630 Dwarf_Word header_length;
8631 if (length == 4)
8632 {
8633 if ((size_t) (lineendp - linep) < 4)
8634 goto invalid_data;
8635 header_length = read_4ubyte_unaligned_inc (dbg, linep);
8636 }
8637 else
8638 {
8639 if ((size_t) (lineendp - linep) < 8)
8640 goto invalid_data;
8641 header_length = read_8ubyte_unaligned_inc (dbg, linep);
8642 }
8643
8644 const unsigned char *header_start = linep;
8645
8646 /* Next the minimum instruction length. */
8647 if ((size_t) (lineendp - linep) < 1)
8648 goto invalid_data;
8649 uint_fast8_t minimum_instr_len = *linep++;
8650
8651 /* Next the maximum operations per instruction, in version 4 format. */
8652 uint_fast8_t max_ops_per_instr;
8653 if (version < 4)
8654 max_ops_per_instr = 1;
8655 else
8656 {
8657 if ((size_t) (lineendp - linep) < 1)
8658 goto invalid_data;
8659 max_ops_per_instr = *linep++;
8660 }
8661
8662 /* We need at least 4 more bytes. */
8663 if ((size_t) (lineendp - linep) < 4)
8664 goto invalid_data;
8665
8666 /* Then the flag determining the default value of the is_stmt
8667 register. */
8668 uint_fast8_t default_is_stmt = *linep++;
8669
8670 /* Now the line base. */
8671 int_fast8_t line_base = *linep++;
8672
8673 /* And the line range. */
8674 uint_fast8_t line_range = *linep++;
8675
8676 /* The opcode base. */
8677 uint_fast8_t opcode_base = *linep++;
8678
8679 /* Print what we got so far. */
8680 printf (_("\n"
8681 " Length: %" PRIu64 "\n"
8682 " DWARF version: %" PRIuFAST16 "\n"
8683 " Prologue length: %" PRIu64 "\n"
8684 " Address size: %zd\n"
8685 " Segment selector size: %zd\n"
8686 " Min instruction length: %" PRIuFAST8 "\n"
8687 " Max operations per instruction: %" PRIuFAST8 "\n"
8688 " Initial value if 'is_stmt': %" PRIuFAST8 "\n"
8689 " Line base: %" PRIdFAST8 "\n"
8690 " Line range: %" PRIuFAST8 "\n"
8691 " Opcode base: %" PRIuFAST8 "\n"
8692 "\n"
8693 "Opcodes:\n"),
8694 (uint64_t) unit_length, version, (uint64_t) header_length,
8695 address_size, (size_t) segment_selector_size,
8696 minimum_instr_len, max_ops_per_instr,
8697 default_is_stmt, line_base,
8698 line_range, opcode_base);
8699
8700 if (version < 2 || version > 5)
8701 {
8702 error (0, 0, _("cannot handle .debug_line version: %u\n"),
8703 (unsigned int) version);
8704 linep = lineendp;
8705 continue;
8706 }
8707
8708 if (address_size != 4 && address_size != 8)
8709 {
8710 error (0, 0, _("cannot handle address size: %u\n"),
8711 (unsigned int) address_size);
8712 linep = lineendp;
8713 continue;
8714 }
8715
8716 if (segment_selector_size != 0)
8717 {
8718 error (0, 0, _("cannot handle segment selector size: %u\n"),
8719 (unsigned int) segment_selector_size);
8720 linep = lineendp;
8721 continue;
8722 }
8723
8724 if (unlikely (linep + opcode_base - 1 >= lineendp))
8725 {
8726 invalid_unit:
8727 error (0, 0,
8728 _("invalid data at offset %tu in section [%zu] '%s'"),
8729 linep - (const unsigned char *) data->d_buf,
8730 elf_ndxscn (scn), section_name (ebl, shdr));
8731 linep = lineendp;
8732 continue;
8733 }
8734 int opcode_base_l10 = 1;
8735 unsigned int tmp = opcode_base;
8736 while (tmp > 10)
8737 {
8738 tmp /= 10;
8739 ++opcode_base_l10;
8740 }
8741 const uint8_t *standard_opcode_lengths = linep - 1;
8742 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
8743 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
8744 " [%*" PRIuFAST8 "] %hhu arguments\n",
8745 (int) linep[cnt - 1]),
8746 opcode_base_l10, cnt, linep[cnt - 1]);
8747 linep += opcode_base - 1;
8748
8749 if (unlikely (linep >= lineendp))
8750 goto invalid_unit;
8751
8752 Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, NULL);
8753
8754 puts (_("\nDirectory table:"));
8755 if (version > 4)
8756 {
8757 struct encpair { uint16_t desc; uint16_t form; };
8758 struct encpair enc[256];
8759
8760 printf (_(" ["));
8761 if ((size_t) (lineendp - linep) < 1)
8762 goto invalid_data;
8763 unsigned char directory_entry_format_count = *linep++;
8764 for (int i = 0; i < directory_entry_format_count; i++)
8765 {
8766 uint16_t desc, form;
8767 if ((size_t) (lineendp - linep) < 1)
8768 goto invalid_data;
8769 get_uleb128 (desc, linep, lineendp);
8770 if ((size_t) (lineendp - linep) < 1)
8771 goto invalid_data;
8772 get_uleb128 (form, linep, lineendp);
8773
8774 enc[i].desc = desc;
8775 enc[i].form = form;
8776
8777 printf ("%s(%s)",
8778 dwarf_line_content_description_name (desc),
8779 dwarf_form_name (form));
8780 if (i + 1 < directory_entry_format_count)
8781 printf (", ");
8782 }
8783 printf ("]\n");
8784
8785 uint64_t directories_count;
8786 if ((size_t) (lineendp - linep) < 1)
8787 goto invalid_data;
8788 get_uleb128 (directories_count, linep, lineendp);
8789
8790 if (directory_entry_format_count == 0
8791 && directories_count != 0)
8792 goto invalid_data;
8793
8794 for (uint64_t i = 0; i < directories_count; i++)
8795 {
8796 printf (" %-5" PRIu64 " ", i);
8797 for (int j = 0; j < directory_entry_format_count; j++)
8798 {
8799 linep = print_form_data (dbg, enc[j].form,
8800 linep, lineendp, length,
8801 str_offsets_base);
8802 if (j + 1 < directory_entry_format_count)
8803 printf (", ");
8804 }
8805 printf ("\n");
8806 if (linep >= lineendp)
8807 goto invalid_unit;
8808 }
8809 }
8810 else
8811 {
8812 while (linep < lineendp && *linep != 0)
8813 {
8814 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
8815 if (unlikely (endp == NULL))
8816 goto invalid_unit;
8817
8818 printf (" %s\n", (char *) linep);
8819
8820 linep = endp + 1;
8821 }
8822 if (linep >= lineendp || *linep != 0)
8823 goto invalid_unit;
8824 /* Skip the final NUL byte. */
8825 ++linep;
8826 }
8827
8828 if (unlikely (linep >= lineendp))
8829 goto invalid_unit;
8830
8831 puts (_("\nFile name table:"));
8832 if (version > 4)
8833 {
8834 struct encpair { uint16_t desc; uint16_t form; };
8835 struct encpair enc[256];
8836
8837 printf (_(" ["));
8838 if ((size_t) (lineendp - linep) < 1)
8839 goto invalid_data;
8840 unsigned char file_name_format_count = *linep++;
8841 for (int i = 0; i < file_name_format_count; i++)
8842 {
8843 uint64_t desc, form;
8844 if ((size_t) (lineendp - linep) < 1)
8845 goto invalid_data;
8846 get_uleb128 (desc, linep, lineendp);
8847 if ((size_t) (lineendp - linep) < 1)
8848 goto invalid_data;
8849 get_uleb128 (form, linep, lineendp);
8850
8851 if (! libdw_valid_user_form (form))
8852 goto invalid_data;
8853
8854 enc[i].desc = desc;
8855 enc[i].form = form;
8856
8857 printf ("%s(%s)",
8858 dwarf_line_content_description_name (desc),
8859 dwarf_form_name (form));
8860 if (i + 1 < file_name_format_count)
8861 printf (", ");
8862 }
8863 printf ("]\n");
8864
8865 uint64_t file_name_count;
8866 if ((size_t) (lineendp - linep) < 1)
8867 goto invalid_data;
8868 get_uleb128 (file_name_count, linep, lineendp);
8869
8870 if (file_name_format_count == 0
8871 && file_name_count != 0)
8872 goto invalid_data;
8873
8874 for (uint64_t i = 0; i < file_name_count; i++)
8875 {
8876 printf (" %-5" PRIu64 " ", i);
8877 for (int j = 0; j < file_name_format_count; j++)
8878 {
8879 linep = print_form_data (dbg, enc[j].form,
8880 linep, lineendp, length,
8881 str_offsets_base);
8882 if (j + 1 < file_name_format_count)
8883 printf (", ");
8884 }
8885 printf ("\n");
8886 if (linep > lineendp)
8887 goto invalid_unit;
8888 }
8889 }
8890 else
8891 {
8892 puts (_(" Entry Dir Time Size Name"));
8893 for (unsigned int cnt = 1; linep < lineendp && *linep != 0; ++cnt)
8894 {
8895 /* First comes the file name. */
8896 char *fname = (char *) linep;
8897 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
8898 if (unlikely (endp == NULL))
8899 goto invalid_unit;
8900 linep = endp + 1;
8901
8902 /* Then the index. */
8903 unsigned int diridx;
8904 if (lineendp - linep < 1)
8905 goto invalid_unit;
8906 get_uleb128 (diridx, linep, lineendp);
8907
8908 /* Next comes the modification time. */
8909 unsigned int mtime;
8910 if (lineendp - linep < 1)
8911 goto invalid_unit;
8912 get_uleb128 (mtime, linep, lineendp);
8913
8914 /* Finally the length of the file. */
8915 unsigned int fsize;
8916 if (lineendp - linep < 1)
8917 goto invalid_unit;
8918 get_uleb128 (fsize, linep, lineendp);
8919
8920 printf (" %-5u %-5u %-9u %-9u %s\n",
8921 cnt, diridx, mtime, fsize, fname);
8922 }
8923 if (linep >= lineendp || *linep != '\0')
8924 goto invalid_unit;
8925 /* Skip the final NUL byte. */
8926 ++linep;
8927 }
8928
8929 unsigned int debug_str_offset = 0;
8930 if (unlikely (linep == header_start + header_length - 4))
8931 {
8932 /* CUBINs contain an unsigned 4-byte offset */
8933 debug_str_offset = read_4ubyte_unaligned_inc (dbg, linep);
8934 }
8935
8936 if (linep == lineendp)
8937 {
8938 puts (_("\nNo line number statements."));
8939 continue;
8940 }
8941
8942 puts (_("\nLine number statements:"));
8943 Dwarf_Word address = 0;
8944 unsigned int op_index = 0;
8945 size_t line = 1;
8946 uint_fast8_t is_stmt = default_is_stmt;
8947
8948 /* Apply the "operation advance" from a special opcode
8949 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
8950 unsigned int op_addr_advance;
8951 #define advance_pc(op_advance) run_advance_pc(op_advance, minimum_instr_len, \
8952 max_ops_per_instr, &op_addr_advance, &address, &op_index)
8953
8954 if (max_ops_per_instr == 0)
8955 {
8956 error (0, 0,
8957 _("invalid maximum operations per instruction is zero"));
8958 linep = lineendp;
8959 continue;
8960 }
8961
8962 while (linep < lineendp)
8963 {
8964 size_t offset = linep - (const unsigned char *) data->d_buf;
8965 unsigned int u128;
8966 int s128;
8967
8968 /* Read the opcode. */
8969 unsigned int opcode = *linep++;
8970
8971 printf (" [%6" PRIx64 "]", (uint64_t)offset);
8972 /* Is this a special opcode? */
8973 if (likely (opcode >= opcode_base))
8974 {
8975 if (unlikely (line_range == 0))
8976 goto invalid_unit;
8977
8978 /* Yes. Handling this is quite easy since the opcode value
8979 is computed with
8980
8981 opcode = (desired line increment - line_base)
8982 + (line_range * address advance) + opcode_base
8983 */
8984 int line_increment = (line_base
8985 + (opcode - opcode_base) % line_range);
8986
8987 /* Perform the increments. */
8988 line += line_increment;
8989 advance_pc ((opcode - opcode_base) / line_range);
8990
8991 printf (_(" special opcode %u: address+%u = "),
8992 opcode, op_addr_advance);
8993 print_dwarf_addr (dwflmod, 0, address, address);
8994 if (op_index > 0)
8995 printf (_(", op_index = %u, line%+d = %zu\n"),
8996 op_index, line_increment, line);
8997 else
8998 printf (_(", line%+d = %zu\n"),
8999 line_increment, line);
9000 }
9001 else if (opcode == 0)
9002 {
9003 /* This an extended opcode. */
9004 if (unlikely (linep + 2 > lineendp))
9005 goto invalid_unit;
9006
9007 /* The length. */
9008 unsigned int len = *linep++;
9009
9010 if (unlikely (linep + len > lineendp))
9011 goto invalid_unit;
9012
9013 /* The sub-opcode. */
9014 opcode = *linep++;
9015
9016 printf (_(" extended opcode %u: "), opcode);
9017
9018 switch (opcode)
9019 {
9020 case DW_LNE_end_sequence:
9021 puts (_(" end of sequence"));
9022
9023 /* Reset the registers we care about. */
9024 address = 0;
9025 op_index = 0;
9026 line = 1;
9027 is_stmt = default_is_stmt;
9028 break;
9029
9030 case DW_LNE_set_address:
9031 op_index = 0;
9032 if (unlikely ((size_t) (lineendp - linep) < address_size))
9033 goto invalid_unit;
9034 if (address_size == 4)
9035 address = read_4ubyte_unaligned_inc (dbg, linep);
9036 else
9037 address = read_8ubyte_unaligned_inc (dbg, linep);
9038 {
9039 printf (_(" set address to "));
9040 print_dwarf_addr (dwflmod, 0, address, address);
9041 printf ("\n");
9042 }
9043 break;
9044
9045 case DW_LNE_define_file:
9046 {
9047 char *fname = (char *) linep;
9048 unsigned char *endp = memchr (linep, '\0',
9049 lineendp - linep);
9050 if (unlikely (endp == NULL))
9051 goto invalid_unit;
9052 linep = endp + 1;
9053
9054 unsigned int diridx;
9055 if (lineendp - linep < 1)
9056 goto invalid_unit;
9057 get_uleb128 (diridx, linep, lineendp);
9058 Dwarf_Word mtime;
9059 if (lineendp - linep < 1)
9060 goto invalid_unit;
9061 get_uleb128 (mtime, linep, lineendp);
9062 Dwarf_Word filelength;
9063 if (lineendp - linep < 1)
9064 goto invalid_unit;
9065 get_uleb128 (filelength, linep, lineendp);
9066
9067 printf (_("\
9068 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
9069 diridx, (uint64_t) mtime, (uint64_t) filelength,
9070 fname);
9071 }
9072 break;
9073
9074 case DW_LNE_set_discriminator:
9075 /* Takes one ULEB128 parameter, the discriminator. */
9076 if (unlikely (standard_opcode_lengths[opcode] != 1
9077 || lineendp - linep < 1))
9078 goto invalid_unit;
9079
9080 get_uleb128 (u128, linep, lineendp);
9081 printf (_(" set discriminator to %u\n"), u128);
9082 break;
9083
9084 case DW_LNE_NVIDIA_inlined_call:
9085 {
9086 if (unlikely (linep >= lineendp))
9087 goto invalid_data;
9088
9089 unsigned int context;
9090 get_uleb128 (context, linep, lineendp);
9091
9092 if (unlikely (linep >= lineendp))
9093 goto invalid_data;
9094
9095 unsigned int function_name;
9096 get_uleb128 (function_name, linep, lineendp);
9097 function_name += debug_str_offset;
9098
9099 Elf_Data *str_data = dbg->sectiondata[IDX_debug_str];
9100 char *function_str;
9101 if (str_data == NULL || function_name >= str_data->d_size
9102 || memchr (str_data->d_buf + function_name, '\0',
9103 str_data->d_size - function_name) == NULL)
9104 function_str = "???";
9105 else
9106 function_str = (char *) str_data->d_buf + function_name;
9107
9108 printf (_(" set inlined context %u,"
9109 " function name %s (0x%x)\n"),
9110 context, function_str, function_name);
9111 break;
9112 }
9113
9114 case DW_LNE_NVIDIA_set_function_name:
9115 {
9116 if (unlikely (linep >= lineendp))
9117 goto invalid_data;
9118
9119 unsigned int function_name;
9120 get_uleb128 (function_name, linep, lineendp);
9121 function_name += debug_str_offset;
9122
9123 Elf_Data *str_data = dbg->sectiondata[IDX_debug_str];
9124 char *function_str;
9125 if (str_data == NULL || function_name >= str_data->d_size
9126 || memchr (str_data->d_buf + function_name, '\0',
9127 str_data->d_size - function_name) == NULL)
9128 function_str = "???";
9129 else
9130 function_str = (char *) str_data->d_buf + function_name;
9131
9132 printf (_(" set function name %s (0x%x)\n"),
9133 function_str, function_name);
9134 }
9135 break;
9136
9137 default:
9138 /* Unknown, ignore it. */
9139 puts (_(" unknown opcode"));
9140 linep += len - 1;
9141 break;
9142 }
9143 }
9144 else if (opcode <= DW_LNS_set_isa)
9145 {
9146 /* This is a known standard opcode. */
9147 switch (opcode)
9148 {
9149 case DW_LNS_copy:
9150 /* Takes no argument. */
9151 puts (_(" copy"));
9152 break;
9153
9154 case DW_LNS_advance_pc:
9155 /* Takes one uleb128 parameter which is added to the
9156 address. */
9157 if (lineendp - linep < 1)
9158 goto invalid_unit;
9159 get_uleb128 (u128, linep, lineendp);
9160 advance_pc (u128);
9161 {
9162 printf (_(" advance address by %u to "),
9163 op_addr_advance);
9164 print_dwarf_addr (dwflmod, 0, address, address);
9165 if (op_index > 0)
9166 printf (_(", op_index to %u"), op_index);
9167 printf ("\n");
9168 }
9169 break;
9170
9171 case DW_LNS_advance_line:
9172 /* Takes one sleb128 parameter which is added to the
9173 line. */
9174 if (lineendp - linep < 1)
9175 goto invalid_unit;
9176 get_sleb128 (s128, linep, lineendp);
9177 line += s128;
9178 printf (_("\
9179 advance line by constant %d to %" PRId64 "\n"),
9180 s128, (int64_t) line);
9181 break;
9182
9183 case DW_LNS_set_file:
9184 /* Takes one uleb128 parameter which is stored in file. */
9185 if (lineendp - linep < 1)
9186 goto invalid_unit;
9187 get_uleb128 (u128, linep, lineendp);
9188 printf (_(" set file to %" PRIu64 "\n"),
9189 (uint64_t) u128);
9190 break;
9191
9192 case DW_LNS_set_column:
9193 /* Takes one uleb128 parameter which is stored in column. */
9194 if (unlikely (standard_opcode_lengths[opcode] != 1
9195 || lineendp - linep < 1))
9196 goto invalid_unit;
9197
9198 get_uleb128 (u128, linep, lineendp);
9199 printf (_(" set column to %" PRIu64 "\n"),
9200 (uint64_t) u128);
9201 break;
9202
9203 case DW_LNS_negate_stmt:
9204 /* Takes no argument. */
9205 is_stmt = 1 - is_stmt;
9206 printf (_(" set '%s' to %" PRIuFAST8 "\n"),
9207 "is_stmt", is_stmt);
9208 break;
9209
9210 case DW_LNS_set_basic_block:
9211 /* Takes no argument. */
9212 puts (_(" set basic block flag"));
9213 break;
9214
9215 case DW_LNS_const_add_pc:
9216 /* Takes no argument. */
9217
9218 if (unlikely (line_range == 0))
9219 goto invalid_unit;
9220
9221 advance_pc ((255 - opcode_base) / line_range);
9222 {
9223 printf (_(" advance address by constant %u to "),
9224 op_addr_advance);
9225 print_dwarf_addr (dwflmod, 0, address, address);
9226 if (op_index > 0)
9227 printf (_(", op_index to %u"), op_index);
9228 printf ("\n");
9229 }
9230 break;
9231
9232 case DW_LNS_fixed_advance_pc:
9233 /* Takes one 16 bit parameter which is added to the
9234 address. */
9235 if (unlikely (standard_opcode_lengths[opcode] != 1
9236 || lineendp - linep < 2))
9237 goto invalid_unit;
9238
9239 u128 = read_2ubyte_unaligned_inc (dbg, linep);
9240 address += u128;
9241 op_index = 0;
9242 {
9243 printf (_("\
9244 advance address by fixed value %u to \n"),
9245 u128);
9246 print_dwarf_addr (dwflmod, 0, address, address);
9247 printf ("\n");
9248 }
9249 break;
9250
9251 case DW_LNS_set_prologue_end:
9252 /* Takes no argument. */
9253 puts (_(" set prologue end flag"));
9254 break;
9255
9256 case DW_LNS_set_epilogue_begin:
9257 /* Takes no argument. */
9258 puts (_(" set epilogue begin flag"));
9259 break;
9260
9261 case DW_LNS_set_isa:
9262 /* Takes one uleb128 parameter which is stored in isa. */
9263 if (unlikely (standard_opcode_lengths[opcode] != 1
9264 || lineendp - linep < 1))
9265 goto invalid_unit;
9266
9267 get_uleb128 (u128, linep, lineendp);
9268 printf (_(" set isa to %u\n"), u128);
9269 break;
9270 }
9271 }
9272 else
9273 {
9274 /* This is a new opcode the generator but not we know about.
9275 Read the parameters associated with it but then discard
9276 everything. Read all the parameters for this opcode. */
9277 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
9278 " unknown opcode with %" PRIu8 " parameters:",
9279 standard_opcode_lengths[opcode]),
9280 standard_opcode_lengths[opcode]);
9281 for (int n = standard_opcode_lengths[opcode];
9282 n > 0 && linep < lineendp; --n)
9283 {
9284 get_uleb128 (u128, linep, lineendp);
9285 if (n != standard_opcode_lengths[opcode])
9286 putc_unlocked (',', stdout);
9287 printf (" %u", u128);
9288 }
9289
9290 /* Next round, ignore this opcode. */
9291 continue;
9292 }
9293 }
9294 }
9295
9296 /* There must only be one data block. */
9297 assert (elf_getdata (scn, data) == NULL);
9298 }
9299
9300
9301 static void
print_debug_loclists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9302 print_debug_loclists_section (Dwfl_Module *dwflmod,
9303 Ebl *ebl,
9304 GElf_Ehdr *ehdr __attribute__ ((unused)),
9305 Elf_Scn *scn, GElf_Shdr *shdr,
9306 Dwarf *dbg)
9307 {
9308 printf (_("\
9309 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9310 elf_ndxscn (scn), section_name (ebl, shdr),
9311 (uint64_t) shdr->sh_offset);
9312
9313 Elf_Data *data = (dbg->sectiondata[IDX_debug_loclists]
9314 ?: elf_rawdata (scn, NULL));
9315 if (unlikely (data == NULL))
9316 {
9317 error (0, 0, _("cannot get .debug_loclists content: %s"),
9318 elf_errmsg (-1));
9319 return;
9320 }
9321
9322 /* For the listptr to get the base address/CU. */
9323 sort_listptr (&known_loclistsptr, "loclistsptr");
9324 size_t listptr_idx = 0;
9325
9326 const unsigned char *readp = data->d_buf;
9327 const unsigned char *const dataend = ((unsigned char *) data->d_buf
9328 + data->d_size);
9329 while (readp < dataend)
9330 {
9331 if (unlikely (readp > dataend - 4))
9332 {
9333 invalid_data:
9334 error (0, 0, _("invalid data in section [%zu] '%s'"),
9335 elf_ndxscn (scn), section_name (ebl, shdr));
9336 return;
9337 }
9338
9339 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9340 printf (_("Table at Offset 0x%" PRIx64 ":\n\n"),
9341 (uint64_t) offset);
9342
9343 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
9344 unsigned int offset_size = 4;
9345 if (unlikely (unit_length == 0xffffffff))
9346 {
9347 if (unlikely (readp > dataend - 8))
9348 goto invalid_data;
9349
9350 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
9351 offset_size = 8;
9352 }
9353 printf (_(" Length: %8" PRIu64 "\n"), unit_length);
9354
9355 /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
9356 bytes to complete the header. And this unit cannot go beyond
9357 the section data. */
9358 if (readp > dataend - 8
9359 || unit_length < 8
9360 || unit_length > (uint64_t) (dataend - readp))
9361 goto invalid_data;
9362
9363 const unsigned char *nexthdr = readp + unit_length;
9364
9365 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
9366 printf (_(" DWARF version: %8" PRIu16 "\n"), version);
9367
9368 if (version != 5)
9369 {
9370 error (0, 0, _("Unknown version"));
9371 goto next_table;
9372 }
9373
9374 uint8_t address_size = *readp++;
9375 printf (_(" Address size: %8" PRIu64 "\n"),
9376 (uint64_t) address_size);
9377
9378 if (address_size != 4 && address_size != 8)
9379 {
9380 error (0, 0, _("unsupported address size"));
9381 goto next_table;
9382 }
9383
9384 uint8_t segment_size = *readp++;
9385 printf (_(" Segment size: %8" PRIu64 "\n"),
9386 (uint64_t) segment_size);
9387
9388 if (segment_size != 0)
9389 {
9390 error (0, 0, _("unsupported segment size"));
9391 goto next_table;
9392 }
9393
9394 uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
9395 printf (_(" Offset entries: %8" PRIu64 "\n"),
9396 (uint64_t) offset_entry_count);
9397
9398 /* We need the CU that uses this unit to get the initial base address. */
9399 Dwarf_Addr cu_base = 0;
9400 struct Dwarf_CU *cu = NULL;
9401 if (listptr_cu (&known_loclistsptr, &listptr_idx,
9402 (Dwarf_Off) offset,
9403 (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
9404 &cu_base, &cu)
9405 || split_dwarf_cu_base (dbg, &cu, &cu_base))
9406 {
9407 Dwarf_Die cudie;
9408 if (dwarf_cu_die (cu, &cudie,
9409 NULL, NULL, NULL, NULL,
9410 NULL, NULL) == NULL)
9411 printf (_(" Unknown CU base: "));
9412 else
9413 printf (_(" CU [%6" PRIx64 "] base: "),
9414 dwarf_dieoffset (&cudie));
9415 print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
9416 printf ("\n");
9417 }
9418 else
9419 printf (_(" Not associated with a CU.\n"));
9420
9421 printf ("\n");
9422
9423 const unsigned char *offset_array_start = readp;
9424 if (offset_entry_count > 0)
9425 {
9426 uint64_t max_entries = (unit_length - 8) / offset_size;
9427 if (offset_entry_count > max_entries)
9428 {
9429 error (0, 0,
9430 _("too many offset entries for unit length"));
9431 offset_entry_count = max_entries;
9432 }
9433
9434 printf (_(" Offsets starting at 0x%" PRIx64 ":\n"),
9435 (uint64_t) (offset_array_start
9436 - (unsigned char *) data->d_buf));
9437 for (uint32_t idx = 0; idx < offset_entry_count; idx++)
9438 {
9439 printf (" [%6" PRIu32 "] ", idx);
9440 if (offset_size == 4)
9441 {
9442 uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
9443 printf ("0x%" PRIx32 "\n", off);
9444 }
9445 else
9446 {
9447 uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
9448 printf ("0x%" PRIx64 "\n", off);
9449 }
9450 }
9451 printf ("\n");
9452 }
9453
9454 Dwarf_Addr base = cu_base;
9455 bool start_of_list = true;
9456 while (readp < nexthdr)
9457 {
9458 Dwarf_Off off = (Dwarf_Off) (readp - (unsigned char *) data->d_buf);
9459 if (listptr_attr (&known_loclistsptr, listptr_idx, off,
9460 DW_AT_GNU_locviews))
9461 {
9462 Dwarf_Off next_off = next_listptr_offset (&known_loclistsptr,
9463 &listptr_idx, off);
9464 const unsigned char *locp = readp;
9465 const unsigned char *locendp;
9466 if (next_off == 0
9467 || next_off > (size_t) (nexthdr - ((const unsigned char *)
9468 data->d_buf)))
9469 locendp = nexthdr;
9470 else
9471 locendp = (const unsigned char *) data->d_buf + next_off;
9472
9473 printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9474 (uint64_t) (readp - (unsigned char *) data->d_buf),
9475 (uint64_t) (readp - offset_array_start));
9476
9477 while (locp < locendp)
9478 {
9479 uint64_t v1, v2;
9480 get_uleb128 (v1, locp, locendp);
9481 if (locp >= locendp)
9482 {
9483 printf (_(" <INVALID DATA>\n"));
9484 break;
9485 }
9486 get_uleb128 (v2, locp, locendp);
9487 printf (" view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
9488 }
9489
9490 printf ("\n");
9491 readp = (unsigned char *) locendp;
9492 continue;
9493 }
9494
9495 uint8_t kind = *readp++;
9496 uint64_t op1, op2, len;
9497
9498 /* Skip padding. */
9499 if (start_of_list && kind == DW_LLE_end_of_list)
9500 continue;
9501
9502 if (start_of_list)
9503 {
9504 base = cu_base;
9505 printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9506 (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
9507 (uint64_t) (readp - offset_array_start - 1));
9508 start_of_list = false;
9509 }
9510
9511 printf (" %s", dwarf_loc_list_encoding_name (kind));
9512 switch (kind)
9513 {
9514 case DW_LLE_end_of_list:
9515 start_of_list = true;
9516 printf ("\n\n");
9517 break;
9518
9519 case DW_LLE_base_addressx:
9520 if ((uint64_t) (nexthdr - readp) < 1)
9521 {
9522 invalid_entry:
9523 error (0, 0, _("invalid loclists data"));
9524 goto next_table;
9525 }
9526 get_uleb128 (op1, readp, nexthdr);
9527 printf (" %" PRIx64 "\n", op1);
9528 if (! print_unresolved_addresses)
9529 {
9530 Dwarf_Addr addr;
9531 if (get_indexed_addr (cu, op1, &addr) != 0)
9532 printf (" ???\n");
9533 else
9534 {
9535 printf (" ");
9536 print_dwarf_addr (dwflmod, address_size, addr, addr);
9537 printf ("\n");
9538 }
9539 }
9540 break;
9541
9542 case DW_LLE_startx_endx:
9543 if ((uint64_t) (nexthdr - readp) < 1)
9544 goto invalid_entry;
9545 get_uleb128 (op1, readp, nexthdr);
9546 if ((uint64_t) (nexthdr - readp) < 1)
9547 goto invalid_entry;
9548 get_uleb128 (op2, readp, nexthdr);
9549 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9550 if (! print_unresolved_addresses)
9551 {
9552 Dwarf_Addr addr1;
9553 Dwarf_Addr addr2;
9554 if (get_indexed_addr (cu, op1, &addr1) != 0
9555 || get_indexed_addr (cu, op2, &addr2) != 0)
9556 {
9557 printf (" ???..\n");
9558 printf (" ???\n");
9559 }
9560 else
9561 {
9562 printf (" ");
9563 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9564 printf ("..\n ");
9565 print_dwarf_addr (dwflmod, address_size,
9566 addr2 - 1, addr2);
9567 printf ("\n");
9568 }
9569 }
9570 if ((uint64_t) (nexthdr - readp) < 1)
9571 goto invalid_entry;
9572 get_uleb128 (len, readp, nexthdr);
9573 if ((uint64_t) (nexthdr - readp) < len)
9574 goto invalid_entry;
9575 print_ops (dwflmod, dbg, 8, 8, version,
9576 address_size, offset_size, cu, len, readp);
9577 readp += len;
9578 break;
9579
9580 case DW_LLE_startx_length:
9581 if ((uint64_t) (nexthdr - readp) < 1)
9582 goto invalid_entry;
9583 get_uleb128 (op1, readp, nexthdr);
9584 if ((uint64_t) (nexthdr - readp) < 1)
9585 goto invalid_entry;
9586 get_uleb128 (op2, readp, nexthdr);
9587 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9588 if (! print_unresolved_addresses)
9589 {
9590 Dwarf_Addr addr1;
9591 Dwarf_Addr addr2;
9592 if (get_indexed_addr (cu, op1, &addr1) != 0)
9593 {
9594 printf (" ???..\n");
9595 printf (" ???\n");
9596 }
9597 else
9598 {
9599 addr2 = addr1 + op2;
9600 printf (" ");
9601 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9602 printf ("..\n ");
9603 print_dwarf_addr (dwflmod, address_size,
9604 addr2 - 1, addr2);
9605 printf ("\n");
9606 }
9607 }
9608 if ((uint64_t) (nexthdr - readp) < 1)
9609 goto invalid_entry;
9610 get_uleb128 (len, readp, nexthdr);
9611 if ((uint64_t) (nexthdr - readp) < len)
9612 goto invalid_entry;
9613 print_ops (dwflmod, dbg, 8, 8, version,
9614 address_size, offset_size, cu, len, readp);
9615 readp += len;
9616 break;
9617
9618 case DW_LLE_offset_pair:
9619 if ((uint64_t) (nexthdr - readp) < 1)
9620 goto invalid_entry;
9621 get_uleb128 (op1, readp, nexthdr);
9622 if ((uint64_t) (nexthdr - readp) < 1)
9623 goto invalid_entry;
9624 get_uleb128 (op2, readp, nexthdr);
9625 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9626 if (! print_unresolved_addresses)
9627 {
9628 op1 += base;
9629 op2 += base;
9630 printf (" ");
9631 print_dwarf_addr (dwflmod, address_size, op1, op1);
9632 printf ("..\n ");
9633 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9634 printf ("\n");
9635 }
9636 if ((uint64_t) (nexthdr - readp) < 1)
9637 goto invalid_entry;
9638 get_uleb128 (len, readp, nexthdr);
9639 if ((uint64_t) (nexthdr - readp) < len)
9640 goto invalid_entry;
9641 print_ops (dwflmod, dbg, 8, 8, version,
9642 address_size, offset_size, cu, len, readp);
9643 readp += len;
9644 break;
9645
9646 case DW_LLE_default_location:
9647 if ((uint64_t) (nexthdr - readp) < 1)
9648 goto invalid_entry;
9649 get_uleb128 (len, readp, nexthdr);
9650 if ((uint64_t) (nexthdr - readp) < len)
9651 goto invalid_entry;
9652 print_ops (dwflmod, dbg, 8, 8, version,
9653 address_size, offset_size, cu, len, readp);
9654 readp += len;
9655 break;
9656
9657 case DW_LLE_base_address:
9658 if (address_size == 4)
9659 {
9660 if ((uint64_t) (nexthdr - readp) < 4)
9661 goto invalid_entry;
9662 op1 = read_4ubyte_unaligned_inc (dbg, readp);
9663 }
9664 else
9665 {
9666 if ((uint64_t) (nexthdr - readp) < 8)
9667 goto invalid_entry;
9668 op1 = read_8ubyte_unaligned_inc (dbg, readp);
9669 }
9670 base = op1;
9671 printf (" 0x%" PRIx64 "\n", base);
9672 if (! print_unresolved_addresses)
9673 {
9674 printf (" ");
9675 print_dwarf_addr (dwflmod, address_size, base, base);
9676 printf ("\n");
9677 }
9678 break;
9679
9680 case DW_LLE_start_end:
9681 if (address_size == 4)
9682 {
9683 if ((uint64_t) (nexthdr - readp) < 8)
9684 goto invalid_entry;
9685 op1 = read_4ubyte_unaligned_inc (dbg, readp);
9686 op2 = read_4ubyte_unaligned_inc (dbg, readp);
9687 }
9688 else
9689 {
9690 if ((uint64_t) (nexthdr - readp) < 16)
9691 goto invalid_entry;
9692 op1 = read_8ubyte_unaligned_inc (dbg, readp);
9693 op2 = read_8ubyte_unaligned_inc (dbg, readp);
9694 }
9695 printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
9696 if (! print_unresolved_addresses)
9697 {
9698 printf (" ");
9699 print_dwarf_addr (dwflmod, address_size, op1, op1);
9700 printf ("..\n ");
9701 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9702 printf ("\n");
9703 }
9704 if ((uint64_t) (nexthdr - readp) < 1)
9705 goto invalid_entry;
9706 get_uleb128 (len, readp, nexthdr);
9707 if ((uint64_t) (nexthdr - readp) < len)
9708 goto invalid_entry;
9709 print_ops (dwflmod, dbg, 8, 8, version,
9710 address_size, offset_size, cu, len, readp);
9711 readp += len;
9712 break;
9713
9714 case DW_LLE_start_length:
9715 if (address_size == 4)
9716 {
9717 if ((uint64_t) (nexthdr - readp) < 4)
9718 goto invalid_entry;
9719 op1 = read_4ubyte_unaligned_inc (dbg, readp);
9720 }
9721 else
9722 {
9723 if ((uint64_t) (nexthdr - readp) < 8)
9724 goto invalid_entry;
9725 op1 = read_8ubyte_unaligned_inc (dbg, readp);
9726 }
9727 if ((uint64_t) (nexthdr - readp) < 1)
9728 goto invalid_entry;
9729 get_uleb128 (op2, readp, nexthdr);
9730 printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
9731 if (! print_unresolved_addresses)
9732 {
9733 op2 = op1 + op2;
9734 printf (" ");
9735 print_dwarf_addr (dwflmod, address_size, op1, op1);
9736 printf ("..\n ");
9737 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9738 printf ("\n");
9739 }
9740 if ((uint64_t) (nexthdr - readp) < 1)
9741 goto invalid_entry;
9742 get_uleb128 (len, readp, nexthdr);
9743 if ((uint64_t) (nexthdr - readp) < len)
9744 goto invalid_entry;
9745 print_ops (dwflmod, dbg, 8, 8, version,
9746 address_size, offset_size, cu, len, readp);
9747 readp += len;
9748 break;
9749
9750 case DW_LLE_GNU_view_pair:
9751 if ((uint64_t) (nexthdr - readp) < 1)
9752 goto invalid_entry;
9753 get_uleb128 (op1, readp, nexthdr);
9754 if ((uint64_t) (nexthdr - readp) < 1)
9755 goto invalid_entry;
9756 get_uleb128 (op2, readp, nexthdr);
9757 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9758 break;
9759
9760 default:
9761 goto invalid_entry;
9762 }
9763 }
9764
9765 next_table:
9766 if (readp != nexthdr)
9767 {
9768 size_t padding = nexthdr - readp;
9769 printf (_(" %zu padding bytes\n\n"), padding);
9770 readp = nexthdr;
9771 }
9772 }
9773 }
9774
9775
9776 static void
print_debug_loc_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9777 print_debug_loc_section (Dwfl_Module *dwflmod,
9778 Ebl *ebl, GElf_Ehdr *ehdr,
9779 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9780 {
9781 Elf_Data *data = (dbg->sectiondata[IDX_debug_loc]
9782 ?: elf_rawdata (scn, NULL));
9783
9784 if (unlikely (data == NULL))
9785 {
9786 error (0, 0, _("cannot get .debug_loc content: %s"),
9787 elf_errmsg (-1));
9788 return;
9789 }
9790
9791 printf (_("\
9792 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9793 elf_ndxscn (scn), section_name (ebl, shdr),
9794 (uint64_t) shdr->sh_offset);
9795
9796 sort_listptr (&known_locsptr, "loclistptr");
9797 size_t listptr_idx = 0;
9798
9799 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
9800 uint_fast8_t offset_size = 4;
9801
9802 bool first = true;
9803 Dwarf_Addr base = 0;
9804 unsigned char *readp = data->d_buf;
9805 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
9806 Dwarf_CU *last_cu = NULL;
9807 while (readp < endp)
9808 {
9809 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9810 Dwarf_CU *cu = last_cu;
9811 unsigned int attr = 0;
9812
9813 if (first && skip_listptr_hole (&known_locsptr, &listptr_idx,
9814 &address_size, &offset_size, &base,
9815 &cu, offset, &readp, endp, &attr))
9816 continue;
9817
9818 if (last_cu != cu)
9819 {
9820 Dwarf_Die cudie;
9821 if (dwarf_cu_die (cu, &cudie,
9822 NULL, NULL, NULL, NULL,
9823 NULL, NULL) == NULL)
9824 printf (_("\n Unknown CU base: "));
9825 else
9826 printf (_("\n CU [%6" PRIx64 "] base: "),
9827 dwarf_dieoffset (&cudie));
9828 print_dwarf_addr (dwflmod, address_size, base, base);
9829 printf ("\n");
9830 }
9831 last_cu = cu;
9832
9833 if (attr == DW_AT_GNU_locviews)
9834 {
9835 Dwarf_Off next_off = next_listptr_offset (&known_locsptr,
9836 &listptr_idx, offset);
9837 const unsigned char *locp = readp;
9838 const unsigned char *locendp;
9839 if (next_off == 0
9840 || next_off > (size_t) (endp
9841 - (const unsigned char *) data->d_buf))
9842 locendp = endp;
9843 else
9844 locendp = (const unsigned char *) data->d_buf + next_off;
9845
9846 while (locp < locendp)
9847 {
9848 uint64_t v1, v2;
9849 get_uleb128 (v1, locp, locendp);
9850 if (locp >= locendp)
9851 {
9852 printf (_(" [%6tx] <INVALID DATA>\n"), offset);
9853 break;
9854 }
9855 get_uleb128 (v2, locp, locendp);
9856 if (first) /* First view pair in a list. */
9857 printf (" [%6tx] ", offset);
9858 else
9859 printf (" ");
9860 printf ("view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
9861 first = false;
9862 }
9863
9864 first = true;
9865 readp = (unsigned char *) locendp;
9866 continue;
9867 }
9868
9869 /* GNU DebugFission encoded addresses as addrx. */
9870 bool is_debugfission = ((cu != NULL
9871 || split_dwarf_cu_base (dbg, &cu, &base))
9872 && (cu->version < 5
9873 && cu->unit_type == DW_UT_split_compile));
9874 if (!is_debugfission
9875 && unlikely (data->d_size - offset < (size_t) address_size * 2))
9876 {
9877 invalid_data:
9878 printf (_(" [%6tx] <INVALID DATA>\n"), offset);
9879 break;
9880 }
9881
9882 Dwarf_Addr begin;
9883 Dwarf_Addr end;
9884 bool use_base = true;
9885 if (is_debugfission)
9886 {
9887 const unsigned char *locp = readp;
9888 const unsigned char *locendp = readp + data->d_size;
9889 if (locp >= locendp)
9890 goto invalid_data;
9891
9892 Dwarf_Word idx;
9893 unsigned char code = *locp++;
9894 switch (code)
9895 {
9896 case DW_LLE_GNU_end_of_list_entry:
9897 begin = 0;
9898 end = 0;
9899 break;
9900
9901 case DW_LLE_GNU_base_address_selection_entry:
9902 if (locp >= locendp)
9903 goto invalid_data;
9904 begin = (Dwarf_Addr) -1;
9905 get_uleb128 (idx, locp, locendp);
9906 if (get_indexed_addr (cu, idx, &end) != 0)
9907 end = idx; /* ... */
9908 break;
9909
9910 case DW_LLE_GNU_start_end_entry:
9911 if (locp >= locendp)
9912 goto invalid_data;
9913 get_uleb128 (idx, locp, locendp);
9914 if (get_indexed_addr (cu, idx, &begin) != 0)
9915 begin = idx; /* ... */
9916 if (locp >= locendp)
9917 goto invalid_data;
9918 get_uleb128 (idx, locp, locendp);
9919 if (get_indexed_addr (cu, idx, &end) != 0)
9920 end = idx; /* ... */
9921 use_base = false;
9922 break;
9923
9924 case DW_LLE_GNU_start_length_entry:
9925 if (locp >= locendp)
9926 goto invalid_data;
9927 get_uleb128 (idx, locp, locendp);
9928 if (get_indexed_addr (cu, idx, &begin) != 0)
9929 begin = idx; /* ... */
9930 if (locendp - locp < 4)
9931 goto invalid_data;
9932 end = read_4ubyte_unaligned_inc (dbg, locp);
9933 end += begin;
9934 use_base = false;
9935 break;
9936
9937 default:
9938 goto invalid_data;
9939 }
9940
9941 readp = (unsigned char *) locp;
9942 }
9943 else if (address_size == 8)
9944 {
9945 begin = read_8ubyte_unaligned_inc (dbg, readp);
9946 end = read_8ubyte_unaligned_inc (dbg, readp);
9947 }
9948 else
9949 {
9950 begin = read_4ubyte_unaligned_inc (dbg, readp);
9951 end = read_4ubyte_unaligned_inc (dbg, readp);
9952 if (begin == (Dwarf_Addr) (uint32_t) -1)
9953 begin = (Dwarf_Addr) -1l;
9954 }
9955
9956 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
9957 {
9958 if (first)
9959 printf (" [%6tx] ", offset);
9960 else
9961 printf (" ");
9962 puts (_("base address"));
9963 printf (" ");
9964 print_dwarf_addr (dwflmod, address_size, end, end);
9965 printf ("\n");
9966 base = end;
9967 first = false;
9968 }
9969 else if (begin == 0 && end == 0) /* End of list entry. */
9970 {
9971 if (first)
9972 printf (_(" [%6tx] empty list\n"), offset);
9973 first = true;
9974 }
9975 else
9976 {
9977 /* We have a location expression entry. */
9978 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
9979
9980 if (first) /* First entry in a list. */
9981 printf (" [%6tx] ", offset);
9982 else
9983 printf (" ");
9984
9985 printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
9986 if (! print_unresolved_addresses)
9987 {
9988 Dwarf_Addr dab = use_base ? base + begin : begin;
9989 Dwarf_Addr dae = use_base ? base + end : end;
9990 printf (" ");
9991 print_dwarf_addr (dwflmod, address_size, dab, dab);
9992 printf ("..\n ");
9993 print_dwarf_addr (dwflmod, address_size, dae - 1, dae);
9994 printf ("\n");
9995 }
9996
9997 if (endp - readp <= (ptrdiff_t) len)
9998 {
9999 fputs (_(" <INVALID DATA>\n"), stdout);
10000 break;
10001 }
10002
10003 print_ops (dwflmod, dbg, 11, 11,
10004 cu != NULL ? cu->version : 3,
10005 address_size, offset_size, cu, len, readp);
10006
10007 first = false;
10008 readp += len;
10009 }
10010 }
10011 }
10012
10013 struct mac_culist
10014 {
10015 Dwarf_Die die;
10016 Dwarf_Off offset;
10017 Dwarf_Files *files;
10018 struct mac_culist *next;
10019 };
10020
10021
10022 static int
mac_compare(const void * p1,const void * p2)10023 mac_compare (const void *p1, const void *p2)
10024 {
10025 struct mac_culist *m1 = (struct mac_culist *) p1;
10026 struct mac_culist *m2 = (struct mac_culist *) p2;
10027
10028 if (m1->offset < m2->offset)
10029 return -1;
10030 if (m1->offset > m2->offset)
10031 return 1;
10032 return 0;
10033 }
10034
10035
10036 static void
print_debug_macinfo_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10037 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10038 Ebl *ebl,
10039 GElf_Ehdr *ehdr __attribute__ ((unused)),
10040 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10041 {
10042 printf (_("\
10043 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10044 elf_ndxscn (scn), section_name (ebl, shdr),
10045 (uint64_t) shdr->sh_offset);
10046 putc_unlocked ('\n', stdout);
10047
10048 /* There is no function in libdw to iterate over the raw content of
10049 the section but it is easy enough to do. */
10050 Elf_Data *data = (dbg->sectiondata[IDX_debug_macinfo]
10051 ?: elf_rawdata (scn, NULL));
10052 if (unlikely (data == NULL))
10053 {
10054 error (0, 0, _("cannot get macro information section data: %s"),
10055 elf_errmsg (-1));
10056 return;
10057 }
10058
10059 /* Get the source file information for all CUs. */
10060 Dwarf_Off offset;
10061 Dwarf_Off ncu = 0;
10062 size_t hsize;
10063 struct mac_culist *culist = NULL;
10064 size_t nculist = 0;
10065 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
10066 {
10067 Dwarf_Die cudie;
10068 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
10069 continue;
10070
10071 Dwarf_Attribute attr;
10072 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
10073 continue;
10074
10075 Dwarf_Word macoff;
10076 if (dwarf_formudata (&attr, &macoff) != 0)
10077 continue;
10078
10079 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
10080 newp->die = cudie;
10081 newp->offset = macoff;
10082 newp->files = NULL;
10083 newp->next = culist;
10084 culist = newp;
10085 ++nculist;
10086 }
10087
10088 /* Convert the list into an array for easier consumption. */
10089 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
10090 * sizeof (*cus));
10091 /* Add sentinel. */
10092 cus[nculist].offset = data->d_size;
10093 cus[nculist].files = (Dwarf_Files *) -1l;
10094 if (nculist > 0)
10095 {
10096 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
10097 {
10098 assert (cnt < nculist);
10099 cus[cnt] = *culist;
10100 culist = culist->next;
10101 }
10102
10103 /* Sort the array according to the offset in the .debug_macinfo
10104 section. Note we keep the sentinel at the end. */
10105 qsort (cus, nculist, sizeof (*cus), mac_compare);
10106 }
10107
10108 const unsigned char *readp = (const unsigned char *) data->d_buf;
10109 const unsigned char *readendp = readp + data->d_size;
10110 int level = 1;
10111
10112 while (readp < readendp)
10113 {
10114 unsigned int opcode = *readp++;
10115 unsigned int u128;
10116 unsigned int u128_2;
10117 const unsigned char *endp;
10118
10119 switch (opcode)
10120 {
10121 case DW_MACINFO_define:
10122 case DW_MACINFO_undef:
10123 case DW_MACINFO_vendor_ext:
10124 /* For the first two opcodes the parameters are
10125 line, string
10126 For the latter
10127 number, string.
10128 We can treat these cases together. */
10129 get_uleb128 (u128, readp, readendp);
10130
10131 endp = memchr (readp, '\0', readendp - readp);
10132 if (unlikely (endp == NULL))
10133 {
10134 printf (_("\
10135 %*s*** non-terminated string at end of section"),
10136 level, "");
10137 return;
10138 }
10139
10140 if (opcode == DW_MACINFO_define)
10141 printf ("%*s#define %s, line %u\n",
10142 level, "", (char *) readp, u128);
10143 else if (opcode == DW_MACINFO_undef)
10144 printf ("%*s#undef %s, line %u\n",
10145 level, "", (char *) readp, u128);
10146 else
10147 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
10148
10149 readp = endp + 1;
10150 break;
10151
10152 case DW_MACINFO_start_file:
10153 /* The two parameters are line and file index, in this order. */
10154 get_uleb128 (u128, readp, readendp);
10155 if (readendp - readp < 1)
10156 {
10157 printf (_("\
10158 %*s*** missing DW_MACINFO_start_file argument at end of section"),
10159 level, "");
10160 return;
10161 }
10162 get_uleb128 (u128_2, readp, readendp);
10163
10164 /* Find the CU DIE for this file. */
10165 size_t macoff = readp - (const unsigned char *) data->d_buf;
10166 const char *fname = "???";
10167 if (macoff >= cus[0].offset && cus[0].offset != data->d_size)
10168 {
10169 while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
10170 ++cus;
10171
10172 if (cus[0].files == NULL
10173 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
10174 cus[0].files = (Dwarf_Files *) -1l;
10175
10176 if (cus[0].files != (Dwarf_Files *) -1l)
10177 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
10178 ?: "???");
10179 }
10180
10181 printf ("%*sstart_file %u, [%u] %s\n",
10182 level, "", u128, u128_2, fname);
10183 ++level;
10184 break;
10185
10186 case DW_MACINFO_end_file:
10187 --level;
10188 printf ("%*send_file\n", level, "");
10189 /* Nothing more to do. */
10190 break;
10191
10192 default:
10193 // XXX gcc seems to generate files with a trailing zero.
10194 if (unlikely (opcode != 0 || readp != readendp))
10195 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
10196 break;
10197 }
10198 }
10199 }
10200
10201
10202 static void
print_debug_macro_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10203 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10204 Ebl *ebl,
10205 GElf_Ehdr *ehdr __attribute__ ((unused)),
10206 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10207 {
10208 printf (_("\
10209 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10210 elf_ndxscn (scn), section_name (ebl, shdr),
10211 (uint64_t) shdr->sh_offset);
10212 putc_unlocked ('\n', stdout);
10213
10214 Elf_Data *data = elf_getdata (scn, NULL);
10215 if (unlikely (data == NULL))
10216 {
10217 error (0, 0, _("cannot get macro information section data: %s"),
10218 elf_errmsg (-1));
10219 return;
10220 }
10221
10222 /* Get the source file information for all CUs. Uses same
10223 datastructure as macinfo. But uses offset field to directly
10224 match .debug_line offset. And just stored in a list. */
10225 Dwarf_Off offset;
10226 Dwarf_Off ncu = 0;
10227 size_t hsize;
10228 struct mac_culist *culist = NULL;
10229 size_t nculist = 0;
10230 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
10231 {
10232 Dwarf_Die cudie;
10233 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
10234 continue;
10235
10236 Dwarf_Attribute attr;
10237 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
10238 continue;
10239
10240 Dwarf_Word lineoff;
10241 if (dwarf_formudata (&attr, &lineoff) != 0)
10242 continue;
10243
10244 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
10245 newp->die = cudie;
10246 newp->offset = lineoff;
10247 newp->files = NULL;
10248 newp->next = culist;
10249 culist = newp;
10250 ++nculist;
10251 }
10252
10253 const unsigned char *readp = (const unsigned char *) data->d_buf;
10254 const unsigned char *readendp = readp + data->d_size;
10255
10256 while (readp < readendp)
10257 {
10258 printf (_(" Offset: 0x%" PRIx64 "\n"),
10259 (uint64_t) (readp - (const unsigned char *) data->d_buf));
10260
10261 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
10262 // optional vendor extension macro entry table.
10263 if (readp + 2 > readendp)
10264 {
10265 invalid_data:
10266 error (0, 0, _("invalid data"));
10267 return;
10268 }
10269 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
10270 printf (_(" Version: %" PRIu16 "\n"), vers);
10271
10272 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
10273 // 5 when it gets standardized.
10274 if (vers != 4 && vers != 5)
10275 {
10276 printf (_(" unknown version, cannot parse section\n"));
10277 return;
10278 }
10279
10280 if (readp + 1 > readendp)
10281 goto invalid_data;
10282 const unsigned char flag = *readp++;
10283 printf (_(" Flag: 0x%" PRIx8), flag);
10284 if (flag != 0)
10285 {
10286 printf (" (");
10287 if ((flag & 0x01) != 0)
10288 {
10289 printf ("offset_size");
10290 if ((flag & 0xFE) != 0)
10291 printf (", ");
10292 }
10293 if ((flag & 0x02) != 0)
10294 {
10295 printf ("debug_line_offset");
10296 if ((flag & 0xFC) != 0)
10297 printf (", ");
10298 }
10299 if ((flag & 0x04) != 0)
10300 {
10301 printf ("operands_table");
10302 if ((flag & 0xF8) != 0)
10303 printf (", ");
10304 }
10305 if ((flag & 0xF8) != 0)
10306 printf ("unknown");
10307 printf (")");
10308 }
10309 printf ("\n");
10310
10311 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
10312 printf (_(" Offset length: %" PRIu8 "\n"), offset_len);
10313 Dwarf_Off line_offset = -1;
10314 if (flag & 0x02)
10315 {
10316 if (offset_len == 8)
10317 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
10318 else
10319 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
10320 printf (_(" .debug_line offset: 0x%" PRIx64 "\n"),
10321 line_offset);
10322 }
10323
10324 struct mac_culist *cu = NULL;
10325 if (line_offset != (Dwarf_Off) -1)
10326 {
10327 cu = culist;
10328 while (cu != NULL && line_offset != cu->offset)
10329 cu = cu->next;
10330 }
10331
10332 Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, (cu != NULL
10333 ? cu->die.cu
10334 : NULL));
10335
10336 const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user + 1];
10337 memset (vendor, 0, sizeof vendor);
10338 if (flag & 0x04)
10339 {
10340 // 1 byte length, for each item, 1 byte opcode, uleb128 number
10341 // of arguments, for each argument 1 byte form code.
10342 if (readp + 1 > readendp)
10343 goto invalid_data;
10344 unsigned int tlen = *readp++;
10345 printf (_(" extension opcode table, %" PRIu8 " items:\n"),
10346 tlen);
10347 for (unsigned int i = 0; i < tlen; i++)
10348 {
10349 if (readp + 1 > readendp)
10350 goto invalid_data;
10351 unsigned int opcode = *readp++;
10352 printf (_(" [%" PRIx8 "]"), opcode);
10353 if (opcode < DW_MACRO_lo_user
10354 || opcode > DW_MACRO_hi_user)
10355 goto invalid_data;
10356 // Record the start of description for this vendor opcode.
10357 // uleb128 nr args, 1 byte per arg form.
10358 vendor[opcode - DW_MACRO_lo_user] = readp;
10359 if (readp + 1 > readendp)
10360 goto invalid_data;
10361 unsigned int args = *readp++;
10362 if (args > 0)
10363 {
10364 printf (_(" %" PRIu8 " arguments:"), args);
10365 while (args > 0)
10366 {
10367 if (readp + 1 > readendp)
10368 goto invalid_data;
10369 unsigned int form = *readp++;
10370 printf (" %s", dwarf_form_name (form));
10371 if (! libdw_valid_user_form (form))
10372 goto invalid_data;
10373 args--;
10374 if (args > 0)
10375 putchar_unlocked (',');
10376 }
10377 }
10378 else
10379 printf (_(" no arguments."));
10380 putchar_unlocked ('\n');
10381 }
10382 }
10383 putchar_unlocked ('\n');
10384
10385 int level = 1;
10386 if (readp + 1 > readendp)
10387 goto invalid_data;
10388 unsigned int opcode = *readp++;
10389 while (opcode != 0)
10390 {
10391 unsigned int u128;
10392 unsigned int u128_2;
10393 const unsigned char *endp;
10394 uint64_t off;
10395
10396 switch (opcode)
10397 {
10398 case DW_MACRO_start_file:
10399 get_uleb128 (u128, readp, readendp);
10400 if (readp >= readendp)
10401 goto invalid_data;
10402 get_uleb128 (u128_2, readp, readendp);
10403
10404 /* Find the CU DIE that matches this line offset. */
10405 const char *fname = "???";
10406 if (cu != NULL)
10407 {
10408 if (cu->files == NULL
10409 && dwarf_getsrcfiles (&cu->die, &cu->files,
10410 NULL) != 0)
10411 cu->files = (Dwarf_Files *) -1l;
10412
10413 if (cu->files != (Dwarf_Files *) -1l)
10414 fname = (dwarf_filesrc (cu->files, u128_2,
10415 NULL, NULL) ?: "???");
10416 }
10417 printf ("%*sstart_file %u, [%u] %s\n",
10418 level, "", u128, u128_2, fname);
10419 ++level;
10420 break;
10421
10422 case DW_MACRO_end_file:
10423 --level;
10424 printf ("%*send_file\n", level, "");
10425 break;
10426
10427 case DW_MACRO_define:
10428 get_uleb128 (u128, readp, readendp);
10429 endp = memchr (readp, '\0', readendp - readp);
10430 if (endp == NULL)
10431 goto invalid_data;
10432 printf ("%*s#define %s, line %u\n",
10433 level, "", readp, u128);
10434 readp = endp + 1;
10435 break;
10436
10437 case DW_MACRO_undef:
10438 get_uleb128 (u128, readp, readendp);
10439 endp = memchr (readp, '\0', readendp - readp);
10440 if (endp == NULL)
10441 goto invalid_data;
10442 printf ("%*s#undef %s, line %u\n",
10443 level, "", readp, u128);
10444 readp = endp + 1;
10445 break;
10446
10447 case DW_MACRO_define_strp:
10448 get_uleb128 (u128, readp, readendp);
10449 if (readp + offset_len > readendp)
10450 goto invalid_data;
10451 if (offset_len == 8)
10452 off = read_8ubyte_unaligned_inc (dbg, readp);
10453 else
10454 off = read_4ubyte_unaligned_inc (dbg, readp);
10455 printf ("%*s#define %s, line %u (indirect)\n",
10456 level, "", dwarf_getstring (dbg, off, NULL), u128);
10457 break;
10458
10459 case DW_MACRO_undef_strp:
10460 get_uleb128 (u128, readp, readendp);
10461 if (readp + offset_len > readendp)
10462 goto invalid_data;
10463 if (offset_len == 8)
10464 off = read_8ubyte_unaligned_inc (dbg, readp);
10465 else
10466 off = read_4ubyte_unaligned_inc (dbg, readp);
10467 printf ("%*s#undef %s, line %u (indirect)\n",
10468 level, "", dwarf_getstring (dbg, off, NULL), u128);
10469 break;
10470
10471 case DW_MACRO_import:
10472 if (readp + offset_len > readendp)
10473 goto invalid_data;
10474 if (offset_len == 8)
10475 off = read_8ubyte_unaligned_inc (dbg, readp);
10476 else
10477 off = read_4ubyte_unaligned_inc (dbg, readp);
10478 printf ("%*s#include offset 0x%" PRIx64 "\n",
10479 level, "", off);
10480 break;
10481
10482 case DW_MACRO_define_sup:
10483 get_uleb128 (u128, readp, readendp);
10484 if (readp + offset_len > readendp)
10485 goto invalid_data;
10486 printf ("%*s#define ", level, "");
10487 readp = print_form_data (dbg, DW_FORM_strp_sup,
10488 readp, readendp, offset_len,
10489 str_offsets_base);
10490 printf (", line %u (sup)\n", u128);
10491 break;
10492
10493 case DW_MACRO_undef_sup:
10494 get_uleb128 (u128, readp, readendp);
10495 if (readp + offset_len > readendp)
10496 goto invalid_data;
10497 printf ("%*s#undef ", level, "");
10498 readp = print_form_data (dbg, DW_FORM_strp_sup,
10499 readp, readendp, offset_len,
10500 str_offsets_base);
10501 printf (", line %u (sup)\n", u128);
10502 break;
10503
10504 case DW_MACRO_import_sup:
10505 if (readp + offset_len > readendp)
10506 goto invalid_data;
10507 if (offset_len == 8)
10508 off = read_8ubyte_unaligned_inc (dbg, readp);
10509 else
10510 off = read_4ubyte_unaligned_inc (dbg, readp);
10511 // XXX Needs support for reading from supplementary object file.
10512 printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
10513 level, "", off);
10514 break;
10515
10516 case DW_MACRO_define_strx:
10517 get_uleb128 (u128, readp, readendp);
10518 if (readp + offset_len > readendp)
10519 goto invalid_data;
10520 printf ("%*s#define ", level, "");
10521 readp = print_form_data (dbg, DW_FORM_strx,
10522 readp, readendp, offset_len,
10523 str_offsets_base);
10524 printf (", line %u (strx)\n", u128);
10525 break;
10526
10527 case DW_MACRO_undef_strx:
10528 get_uleb128 (u128, readp, readendp);
10529 if (readp + offset_len > readendp)
10530 goto invalid_data;
10531 printf ("%*s#undef ", level, "");
10532 readp = print_form_data (dbg, DW_FORM_strx,
10533 readp, readendp, offset_len,
10534 str_offsets_base);
10535 printf (", line %u (strx)\n", u128);
10536 break;
10537
10538 default:
10539 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
10540 if (opcode < DW_MACRO_lo_user
10541 || opcode > DW_MACRO_lo_user
10542 || vendor[opcode - DW_MACRO_lo_user] == NULL)
10543 goto invalid_data;
10544
10545 const unsigned char *op_desc;
10546 op_desc = vendor[opcode - DW_MACRO_lo_user];
10547
10548 // Just skip the arguments, we cannot really interpret them,
10549 // but print as much as we can.
10550 unsigned int args = *op_desc++;
10551 while (args > 0 && readp < readendp)
10552 {
10553 unsigned int form = *op_desc++;
10554 readp = print_form_data (dbg, form, readp, readendp,
10555 offset_len, str_offsets_base);
10556 args--;
10557 if (args > 0)
10558 printf (", ");
10559 }
10560 putchar_unlocked ('\n');
10561 }
10562
10563 if (readp + 1 > readendp)
10564 goto invalid_data;
10565 opcode = *readp++;
10566 if (opcode == 0)
10567 putchar_unlocked ('\n');
10568 }
10569 }
10570 }
10571
10572
10573 /* Callback for printing global names. */
10574 static int
print_pubnames(Dwarf * dbg,Dwarf_Global * global,void * arg)10575 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
10576 void *arg)
10577 {
10578 int *np = (int *) arg;
10579
10580 printf (_(" [%5d] DIE offset: %6" PRId64
10581 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
10582 (*np)++, global->die_offset, global->cu_offset, global->name);
10583
10584 return 0;
10585 }
10586
10587
10588 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
10589 static void
print_debug_pubnames_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10590 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10591 Ebl *ebl,
10592 GElf_Ehdr *ehdr __attribute__ ((unused)),
10593 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10594 {
10595 printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10596 elf_ndxscn (scn), section_name (ebl, shdr),
10597 (uint64_t) shdr->sh_offset);
10598
10599 int n = 0;
10600 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
10601 }
10602
10603 /* Print the content of the DWARF string section '.debug_str'. */
10604 static void
print_debug_str_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10605 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10606 Ebl *ebl,
10607 GElf_Ehdr *ehdr __attribute__ ((unused)),
10608 Elf_Scn *scn, GElf_Shdr *shdr,
10609 Dwarf *dbg __attribute__ ((unused)))
10610 {
10611 Elf_Data *data = elf_rawdata (scn, NULL);
10612 const size_t sh_size = data ? data->d_size : 0;
10613
10614 /* Compute floor(log16(shdr->sh_size)). */
10615 GElf_Addr tmp = sh_size;
10616 int digits = 1;
10617 while (tmp >= 16)
10618 {
10619 ++digits;
10620 tmp >>= 4;
10621 }
10622 digits = MAX (4, digits);
10623
10624 printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
10625 " %*s String\n"),
10626 elf_ndxscn (scn),
10627 section_name (ebl, shdr), (uint64_t) shdr->sh_offset,
10628 /* TRANS: the debugstr| prefix makes the string unique. */
10629 digits + 2, sgettext ("debugstr|Offset"));
10630
10631 Dwarf_Off offset = 0;
10632 while (offset < sh_size)
10633 {
10634 size_t len;
10635 const char *str = (const char *) data->d_buf + offset;
10636 const char *endp = memchr (str, '\0', sh_size - offset);
10637 if (unlikely (endp == NULL))
10638 {
10639 printf (_(" *** error, missing string terminator\n"));
10640 break;
10641 }
10642
10643 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
10644 len = endp - str;
10645 offset += len + 1;
10646 }
10647 }
10648
10649 static void
print_debug_str_offsets_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10650 print_debug_str_offsets_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10651 Ebl *ebl,
10652 GElf_Ehdr *ehdr __attribute__ ((unused)),
10653 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10654 {
10655 printf (_("\
10656 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10657 elf_ndxscn (scn), section_name (ebl, shdr),
10658 (uint64_t) shdr->sh_offset);
10659
10660 if (shdr->sh_size == 0)
10661 return;
10662
10663 /* We like to get the section from libdw to make sure they are relocated. */
10664 Elf_Data *data = (dbg->sectiondata[IDX_debug_str_offsets]
10665 ?: elf_rawdata (scn, NULL));
10666 if (unlikely (data == NULL))
10667 {
10668 error (0, 0, _("cannot get .debug_str_offsets section data: %s"),
10669 elf_errmsg (-1));
10670 return;
10671 }
10672
10673 size_t idx = 0;
10674 sort_listptr (&known_stroffbases, "str_offsets");
10675
10676 const unsigned char *start = (const unsigned char *) data->d_buf;
10677 const unsigned char *readp = start;
10678 const unsigned char *readendp = ((const unsigned char *) data->d_buf
10679 + data->d_size);
10680
10681 while (readp < readendp)
10682 {
10683 /* Most string offset tables will have a header. For split
10684 dwarf unit GNU DebugFission didn't add one. But they were
10685 also only defined for split units (main or skeleton units
10686 didn't have indirect strings). So if we don't have a
10687 DW_AT_str_offsets_base at all and this is offset zero, then
10688 just start printing offsets immediately, if this is a .dwo
10689 section. */
10690 Dwarf_Off off = (Dwarf_Off) (readp
10691 - (const unsigned char *) data->d_buf);
10692
10693 printf ("Table at offset %" PRIx64 " ", off);
10694
10695 struct listptr *listptr = get_listptr (&known_stroffbases, idx++);
10696 const unsigned char *next_unitp = readendp;
10697 uint8_t offset_size;
10698 bool has_header;
10699 if (listptr == NULL)
10700 {
10701 /* This can happen for .dwo files. There is only an header
10702 in the case this is a version 5 split DWARF file. */
10703 Dwarf_CU *cu;
10704 uint8_t unit_type;
10705 if (dwarf_get_units (dbg, NULL, &cu, NULL, &unit_type,
10706 NULL, NULL) != 0)
10707 {
10708 error (0, 0, "Warning: Cannot find any DWARF unit.");
10709 /* Just guess some values. */
10710 has_header = false;
10711 offset_size = 4;
10712 }
10713 else if (off == 0
10714 && (unit_type == DW_UT_split_type
10715 || unit_type == DW_UT_split_compile))
10716 {
10717 has_header = cu->version > 4;
10718 offset_size = cu->offset_size;
10719 }
10720 else
10721 {
10722 error (0, 0,
10723 "Warning: No CU references .debug_str_offsets after %"
10724 PRIx64, off);
10725 has_header = cu->version > 4;
10726 offset_size = cu->offset_size;
10727 }
10728 printf ("\n");
10729 }
10730 else
10731 {
10732 /* This must be DWARF5, since GNU DebugFission didn't define
10733 DW_AT_str_offsets_base. */
10734 has_header = true;
10735
10736 Dwarf_Die cudie;
10737 if (dwarf_cu_die (listptr->cu, &cudie,
10738 NULL, NULL, NULL, NULL,
10739 NULL, NULL) == NULL)
10740 printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
10741 else
10742 printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
10743 }
10744
10745 if (has_header)
10746 {
10747 uint64_t unit_length;
10748 uint16_t version;
10749 uint16_t padding;
10750
10751 unit_length = read_4ubyte_unaligned_inc (dbg, readp);
10752 if (unlikely (unit_length == 0xffffffff))
10753 {
10754 if (unlikely (readp > readendp - 8))
10755 {
10756 invalid_data:
10757 error (0, 0, "Invalid data");
10758 return;
10759 }
10760 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
10761 offset_size = 8;
10762 }
10763 else
10764 offset_size = 4;
10765
10766 printf ("\n");
10767 printf (_(" Length: %8" PRIu64 "\n"),
10768 unit_length);
10769 printf (_(" Offset size: %8" PRIu8 "\n"),
10770 offset_size);
10771
10772 /* We need at least 2-bytes (version) + 2-bytes (padding) =
10773 4 bytes to complete the header. And this unit cannot go
10774 beyond the section data. */
10775 if (readp > readendp - 4
10776 || unit_length < 4
10777 || unit_length > (uint64_t) (readendp - readp))
10778 goto invalid_data;
10779
10780 next_unitp = readp + unit_length;
10781
10782 version = read_2ubyte_unaligned_inc (dbg, readp);
10783 printf (_(" DWARF version: %8" PRIu16 "\n"), version);
10784
10785 if (version != 5)
10786 {
10787 error (0, 0, _("Unknown version"));
10788 goto next_unit;
10789 }
10790
10791 padding = read_2ubyte_unaligned_inc (dbg, readp);
10792 printf (_(" Padding: %8" PRIx16 "\n"), padding);
10793
10794 if (listptr != NULL
10795 && listptr->offset != (Dwarf_Off) (readp - start))
10796 {
10797 error (0, 0, "String offsets index doesn't start after header");
10798 goto next_unit;
10799 }
10800
10801 printf ("\n");
10802 }
10803
10804 int digits = 1;
10805 size_t offsets = (next_unitp - readp) / offset_size;
10806 while (offsets >= 10)
10807 {
10808 ++digits;
10809 offsets /= 10;
10810 }
10811
10812 unsigned int uidx = 0;
10813 size_t index_offset = readp - (const unsigned char *) data->d_buf;
10814 printf (" Offsets start at 0x%zx:\n", index_offset);
10815 while (readp <= next_unitp - offset_size)
10816 {
10817 Dwarf_Word offset;
10818 if (offset_size == 4)
10819 offset = read_4ubyte_unaligned_inc (dbg, readp);
10820 else
10821 offset = read_8ubyte_unaligned_inc (dbg, readp);
10822 const char *str = dwarf_getstring (dbg, offset, NULL);
10823 printf (" [%*u] [%*" PRIx64 "] \"%s\"\n",
10824 digits, uidx++, (int) offset_size * 2, offset, str ?: "???");
10825 }
10826 printf ("\n");
10827
10828 if (readp != next_unitp)
10829 error (0, 0, "extra %zd bytes at end of unit",
10830 (size_t) (next_unitp - readp));
10831
10832 next_unit:
10833 readp = next_unitp;
10834 }
10835 }
10836
10837
10838 /* Print the content of the call frame search table section
10839 '.eh_frame_hdr'. */
10840 static void
print_debug_frame_hdr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10841 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10842 Ebl *ebl __attribute__ ((unused)),
10843 GElf_Ehdr *ehdr __attribute__ ((unused)),
10844 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10845 {
10846 printf (_("\
10847 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
10848 elf_ndxscn (scn));
10849
10850 Elf_Data *data = elf_rawdata (scn, NULL);
10851
10852 if (unlikely (data == NULL))
10853 {
10854 error (0, 0, _("cannot get %s content: %s"),
10855 ".eh_frame_hdr", elf_errmsg (-1));
10856 return;
10857 }
10858
10859 const unsigned char *readp = data->d_buf;
10860 const unsigned char *const dataend = ((unsigned char *) data->d_buf
10861 + data->d_size);
10862
10863 if (unlikely (readp + 4 > dataend))
10864 {
10865 invalid_data:
10866 error (0, 0, _("invalid data"));
10867 return;
10868 }
10869
10870 unsigned int version = *readp++;
10871 unsigned int eh_frame_ptr_enc = *readp++;
10872 unsigned int fde_count_enc = *readp++;
10873 unsigned int table_enc = *readp++;
10874
10875 printf (" version: %u\n"
10876 " eh_frame_ptr_enc: %#x ",
10877 version, eh_frame_ptr_enc);
10878 print_encoding_base ("", eh_frame_ptr_enc);
10879 printf (" fde_count_enc: %#x ", fde_count_enc);
10880 print_encoding_base ("", fde_count_enc);
10881 printf (" table_enc: %#x ", table_enc);
10882 print_encoding_base ("", table_enc);
10883
10884 uint64_t eh_frame_ptr = 0;
10885 if (eh_frame_ptr_enc != DW_EH_PE_omit)
10886 {
10887 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
10888 dbg);
10889 if (unlikely (readp == NULL))
10890 goto invalid_data;
10891
10892 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
10893 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
10894 printf (" (offset: %#" PRIx64 ")",
10895 /* +4 because of the 4 byte header of the section. */
10896 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
10897
10898 putchar_unlocked ('\n');
10899 }
10900
10901 uint64_t fde_count = 0;
10902 if (fde_count_enc != DW_EH_PE_omit)
10903 {
10904 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
10905 if (unlikely (readp == NULL))
10906 goto invalid_data;
10907
10908 printf (" fde_count: %" PRIu64 "\n", fde_count);
10909 }
10910
10911 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
10912 return;
10913
10914 puts (" Table:");
10915
10916 /* Optimize for the most common case. */
10917 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
10918 while (fde_count > 0 && readp + 8 <= dataend)
10919 {
10920 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
10921 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
10922 + (int64_t) initial_location);
10923 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
10924 // XXX Possibly print symbol name or section offset for initial_offset
10925 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
10926 " fde=[%6" PRIx64 "]\n",
10927 initial_location, initial_offset,
10928 address, address - (eh_frame_ptr + 4));
10929 }
10930 else
10931 while (0 && readp < dataend)
10932 {
10933
10934 }
10935 }
10936
10937
10938 /* Print the content of the exception handling table section
10939 '.eh_frame_hdr'. */
10940 static void
print_debug_exception_table(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10941 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
10942 Ebl *ebl __attribute__ ((unused)),
10943 GElf_Ehdr *ehdr __attribute__ ((unused)),
10944 Elf_Scn *scn,
10945 GElf_Shdr *shdr __attribute__ ((unused)),
10946 Dwarf *dbg __attribute__ ((unused)))
10947 {
10948 printf (_("\
10949 \nException handling table section [%2zu] '.gcc_except_table':\n"),
10950 elf_ndxscn (scn));
10951
10952 Elf_Data *data = elf_rawdata (scn, NULL);
10953
10954 if (unlikely (data == NULL))
10955 {
10956 error (0, 0, _("cannot get %s content: %s"),
10957 ".gcc_except_table", elf_errmsg (-1));
10958 return;
10959 }
10960
10961 const unsigned char *readp = data->d_buf;
10962 const unsigned char *const dataend = readp + data->d_size;
10963
10964 if (unlikely (readp + 1 > dataend))
10965 {
10966 invalid_data:
10967 error (0, 0, _("invalid data"));
10968 return;
10969 }
10970 unsigned int lpstart_encoding = *readp++;
10971 printf (_(" LPStart encoding: %#x "), lpstart_encoding);
10972 print_encoding_base ("", lpstart_encoding);
10973 if (lpstart_encoding != DW_EH_PE_omit)
10974 {
10975 uint64_t lpstart;
10976 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
10977 printf (" LPStart: %#" PRIx64 "\n", lpstart);
10978 }
10979
10980 if (unlikely (readp + 1 > dataend))
10981 goto invalid_data;
10982 unsigned int ttype_encoding = *readp++;
10983 printf (_(" TType encoding: %#x "), ttype_encoding);
10984 print_encoding_base ("", ttype_encoding);
10985 const unsigned char *ttype_base = NULL;
10986 if (ttype_encoding != DW_EH_PE_omit)
10987 {
10988 unsigned int ttype_base_offset;
10989 get_uleb128 (ttype_base_offset, readp, dataend);
10990 printf (" TType base offset: %#x\n", ttype_base_offset);
10991 if ((size_t) (dataend - readp) > ttype_base_offset)
10992 ttype_base = readp + ttype_base_offset;
10993 }
10994
10995 if (unlikely (readp + 1 > dataend))
10996 goto invalid_data;
10997 unsigned int call_site_encoding = *readp++;
10998 printf (_(" Call site encoding: %#x "), call_site_encoding);
10999 print_encoding_base ("", call_site_encoding);
11000 unsigned int call_site_table_len;
11001 get_uleb128 (call_site_table_len, readp, dataend);
11002
11003 const unsigned char *const action_table = readp + call_site_table_len;
11004 if (unlikely (action_table > dataend))
11005 goto invalid_data;
11006 unsigned int u = 0;
11007 unsigned int max_action = 0;
11008 while (readp < action_table)
11009 {
11010 if (u == 0)
11011 puts (_("\n Call site table:"));
11012
11013 uint64_t call_site_start;
11014 readp = read_encoded (call_site_encoding, readp, dataend,
11015 &call_site_start, dbg);
11016 uint64_t call_site_length;
11017 readp = read_encoded (call_site_encoding, readp, dataend,
11018 &call_site_length, dbg);
11019 uint64_t landing_pad;
11020 readp = read_encoded (call_site_encoding, readp, dataend,
11021 &landing_pad, dbg);
11022 unsigned int action;
11023 get_uleb128 (action, readp, dataend);
11024 max_action = MAX (action, max_action);
11025 printf (_(" [%4u] Call site start: %#" PRIx64 "\n"
11026 " Call site length: %" PRIu64 "\n"
11027 " Landing pad: %#" PRIx64 "\n"
11028 " Action: %u\n"),
11029 u++, call_site_start, call_site_length, landing_pad, action);
11030 }
11031 if (readp != action_table)
11032 goto invalid_data;
11033
11034 unsigned int max_ar_filter = 0;
11035 if (max_action > 0)
11036 {
11037 puts ("\n Action table:");
11038
11039 size_t maxdata = (size_t) (dataend - action_table);
11040 if (max_action > maxdata || maxdata - max_action < 1)
11041 {
11042 invalid_action_table:
11043 fputs (_(" <INVALID DATA>\n"), stdout);
11044 return;
11045 }
11046
11047 const unsigned char *const action_table_end
11048 = action_table + max_action + 1;
11049
11050 u = 0;
11051 do
11052 {
11053 int ar_filter;
11054 get_sleb128 (ar_filter, readp, action_table_end);
11055 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
11056 max_ar_filter = ar_filter;
11057 int ar_disp;
11058 if (readp >= action_table_end)
11059 goto invalid_action_table;
11060 get_sleb128 (ar_disp, readp, action_table_end);
11061
11062 printf (" [%4u] ar_filter: % d\n"
11063 " ar_disp: % -5d",
11064 u, ar_filter, ar_disp);
11065 if (abs (ar_disp) & 1)
11066 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
11067 else if (ar_disp != 0)
11068 puts (" -> ???");
11069 else
11070 putchar_unlocked ('\n');
11071 ++u;
11072 }
11073 while (readp < action_table_end);
11074 }
11075
11076 if (max_ar_filter > 0 && ttype_base != NULL)
11077 {
11078 unsigned char dsize;
11079 puts ("\n TType table:");
11080
11081 // XXX Not *4, size of encoding;
11082 switch (ttype_encoding & 7)
11083 {
11084 case DW_EH_PE_udata2:
11085 case DW_EH_PE_sdata2:
11086 dsize = 2;
11087 break;
11088 case DW_EH_PE_udata4:
11089 case DW_EH_PE_sdata4:
11090 dsize = 4;
11091 break;
11092 case DW_EH_PE_udata8:
11093 case DW_EH_PE_sdata8:
11094 dsize = 8;
11095 break;
11096 default:
11097 dsize = 0;
11098 error (1, 0, _("invalid TType encoding"));
11099 }
11100
11101 if (max_ar_filter
11102 > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
11103 goto invalid_data;
11104
11105 readp = ttype_base - max_ar_filter * dsize;
11106 do
11107 {
11108 uint64_t ttype;
11109 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
11110 dbg);
11111 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
11112 }
11113 while (readp < ttype_base);
11114 }
11115 }
11116
11117 /* Print the content of the '.gdb_index' section.
11118 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
11119 */
11120 static void
print_gdb_index_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)11121 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl,
11122 GElf_Ehdr *ehdr __attribute__ ((unused)),
11123 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
11124 {
11125 printf (_("\nGDB section [%2zu] '%s' at offset %#" PRIx64
11126 " contains %" PRId64 " bytes :\n"),
11127 elf_ndxscn (scn), section_name (ebl, shdr),
11128 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
11129
11130 Elf_Data *data = elf_rawdata (scn, NULL);
11131
11132 if (unlikely (data == NULL))
11133 {
11134 error (0, 0, _("cannot get %s content: %s"),
11135 ".gdb_index", elf_errmsg (-1));
11136 return;
11137 }
11138
11139 // .gdb_index is always in little endian.
11140 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
11141 dbg = &dummy_dbg;
11142
11143 const unsigned char *readp = data->d_buf;
11144 const unsigned char *const dataend = readp + data->d_size;
11145
11146 if (unlikely (readp + 4 > dataend))
11147 {
11148 invalid_data:
11149 error (0, 0, _("invalid data"));
11150 return;
11151 }
11152
11153 int32_t vers = read_4ubyte_unaligned (dbg, readp);
11154 printf (_(" Version: %" PRId32 "\n"), vers);
11155
11156 // The only difference between version 4 and version 5 is the
11157 // hash used for generating the table. Version 6 contains symbols
11158 // for inlined functions, older versions didn't. Version 7 adds
11159 // symbol kinds. Version 8 just indicates that it correctly includes
11160 // TUs for symbols.
11161 if (vers < 4 || vers > 8)
11162 {
11163 printf (_(" unknown version, cannot parse section\n"));
11164 return;
11165 }
11166
11167 readp += 4;
11168 if (unlikely (readp + 4 > dataend))
11169 goto invalid_data;
11170
11171 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
11172 printf (_(" CU offset: %#" PRIx32 "\n"), cu_off);
11173
11174 readp += 4;
11175 if (unlikely (readp + 4 > dataend))
11176 goto invalid_data;
11177
11178 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
11179 printf (_(" TU offset: %#" PRIx32 "\n"), tu_off);
11180
11181 readp += 4;
11182 if (unlikely (readp + 4 > dataend))
11183 goto invalid_data;
11184
11185 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
11186 printf (_(" address offset: %#" PRIx32 "\n"), addr_off);
11187
11188 readp += 4;
11189 if (unlikely (readp + 4 > dataend))
11190 goto invalid_data;
11191
11192 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
11193 printf (_(" symbol offset: %#" PRIx32 "\n"), sym_off);
11194
11195 readp += 4;
11196 if (unlikely (readp + 4 > dataend))
11197 goto invalid_data;
11198
11199 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
11200 printf (_(" constant offset: %#" PRIx32 "\n"), const_off);
11201
11202 if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
11203 < const_off))
11204 goto invalid_data;
11205
11206 readp = data->d_buf + cu_off;
11207
11208 const unsigned char *nextp = data->d_buf + tu_off;
11209 if (tu_off >= data->d_size)
11210 goto invalid_data;
11211
11212 size_t cu_nr = (nextp - readp) / 16;
11213
11214 printf (_("\n CU list at offset %#" PRIx32
11215 " contains %zu entries:\n"),
11216 cu_off, cu_nr);
11217
11218 size_t n = 0;
11219 while (dataend - readp >= 16 && n < cu_nr)
11220 {
11221 uint64_t off = read_8ubyte_unaligned (dbg, readp);
11222 readp += 8;
11223
11224 uint64_t len = read_8ubyte_unaligned (dbg, readp);
11225 readp += 8;
11226
11227 printf (" [%4zu] start: %0#8" PRIx64
11228 ", length: %5" PRIu64 "\n", n, off, len);
11229 n++;
11230 }
11231
11232 readp = data->d_buf + tu_off;
11233 nextp = data->d_buf + addr_off;
11234 if (addr_off >= data->d_size)
11235 goto invalid_data;
11236
11237 size_t tu_nr = (nextp - readp) / 24;
11238
11239 printf (_("\n TU list at offset %#" PRIx32
11240 " contains %zu entries:\n"),
11241 tu_off, tu_nr);
11242
11243 n = 0;
11244 while (dataend - readp >= 24 && n < tu_nr)
11245 {
11246 uint64_t off = read_8ubyte_unaligned (dbg, readp);
11247 readp += 8;
11248
11249 uint64_t type = read_8ubyte_unaligned (dbg, readp);
11250 readp += 8;
11251
11252 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
11253 readp += 8;
11254
11255 printf (" [%4zu] CU offset: %5" PRId64
11256 ", type offset: %5" PRId64
11257 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
11258 n++;
11259 }
11260
11261 readp = data->d_buf + addr_off;
11262 nextp = data->d_buf + sym_off;
11263 if (sym_off >= data->d_size)
11264 goto invalid_data;
11265
11266 size_t addr_nr = (nextp - readp) / 20;
11267
11268 printf (_("\n Address list at offset %#" PRIx32
11269 " contains %zu entries:\n"),
11270 addr_off, addr_nr);
11271
11272 n = 0;
11273 while (dataend - readp >= 20 && n < addr_nr)
11274 {
11275 uint64_t low = read_8ubyte_unaligned (dbg, readp);
11276 readp += 8;
11277
11278 uint64_t high = read_8ubyte_unaligned (dbg, readp);
11279 readp += 8;
11280
11281 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
11282 readp += 4;
11283
11284 printf (" [%4zu] ", n);
11285 print_dwarf_addr (dwflmod, 8, low, low);
11286 printf ("..");
11287 print_dwarf_addr (dwflmod, 8, high - 1, high);
11288 printf (", CU index: %5" PRId32 "\n", idx);
11289 n++;
11290 }
11291
11292 const unsigned char *const_start = data->d_buf + const_off;
11293 if (const_off >= data->d_size)
11294 goto invalid_data;
11295
11296 readp = data->d_buf + sym_off;
11297 nextp = const_start;
11298 size_t sym_nr = (nextp - readp) / 8;
11299
11300 printf (_("\n Symbol table at offset %#" PRIx32
11301 " contains %zu slots:\n"),
11302 addr_off, sym_nr);
11303
11304 n = 0;
11305 while (dataend - readp >= 8 && n < sym_nr)
11306 {
11307 uint32_t name = read_4ubyte_unaligned (dbg, readp);
11308 readp += 4;
11309
11310 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
11311 readp += 4;
11312
11313 if (name != 0 || vector != 0)
11314 {
11315 const unsigned char *sym = const_start + name;
11316 if (unlikely ((size_t) (dataend - const_start) < name
11317 || memchr (sym, '\0', dataend - sym) == NULL))
11318 goto invalid_data;
11319
11320 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
11321
11322 const unsigned char *readcus = const_start + vector;
11323 if (unlikely ((size_t) (dataend - const_start) < vector))
11324 goto invalid_data;
11325 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
11326 while (cus--)
11327 {
11328 uint32_t cu_kind, cu, kind;
11329 bool is_static;
11330 readcus += 4;
11331 if (unlikely (readcus + 4 > dataend))
11332 goto invalid_data;
11333 cu_kind = read_4ubyte_unaligned (dbg, readcus);
11334 cu = cu_kind & ((1 << 24) - 1);
11335 kind = (cu_kind >> 28) & 7;
11336 is_static = cu_kind & (1U << 31);
11337 if (cu > cu_nr - 1)
11338 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
11339 else
11340 printf ("%" PRId32, cu);
11341 if (kind != 0)
11342 {
11343 printf (" (");
11344 switch (kind)
11345 {
11346 case 1:
11347 printf ("type");
11348 break;
11349 case 2:
11350 printf ("var");
11351 break;
11352 case 3:
11353 printf ("func");
11354 break;
11355 case 4:
11356 printf ("other");
11357 break;
11358 default:
11359 printf ("unknown-0x%" PRIx32, kind);
11360 break;
11361 }
11362 printf (":%c)", (is_static ? 'S' : 'G'));
11363 }
11364 if (cus > 0)
11365 printf (", ");
11366 }
11367 printf ("\n");
11368 }
11369 n++;
11370 }
11371 }
11372
11373 /* Returns true and sets split DWARF CU id if there is a split compile
11374 unit in the given Dwarf, and no non-split units are found (before it). */
11375 static bool
is_split_dwarf(Dwarf * dbg,uint64_t * id,Dwarf_CU ** split_cu)11376 is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu)
11377 {
11378 Dwarf_CU *cu = NULL;
11379 while (dwarf_get_units (dbg, cu, &cu, NULL, NULL, NULL, NULL) == 0)
11380 {
11381 uint8_t unit_type;
11382 if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11383 id, NULL, NULL) != 0)
11384 return false;
11385
11386 if (unit_type != DW_UT_split_compile && unit_type != DW_UT_split_type)
11387 return false;
11388
11389 /* We really only care about the split compile unit, the types
11390 should be fine and self sufficient. Also they don't have an
11391 id that we can match with a skeleton unit. */
11392 if (unit_type == DW_UT_split_compile)
11393 {
11394 *split_cu = cu;
11395 return true;
11396 }
11397 }
11398
11399 return false;
11400 }
11401
11402 /* Check that there is one and only one Dwfl_Module, return in arg. */
11403 static int
getone_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)11404 getone_dwflmod (Dwfl_Module *dwflmod,
11405 void **userdata __attribute__ ((unused)),
11406 const char *name __attribute__ ((unused)),
11407 Dwarf_Addr base __attribute__ ((unused)),
11408 void *arg)
11409 {
11410 Dwfl_Module **m = (Dwfl_Module **) arg;
11411 if (*m != NULL)
11412 return DWARF_CB_ABORT;
11413 *m = dwflmod;
11414 return DWARF_CB_OK;
11415 }
11416
11417 static void
print_debug(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr)11418 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
11419 {
11420 /* Used for skeleton file, if necessary for split DWARF. */
11421 Dwfl *skel_dwfl = NULL;
11422 Dwfl_Module *skel_mod = NULL;
11423 char *skel_name = NULL;
11424 Dwarf *split_dbg = NULL;
11425 Dwarf_CU *split_cu = NULL;
11426
11427 /* Before we start the real work get a debug context descriptor. */
11428 Dwarf_Addr dwbias;
11429 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
11430 Dwarf dummy_dbg =
11431 {
11432 .elf = ebl->elf,
11433 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
11434 };
11435 if (dbg == NULL)
11436 {
11437 if ((print_debug_sections & ~(section_exception|section_frame)) != 0)
11438 error (0, 0, _("cannot get debug context descriptor: %s"),
11439 dwfl_errmsg (-1));
11440 dbg = &dummy_dbg;
11441 }
11442 else
11443 {
11444 /* If we are asked about a split dwarf (.dwo) file, use the user
11445 provided, or find the corresponding skeleton file. If we got
11446 a skeleton file, replace the given dwflmod and dbg, with one
11447 derived from the skeleton file to provide enough context. */
11448 uint64_t split_id;
11449 if (is_split_dwarf (dbg, &split_id, &split_cu))
11450 {
11451 if (dwarf_skeleton != NULL)
11452 skel_name = strdup (dwarf_skeleton);
11453 else
11454 {
11455 /* Replace file.dwo with file.o and see if that matches. */
11456 const char *fname;
11457 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL,
11458 &fname, NULL);
11459 if (fname != NULL)
11460 {
11461 size_t flen = strlen (fname);
11462 if (flen > 4 && strcmp (".dwo", fname + flen - 4) == 0)
11463 {
11464 skel_name = strdup (fname);
11465 if (skel_name != NULL)
11466 {
11467 skel_name[flen - 3] = 'o';
11468 skel_name[flen - 2] = '\0';
11469 }
11470 }
11471 }
11472 }
11473
11474 if (skel_name != NULL)
11475 {
11476 int skel_fd = open (skel_name, O_RDONLY);
11477 if (skel_fd == -1)
11478 fprintf (stderr, "Warning: Couldn't open DWARF skeleton file"
11479 " '%s'\n", skel_name);
11480 else
11481 skel_dwfl = create_dwfl (skel_fd, skel_name);
11482
11483 if (skel_dwfl != NULL)
11484 {
11485 if (dwfl_getmodules (skel_dwfl, &getone_dwflmod,
11486 &skel_mod, 0) != 0)
11487 {
11488 fprintf (stderr, "Warning: Bad DWARF skeleton,"
11489 " multiple modules '%s'\n", skel_name);
11490 dwfl_end (skel_dwfl);
11491 skel_mod = NULL;
11492 }
11493 }
11494 else if (skel_fd != -1)
11495 fprintf (stderr, "Warning: Couldn't create skeleton dwfl for"
11496 " '%s': %s\n", skel_name, dwfl_errmsg (-1));
11497
11498 if (skel_mod != NULL)
11499 {
11500 Dwarf *skel_dbg = dwfl_module_getdwarf (skel_mod, &dwbias);
11501 if (skel_dbg != NULL)
11502 {
11503 /* First check the skeleton CU DIE, only fetch
11504 the split DIE if we know the id matches to
11505 not unnecessary search for any split DIEs we
11506 don't need. */
11507 Dwarf_CU *cu = NULL;
11508 while (dwarf_get_units (skel_dbg, cu, &cu,
11509 NULL, NULL, NULL, NULL) == 0)
11510 {
11511 uint8_t unit_type;
11512 uint64_t skel_id;
11513 if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11514 &skel_id, NULL, NULL) == 0
11515 && unit_type == DW_UT_skeleton
11516 && split_id == skel_id)
11517 {
11518 Dwarf_Die subdie;
11519 if (dwarf_cu_info (cu, NULL, NULL, NULL,
11520 &subdie,
11521 NULL, NULL, NULL) == 0
11522 && dwarf_tag (&subdie) != DW_TAG_invalid)
11523 {
11524 split_dbg = dwarf_cu_getdwarf (subdie.cu);
11525 if (split_dbg == NULL)
11526 fprintf (stderr,
11527 "Warning: Couldn't get split_dbg:"
11528 " %s\n", dwarf_errmsg (-1));
11529 break;
11530 }
11531 else
11532 {
11533 /* Everything matches up, but not
11534 according to libdw. Which means
11535 the user knew better. So...
11536 Terrible hack... We can never
11537 destroy the underlying dwfl
11538 because it would free the wrong
11539 Dwarfs... So we leak memory...*/
11540 if (cu->split == NULL
11541 && dwarf_skeleton != NULL)
11542 {
11543 do_not_close_dwfl = true;
11544 __libdw_link_skel_split (cu, split_cu);
11545 split_dbg = dwarf_cu_getdwarf (split_cu);
11546 break;
11547 }
11548 else
11549 fprintf (stderr, "Warning: Couldn't get"
11550 " skeleton subdie: %s\n",
11551 dwarf_errmsg (-1));
11552 }
11553 }
11554 }
11555 if (split_dbg == NULL)
11556 fprintf (stderr, "Warning: '%s' didn't contain a skeleton for split id %" PRIx64 "\n", skel_name, split_id);
11557 }
11558 else
11559 fprintf (stderr, "Warning: Couldn't get skeleton DWARF:"
11560 " %s\n", dwfl_errmsg (-1));
11561 }
11562 }
11563
11564 if (split_dbg != NULL)
11565 {
11566 dbg = split_dbg;
11567 dwflmod = skel_mod;
11568 }
11569 else if (skel_name == NULL)
11570 fprintf (stderr,
11571 "Warning: split DWARF file, but no skeleton found.\n");
11572 }
11573 else if (dwarf_skeleton != NULL)
11574 fprintf (stderr, "Warning: DWARF skeleton given,"
11575 " but not a split DWARF file\n");
11576 }
11577
11578 /* Get the section header string table index. */
11579 size_t shstrndx;
11580 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
11581 error_exit (0, _("cannot get section header string table index"));
11582
11583 /* If the .debug_info section is listed as implicitly required then
11584 we must make sure to handle it before handling any other debug
11585 section. Various other sections depend on the CU DIEs being
11586 scanned (silently) first. */
11587 bool implicit_info = (implicit_debug_sections & section_info) != 0;
11588 bool explicit_info = (print_debug_sections & section_info) != 0;
11589 if (implicit_info)
11590 {
11591 Elf_Scn *scn = NULL;
11592 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11593 {
11594 GElf_Shdr shdr_mem;
11595 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11596
11597 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11598 {
11599 const char *name = elf_strptr (ebl->elf, shstrndx,
11600 shdr->sh_name);
11601 if (name == NULL)
11602 continue;
11603
11604 if (strcmp (name, ".debug_info") == 0
11605 || strcmp (name, ".debug_info.dwo") == 0
11606 || strcmp (name, ".zdebug_info") == 0
11607 || strcmp (name, ".zdebug_info.dwo") == 0
11608 || strcmp (name, ".gnu.debuglto_.debug_info") == 0)
11609 {
11610 print_debug_info_section (dwflmod, ebl, ehdr,
11611 scn, shdr, dbg);
11612 break;
11613 }
11614 }
11615 }
11616 print_debug_sections &= ~section_info;
11617 implicit_debug_sections &= ~section_info;
11618 }
11619
11620 /* Look through all the sections for the debugging sections to print. */
11621 Elf_Scn *scn = NULL;
11622 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11623 {
11624 GElf_Shdr shdr_mem;
11625 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11626
11627 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11628 {
11629 static const struct
11630 {
11631 const char *name;
11632 enum section_e bitmask;
11633 void (*fp) (Dwfl_Module *, Ebl *,
11634 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
11635 } debug_sections[] =
11636 {
11637 #define NEW_SECTION(name) \
11638 { ".debug_" #name, section_##name, print_debug_##name##_section }
11639 NEW_SECTION (abbrev),
11640 NEW_SECTION (addr),
11641 NEW_SECTION (aranges),
11642 NEW_SECTION (frame),
11643 NEW_SECTION (info),
11644 NEW_SECTION (types),
11645 NEW_SECTION (line),
11646 NEW_SECTION (loc),
11647 /* loclists is loc for DWARF5. */
11648 { ".debug_loclists", section_loc,
11649 print_debug_loclists_section },
11650 NEW_SECTION (pubnames),
11651 NEW_SECTION (str),
11652 /* A DWARF5 specialised debug string section. */
11653 { ".debug_line_str", section_str,
11654 print_debug_str_section },
11655 /* DWARF5 string offsets table. */
11656 { ".debug_str_offsets", section_str,
11657 print_debug_str_offsets_section },
11658 NEW_SECTION (macinfo),
11659 NEW_SECTION (macro),
11660 NEW_SECTION (ranges),
11661 /* rnglists is ranges for DWARF5. */
11662 { ".debug_rnglists", section_ranges,
11663 print_debug_rnglists_section },
11664 { ".eh_frame", section_frame | section_exception,
11665 print_debug_frame_section },
11666 { ".eh_frame_hdr", section_frame | section_exception,
11667 print_debug_frame_hdr_section },
11668 { ".gcc_except_table", section_frame | section_exception,
11669 print_debug_exception_table },
11670 { ".gdb_index", section_gdb_index, print_gdb_index_section }
11671 };
11672 const int ndebug_sections = (sizeof (debug_sections)
11673 / sizeof (debug_sections[0]));
11674 const char *name = elf_strptr (ebl->elf, shstrndx,
11675 shdr->sh_name);
11676 if (name == NULL)
11677 continue;
11678
11679 int n;
11680 for (n = 0; n < ndebug_sections; ++n)
11681 {
11682 size_t dbglen = strlen (debug_sections[n].name);
11683 size_t scnlen = strlen (name);
11684 if ((strncmp (name, debug_sections[n].name, dbglen) == 0
11685 && (dbglen == scnlen
11686 || (scnlen == dbglen + 4
11687 && strstr (name, ".dwo") == name + dbglen)))
11688 || (name[0] == '.' && name[1] == 'z'
11689 && debug_sections[n].name[1] == 'd'
11690 && strncmp (&name[2], &debug_sections[n].name[1],
11691 dbglen - 1) == 0
11692 && (scnlen == dbglen + 1
11693 || (scnlen == dbglen + 5
11694 && strstr (name, ".dwo") == name + dbglen + 1)))
11695 || (scnlen > 14 /* .gnu.debuglto_ prefix. */
11696 && startswith (name, ".gnu.debuglto_")
11697 && strcmp (&name[14], debug_sections[n].name) == 0)
11698 )
11699 {
11700 if ((print_debug_sections | implicit_debug_sections)
11701 & debug_sections[n].bitmask)
11702 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
11703 break;
11704 }
11705 }
11706 }
11707 }
11708
11709 dwfl_end (skel_dwfl);
11710 free (skel_name);
11711
11712 /* Turn implicit and/or explicit back on in case we go over another file. */
11713 if (implicit_info)
11714 implicit_debug_sections |= section_info;
11715 if (explicit_info)
11716 print_debug_sections |= section_info;
11717
11718 reset_listptr (&known_locsptr);
11719 reset_listptr (&known_loclistsptr);
11720 reset_listptr (&known_rangelistptr);
11721 reset_listptr (&known_rnglistptr);
11722 reset_listptr (&known_addrbases);
11723 reset_listptr (&known_stroffbases);
11724 }
11725
11726
11727 #define ITEM_INDENT 4
11728 #define WRAP_COLUMN 75
11729
11730 /* Print "NAME: FORMAT", wrapping when output text would make the line
11731 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
11732 but this function is also used for registers which should be printed
11733 aligned. Fortunately registers output uses fixed fields width (such
11734 as %11d) for the alignment.
11735
11736 Line breaks should not depend on the particular values although that
11737 may happen in some cases of the core items. */
11738
11739 static unsigned int
11740 __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,...)11741 print_core_item (unsigned int colno, char sep, unsigned int wrap,
11742 size_t name_width, const char *name, const char *format, ...)
11743 {
11744 size_t len = strlen (name);
11745 if (name_width < len)
11746 name_width = len;
11747
11748 char *out;
11749 va_list ap;
11750 va_start (ap, format);
11751 int out_len = vasprintf (&out, format, ap);
11752 va_end (ap);
11753 if (out_len == -1)
11754 error_exit (0, _("memory exhausted"));
11755
11756 size_t n = name_width + sizeof ": " - 1 + out_len;
11757
11758 if (colno == 0)
11759 {
11760 printf ("%*s", ITEM_INDENT, "");
11761 colno = ITEM_INDENT + n;
11762 }
11763 else if (colno + 2 + n < wrap)
11764 {
11765 printf ("%c ", sep);
11766 colno += 2 + n;
11767 }
11768 else
11769 {
11770 printf ("\n%*s", ITEM_INDENT, "");
11771 colno = ITEM_INDENT + n;
11772 }
11773
11774 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
11775
11776 free (out);
11777
11778 return colno;
11779 }
11780
11781 static const void *
convert(Elf * core,Elf_Type type,uint_fast16_t count,void * value,const void * data,size_t size)11782 convert (Elf *core, Elf_Type type, uint_fast16_t count,
11783 void *value, const void *data, size_t size)
11784 {
11785 Elf_Data valuedata =
11786 {
11787 .d_type = type,
11788 .d_buf = value,
11789 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
11790 .d_version = EV_CURRENT,
11791 };
11792 Elf_Data indata =
11793 {
11794 .d_type = type,
11795 .d_buf = (void *) data,
11796 .d_size = valuedata.d_size,
11797 .d_version = EV_CURRENT,
11798 };
11799
11800 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
11801 ? elf32_xlatetom : elf64_xlatetom)
11802 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
11803 if (d == NULL)
11804 error_exit (0, _("cannot convert core note data: %s"),
11805 elf_errmsg (-1));
11806
11807 return data + indata.d_size;
11808 }
11809
11810 typedef uint8_t GElf_Byte;
11811
11812 static unsigned int
handle_core_item(Elf * core,const Ebl_Core_Item * item,const void * desc,unsigned int colno,size_t * repeated_size)11813 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
11814 unsigned int colno, size_t *repeated_size)
11815 {
11816 uint_fast16_t count = item->count ?: 1;
11817 /* Ebl_Core_Item count is always a small number.
11818 Make sure the backend didn't put in some large bogus value. */
11819 assert (count < 128);
11820
11821 #define TYPES \
11822 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
11823 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
11824 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
11825 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
11826 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
11827 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
11828
11829 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
11830 typedef union { TYPES; } value_t;
11831 void *data = alloca (count * sizeof (value_t));
11832 #undef DO_TYPE
11833
11834 #define DO_TYPE(NAME, Name, hex, dec) \
11835 GElf_##Name *value_##Name __attribute__((unused)) = data
11836 TYPES;
11837 #undef DO_TYPE
11838
11839 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
11840 size_t convsize = size;
11841 if (repeated_size != NULL)
11842 {
11843 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
11844 {
11845 data = alloca (*repeated_size);
11846 count *= *repeated_size / size;
11847 convsize = count * size;
11848 *repeated_size -= convsize;
11849 }
11850 else if (item->count != 0 || item->format != '\n')
11851 *repeated_size -= size;
11852 }
11853
11854 convert (core, item->type, count, data, desc + item->offset, convsize);
11855
11856 Elf_Type type = item->type;
11857 if (type == ELF_T_ADDR)
11858 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
11859
11860 switch (item->format)
11861 {
11862 case 'd':
11863 assert (count == 1);
11864 switch (type)
11865 {
11866 #define DO_TYPE(NAME, Name, hex, dec) \
11867 case ELF_T_##NAME: \
11868 colno = print_core_item (colno, ',', WRAP_COLUMN, \
11869 0, item->name, dec, value_##Name[0]); \
11870 break
11871 TYPES;
11872 #undef DO_TYPE
11873 default:
11874 abort ();
11875 }
11876 break;
11877
11878 case 'x':
11879 assert (count == 1);
11880 switch (type)
11881 {
11882 #define DO_TYPE(NAME, Name, hex, dec) \
11883 case ELF_T_##NAME: \
11884 colno = print_core_item (colno, ',', WRAP_COLUMN, \
11885 0, item->name, hex, value_##Name[0]); \
11886 break
11887 TYPES;
11888 #undef DO_TYPE
11889 default:
11890 abort ();
11891 }
11892 break;
11893
11894 case 'b':
11895 case 'B':
11896 assert (size % sizeof (unsigned int) == 0);
11897 unsigned int nbits = count * size * 8;
11898 unsigned int pop = 0;
11899 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
11900 pop += __builtin_popcount (*i);
11901 bool negate = pop > nbits / 2;
11902 const unsigned int bias = item->format == 'b';
11903
11904 {
11905 char printed[(negate ? nbits - pop : pop) * 16 + 1];
11906 char *p = printed;
11907 *p = '\0';
11908
11909 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
11910 {
11911 assert (size == sizeof (unsigned int) * 2);
11912 for (unsigned int *i = data;
11913 (void *) i < data + count * size; i += 2)
11914 {
11915 unsigned int w = i[1];
11916 i[1] = i[0];
11917 i[0] = w;
11918 }
11919 }
11920
11921 unsigned int lastbit = 0;
11922 unsigned int run = 0;
11923 for (const unsigned int *i = data;
11924 (void *) i < data + count * size; ++i)
11925 {
11926 unsigned int bit = ((void *) i - data) * 8;
11927 unsigned int w = negate ? ~*i : *i;
11928 while (w != 0)
11929 {
11930 /* Note that a right shift equal to (or greater than)
11931 the number of bits of w is undefined behaviour. In
11932 particular when the least significant bit is bit 32
11933 (w = 0x8000000) then w >>= n is undefined. So
11934 explicitly handle that case separately. */
11935 unsigned int n = ffs (w);
11936 if (n < sizeof (w) * 8)
11937 w >>= n;
11938 else
11939 w = 0;
11940 bit += n;
11941
11942 if (lastbit != 0 && lastbit + 1 == bit)
11943 ++run;
11944 else
11945 {
11946 if (lastbit == 0)
11947 p += sprintf (p, "%u", bit - bias);
11948 else if (run == 0)
11949 p += sprintf (p, ",%u", bit - bias);
11950 else
11951 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
11952 run = 0;
11953 }
11954
11955 lastbit = bit;
11956 }
11957 }
11958 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
11959 p += sprintf (p, "-%u", lastbit - bias);
11960
11961 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11962 negate ? "~<%s>" : "<%s>", printed);
11963 }
11964 break;
11965
11966 case 'T':
11967 case (char) ('T'|0x80):
11968 assert (count == 2);
11969 Dwarf_Word sec;
11970 Dwarf_Word usec;
11971 switch (type)
11972 {
11973 #define DO_TYPE(NAME, Name, hex, dec) \
11974 case ELF_T_##NAME: \
11975 sec = value_##Name[0]; \
11976 usec = value_##Name[1]; \
11977 break
11978 TYPES;
11979 #undef DO_TYPE
11980 default:
11981 abort ();
11982 }
11983 if (unlikely (item->format == (char) ('T'|0x80)))
11984 {
11985 /* This is a hack for an ill-considered 64-bit ABI where
11986 tv_usec is actually a 32-bit field with 32 bits of padding
11987 rounding out struct timeval. We've already converted it as
11988 a 64-bit field. For little-endian, this just means the
11989 high half is the padding; it's presumably zero, but should
11990 be ignored anyway. For big-endian, it means the 32-bit
11991 field went into the high half of USEC. */
11992 GElf_Ehdr ehdr_mem;
11993 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
11994 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
11995 usec >>= 32;
11996 else
11997 usec &= UINT32_MAX;
11998 }
11999 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
12000 "%" PRIu64 ".%.6" PRIu64, sec, usec);
12001 break;
12002
12003 case 'c':
12004 assert (count == 1);
12005 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
12006 "%c", value_Byte[0]);
12007 break;
12008
12009 case 's':
12010 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
12011 "%.*s", (int) count, value_Byte);
12012 break;
12013
12014 case '\n':
12015 /* This is a list of strings separated by '\n'. */
12016 assert (item->count == 0);
12017 assert (repeated_size != NULL);
12018 assert (item->name == NULL);
12019 if (unlikely (item->offset >= *repeated_size))
12020 break;
12021
12022 const char *s = desc + item->offset;
12023 size = *repeated_size - item->offset;
12024 *repeated_size = 0;
12025 while (size > 0)
12026 {
12027 const char *eol = memchr (s, '\n', size);
12028 int len = size;
12029 if (eol != NULL)
12030 len = eol - s;
12031 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
12032 if (eol == NULL)
12033 break;
12034 size -= eol + 1 - s;
12035 s = eol + 1;
12036 }
12037
12038 colno = WRAP_COLUMN;
12039 break;
12040
12041 case 'h':
12042 break;
12043
12044 default:
12045 error (0, 0, "XXX not handling format '%c' for %s",
12046 item->format, item->name);
12047 break;
12048 }
12049
12050 #undef TYPES
12051
12052 return colno;
12053 }
12054
12055
12056 /* Sort items by group, and by layout offset within each group. */
12057 static int
compare_core_items(const void * a,const void * b)12058 compare_core_items (const void *a, const void *b)
12059 {
12060 const Ebl_Core_Item *const *p1 = a;
12061 const Ebl_Core_Item *const *p2 = b;
12062 const Ebl_Core_Item *item1 = *p1;
12063 const Ebl_Core_Item *item2 = *p2;
12064
12065 return ((item1->group == item2->group ? 0
12066 : strcmp (item1->group, item2->group))
12067 ?: (int) item1->offset - (int) item2->offset);
12068 }
12069
12070 /* Sort item groups by layout offset of the first item in the group. */
12071 static int
compare_core_item_groups(const void * a,const void * b)12072 compare_core_item_groups (const void *a, const void *b)
12073 {
12074 const Ebl_Core_Item *const *const *p1 = a;
12075 const Ebl_Core_Item *const *const *p2 = b;
12076 const Ebl_Core_Item *const *group1 = *p1;
12077 const Ebl_Core_Item *const *group2 = *p2;
12078 const Ebl_Core_Item *item1 = *group1;
12079 const Ebl_Core_Item *item2 = *group2;
12080
12081 return (int) item1->offset - (int) item2->offset;
12082 }
12083
12084 static unsigned int
handle_core_items(Elf * core,const void * desc,size_t descsz,const Ebl_Core_Item * items,size_t nitems)12085 handle_core_items (Elf *core, const void *desc, size_t descsz,
12086 const Ebl_Core_Item *items, size_t nitems)
12087 {
12088 if (nitems == 0)
12089 return 0;
12090 unsigned int colno = 0;
12091
12092 /* FORMAT '\n' makes sense to be present only as a single item as it
12093 processes all the data of a note. FORMATs 'b' and 'B' have a special case
12094 if present as a single item but they can be also processed with other
12095 items below. */
12096 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
12097 || items[0].format == 'B'))
12098 {
12099 assert (items[0].offset == 0);
12100 size_t size = descsz;
12101 colno = handle_core_item (core, items, desc, colno, &size);
12102 /* If SIZE is not zero here there is some remaining data. But we do not
12103 know how to process it anyway. */
12104 return colno;
12105 }
12106 for (size_t i = 0; i < nitems; ++i)
12107 assert (items[i].format != '\n');
12108
12109 /* Sort to collect the groups together. */
12110 const Ebl_Core_Item *sorted_items[nitems];
12111 for (size_t i = 0; i < nitems; ++i)
12112 sorted_items[i] = &items[i];
12113 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
12114
12115 /* Collect the unique groups and sort them. */
12116 const Ebl_Core_Item **groups[nitems];
12117 groups[0] = &sorted_items[0];
12118 size_t ngroups = 1;
12119 for (size_t i = 1; i < nitems; ++i)
12120 if (sorted_items[i]->group != sorted_items[i - 1]->group
12121 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
12122 groups[ngroups++] = &sorted_items[i];
12123 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
12124
12125 /* Write out all the groups. */
12126 const void *last = desc;
12127 do
12128 {
12129 for (size_t i = 0; i < ngroups; ++i)
12130 {
12131 for (const Ebl_Core_Item **item = groups[i];
12132 (item < &sorted_items[nitems]
12133 && ((*item)->group == groups[i][0]->group
12134 || !strcmp ((*item)->group, groups[i][0]->group)));
12135 ++item)
12136 colno = handle_core_item (core, *item, desc, colno, NULL);
12137
12138 /* Force a line break at the end of the group. */
12139 colno = WRAP_COLUMN;
12140 }
12141
12142 if (descsz == 0)
12143 break;
12144
12145 /* This set of items consumed a certain amount of the note's data.
12146 If there is more data there, we have another unit of the same size.
12147 Loop to print that out too. */
12148 const Ebl_Core_Item *item = &items[nitems - 1];
12149 size_t eltsz = item->offset + gelf_fsize (core, item->type,
12150 item->count ?: 1, EV_CURRENT);
12151
12152 int reps = -1;
12153 do
12154 {
12155 ++reps;
12156 desc += eltsz;
12157 descsz -= eltsz;
12158 }
12159 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
12160
12161 if (reps == 1)
12162 {
12163 /* For just one repeat, print it unabridged twice. */
12164 desc -= eltsz;
12165 descsz += eltsz;
12166 }
12167 else if (reps > 1)
12168 printf (_("\n%*s... <repeats %u more times> ..."),
12169 ITEM_INDENT, "", reps);
12170
12171 last = desc;
12172 }
12173 while (descsz > 0);
12174
12175 return colno;
12176 }
12177
12178 static unsigned int
handle_bit_registers(const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)12179 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
12180 unsigned int colno)
12181 {
12182 desc += regloc->offset;
12183
12184 abort (); /* XXX */
12185 return colno;
12186 }
12187
12188
12189 static unsigned int
handle_core_register(Ebl * ebl,Elf * core,int maxregname,const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)12190 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
12191 const Ebl_Register_Location *regloc, const void *desc,
12192 unsigned int colno)
12193 {
12194 if (regloc->bits % 8 != 0)
12195 return handle_bit_registers (regloc, desc, colno);
12196
12197 desc += regloc->offset;
12198
12199 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
12200 {
12201 char name[REGNAMESZ];
12202 int bits;
12203 int type;
12204 register_info (ebl, reg, regloc, name, &bits, &type);
12205
12206 #define TYPES \
12207 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
12208 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
12209 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
12210 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
12211
12212 #define BITS(bits, xtype, sfmt, ufmt) \
12213 uint##bits##_t b##bits; int##bits##_t b##bits##s
12214 union { TYPES; uint64_t b128[2]; } value;
12215 #undef BITS
12216
12217 switch (type)
12218 {
12219 case DW_ATE_unsigned:
12220 case DW_ATE_signed:
12221 case DW_ATE_address:
12222 switch (bits)
12223 {
12224 #define BITS(bits, xtype, sfmt, ufmt) \
12225 case bits: \
12226 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
12227 if (type == DW_ATE_signed) \
12228 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
12229 maxregname, name, \
12230 sfmt, value.b##bits##s); \
12231 else \
12232 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
12233 maxregname, name, \
12234 ufmt, value.b##bits); \
12235 break
12236
12237 TYPES;
12238
12239 case 128:
12240 assert (type == DW_ATE_unsigned);
12241 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
12242 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
12243 colno = print_core_item (colno, ' ', WRAP_COLUMN,
12244 maxregname, name,
12245 "0x%.16" PRIx64 "%.16" PRIx64,
12246 value.b128[!be], value.b128[be]);
12247 break;
12248
12249 default:
12250 abort ();
12251 #undef BITS
12252 }
12253 break;
12254
12255 default:
12256 /* Print each byte in hex, the whole thing in native byte order. */
12257 assert (bits % 8 == 0);
12258 const uint8_t *bytes = desc;
12259 desc += bits / 8;
12260 char hex[bits / 4 + 1];
12261 hex[bits / 4] = '\0';
12262 int incr = 1;
12263 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
12264 {
12265 bytes += bits / 8 - 1;
12266 incr = -1;
12267 }
12268 size_t idx = 0;
12269 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
12270 {
12271 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
12272 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
12273 }
12274 colno = print_core_item (colno, ' ', WRAP_COLUMN,
12275 maxregname, name, "0x%s", hex);
12276 break;
12277 }
12278 desc += regloc->pad;
12279
12280 #undef TYPES
12281 }
12282
12283 return colno;
12284 }
12285
12286
12287 struct register_info
12288 {
12289 const Ebl_Register_Location *regloc;
12290 const char *set;
12291 char name[REGNAMESZ];
12292 int regno;
12293 int bits;
12294 int type;
12295 };
12296
12297 static int
register_bitpos(const struct register_info * r)12298 register_bitpos (const struct register_info *r)
12299 {
12300 return (r->regloc->offset * 8
12301 + ((r->regno - r->regloc->regno)
12302 * (r->regloc->bits + r->regloc->pad * 8)));
12303 }
12304
12305 static int
compare_sets_by_info(const struct register_info * r1,const struct register_info * r2)12306 compare_sets_by_info (const struct register_info *r1,
12307 const struct register_info *r2)
12308 {
12309 return ((int) r2->bits - (int) r1->bits
12310 ?: register_bitpos (r1) - register_bitpos (r2));
12311 }
12312
12313 /* Sort registers by set, and by size and layout offset within each set. */
12314 static int
compare_registers(const void * a,const void * b)12315 compare_registers (const void *a, const void *b)
12316 {
12317 const struct register_info *r1 = a;
12318 const struct register_info *r2 = b;
12319
12320 /* Unused elements sort last. */
12321 if (r1->regloc == NULL)
12322 return r2->regloc == NULL ? 0 : 1;
12323 if (r2->regloc == NULL)
12324 return -1;
12325
12326 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
12327 ?: compare_sets_by_info (r1, r2));
12328 }
12329
12330 /* Sort register sets by layout offset of the first register in the set. */
12331 static int
compare_register_sets(const void * a,const void * b)12332 compare_register_sets (const void *a, const void *b)
12333 {
12334 const struct register_info *const *p1 = a;
12335 const struct register_info *const *p2 = b;
12336 return compare_sets_by_info (*p1, *p2);
12337 }
12338
12339 static inline bool
same_set(const struct register_info * a,const struct register_info * b,const struct register_info * regs,size_t maxnreg)12340 same_set (const struct register_info *a,
12341 const struct register_info *b,
12342 const struct register_info *regs,
12343 size_t maxnreg)
12344 {
12345 return (a < ®s[maxnreg] && a->regloc != NULL
12346 && b < ®s[maxnreg] && b->regloc != NULL
12347 && a->bits == b->bits
12348 && (a->set == b->set || !strcmp (a->set, b->set)));
12349 }
12350
12351 static unsigned int
handle_core_registers(Ebl * ebl,Elf * core,const void * desc,const Ebl_Register_Location * reglocs,size_t nregloc)12352 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
12353 const Ebl_Register_Location *reglocs, size_t nregloc)
12354 {
12355 if (nregloc == 0)
12356 return 0;
12357
12358 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
12359 if (maxnreg <= 0)
12360 {
12361 for (size_t i = 0; i < nregloc; ++i)
12362 if (maxnreg < reglocs[i].regno + reglocs[i].count)
12363 maxnreg = reglocs[i].regno + reglocs[i].count;
12364 assert (maxnreg > 0);
12365 }
12366
12367 struct register_info regs[maxnreg];
12368 memset (regs, 0, sizeof regs);
12369
12370 /* Sort to collect the sets together. */
12371 int maxreg = 0;
12372 for (size_t i = 0; i < nregloc; ++i)
12373 for (int reg = reglocs[i].regno;
12374 reg < reglocs[i].regno + reglocs[i].count;
12375 ++reg)
12376 {
12377 assert (reg < maxnreg);
12378 if (reg > maxreg)
12379 maxreg = reg;
12380 struct register_info *info = ®s[reg];
12381 info->regloc = ®locs[i];
12382 info->regno = reg;
12383 info->set = register_info (ebl, reg, ®locs[i],
12384 info->name, &info->bits, &info->type);
12385 }
12386 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
12387
12388 /* Collect the unique sets and sort them. */
12389 struct register_info *sets[maxreg + 1];
12390 sets[0] = ®s[0];
12391 size_t nsets = 1;
12392 for (int i = 1; i <= maxreg; ++i)
12393 if (regs[i].regloc != NULL
12394 && !same_set (®s[i], ®s[i - 1], regs, maxnreg))
12395 sets[nsets++] = ®s[i];
12396 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
12397
12398 /* Write out all the sets. */
12399 unsigned int colno = 0;
12400 for (size_t i = 0; i < nsets; ++i)
12401 {
12402 /* Find the longest name of a register in this set. */
12403 size_t maxname = 0;
12404 const struct register_info *end;
12405 for (end = sets[i]; same_set (sets[i], end, regs, maxnreg); ++end)
12406 {
12407 size_t len = strlen (end->name);
12408 if (len > maxname)
12409 maxname = len;
12410 }
12411
12412 for (const struct register_info *reg = sets[i];
12413 reg < end;
12414 reg += reg->regloc->count ?: 1)
12415 colno = handle_core_register (ebl, core, maxname,
12416 reg->regloc, desc, colno);
12417
12418 /* Force a line break at the end of the group. */
12419 colno = WRAP_COLUMN;
12420 }
12421
12422 return colno;
12423 }
12424
12425 static void
handle_auxv_note(Ebl * ebl,Elf * core,GElf_Word descsz,GElf_Off desc_pos)12426 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12427 {
12428 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
12429 if (data == NULL)
12430 elf_error:
12431 error_exit (0, _("cannot convert core note data: %s"), elf_errmsg (-1));
12432
12433 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
12434 for (size_t i = 0; i < nauxv; ++i)
12435 {
12436 GElf_auxv_t av_mem;
12437 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
12438 if (av == NULL)
12439 goto elf_error;
12440
12441 const char *name;
12442 const char *fmt;
12443 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
12444 {
12445 /* Unknown type. */
12446 if (av->a_un.a_val == 0)
12447 printf (" %" PRIu64 "\n", av->a_type);
12448 else
12449 printf (" %" PRIu64 ": %#" PRIx64 "\n",
12450 av->a_type, av->a_un.a_val);
12451 }
12452 else
12453 switch (fmt[0])
12454 {
12455 case '\0': /* Normally zero. */
12456 if (av->a_un.a_val == 0)
12457 {
12458 printf (" %s\n", name);
12459 break;
12460 }
12461 FALLTHROUGH;
12462 case 'x': /* hex */
12463 case 'p': /* address */
12464 case 's': /* address of string */
12465 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
12466 break;
12467 case 'u':
12468 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
12469 break;
12470 case 'd':
12471 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
12472 break;
12473
12474 case 'b':
12475 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
12476 GElf_Xword bit = 1;
12477 const char *pfx = "<";
12478 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
12479 {
12480 if (av->a_un.a_val & bit)
12481 {
12482 printf ("%s%s", pfx, p);
12483 pfx = " ";
12484 }
12485 bit <<= 1;
12486 }
12487 printf (">\n");
12488 break;
12489
12490 default:
12491 abort ();
12492 }
12493 }
12494 }
12495
12496 static bool
buf_has_data(unsigned char const * ptr,unsigned char const * end,size_t sz)12497 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
12498 {
12499 return ptr < end && (size_t) (end - ptr) >= sz;
12500 }
12501
12502 static bool
buf_read_int(Elf * core,unsigned char const ** ptrp,unsigned char const * end,int * retp)12503 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12504 int *retp)
12505 {
12506 if (! buf_has_data (*ptrp, end, 4))
12507 return false;
12508
12509 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
12510 return true;
12511 }
12512
12513 static bool
buf_read_ulong(Elf * core,unsigned char const ** ptrp,unsigned char const * end,uint64_t * retp)12514 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12515 uint64_t *retp)
12516 {
12517 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12518 if (! buf_has_data (*ptrp, end, sz))
12519 return false;
12520
12521 union
12522 {
12523 uint64_t u64;
12524 uint32_t u32;
12525 } u;
12526
12527 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
12528
12529 if (sz == 4)
12530 *retp = u.u32;
12531 else
12532 *retp = u.u64;
12533 return true;
12534 }
12535
12536 static void
handle_siginfo_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12537 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12538 {
12539 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12540 if (data == NULL)
12541 error_exit (0, _("cannot convert core note data: %s"), elf_errmsg (-1));
12542
12543 unsigned char const *ptr = data->d_buf;
12544 unsigned char const *const end = data->d_buf + data->d_size;
12545
12546 /* Siginfo head is three ints: signal number, error number, origin
12547 code. */
12548 int si_signo, si_errno, si_code;
12549 if (! buf_read_int (core, &ptr, end, &si_signo)
12550 || ! buf_read_int (core, &ptr, end, &si_errno)
12551 || ! buf_read_int (core, &ptr, end, &si_code))
12552 {
12553 fail:
12554 printf (" Not enough data in NT_SIGINFO note.\n");
12555 return;
12556 }
12557
12558 /* Next is a pointer-aligned union of structures. On 64-bit
12559 machines, that implies a word of padding. */
12560 if (gelf_getclass (core) == ELFCLASS64)
12561 ptr += 4;
12562
12563 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
12564 si_signo, si_errno, si_code);
12565
12566 if (si_code > 0)
12567 switch (si_signo)
12568 {
12569 case CORE_SIGILL:
12570 case CORE_SIGFPE:
12571 case CORE_SIGSEGV:
12572 case CORE_SIGBUS:
12573 {
12574 uint64_t addr;
12575 if (! buf_read_ulong (core, &ptr, end, &addr))
12576 goto fail;
12577 printf (" fault address: %#" PRIx64 "\n", addr);
12578 break;
12579 }
12580 default:
12581 ;
12582 }
12583 else if (si_code == CORE_SI_USER)
12584 {
12585 int pid, uid;
12586 if (! buf_read_int (core, &ptr, end, &pid)
12587 || ! buf_read_int (core, &ptr, end, &uid))
12588 goto fail;
12589 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
12590 }
12591 }
12592
12593 static void
handle_file_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12594 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12595 {
12596 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12597 if (data == NULL)
12598 error_exit (0, _("cannot convert core note data: %s"), elf_errmsg (-1));
12599
12600 unsigned char const *ptr = data->d_buf;
12601 unsigned char const *const end = data->d_buf + data->d_size;
12602
12603 uint64_t count, page_size;
12604 if (! buf_read_ulong (core, &ptr, end, &count)
12605 || ! buf_read_ulong (core, &ptr, end, &page_size))
12606 {
12607 fail:
12608 printf (" Not enough data in NT_FILE note.\n");
12609 return;
12610 }
12611
12612 size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12613 uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
12614 if (count > maxcount)
12615 goto fail;
12616
12617 /* Where file names are stored. */
12618 unsigned char const *const fstart = ptr + 3 * count * addrsize;
12619 char const *fptr = (char *) fstart;
12620
12621 printf (" %" PRId64 " files:\n", count);
12622 for (uint64_t i = 0; i < count; ++i)
12623 {
12624 uint64_t mstart, mend, moffset;
12625 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
12626 || ! buf_read_ulong (core, &ptr, fstart, &mend)
12627 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
12628 goto fail;
12629
12630 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
12631 if (fnext == NULL)
12632 goto fail;
12633
12634 int ct = printf (" %08" PRIx64 "-%08" PRIx64
12635 " %08" PRIx64 " %" PRId64,
12636 mstart, mend, moffset * page_size, mend - mstart);
12637 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
12638
12639 fptr = fnext + 1;
12640 }
12641 }
12642
12643 static void
handle_core_note(Ebl * ebl,const GElf_Nhdr * nhdr,const char * name,const void * desc)12644 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
12645 const char *name, const void *desc)
12646 {
12647 GElf_Word regs_offset;
12648 size_t nregloc;
12649 const Ebl_Register_Location *reglocs;
12650 size_t nitems;
12651 const Ebl_Core_Item *items;
12652
12653 if (! ebl_core_note (ebl, nhdr, name, desc,
12654 ®s_offset, &nregloc, ®locs, &nitems, &items))
12655 return;
12656
12657 /* Pass 0 for DESCSZ when there are registers in the note,
12658 so that the ITEMS array does not describe the whole thing.
12659 For non-register notes, the actual descsz might be a multiple
12660 of the unit size, not just exactly the unit size. */
12661 unsigned int colno = handle_core_items (ebl->elf, desc,
12662 nregloc == 0 ? nhdr->n_descsz : 0,
12663 items, nitems);
12664 if (colno != 0)
12665 putchar_unlocked ('\n');
12666
12667 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
12668 reglocs, nregloc);
12669 if (colno != 0)
12670 putchar_unlocked ('\n');
12671 }
12672
12673 static void
handle_notes_data(Ebl * ebl,const GElf_Ehdr * ehdr,GElf_Off start,Elf_Data * data)12674 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
12675 GElf_Off start, Elf_Data *data)
12676 {
12677 fputs_unlocked (_(" Owner Data size Type\n"), stdout);
12678
12679 if (data == NULL)
12680 goto bad_note;
12681
12682 size_t offset = 0;
12683 GElf_Nhdr nhdr;
12684 size_t name_offset;
12685 size_t desc_offset;
12686 while (offset < data->d_size
12687 && (offset = gelf_getnote (data, offset,
12688 &nhdr, &name_offset, &desc_offset)) > 0)
12689 {
12690 const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
12691 const char *desc = data->d_buf + desc_offset;
12692
12693 /* GNU Build Attributes are weird, they store most of their data
12694 into the owner name field. Extract just the owner name
12695 prefix here, then use the rest later as data. */
12696 bool is_gnu_build_attr
12697 = startswith (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX);
12698 const char *print_name = (is_gnu_build_attr
12699 ? ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX : name);
12700 size_t print_namesz = (is_gnu_build_attr
12701 ? strlen (print_name) : nhdr.n_namesz);
12702
12703 char buf[100];
12704 char buf2[100];
12705 printf (_(" %-13.*s %9" PRId32 " %s\n"),
12706 (int) print_namesz, print_name, nhdr.n_descsz,
12707 ehdr->e_type == ET_CORE
12708 ? ebl_core_note_type_name (ebl, nhdr.n_type,
12709 buf, sizeof (buf))
12710 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
12711 nhdr.n_descsz,
12712 buf2, sizeof (buf2)));
12713
12714 /* Filter out invalid entries. */
12715 if (memchr (name, '\0', nhdr.n_namesz) != NULL
12716 /* XXX For now help broken Linux kernels. */
12717 || 1)
12718 {
12719 if (ehdr->e_type == ET_CORE)
12720 {
12721 if (nhdr.n_type == NT_AUXV
12722 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
12723 || (nhdr.n_namesz == 5 && name[4] == '\0'))
12724 && !memcmp (name, "CORE", 4))
12725 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
12726 start + desc_offset);
12727 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
12728 switch (nhdr.n_type)
12729 {
12730 case NT_SIGINFO:
12731 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
12732 start + desc_offset);
12733 break;
12734
12735 case NT_FILE:
12736 handle_file_note (ebl->elf, nhdr.n_descsz,
12737 start + desc_offset);
12738 break;
12739
12740 default:
12741 handle_core_note (ebl, &nhdr, name, desc);
12742 }
12743 else
12744 handle_core_note (ebl, &nhdr, name, desc);
12745 }
12746 else
12747 ebl_object_note (ebl, nhdr.n_namesz, name, nhdr.n_type,
12748 nhdr.n_descsz, desc);
12749 }
12750 }
12751
12752 if (offset == data->d_size)
12753 return;
12754
12755 bad_note:
12756 error (0, 0,
12757 _("cannot get content of note: %s"),
12758 data != NULL ? "garbage data" : elf_errmsg (-1));
12759 }
12760
12761 static void
handle_notes(Ebl * ebl,GElf_Ehdr * ehdr)12762 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
12763 {
12764 /* If we have section headers, just look for SHT_NOTE sections.
12765 In a debuginfo file, the program headers are not reliable. */
12766 if (shnum != 0)
12767 {
12768 /* Get the section header string table index. */
12769 size_t shstrndx;
12770 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
12771 error_exit (0, _("cannot get section header string table index"));
12772
12773 Elf_Scn *scn = NULL;
12774 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12775 {
12776 GElf_Shdr shdr_mem;
12777 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
12778
12779 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
12780 /* Not what we are looking for. */
12781 continue;
12782
12783 if (notes_section != NULL)
12784 {
12785 char *sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
12786 if (sname == NULL || strcmp (sname, notes_section) != 0)
12787 continue;
12788 }
12789
12790 printf (_("\
12791 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12792 elf_ndxscn (scn),
12793 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
12794 shdr->sh_size, shdr->sh_offset);
12795
12796 handle_notes_data (ebl, ehdr, shdr->sh_offset,
12797 elf_getdata (scn, NULL));
12798 }
12799 return;
12800 }
12801
12802 /* We have to look through the program header to find the note
12803 sections. There can be more than one. */
12804 for (size_t cnt = 0; cnt < phnum; ++cnt)
12805 {
12806 GElf_Phdr mem;
12807 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
12808
12809 if (phdr == NULL || phdr->p_type != PT_NOTE)
12810 /* Not what we are looking for. */
12811 continue;
12812
12813 printf (_("\
12814 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12815 phdr->p_filesz, phdr->p_offset);
12816
12817 handle_notes_data (ebl, ehdr, phdr->p_offset,
12818 elf_getdata_rawchunk (ebl->elf,
12819 phdr->p_offset, phdr->p_filesz,
12820 (phdr->p_align == 8
12821 ? ELF_T_NHDR8 : ELF_T_NHDR)));
12822 }
12823 }
12824
12825
12826 static void
hex_dump(const uint8_t * data,size_t len)12827 hex_dump (const uint8_t *data, size_t len)
12828 {
12829 size_t pos = 0;
12830 while (pos < len)
12831 {
12832 printf (" 0x%08zx ", pos);
12833
12834 const size_t chunk = MIN (len - pos, 16);
12835
12836 for (size_t i = 0; i < chunk; ++i)
12837 if (i % 4 == 3)
12838 printf ("%02x ", data[pos + i]);
12839 else
12840 printf ("%02x", data[pos + i]);
12841
12842 if (chunk < 16)
12843 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
12844
12845 for (size_t i = 0; i < chunk; ++i)
12846 {
12847 unsigned char b = data[pos + i];
12848 printf ("%c", isprint (b) ? b : '.');
12849 }
12850
12851 putchar ('\n');
12852 pos += chunk;
12853 }
12854 }
12855
12856 static void
dump_data_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12857 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12858 {
12859 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12860 printf (_("\nSection [%zu] '%s' has no data to dump.\n"),
12861 elf_ndxscn (scn), name);
12862 else
12863 {
12864 if (print_decompress)
12865 {
12866 /* We try to decompress the section, but keep the old shdr around
12867 so we can show both the original shdr size and the uncompressed
12868 data size. */
12869 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12870 {
12871 if (elf_compress (scn, 0, 0) < 0)
12872 printf ("WARNING: %s [%zd]\n",
12873 _("Couldn't uncompress section"),
12874 elf_ndxscn (scn));
12875 }
12876 else if (startswith (name, ".zdebug"))
12877 {
12878 if (elf_compress_gnu (scn, 0, 0) < 0)
12879 printf ("WARNING: %s [%zd]\n",
12880 _("Couldn't uncompress section"),
12881 elf_ndxscn (scn));
12882 }
12883 }
12884
12885 Elf_Data *data = elf_rawdata (scn, NULL);
12886 if (data == NULL)
12887 error (0, 0, _("cannot get data for section [%zu] '%s': %s"),
12888 elf_ndxscn (scn), name, elf_errmsg (-1));
12889 else
12890 {
12891 if (data->d_size == shdr->sh_size)
12892 printf (_("\nHex dump of section [%zu] '%s', %" PRIu64
12893 " bytes at offset %#0" PRIx64 ":\n"),
12894 elf_ndxscn (scn), name,
12895 shdr->sh_size, shdr->sh_offset);
12896 else
12897 printf (_("\nHex dump of section [%zu] '%s', %" PRIu64
12898 " bytes (%zd uncompressed) at offset %#0"
12899 PRIx64 ":\n"),
12900 elf_ndxscn (scn), name,
12901 shdr->sh_size, data->d_size, shdr->sh_offset);
12902 hex_dump (data->d_buf, data->d_size);
12903 }
12904 }
12905 }
12906
12907 static void
print_string_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12908 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12909 {
12910 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12911 printf (_("\nSection [%zu] '%s' has no strings to dump.\n"),
12912 elf_ndxscn (scn), name);
12913 else
12914 {
12915 if (print_decompress)
12916 {
12917 /* We try to decompress the section, but keep the old shdr around
12918 so we can show both the original shdr size and the uncompressed
12919 data size. */
12920 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12921 {
12922 if (elf_compress (scn, 0, 0) < 0)
12923 printf ("WARNING: %s [%zd]\n",
12924 _("Couldn't uncompress section"),
12925 elf_ndxscn (scn));
12926 }
12927 else if (startswith (name, ".zdebug"))
12928 {
12929 if (elf_compress_gnu (scn, 0, 0) < 0)
12930 printf ("WARNING: %s [%zd]\n",
12931 _("Couldn't uncompress section"),
12932 elf_ndxscn (scn));
12933 }
12934 }
12935
12936 Elf_Data *data = elf_rawdata (scn, NULL);
12937 if (data == NULL)
12938 error (0, 0, _("cannot get data for section [%zu] '%s': %s"),
12939 elf_ndxscn (scn), name, elf_errmsg (-1));
12940 else
12941 {
12942 if (data->d_size == shdr->sh_size)
12943 printf (_("\nString section [%zu] '%s' contains %" PRIu64
12944 " bytes at offset %#0" PRIx64 ":\n"),
12945 elf_ndxscn (scn), name,
12946 shdr->sh_size, shdr->sh_offset);
12947 else
12948 printf (_("\nString section [%zu] '%s' contains %" PRIu64
12949 " bytes (%zd uncompressed) at offset %#0"
12950 PRIx64 ":\n"),
12951 elf_ndxscn (scn), name,
12952 shdr->sh_size, data->d_size, shdr->sh_offset);
12953
12954 const char *start = data->d_buf;
12955 const char *const limit = start + data->d_size;
12956 do
12957 {
12958 const char *end = memchr (start, '\0', limit - start);
12959 const size_t pos = start - (const char *) data->d_buf;
12960 if (unlikely (end == NULL))
12961 {
12962 printf (" [%6zx]- %.*s\n",
12963 pos, (int) (limit - start), start);
12964 break;
12965 }
12966 printf (" [%6zx] %s\n", pos, start);
12967 start = end + 1;
12968 } while (start < limit);
12969 }
12970 }
12971 }
12972
12973 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))12974 for_each_section_argument (Elf *elf, const struct section_argument *list,
12975 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
12976 const char *name))
12977 {
12978 /* Get the section header string table index. */
12979 size_t shstrndx;
12980 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
12981 error_exit (0, _("cannot get section header string table index"));
12982
12983 for (const struct section_argument *a = list; a != NULL; a = a->next)
12984 {
12985 Elf_Scn *scn;
12986 GElf_Shdr shdr_mem;
12987 const char *name = NULL;
12988
12989 char *endp = NULL;
12990 unsigned long int shndx = strtoul (a->arg, &endp, 0);
12991 if (endp != a->arg && *endp == '\0')
12992 {
12993 scn = elf_getscn (elf, shndx);
12994 if (scn == NULL)
12995 {
12996 error (0, 0, _("\nsection [%lu] does not exist"), shndx);
12997 continue;
12998 }
12999
13000 if (gelf_getshdr (scn, &shdr_mem) == NULL)
13001 error_exit (0, _("cannot get section header: %s"),
13002 elf_errmsg (-1));
13003 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
13004 (*dump) (scn, &shdr_mem, name);
13005 }
13006 else
13007 {
13008 /* Need to look up the section by name. */
13009 scn = NULL;
13010 bool found = false;
13011 while ((scn = elf_nextscn (elf, scn)) != NULL)
13012 {
13013 if (gelf_getshdr (scn, &shdr_mem) == NULL)
13014 continue;
13015 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
13016 if (name == NULL)
13017 continue;
13018 if (!strcmp (name, a->arg))
13019 {
13020 found = true;
13021 (*dump) (scn, &shdr_mem, name);
13022 }
13023 }
13024
13025 if (unlikely (!found) && !a->implicit)
13026 error (0, 0, _("\nsection '%s' does not exist"), a->arg);
13027 }
13028 }
13029 }
13030
13031 static void
dump_data(Ebl * ebl)13032 dump_data (Ebl *ebl)
13033 {
13034 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
13035 }
13036
13037 static void
dump_strings(Ebl * ebl)13038 dump_strings (Ebl *ebl)
13039 {
13040 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
13041 }
13042
13043 static void
print_strings(Ebl * ebl)13044 print_strings (Ebl *ebl)
13045 {
13046 /* Get the section header string table index. */
13047 size_t shstrndx;
13048 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
13049 error_exit (0, _("cannot get section header string table index"));
13050
13051 Elf_Scn *scn;
13052 GElf_Shdr shdr_mem;
13053 const char *name;
13054 scn = NULL;
13055 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
13056 {
13057 if (gelf_getshdr (scn, &shdr_mem) == NULL)
13058 continue;
13059
13060 if (shdr_mem.sh_type != SHT_PROGBITS
13061 || !(shdr_mem.sh_flags & SHF_STRINGS))
13062 continue;
13063
13064 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
13065 if (name == NULL)
13066 continue;
13067
13068 print_string_section (scn, &shdr_mem, name);
13069 }
13070 }
13071
13072 static void
dump_archive_index(Elf * elf,const char * fname)13073 dump_archive_index (Elf *elf, const char *fname)
13074 {
13075 size_t narsym;
13076 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
13077 if (arsym == NULL)
13078 {
13079 int result = elf_errno ();
13080 if (unlikely (result != ELF_E_NO_INDEX))
13081 error_exit (0, _("cannot get symbol index of archive '%s': %s"),
13082 fname, elf_errmsg (result));
13083 else
13084 printf (_("\nArchive '%s' has no symbol index\n"), fname);
13085 return;
13086 }
13087
13088 printf (_("\nIndex of archive '%s' has %zu entries:\n"),
13089 fname, narsym);
13090
13091 size_t as_off = 0;
13092 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
13093 {
13094 if (s->as_off != as_off)
13095 {
13096 as_off = s->as_off;
13097
13098 Elf *subelf = NULL;
13099 if (unlikely (elf_rand (elf, as_off) == 0)
13100 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
13101 == NULL))
13102 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
13103 while (1)
13104 #endif
13105 error_exit (0,
13106 _("cannot extract member at offset %zu in '%s': %s"),
13107 as_off, fname, elf_errmsg (-1));
13108
13109 const Elf_Arhdr *h = elf_getarhdr (subelf);
13110
13111 printf (_("Archive member '%s' contains:\n"), h->ar_name);
13112
13113 elf_end (subelf);
13114 }
13115
13116 printf ("\t%s\n", s->as_name);
13117 }
13118 }
13119
13120 #include "debugpred.h"
13121