1 /* Print information from ELF file in human-readable form.
2 Copyright (C) 1999-2018 Red Hat, Inc.
3 Copyright (C) 2023 Mark J. Wielaard <mark@klomp.org>
4 This file is part of elfutils.
5
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 elfutils is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <argp.h>
24 #include <assert.h>
25 #include <ctype.h>
26 #include <dwarf.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <gelf.h>
30 #include <inttypes.h>
31 #include <langinfo.h>
32 #include <libdw.h>
33 #include <libdwfl.h>
34 #include <locale.h>
35 #include <stdarg.h>
36 #include <stdbool.h>
37 #include <stdio.h>
38 #include <stdio_ext.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <strings.h>
42 #include <time.h>
43 #include <unistd.h>
44 #include <sys/stat.h>
45 #include <signal.h>
46
47 #include <libeu.h>
48 #include <system.h>
49 #include <printversion.h>
50 #include "../libelf/libelfP.h"
51 #include "../libelf/common.h"
52 #include "../libebl/libeblP.h"
53 #include "../libdwelf/libdwelf.h"
54 #include "../libdw/libdwP.h"
55 #include "../libdwfl/libdwflP.h"
56 #include "../libdw/memory-access.h"
57
58 #include "../libdw/known-dwarf.h"
59
60 #ifdef __linux__
61 #define CORE_SIGILL SIGILL
62 #define CORE_SIGBUS SIGBUS
63 #define CORE_SIGFPE SIGFPE
64 #define CORE_SIGSEGV SIGSEGV
65 #define CORE_SI_USER SI_USER
66 #else
67 /* We want the linux version of those as that is what shows up in the core files. */
68 #define CORE_SIGILL 4 /* Illegal instruction (ANSI). */
69 #define CORE_SIGBUS 7 /* BUS error (4.2 BSD). */
70 #define CORE_SIGFPE 8 /* Floating-point exception (ANSI). */
71 #define CORE_SIGSEGV 11 /* Segmentation violation (ANSI). */
72 #define CORE_SI_USER 0 /* Sent by kill, sigsend. */
73 #endif
74
75 /* Name and version of program. */
76 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
77
78 /* Bug report address. */
79 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
80
81 /* argp key value for --elf-section, non-ascii. */
82 #define ELF_INPUT_SECTION 256
83
84 /* argp key value for --dwarf-skeleton, non-ascii. */
85 #define DWARF_SKELETON 257
86
87 /* argp key value for --dyn-syms, non-ascii. */
88 #define PRINT_DYNSYM_TABLE 258
89
90 /* Terrible hack for hooking unrelated skeleton/split compile units,
91 see __libdw_link_skel_split in print_debug. */
92 static bool do_not_close_dwfl = false;
93
94 /* Definitions of arguments for argp functions. */
95 static const struct argp_option options[] =
96 {
97 { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 },
98 { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL,
99 N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF "
100 "input data"), 0 },
101 { "dwarf-skeleton", DWARF_SKELETON, "FILE", 0,
102 N_("Used with -w to find the skeleton Compile Units in FILE associated "
103 "with the Split Compile units in a .dwo input file"), 0 },
104 { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
105 { "all", 'a', NULL, 0,
106 N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
107 { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
108 { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
109 { "histogram", 'I', NULL, 0,
110 N_("Display histogram of bucket list lengths"), 0 },
111 { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
112 { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
113 { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
114 { "section-groups", 'g', NULL, 0, N_("Display the section groups"), 0 },
115 { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
116 { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
117 { "symbols", 's', "SECTION", OPTION_ARG_OPTIONAL,
118 N_("Display the symbol table sections"), 0 },
119 { "syms", 's', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
120 { "dyn-syms", PRINT_DYNSYM_TABLE, NULL, 0,
121 N_("Display (only) the dynamic symbol table"), 0 },
122 { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
123 { "notes", 'n', "SECTION", OPTION_ARG_OPTIONAL, N_("Display the ELF notes"), 0 },
124 { "arch-specific", 'A', NULL, 0,
125 N_("Display architecture specific information, if any"), 0 },
126 { "exception", 'e', NULL, 0,
127 N_("Display sections for exception handling"), 0 },
128
129 { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
130 { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
131 N_("Display DWARF section content. SECTION can be one of abbrev, addr, "
132 "aranges, decodedaranges, frame, gdb_index, info, info+, loc, line, "
133 "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 },
134 { "hex-dump", 'x', "SECTION", 0,
135 N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
136 { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
137 N_("Print string contents of sections"), 0 },
138 { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
139 { "archive-index", 'c', NULL, 0,
140 N_("Display the symbol index of an archive"), 0 },
141 { "use-dynamic", 'D', NULL, 0,
142 N_("Use the dynamic segment when possible for displaying info"), 0 },
143
144 { NULL, 0, NULL, 0, N_("Output control:"), 0 },
145 { "numeric-addresses", 'N', NULL, 0,
146 N_("Do not find symbol names for addresses in DWARF data"), 0 },
147 { "unresolved-address-offsets", 'U', NULL, 0,
148 N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
149 { "wide", 'W', NULL, 0,
150 N_("Ignored for compatibility (lines always wide)"), 0 },
151 { "decompress", 'z', NULL, 0,
152 N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 },
153 { NULL, 0, NULL, 0, NULL, 0 }
154 };
155
156 /* Short description of program. */
157 static const char doc[] = N_("\
158 Print information from ELF file in human-readable form.");
159
160 /* Strings for arguments in help texts. */
161 static const char args_doc[] = N_("FILE...");
162
163 /* Prototype for option handler. */
164 static error_t parse_opt (int key, char *arg, struct argp_state *state);
165
166 /* Data structure to communicate with argp functions. */
167 static struct argp argp =
168 {
169 options, parse_opt, args_doc, doc, NULL, NULL, NULL
170 };
171
172 /* If non-null, the section from which we should read to (compressed) ELF. */
173 static const char *elf_input_section = NULL;
174
175 /* If non-null, the file that contains the skeleton CUs. */
176 static const char *dwarf_skeleton = NULL;
177
178 /* Flags set by the option controlling the output. */
179
180 /* True if dynamic segment should be printed. */
181 static bool print_dynamic_table;
182
183 /* True if the file header should be printed. */
184 static bool print_file_header;
185
186 /* True if the program headers should be printed. */
187 static bool print_program_header;
188
189 /* True if relocations should be printed. */
190 static bool print_relocations;
191
192 /* True if the section headers should be printed. */
193 static bool print_section_header;
194
195 /* True if the symbol table should be printed. */
196 static bool print_symbol_table;
197
198 /* True if (only) the dynsym table should be printed. */
199 static bool print_dynsym_table;
200
201 /* True if reconstruct dynamic symbol table from the PT_DYNAMIC segment. */
202 static bool use_dynamic_segment;
203
204 /* A specific section name, or NULL to print all symbol tables. */
205 static char *symbol_table_section;
206
207 /* A specific section name, or NULL to print all ELF notes. */
208 static char *notes_section;
209
210 /* True if the version information should be printed. */
211 static bool print_version_info;
212
213 /* True if section groups should be printed. */
214 static bool print_section_groups;
215
216 /* True if bucket list length histogram should be printed. */
217 static bool print_histogram;
218
219 /* True if the architecture specific data should be printed. */
220 static bool print_arch;
221
222 /* True if note section content should be printed. */
223 static bool print_notes;
224
225 /* True if SHF_STRINGS section content should be printed. */
226 static bool print_string_sections;
227
228 /* True if archive index should be printed. */
229 static bool print_archive_index;
230
231 /* True if any of the control options except print_archive_index is set. */
232 static bool any_control_option;
233
234 /* True if we should print addresses from DWARF in symbolic form. */
235 static bool print_address_names = true;
236
237 /* True if we should print raw values instead of relativized addresses. */
238 static bool print_unresolved_addresses = false;
239
240 /* True if we should print the .debug_aranges section using libdw. */
241 static bool decodedaranges = false;
242
243 /* True if we should print the .debug_aranges section using libdw. */
244 static bool decodedline = false;
245
246 /* True if we want to show more information about compressed sections. */
247 static bool print_decompress = false;
248
249 /* True if we want to show split compile units for debug_info skeletons. */
250 static bool show_split_units = false;
251
252 /* Select printing of debugging sections. */
253 static enum section_e
254 {
255 section_abbrev = 1, /* .debug_abbrev */
256 section_aranges = 2, /* .debug_aranges */
257 section_frame = 4, /* .debug_frame or .eh_frame & al. */
258 section_info = 8, /* .debug_info, (implies .debug_types) */
259 section_line = 16, /* .debug_line */
260 section_loc = 32, /* .debug_loc */
261 section_pubnames = 64, /* .debug_pubnames */
262 section_str = 128, /* .debug_str */
263 section_macinfo = 256, /* .debug_macinfo */
264 section_ranges = 512, /* .debug_ranges */
265 section_exception = 1024, /* .eh_frame & al. */
266 section_gdb_index = 2048, /* .gdb_index */
267 section_macro = 4096, /* .debug_macro */
268 section_addr = 8192, /* .debug_addr */
269 section_types = 16384, /* .debug_types (implied by .debug_info) */
270 section_all = (section_abbrev | section_aranges | section_frame
271 | section_info | section_line | section_loc
272 | section_pubnames | section_str | section_macinfo
273 | section_ranges | section_exception | section_gdb_index
274 | section_macro | section_addr | section_types)
275 } print_debug_sections, implicit_debug_sections;
276
277 /* Select hex dumping of sections. */
278 static struct section_argument *dump_data_sections;
279 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
280
281 /* Select string dumping of sections. */
282 static struct section_argument *string_sections;
283 static struct section_argument **string_sections_tail = &string_sections;
284
285 struct section_argument
286 {
287 struct section_argument *next;
288 const char *arg;
289 bool implicit;
290 };
291
292 /* Numbers of sections and program headers in the file. */
293 static size_t shnum;
294 static size_t phnum;
295
296
297 /* Declarations of local functions. */
298 static void process_file (int fd, const char *fname, bool only_one);
299 static void process_elf_file (Dwfl_Module *dwflmod, int fd);
300 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
301 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
302 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
303 static void print_scngrp (Ebl *ebl);
304 static void print_dynamic (Ebl *ebl);
305 static void print_relocs (Ebl *ebl, Dwfl_Module *mod, GElf_Ehdr *ehdr);
306 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
307 GElf_Shdr *shdr);
308 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
309 GElf_Shdr *shdr);
310 static void handle_relocs_relr (Ebl *ebl, Dwfl_Module *mod, Elf_Scn *scn,
311 GElf_Shdr *shdr);
312 static bool print_symtab (Ebl *ebl, int type);
313 static bool handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
314 static bool handle_dynamic_symtab (Ebl *ebl);
315 static void
316 process_symtab(
317 Ebl * ebl,
318 unsigned int nsyms,
319 Elf64_Word idx,
320 Elf32_Word verneed_stridx,
321 Elf32_Word verdef_stridx,
322 Elf_Data * symdata,
323 Elf_Data * versym_data,
324 Elf_Data * symstr_data,
325 Elf_Data * verneed_data,
326 Elf_Data * verdef_data,
327 Elf_Data * xndx_data);
328 static void print_verinfo (Ebl *ebl);
329 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
330 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
331 static void handle_versym (Ebl *ebl, Elf_Scn *scn,
332 GElf_Shdr *shdr);
333 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
334 static void handle_hash (Ebl *ebl);
335 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
336 static void print_liblist (Ebl *ebl);
337 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
338 static void dump_data (Ebl *ebl);
339 static void dump_strings (Ebl *ebl);
340 static void print_strings (Ebl *ebl);
341 static void dump_archive_index (Elf *, const char *);
342 static void print_dwarf_addr (Dwfl_Module *dwflmod, int address_size,
343 Dwarf_Addr address, Dwarf_Addr raw);
344
345 enum dyn_idx
346 {
347 i_symtab_shndx,
348 i_strsz,
349 i_verneed,
350 i_verneednum,
351 i_verdef,
352 i_verdefnum,
353 i_versym,
354 i_symtab,
355 i_strtab,
356 i_hash,
357 i_gnu_hash,
358 i_max
359 };
360
361 /* Declarations of local functions for use-dynamic. */
362 static Elf_Data *get_dynscn_strtab (Elf *elf, GElf_Phdr *phdr);
363 static void get_dynscn_addrs (Elf *elf, GElf_Phdr *phdr, GElf_Addr addrs[i_max]);
364 static void find_offsets (Elf *elf, GElf_Addr main_bias, size_t n,
365 GElf_Addr addrs[n], GElf_Off offs[n]);
366
367 /* Looked up once with gettext in main. */
368 static char *yes_str;
369 static char *no_str;
370
371 static void
cleanup_list(struct section_argument * list)372 cleanup_list (struct section_argument *list)
373 {
374 while (list != NULL)
375 {
376 struct section_argument *a = list;
377 list = a->next;
378 free (a);
379 }
380 }
381
382 int
main(int argc,char * argv[])383 main (int argc, char *argv[])
384 {
385 /* We use no threads here which can interfere with handling a stream. */
386 (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
387
388 /* Set locale. */
389 setlocale (LC_ALL, "");
390
391 /* Initialize the message catalog. */
392 textdomain (PACKAGE_TARNAME);
393
394 /* Look up once. */
395 yes_str = _("yes");
396 no_str = _("no");
397
398 /* Parse and process arguments. */
399 int remaining;
400 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
401
402 /* Before we start tell the ELF library which version we are using. */
403 elf_version (EV_CURRENT);
404
405 /* Now process all the files given at the command line. */
406 bool only_one = remaining + 1 == argc;
407 do
408 {
409 /* Open the file. */
410 int fd = open (argv[remaining], O_RDONLY);
411 if (fd == -1)
412 {
413 error (0, errno, _("cannot open input file '%s'"), argv[remaining]);
414 continue;
415 }
416
417 process_file (fd, argv[remaining], only_one);
418
419 close (fd);
420 }
421 while (++remaining < argc);
422
423 cleanup_list (dump_data_sections);
424 cleanup_list (string_sections);
425
426 return error_message_count != 0;
427 }
428
429 static void
add_dump_section(const char * name,int key,bool implicit)430 add_dump_section (const char *name,
431 int key,
432 bool implicit)
433 {
434 struct section_argument *a = xmalloc (sizeof *a);
435 a->arg = name;
436 a->next = NULL;
437 a->implicit = implicit;
438 struct section_argument ***tailp
439 = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
440 **tailp = a;
441 *tailp = &a->next;
442 }
443
444 /* Handle program arguments. */
445 static error_t
parse_opt(int key,char * arg,struct argp_state * state)446 parse_opt (int key, char *arg,
447 struct argp_state *state __attribute__ ((unused)))
448 {
449 switch (key)
450 {
451 case 'a':
452 print_file_header = true;
453 print_program_header = true;
454 print_relocations = true;
455 print_section_header = true;
456 print_symbol_table = true;
457 print_version_info = true;
458 print_dynamic_table = true;
459 print_section_groups = true;
460 print_histogram = true;
461 print_arch = true;
462 print_notes = true;
463 implicit_debug_sections |= section_exception;
464 add_dump_section (".strtab", key, true);
465 add_dump_section (".dynstr", key, true);
466 add_dump_section (".comment", key, true);
467 any_control_option = true;
468 break;
469 case 'A':
470 print_arch = true;
471 any_control_option = true;
472 break;
473 case 'd':
474 print_dynamic_table = true;
475 any_control_option = true;
476 break;
477 case 'D':
478 use_dynamic_segment = true;
479 break;
480 case 'e':
481 print_debug_sections |= section_exception;
482 any_control_option = true;
483 break;
484 case 'g':
485 print_section_groups = true;
486 any_control_option = true;
487 break;
488 case 'h':
489 print_file_header = true;
490 any_control_option = true;
491 break;
492 case 'I':
493 print_histogram = true;
494 any_control_option = true;
495 break;
496 case 'l':
497 print_program_header = true;
498 any_control_option = true;
499 break;
500 case 'n':
501 print_notes = true;
502 any_control_option = true;
503 notes_section = arg;
504 break;
505 case 'r':
506 print_relocations = true;
507 any_control_option = true;
508 break;
509 case 'S':
510 print_section_header = true;
511 any_control_option = true;
512 break;
513 case 's':
514 print_symbol_table = true;
515 any_control_option = true;
516 symbol_table_section = arg;
517 break;
518 case PRINT_DYNSYM_TABLE:
519 print_dynsym_table = true;
520 any_control_option = true;
521 break;
522 case 'V':
523 print_version_info = true;
524 any_control_option = true;
525 break;
526 case 'c':
527 print_archive_index = true;
528 break;
529 case 'w':
530 if (arg == NULL)
531 {
532 print_debug_sections = section_all;
533 implicit_debug_sections = section_info;
534 show_split_units = true;
535 }
536 else if (strcmp (arg, "abbrev") == 0)
537 print_debug_sections |= section_abbrev;
538 else if (strcmp (arg, "addr") == 0)
539 {
540 print_debug_sections |= section_addr;
541 implicit_debug_sections |= section_info;
542 }
543 else if (strcmp (arg, "aranges") == 0)
544 print_debug_sections |= section_aranges;
545 else if (strcmp (arg, "decodedaranges") == 0)
546 {
547 print_debug_sections |= section_aranges;
548 decodedaranges = true;
549 }
550 else if (strcmp (arg, "ranges") == 0)
551 {
552 print_debug_sections |= section_ranges;
553 implicit_debug_sections |= section_info;
554 }
555 else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
556 print_debug_sections |= section_frame;
557 else if (strcmp (arg, "info") == 0)
558 {
559 print_debug_sections |= section_info;
560 print_debug_sections |= section_types;
561 }
562 else if (strcmp (arg, "info+") == 0)
563 {
564 print_debug_sections |= section_info;
565 print_debug_sections |= section_types;
566 show_split_units = true;
567 }
568 else if (strcmp (arg, "loc") == 0)
569 {
570 print_debug_sections |= section_loc;
571 implicit_debug_sections |= section_info;
572 }
573 else if (strcmp (arg, "line") == 0)
574 print_debug_sections |= section_line;
575 else if (strcmp (arg, "decodedline") == 0)
576 {
577 print_debug_sections |= section_line;
578 decodedline = true;
579 }
580 else if (strcmp (arg, "pubnames") == 0)
581 print_debug_sections |= section_pubnames;
582 else if (strcmp (arg, "str") == 0)
583 {
584 print_debug_sections |= section_str;
585 /* For mapping string offset tables to CUs. */
586 implicit_debug_sections |= section_info;
587 }
588 else if (strcmp (arg, "macinfo") == 0)
589 print_debug_sections |= section_macinfo;
590 else if (strcmp (arg, "macro") == 0)
591 print_debug_sections |= section_macro;
592 else if (strcmp (arg, "exception") == 0)
593 print_debug_sections |= section_exception;
594 else if (strcmp (arg, "gdb_index") == 0)
595 print_debug_sections |= section_gdb_index;
596 else
597 {
598 fprintf (stderr, _("Unknown DWARF debug section `%s'.\n"),
599 arg);
600 argp_help (&argp, stderr, ARGP_HELP_SEE,
601 program_invocation_short_name);
602 exit (1);
603 }
604 any_control_option = true;
605 break;
606 case 'p':
607 any_control_option = true;
608 if (arg == NULL)
609 {
610 print_string_sections = true;
611 break;
612 }
613 FALLTHROUGH;
614 case 'x':
615 add_dump_section (arg, key, false);
616 any_control_option = true;
617 break;
618 case 'N':
619 print_address_names = false;
620 break;
621 case 'U':
622 print_unresolved_addresses = true;
623 break;
624 case ARGP_KEY_NO_ARGS:
625 fputs (_("Missing file name.\n"), stderr);
626 goto do_argp_help;
627 case ARGP_KEY_FINI:
628 if (! any_control_option && ! print_archive_index)
629 {
630 fputs (_("No operation specified.\n"), stderr);
631 do_argp_help:
632 argp_help (&argp, stderr, ARGP_HELP_SEE,
633 program_invocation_short_name);
634 exit (EXIT_FAILURE);
635 }
636 break;
637 case 'W': /* Ignored. */
638 break;
639 case 'z':
640 print_decompress = true;
641 break;
642 case ELF_INPUT_SECTION:
643 if (arg == NULL)
644 elf_input_section = ".gnu_debugdata";
645 else
646 elf_input_section = arg;
647 break;
648 case DWARF_SKELETON:
649 dwarf_skeleton = arg;
650 break;
651 default:
652 return ARGP_ERR_UNKNOWN;
653 }
654 return 0;
655 }
656
657
658 /* Create a file descriptor to read the data from the
659 elf_input_section given a file descriptor to an ELF file. */
660 static int
open_input_section(int fd)661 open_input_section (int fd)
662 {
663 size_t shnums;
664 size_t cnt;
665 size_t shstrndx;
666 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
667 if (elf == NULL)
668 {
669 error (0, 0, _("cannot generate Elf descriptor: %s"),
670 elf_errmsg (-1));
671 return -1;
672 }
673
674 if (elf_getshdrnum (elf, &shnums) < 0)
675 {
676 error (0, 0, _("cannot determine number of sections: %s"),
677 elf_errmsg (-1));
678 open_error:
679 elf_end (elf);
680 return -1;
681 }
682
683 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
684 {
685 error (0, 0, _("cannot get section header string table index"));
686 goto open_error;
687 }
688
689 for (cnt = 0; cnt < shnums; ++cnt)
690 {
691 Elf_Scn *scn = elf_getscn (elf, cnt);
692 if (scn == NULL)
693 {
694 error (0, 0, _("cannot get section: %s"),
695 elf_errmsg (-1));
696 goto open_error;
697 }
698
699 GElf_Shdr shdr_mem;
700 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
701 if (unlikely (shdr == NULL))
702 {
703 error (0, 0, _("cannot get section header: %s"),
704 elf_errmsg (-1));
705 goto open_error;
706 }
707
708 const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
709 if (sname == NULL)
710 {
711 error (0, 0, _("cannot get section name"));
712 goto open_error;
713 }
714
715 if (strcmp (sname, elf_input_section) == 0)
716 {
717 Elf_Data *data = elf_rawdata (scn, NULL);
718 if (data == NULL)
719 {
720 error (0, 0, _("cannot get %s content: %s"),
721 sname, elf_errmsg (-1));
722 goto open_error;
723 }
724
725 /* Create (and immediately unlink) a temporary file to store
726 section data in to create a file descriptor for it. */
727 const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
728 static const char suffix[] = "/readelfXXXXXX";
729 int tmplen = strlen (tmpdir) + sizeof (suffix);
730 char *tempname = alloca (tmplen);
731 sprintf (tempname, "%s%s", tmpdir, suffix);
732
733 int sfd = mkstemp (tempname);
734 if (sfd == -1)
735 {
736 error (0, 0, _("cannot create temp file '%s'"),
737 tempname);
738 goto open_error;
739 }
740 unlink (tempname);
741
742 ssize_t size = data->d_size;
743 if (write_retry (sfd, data->d_buf, size) != size)
744 {
745 error (0, 0, _("cannot write section data"));
746 goto open_error;
747 }
748
749 if (elf_end (elf) != 0)
750 {
751 error (0, 0, _("error while closing Elf descriptor: %s"),
752 elf_errmsg (-1));
753 return -1;
754 }
755
756 if (lseek (sfd, 0, SEEK_SET) == -1)
757 {
758 error (0, 0, _("error while rewinding file descriptor"));
759 return -1;
760 }
761
762 return sfd;
763 }
764 }
765
766 /* Named section not found. */
767 if (elf_end (elf) != 0)
768 error (0, 0, _("error while closing Elf descriptor: %s"),
769 elf_errmsg (-1));
770 return -1;
771 }
772
773 /* Check if the file is an archive, and if so dump its index. */
774 static void
check_archive_index(int fd,const char * fname,bool only_one)775 check_archive_index (int fd, const char *fname, bool only_one)
776 {
777 /* Create an `Elf' descriptor. */
778 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
779 if (elf == NULL)
780 error (0, 0, _("cannot generate Elf descriptor: %s"),
781 elf_errmsg (-1));
782 else
783 {
784 if (elf_kind (elf) == ELF_K_AR)
785 {
786 if (!only_one)
787 printf ("\n%s:\n\n", fname);
788 dump_archive_index (elf, fname);
789 }
790 else
791 error (0, 0,
792 _("'%s' is not an archive, cannot print archive index"),
793 fname);
794
795 /* Now we can close the descriptor. */
796 if (elf_end (elf) != 0)
797 error (0, 0, _("error while closing Elf descriptor: %s"),
798 elf_errmsg (-1));
799 }
800 }
801
802 /* Trivial callback used for checking if we opened an archive. */
803 static int
count_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)804 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
805 void **userdata __attribute__ ((unused)),
806 const char *name __attribute__ ((unused)),
807 Dwarf_Addr base __attribute__ ((unused)),
808 void *arg)
809 {
810 if (*(bool *) arg)
811 return DWARF_CB_ABORT;
812 *(bool *) arg = true;
813 return DWARF_CB_OK;
814 }
815
816 struct process_dwflmod_args
817 {
818 int fd;
819 bool only_one;
820 };
821
822 static int
process_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)823 process_dwflmod (Dwfl_Module *dwflmod,
824 void **userdata __attribute__ ((unused)),
825 const char *name __attribute__ ((unused)),
826 Dwarf_Addr base __attribute__ ((unused)),
827 void *arg)
828 {
829 const struct process_dwflmod_args *a = arg;
830
831 /* Print the file name. */
832 if (!a->only_one)
833 {
834 const char *fname;
835 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
836
837 printf ("\n%s:\n\n", fname);
838 }
839
840 process_elf_file (dwflmod, a->fd);
841
842 return DWARF_CB_OK;
843 }
844
845 /* Stub libdwfl callback, only the ELF handle already open is ever used.
846 Only used for finding the alternate debug file if the Dwarf comes from
847 the main file. We are not interested in separate debuginfo. */
848 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)849 find_no_debuginfo (Dwfl_Module *mod,
850 void **userdata,
851 const char *modname,
852 Dwarf_Addr base,
853 const char *file_name,
854 const char *debuglink_file,
855 GElf_Word debuglink_crc,
856 char **debuginfo_file_name)
857 {
858 Dwarf_Addr dwbias;
859 dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
860
861 /* We are only interested if the Dwarf has been setup on the main
862 elf file but is only missing the alternate debug link. If dwbias
863 hasn't even been setup, this is searching for separate debuginfo
864 for the main elf. We don't care in that case. */
865 if (dwbias == (Dwarf_Addr) -1)
866 return -1;
867
868 return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
869 file_name, debuglink_file,
870 debuglink_crc, debuginfo_file_name);
871 }
872
873 static Dwfl *
create_dwfl(int fd,const char * fname)874 create_dwfl (int fd, const char *fname)
875 {
876 /* Duplicate an fd for dwfl_report_offline to swallow. */
877 int dwfl_fd = dup (fd);
878 if (unlikely (dwfl_fd < 0))
879 error_exit (errno, "dup");
880
881 /* Use libdwfl in a trivial way to open the libdw handle for us.
882 This takes care of applying relocations to DWARF data in ET_REL files. */
883 static const Dwfl_Callbacks callbacks =
884 {
885 .section_address = dwfl_offline_section_address,
886 .find_debuginfo = find_no_debuginfo
887 };
888 Dwfl *dwfl = dwfl_begin (&callbacks);
889 if (likely (dwfl != NULL))
890 /* Let 0 be the logical address of the file (or first in archive). */
891 dwfl->offline_next_address = 0;
892 if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
893 {
894 struct stat st;
895 if (fstat (dwfl_fd, &st) != 0)
896 error (0, errno, _("cannot stat input file"));
897 else if (unlikely (st.st_size == 0))
898 error (0, 0, _("input file is empty"));
899 else
900 error (0, 0, _("failed reading '%s': %s"),
901 fname, dwfl_errmsg (-1));
902 close (dwfl_fd); /* Consumed on success, not on failure. */
903 dwfl = NULL;
904 }
905 else
906 dwfl_report_end (dwfl, NULL, NULL);
907
908 return dwfl;
909 }
910
911 /* Process one input file. */
912 static void
process_file(int fd,const char * fname,bool only_one)913 process_file (int fd, const char *fname, bool only_one)
914 {
915 if (print_archive_index)
916 check_archive_index (fd, fname, only_one);
917
918 if (!any_control_option)
919 return;
920
921 if (elf_input_section != NULL)
922 {
923 /* Replace fname and fd with section content. */
924 char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
925 sprintf (fnname, "%s:%s", fname, elf_input_section);
926 fd = open_input_section (fd);
927 if (fd == -1)
928 {
929 error (0, 0, _("No such section '%s' in '%s'"),
930 elf_input_section, fname);
931 return;
932 }
933 fname = fnname;
934 }
935
936 Dwfl *dwfl = create_dwfl (fd, fname);
937 if (dwfl != NULL)
938 {
939 if (only_one)
940 {
941 /* Clear ONLY_ONE if we have multiple modules, from an archive. */
942 bool seen = false;
943 only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
944 }
945
946 /* Process the one or more modules gleaned from this file. */
947 struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
948 dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
949 }
950 /* Terrible hack for hooking unrelated skeleton/split compile units,
951 see __libdw_link_skel_split in print_debug. */
952 if (! do_not_close_dwfl)
953 dwfl_end (dwfl);
954
955 /* Need to close the replaced fd if we created it. Caller takes
956 care of original. */
957 if (elf_input_section != NULL)
958 close (fd);
959 }
960
961 /* Check whether there are any compressed sections in the ELF file. */
962 static bool
elf_contains_chdrs(Elf * elf)963 elf_contains_chdrs (Elf *elf)
964 {
965 Elf_Scn *scn = NULL;
966 while ((scn = elf_nextscn (elf, scn)) != NULL)
967 {
968 GElf_Shdr shdr_mem;
969 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
970 if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
971 return true;
972 }
973 return false;
974 }
975
976 /* Process one ELF file. */
977 static void
process_elf_file(Dwfl_Module * dwflmod,int fd)978 process_elf_file (Dwfl_Module *dwflmod, int fd)
979 {
980 GElf_Addr dwflbias;
981 Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
982
983 GElf_Ehdr ehdr_mem;
984 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
985
986 if (ehdr == NULL)
987 {
988 error (0, 0, _("cannot read ELF header: %s"), elf_errmsg (-1));
989 return;
990 }
991
992 Ebl *ebl = ebl_openbackend (elf);
993 if (unlikely (ebl == NULL))
994 {
995 ebl_error:
996 error (0, errno, _("cannot create EBL handle"));
997 return;
998 }
999
1000 /* Determine the number of sections. */
1001 if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
1002 error_exit (0, _("cannot determine number of sections: %s"),
1003 elf_errmsg (-1));
1004
1005 /* Determine the number of phdrs. */
1006 if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
1007 error_exit (0, _("cannot determine number of program headers: %s"),
1008 elf_errmsg (-1));
1009
1010 /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
1011 may have applied relocation to some sections. If there are any
1012 compressed sections, any pass (or libdw/libdwfl) might have
1013 uncompressed them. So we need to get a fresh Elf handle on the
1014 file to display those. */
1015 bool print_unchanged = ((print_section_header
1016 || print_relocations
1017 || dump_data_sections != NULL
1018 || print_notes)
1019 && (ehdr->e_type == ET_REL
1020 || elf_contains_chdrs (ebl->elf)));
1021
1022 Elf *pure_elf = NULL;
1023 Ebl *pure_ebl = ebl;
1024 if (print_unchanged)
1025 {
1026 /* Read the file afresh. */
1027 off_t aroff = elf_getaroff (elf);
1028 pure_elf = dwelf_elf_begin (fd);
1029 if (aroff > 0)
1030 {
1031 /* Archive member. */
1032 (void) elf_rand (pure_elf, aroff);
1033 Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
1034 elf_end (pure_elf);
1035 pure_elf = armem;
1036 }
1037 if (pure_elf == NULL)
1038 {
1039 error (0, 0, _("cannot read ELF: %s"), elf_errmsg (-1));
1040 return;
1041 }
1042 pure_ebl = ebl_openbackend (pure_elf);
1043 if (pure_ebl == NULL)
1044 goto ebl_error;
1045 }
1046
1047 bool symtab_printed = false;
1048
1049 if (print_file_header)
1050 print_ehdr (ebl, ehdr);
1051 if (print_section_header)
1052 print_shdr (pure_ebl, ehdr);
1053 if (print_program_header)
1054 print_phdr (ebl, ehdr);
1055 if (print_section_groups)
1056 print_scngrp (ebl);
1057 if (print_dynamic_table)
1058 print_dynamic (ebl);
1059 if (print_relocations)
1060 print_relocs (pure_ebl, dwflmod, ehdr);
1061 if (print_histogram)
1062 handle_hash (ebl);
1063 if (print_symbol_table || print_dynsym_table)
1064 symtab_printed |= print_symtab (ebl, SHT_DYNSYM);
1065 if (print_version_info)
1066 print_verinfo (ebl);
1067 if (print_symbol_table && !use_dynamic_segment)
1068 symtab_printed |= print_symtab (ebl, SHT_SYMTAB);
1069
1070 if ((print_symbol_table || print_dynsym_table)
1071 && !symtab_printed && symbol_table_section != NULL)
1072 printf ("WARNING: %s: '%s'\n", _("cannot find section"),
1073 symbol_table_section);
1074
1075 if (print_arch)
1076 print_liblist (ebl);
1077 if (print_arch)
1078 print_attributes (ebl, ehdr);
1079 if (dump_data_sections != NULL)
1080 dump_data (pure_ebl);
1081 if (string_sections != NULL)
1082 dump_strings (ebl);
1083 if ((print_debug_sections | implicit_debug_sections) != 0)
1084 print_debug (dwflmod, ebl, ehdr);
1085 if (print_notes)
1086 handle_notes (pure_ebl, ehdr);
1087 if (print_string_sections)
1088 print_strings (ebl);
1089
1090 if (pure_ebl != ebl)
1091 {
1092 ebl_closebackend (ebl);
1093 ebl_closebackend (pure_ebl);
1094 elf_end (pure_elf);
1095 }
1096 else
1097 ebl_closebackend (ebl);
1098 }
1099
1100
1101 /* Print file type. */
1102 static void
print_file_type(unsigned short int e_type)1103 print_file_type (unsigned short int e_type)
1104 {
1105 if (likely (e_type <= ET_CORE))
1106 {
1107 static const char *const knowntypes[] =
1108 {
1109 N_("NONE (None)"),
1110 N_("REL (Relocatable file)"),
1111 N_("EXEC (Executable file)"),
1112 N_("DYN (Shared object file)"),
1113 N_("CORE (Core file)")
1114 };
1115 puts (_(knowntypes[e_type]));
1116 }
1117 else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
1118 printf (_("OS Specific: (%x)\n"), e_type);
1119 else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
1120 printf (_("Processor Specific: (%x)\n"), e_type);
1121 else
1122 puts ("???");
1123 }
1124
1125
1126 /* Print ELF header. */
1127 static void
print_ehdr(Ebl * ebl,GElf_Ehdr * ehdr)1128 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
1129 {
1130 fputs_unlocked (_("ELF Header:\n Magic: "), stdout);
1131 for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
1132 printf (" %02hhx", ehdr->e_ident[cnt]);
1133
1134 printf (_("\n Class: %s\n"),
1135 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
1136 : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
1137 : "\?\?\?");
1138
1139 printf (_(" Data: %s\n"),
1140 ehdr->e_ident[EI_DATA] == ELFDATA2LSB
1141 ? "2's complement, little endian"
1142 : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
1143 ? "2's complement, big endian" : "\?\?\?");
1144
1145 printf (_(" Ident Version: %hhd %s\n"),
1146 ehdr->e_ident[EI_VERSION],
1147 ehdr->e_ident[EI_VERSION] == EV_CURRENT ? _("(current)")
1148 : "(\?\?\?)");
1149
1150 char buf[512];
1151 printf (_(" OS/ABI: %s\n"),
1152 ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
1153
1154 printf (_(" ABI Version: %hhd\n"),
1155 ehdr->e_ident[EI_ABIVERSION]);
1156
1157 fputs_unlocked (_(" Type: "), stdout);
1158 print_file_type (ehdr->e_type);
1159
1160 const char *machine = dwelf_elf_e_machine_string (ehdr->e_machine);
1161 if (machine != NULL)
1162 printf (_(" Machine: %s\n"), machine);
1163 else
1164 printf (_(" Machine: <unknown>: 0x%x\n"),
1165 ehdr->e_machine);
1166
1167 printf (_(" Version: %d %s\n"),
1168 ehdr->e_version,
1169 ehdr->e_version == EV_CURRENT ? _("(current)") : "(\?\?\?)");
1170
1171 printf (_(" Entry point address: %#" PRIx64 "\n"),
1172 ehdr->e_entry);
1173
1174 printf (_(" Start of program headers: %" PRId64 " %s\n"),
1175 ehdr->e_phoff, _("(bytes into file)"));
1176
1177 printf (_(" Start of section headers: %" PRId64 " %s\n"),
1178 ehdr->e_shoff, _("(bytes into file)"));
1179
1180 printf (_(" Flags: %s\n"),
1181 ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
1182
1183 printf (_(" Size of this header: %" PRId16 " %s\n"),
1184 ehdr->e_ehsize, _("(bytes)"));
1185
1186 printf (_(" Size of program header entries: %" PRId16 " %s\n"),
1187 ehdr->e_phentsize, _("(bytes)"));
1188
1189 printf (_(" Number of program headers entries: %" PRId16),
1190 ehdr->e_phnum);
1191 if (ehdr->e_phnum == PN_XNUM)
1192 {
1193 GElf_Shdr shdr_mem;
1194 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1195 if (shdr != NULL)
1196 printf (_(" (%" PRIu32 " in [0].sh_info)"),
1197 (uint32_t) shdr->sh_info);
1198 else
1199 fputs_unlocked (_(" ([0] not available)"), stdout);
1200 }
1201 fputc_unlocked ('\n', stdout);
1202
1203 printf (_(" Size of section header entries: %" PRId16 " %s\n"),
1204 ehdr->e_shentsize, _("(bytes)"));
1205
1206 printf (_(" Number of section headers entries: %" PRId16),
1207 ehdr->e_shnum);
1208 if (ehdr->e_shnum == 0)
1209 {
1210 GElf_Shdr shdr_mem;
1211 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1212 if (shdr != NULL)
1213 printf (_(" (%" PRIu32 " in [0].sh_size)"),
1214 (uint32_t) shdr->sh_size);
1215 else
1216 fputs_unlocked (_(" ([0] not available)"), stdout);
1217 }
1218 fputc_unlocked ('\n', stdout);
1219
1220 if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1221 {
1222 GElf_Shdr shdr_mem;
1223 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1224 if (shdr != NULL)
1225 /* We managed to get the zeroth section. */
1226 snprintf (buf, sizeof (buf), _(" (%" PRIu32 " in [0].sh_link)"),
1227 (uint32_t) shdr->sh_link);
1228 else
1229 {
1230 strncpy (buf, _(" ([0] not available)"), sizeof (buf) - 1);
1231 buf[sizeof (buf) - 1] = '\0';
1232 }
1233
1234 printf (_(" Section header string table index: XINDEX%s\n\n"),
1235 buf);
1236 }
1237 else
1238 printf (_(" Section header string table index: %" PRId16 "\n\n"),
1239 ehdr->e_shstrndx);
1240 }
1241
1242
1243 static const char *
get_visibility_type(int value)1244 get_visibility_type (int value)
1245 {
1246 switch (value)
1247 {
1248 case STV_DEFAULT:
1249 return "DEFAULT";
1250 case STV_INTERNAL:
1251 return "INTERNAL";
1252 case STV_HIDDEN:
1253 return "HIDDEN";
1254 case STV_PROTECTED:
1255 return "PROTECTED";
1256 default:
1257 return "???";
1258 }
1259 }
1260
1261 static const char *
elf_ch_type_name(unsigned int code)1262 elf_ch_type_name (unsigned int code)
1263 {
1264 switch (code)
1265 {
1266 case 0:
1267 return "NONE";
1268 case ELFCOMPRESS_ZLIB:
1269 return "ZLIB";
1270 case ELFCOMPRESS_ZSTD:
1271 return "ZSTD";
1272 default:
1273 return "UNKNOWN";
1274 }
1275 }
1276
1277 /* Print the section headers. */
1278 static void
print_shdr(Ebl * ebl,GElf_Ehdr * ehdr)1279 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1280 {
1281 size_t cnt;
1282 size_t shstrndx;
1283
1284 if (! print_file_header)
1285 {
1286 size_t sections;
1287 if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0))
1288 error_exit (0, _("cannot get number of sections: %s"),
1289 elf_errmsg (-1));
1290
1291 printf (_("\
1292 There are %zd section headers, starting at offset %#" PRIx64 ":\n\
1293 \n"),
1294 sections, ehdr->e_shoff);
1295 }
1296
1297 /* Get the section header string table index. */
1298 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1299 error_exit (0, _("cannot get section header string table index: %s"),
1300 elf_errmsg (-1));
1301
1302 puts (_("Section Headers:"));
1303
1304 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1305 puts (_("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1306 else
1307 puts (_("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1308
1309 if (print_decompress)
1310 {
1311 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1312 puts (_(" [Compression Size Al]"));
1313 else
1314 puts (_(" [Compression Size Al]"));
1315 }
1316
1317 for (cnt = 0; cnt < shnum; ++cnt)
1318 {
1319 Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1320
1321 if (unlikely (scn == NULL))
1322 error_exit (0, _("cannot get section: %s"),
1323 elf_errmsg (-1));
1324
1325 /* Get the section header. */
1326 GElf_Shdr shdr_mem;
1327 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1328 if (unlikely (shdr == NULL))
1329 error_exit (0, _("cannot get section header: %s"),
1330 elf_errmsg (-1));
1331
1332 char flagbuf[20];
1333 char *cp = flagbuf;
1334 if (shdr->sh_flags & SHF_WRITE)
1335 *cp++ = 'W';
1336 if (shdr->sh_flags & SHF_ALLOC)
1337 *cp++ = 'A';
1338 if (shdr->sh_flags & SHF_EXECINSTR)
1339 *cp++ = 'X';
1340 if (shdr->sh_flags & SHF_MERGE)
1341 *cp++ = 'M';
1342 if (shdr->sh_flags & SHF_STRINGS)
1343 *cp++ = 'S';
1344 if (shdr->sh_flags & SHF_INFO_LINK)
1345 *cp++ = 'I';
1346 if (shdr->sh_flags & SHF_LINK_ORDER)
1347 *cp++ = 'L';
1348 if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1349 *cp++ = 'N';
1350 if (shdr->sh_flags & SHF_GROUP)
1351 *cp++ = 'G';
1352 if (shdr->sh_flags & SHF_TLS)
1353 *cp++ = 'T';
1354 if (shdr->sh_flags & SHF_COMPRESSED)
1355 *cp++ = 'C';
1356 if (shdr->sh_flags & SHF_ORDERED)
1357 *cp++ = 'O';
1358 if (shdr->sh_flags & SHF_EXCLUDE)
1359 *cp++ = 'E';
1360 if (shdr->sh_flags & SHF_GNU_RETAIN)
1361 *cp++ = 'R';
1362 *cp = '\0';
1363
1364 const char *sname;
1365 char buf[128];
1366 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>";
1367 printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1368 " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1369 " %2" PRId64 "\n",
1370 cnt, sname,
1371 ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1372 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1373 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1374 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1375 shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1376 shdr->sh_addralign);
1377
1378 if (print_decompress)
1379 {
1380 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1381 {
1382 GElf_Chdr chdr;
1383 if (gelf_getchdr (scn, &chdr) != NULL)
1384 printf (" [ELF %s (%" PRId32 ") %0*" PRIx64
1385 " %2" PRId64 "]\n",
1386 elf_ch_type_name (chdr.ch_type),
1387 chdr.ch_type,
1388 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8,
1389 chdr.ch_size, chdr.ch_addralign);
1390 else
1391 error (0, 0,
1392 _("bad compression header for section %zd: %s"),
1393 elf_ndxscn (scn), elf_errmsg (-1));
1394 }
1395 else if (startswith (sname, ".zdebug"))
1396 {
1397 ssize_t size;
1398 if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0)
1399 printf (" [GNU ZLIB %0*zx ]\n",
1400 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size);
1401 else
1402 error (0, 0,
1403 _("bad gnu compressed size for section %zd: %s"),
1404 elf_ndxscn (scn), elf_errmsg (-1));
1405 }
1406 }
1407 }
1408
1409 fputc_unlocked ('\n', stdout);
1410 }
1411
1412
1413 /* Print the program header. */
1414 static void
print_phdr(Ebl * ebl,GElf_Ehdr * ehdr)1415 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1416 {
1417 if (phnum == 0)
1418 /* No program header, this is OK in relocatable objects. */
1419 return;
1420
1421 puts (_("Program Headers:"));
1422 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1423 puts (_("\
1424 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1425 else
1426 puts (_("\
1427 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1428
1429 /* Process all program headers. */
1430 bool has_relro = false;
1431 GElf_Addr relro_from = 0;
1432 GElf_Addr relro_to = 0;
1433 for (size_t cnt = 0; cnt < phnum; ++cnt)
1434 {
1435 char buf[128];
1436 GElf_Phdr mem;
1437 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1438
1439 /* If for some reason the header cannot be returned show this. */
1440 if (unlikely (phdr == NULL))
1441 {
1442 puts (" ???");
1443 continue;
1444 }
1445
1446 printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1447 " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1448 ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1449 phdr->p_offset,
1450 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1451 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1452 phdr->p_filesz,
1453 phdr->p_memsz,
1454 phdr->p_flags & PF_R ? 'R' : ' ',
1455 phdr->p_flags & PF_W ? 'W' : ' ',
1456 phdr->p_flags & PF_X ? 'E' : ' ',
1457 phdr->p_align);
1458
1459 if (phdr->p_type == PT_INTERP)
1460 {
1461 /* If we are sure the file offset is valid then we can show
1462 the user the name of the interpreter. We check whether
1463 there is a section at the file offset. Normally there
1464 would be a section called ".interp". But in separate
1465 .debug files it is a NOBITS section (and so doesn't match
1466 with gelf_offscn). Which probably means the offset is
1467 not valid another reason could be because the ELF file
1468 just doesn't contain any section headers, in that case
1469 just play it safe and don't display anything. */
1470
1471 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1472 GElf_Shdr shdr_mem;
1473 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1474
1475 size_t maxsize;
1476 char *filedata = elf_rawfile (ebl->elf, &maxsize);
1477
1478 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
1479 && filedata != NULL && phdr->p_offset < maxsize
1480 && phdr->p_filesz <= maxsize - phdr->p_offset
1481 && memchr (filedata + phdr->p_offset, '\0',
1482 phdr->p_filesz) != NULL)
1483 printf (_("\t[Requesting program interpreter: %s]\n"),
1484 filedata + phdr->p_offset);
1485 }
1486 else if (phdr->p_type == PT_GNU_RELRO)
1487 {
1488 has_relro = true;
1489 relro_from = phdr->p_vaddr;
1490 relro_to = relro_from + phdr->p_memsz;
1491 }
1492 }
1493
1494 size_t sections;
1495 if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0))
1496 error_exit (0, _("cannot get number of sections: %s"),
1497 elf_errmsg (-1));
1498
1499 if (sections == 0)
1500 /* No sections in the file. Punt. */
1501 return;
1502
1503 /* Get the section header string table index. */
1504 size_t shstrndx;
1505 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1506 error_exit (0, _("cannot get section header string table index"));
1507
1508 puts (_("\n Section to Segment mapping:\n Segment Sections..."));
1509
1510 for (size_t cnt = 0; cnt < phnum; ++cnt)
1511 {
1512 /* Print the segment number. */
1513 printf (" %2.2zu ", cnt);
1514
1515 GElf_Phdr phdr_mem;
1516 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1517 /* This must not happen. */
1518 if (unlikely (phdr == NULL))
1519 error_exit (0, _("cannot get program header: %s"),
1520 elf_errmsg (-1));
1521
1522 /* Iterate over the sections. */
1523 bool in_relro = false;
1524 bool in_ro = false;
1525 for (size_t inner = 1; inner < shnum; ++inner)
1526 {
1527 Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1528 /* This should not happen. */
1529 if (unlikely (scn == NULL))
1530 error_exit (0, _("cannot get section: %s"),
1531 elf_errmsg (-1));
1532
1533 /* Get the section header. */
1534 GElf_Shdr shdr_mem;
1535 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1536 if (unlikely (shdr == NULL))
1537 error_exit (0, _("cannot get section header: %s"),
1538 elf_errmsg (-1));
1539
1540 if (shdr->sh_size > 0
1541 /* Compare allocated sections by VMA, unallocated
1542 sections by file offset. */
1543 && (shdr->sh_flags & SHF_ALLOC
1544 ? (shdr->sh_addr >= phdr->p_vaddr
1545 && (shdr->sh_addr + shdr->sh_size
1546 <= phdr->p_vaddr + phdr->p_memsz))
1547 : (shdr->sh_offset >= phdr->p_offset
1548 && (shdr->sh_offset + shdr->sh_size
1549 <= phdr->p_offset + phdr->p_filesz))))
1550 {
1551 if (has_relro && !in_relro
1552 && shdr->sh_addr >= relro_from
1553 && shdr->sh_addr + shdr->sh_size <= relro_to)
1554 {
1555 fputs_unlocked (" [RELRO:", stdout);
1556 in_relro = true;
1557 }
1558 else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1559 {
1560 fputs_unlocked ("]", stdout);
1561 in_relro = false;
1562 }
1563 else if (has_relro && in_relro
1564 && shdr->sh_addr + shdr->sh_size > relro_to)
1565 fputs_unlocked ("] <RELRO:", stdout);
1566 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1567 {
1568 if (!in_ro)
1569 {
1570 fputs_unlocked (" [RO:", stdout);
1571 in_ro = true;
1572 }
1573 }
1574 else
1575 {
1576 /* Determine the segment this section is part of. */
1577 size_t cnt2;
1578 GElf_Phdr phdr2_mem;
1579 GElf_Phdr *phdr2 = NULL;
1580 for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1581 {
1582 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1583
1584 if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1585 && shdr->sh_addr >= phdr2->p_vaddr
1586 && (shdr->sh_addr + shdr->sh_size
1587 <= phdr2->p_vaddr + phdr2->p_memsz))
1588 break;
1589 }
1590
1591 if (cnt2 < phnum)
1592 {
1593 if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1594 {
1595 fputs_unlocked (" [RO:", stdout);
1596 in_ro = true;
1597 }
1598 else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1599 {
1600 fputs_unlocked ("]", stdout);
1601 in_ro = false;
1602 }
1603 }
1604 }
1605
1606 printf (" %s",
1607 elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1608
1609 /* Signal that this section is only partially covered. */
1610 if (has_relro && in_relro
1611 && shdr->sh_addr + shdr->sh_size > relro_to)
1612 {
1613 fputs_unlocked (">", stdout);
1614 in_relro = false;
1615 }
1616 }
1617 }
1618 if (in_relro || in_ro)
1619 fputs_unlocked ("]", stdout);
1620
1621 /* Finish the line. */
1622 fputc_unlocked ('\n', stdout);
1623 }
1624 }
1625
1626
1627 static const char *
section_name(Ebl * ebl,GElf_Shdr * shdr)1628 section_name (Ebl *ebl, GElf_Shdr *shdr)
1629 {
1630 size_t shstrndx;
1631 if (shdr == NULL || elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
1632 return "???";
1633 return elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "???";
1634 }
1635
1636
1637 static void
handle_scngrp(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1638 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1639 {
1640 /* Get the data of the section. */
1641 Elf_Data *data = elf_getdata (scn, NULL);
1642
1643 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1644 GElf_Shdr symshdr_mem;
1645 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1646 Elf_Data *symdata = elf_getdata (symscn, NULL);
1647
1648 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1649 || symdata == NULL)
1650 return;
1651
1652 /* Get the section header string table index. */
1653 size_t shstrndx;
1654 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1655 error_exit (0, _("cannot get section header string table index"));
1656
1657 Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1658
1659 GElf_Sym sym_mem;
1660 GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1661
1662 printf ((grpref[0] & GRP_COMDAT)
1663 ? ngettext ("\
1664 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1665 "\
1666 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1667 data->d_size / sizeof (Elf32_Word) - 1)
1668 : ngettext ("\
1669 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1670 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1671 data->d_size / sizeof (Elf32_Word) - 1),
1672 elf_ndxscn (scn),
1673 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1674 (sym == NULL ? NULL
1675 : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1676 ?: _("<INVALID SYMBOL>"),
1677 data->d_size / sizeof (Elf32_Word) - 1);
1678
1679 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1680 {
1681 GElf_Shdr grpshdr_mem;
1682 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1683 &grpshdr_mem);
1684
1685 const char *str;
1686 printf (" [%2u] %s\n",
1687 grpref[cnt],
1688 grpshdr != NULL
1689 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1690 ? str : _("<INVALID SECTION>"));
1691 }
1692 }
1693
1694
1695 static void
print_scngrp(Ebl * ebl)1696 print_scngrp (Ebl *ebl)
1697 {
1698 /* Find all relocation sections and handle them. */
1699 Elf_Scn *scn = NULL;
1700
1701 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1702 {
1703 /* Handle the section if it is a symbol table. */
1704 GElf_Shdr shdr_mem;
1705 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1706
1707 if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1708 {
1709 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1710 {
1711 if (elf_compress (scn, 0, 0) < 0)
1712 printf ("WARNING: %s [%zd]\n",
1713 _("Couldn't uncompress section"),
1714 elf_ndxscn (scn));
1715 shdr = gelf_getshdr (scn, &shdr_mem);
1716 if (unlikely (shdr == NULL))
1717 error_exit (0, _("cannot get section [%zd] header: %s"),
1718 elf_ndxscn (scn),
1719 elf_errmsg (-1));
1720 }
1721 handle_scngrp (ebl, scn, shdr);
1722 }
1723 }
1724 }
1725
1726
1727 static const struct flags
1728 {
1729 int mask;
1730 const char *str;
1731 } dt_flags[] =
1732 {
1733 { DF_ORIGIN, "ORIGIN" },
1734 { DF_SYMBOLIC, "SYMBOLIC" },
1735 { DF_TEXTREL, "TEXTREL" },
1736 { DF_BIND_NOW, "BIND_NOW" },
1737 { DF_STATIC_TLS, "STATIC_TLS" }
1738 };
1739 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1740
1741 static const struct flags dt_flags_1[] =
1742 {
1743 { DF_1_NOW, "NOW" },
1744 { DF_1_GLOBAL, "GLOBAL" },
1745 { DF_1_GROUP, "GROUP" },
1746 { DF_1_NODELETE, "NODELETE" },
1747 { DF_1_LOADFLTR, "LOADFLTR" },
1748 { DF_1_INITFIRST, "INITFIRST" },
1749 { DF_1_NOOPEN, "NOOPEN" },
1750 { DF_1_ORIGIN, "ORIGIN" },
1751 { DF_1_DIRECT, "DIRECT" },
1752 { DF_1_TRANS, "TRANS" },
1753 { DF_1_INTERPOSE, "INTERPOSE" },
1754 { DF_1_NODEFLIB, "NODEFLIB" },
1755 { DF_1_NODUMP, "NODUMP" },
1756 { DF_1_CONFALT, "CONFALT" },
1757 { DF_1_ENDFILTEE, "ENDFILTEE" },
1758 { DF_1_DISPRELDNE, "DISPRELDNE" },
1759 { DF_1_DISPRELPND, "DISPRELPND" },
1760 };
1761 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1762
1763 static const struct flags dt_feature_1[] =
1764 {
1765 { DTF_1_PARINIT, "PARINIT" },
1766 { DTF_1_CONFEXP, "CONFEXP" }
1767 };
1768 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1769 / sizeof (dt_feature_1[0]));
1770
1771 static const struct flags dt_posflag_1[] =
1772 {
1773 { DF_P1_LAZYLOAD, "LAZYLOAD" },
1774 { DF_P1_GROUPPERM, "GROUPPERM" }
1775 };
1776 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1777 / sizeof (dt_posflag_1[0]));
1778
1779
1780 static void
print_flags(int class,GElf_Xword d_val,const struct flags * flags,int nflags)1781 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1782 int nflags)
1783 {
1784 bool first = true;
1785 int cnt;
1786
1787 for (cnt = 0; cnt < nflags; ++cnt)
1788 if (d_val & flags[cnt].mask)
1789 {
1790 if (!first)
1791 putchar_unlocked (' ');
1792 fputs_unlocked (flags[cnt].str, stdout);
1793 d_val &= ~flags[cnt].mask;
1794 first = false;
1795 }
1796
1797 if (d_val != 0)
1798 {
1799 if (!first)
1800 putchar_unlocked (' ');
1801 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1802 }
1803
1804 putchar_unlocked ('\n');
1805 }
1806
1807
1808 static void
print_dt_flags(int class,GElf_Xword d_val)1809 print_dt_flags (int class, GElf_Xword d_val)
1810 {
1811 print_flags (class, d_val, dt_flags, ndt_flags);
1812 }
1813
1814
1815 static void
print_dt_flags_1(int class,GElf_Xword d_val)1816 print_dt_flags_1 (int class, GElf_Xword d_val)
1817 {
1818 print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1819 }
1820
1821
1822 static void
print_dt_feature_1(int class,GElf_Xword d_val)1823 print_dt_feature_1 (int class, GElf_Xword d_val)
1824 {
1825 print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1826 }
1827
1828
1829 static void
print_dt_posflag_1(int class,GElf_Xword d_val)1830 print_dt_posflag_1 (int class, GElf_Xword d_val)
1831 {
1832 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1833 }
1834
1835
1836 static size_t
get_dyn_ents(Elf_Data * dyn_data)1837 get_dyn_ents (Elf_Data * dyn_data)
1838 {
1839 GElf_Dyn *dyn;
1840 GElf_Dyn dyn_mem;
1841 size_t dyn_idx = 0;
1842 do
1843 {
1844 dyn = gelf_getdyn(dyn_data, dyn_idx, &dyn_mem);
1845 if (dyn != NULL)
1846 ++dyn_idx;
1847 }
1848 while (dyn != NULL && dyn->d_tag != DT_NULL);
1849
1850 return dyn_idx;
1851 }
1852
1853
1854 static void
handle_dynamic(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,GElf_Phdr * phdr)1855 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, GElf_Phdr *phdr)
1856 {
1857 int class = gelf_getclass (ebl->elf);
1858 GElf_Shdr glink_mem;
1859 GElf_Shdr *glink;
1860 Elf_Data *data;
1861 size_t cnt;
1862 size_t shstrndx;
1863 size_t dyn_ents;
1864
1865 /* Get the data of the section. */
1866 if (use_dynamic_segment && phdr != NULL)
1867 data = elf_getdata_rawchunk(ebl->elf, phdr->p_offset,
1868 phdr->p_filesz, ELF_T_DYN);
1869 else
1870 data = elf_getdata (scn, NULL);
1871
1872 if (data == NULL)
1873 return;
1874
1875 /* Get the dynamic section entry number */
1876 dyn_ents = get_dyn_ents (data);
1877
1878 if (!use_dynamic_segment && shdr != NULL)
1879 {
1880 /* Get the section header string table index. */
1881 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1882 error_exit (0, _("cannot get section header string table index"));
1883
1884 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1885 if (glink == NULL)
1886 error_exit (0, _("invalid sh_link value in section %zu"),
1887 elf_ndxscn (scn));
1888
1889 printf (ngettext ("\
1890 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1891 "\
1892 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1893 dyn_ents),
1894 (unsigned long int) dyn_ents,
1895 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1896 shdr->sh_offset,
1897 (int) shdr->sh_link,
1898 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1899 }
1900 else if (phdr != NULL)
1901 {
1902 printf (ngettext ("\
1903 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 "\n",
1904 "\
1905 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 "\n",
1906 dyn_ents),
1907 (unsigned long int) dyn_ents,
1908 class == ELFCLASS32 ? 10 : 18, phdr->p_paddr,
1909 phdr->p_offset);
1910 }
1911
1912 fputs_unlocked (_(" Type Value\n"), stdout);
1913
1914 /* if --use-dynamic option is enabled,
1915 use the string table to get the related library info. */
1916 Elf_Data *strtab_data = NULL;
1917 if (use_dynamic_segment && phdr != NULL)
1918 {
1919 strtab_data = get_dynscn_strtab(ebl->elf, phdr);
1920 if (strtab_data == NULL)
1921 error_exit (0, _("cannot get string table by using dynamic segment"));
1922 }
1923
1924 for (cnt = 0; cnt < dyn_ents; ++cnt)
1925 {
1926 GElf_Dyn dynmem;
1927 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1928 if (dyn == NULL)
1929 break;
1930
1931 char buf[64];
1932 printf (" %-17s ",
1933 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1934
1935 char *name = NULL;
1936 if (dyn->d_tag == DT_NEEDED
1937 || dyn->d_tag == DT_SONAME
1938 || dyn->d_tag == DT_RPATH
1939 || dyn->d_tag == DT_RUNPATH)
1940 {
1941 if (! use_dynamic_segment && shdr != NULL)
1942 name = elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val);
1943 else if (dyn->d_un.d_val < strtab_data->d_size
1944 && memrchr (strtab_data->d_buf + dyn->d_un.d_val, '\0',
1945 strtab_data->d_size - 1 - dyn->d_un.d_val) != NULL)
1946 name = ((char *) strtab_data->d_buf) + dyn->d_un.d_val;
1947 }
1948
1949 switch (dyn->d_tag)
1950 {
1951 case DT_NULL:
1952 case DT_DEBUG:
1953 case DT_BIND_NOW:
1954 case DT_TEXTREL:
1955 /* No further output. */
1956 fputc_unlocked ('\n', stdout);
1957 break;
1958
1959 case DT_NEEDED:
1960 printf (_("Shared library: [%s]\n"), name);
1961 break;
1962
1963 case DT_SONAME:
1964 printf (_("Library soname: [%s]\n"), name);
1965 break;
1966
1967 case DT_RPATH:
1968 printf (_("Library rpath: [%s]\n"), name);
1969 break;
1970
1971 case DT_RUNPATH:
1972 printf (_("Library runpath: [%s]\n"), name);
1973 break;
1974
1975 case DT_PLTRELSZ:
1976 case DT_RELASZ:
1977 case DT_STRSZ:
1978 case DT_RELSZ:
1979 case DT_RELRSZ:
1980 case DT_RELAENT:
1981 case DT_SYMENT:
1982 case DT_RELENT:
1983 case DT_RELRENT:
1984 case DT_PLTPADSZ:
1985 case DT_MOVEENT:
1986 case DT_MOVESZ:
1987 case DT_INIT_ARRAYSZ:
1988 case DT_FINI_ARRAYSZ:
1989 case DT_SYMINSZ:
1990 case DT_SYMINENT:
1991 case DT_GNU_CONFLICTSZ:
1992 case DT_GNU_LIBLISTSZ:
1993 printf (_("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1994 break;
1995
1996 case DT_VERDEFNUM:
1997 case DT_VERNEEDNUM:
1998 case DT_RELACOUNT:
1999 case DT_RELCOUNT:
2000 printf ("%" PRId64 "\n", dyn->d_un.d_val);
2001 break;
2002
2003 case DT_PLTREL:;
2004 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
2005 NULL, 0);
2006 puts (tagname ?: "???");
2007 break;
2008
2009 case DT_FLAGS:
2010 print_dt_flags (class, dyn->d_un.d_val);
2011 break;
2012
2013 case DT_FLAGS_1:
2014 print_dt_flags_1 (class, dyn->d_un.d_val);
2015 break;
2016
2017 case DT_FEATURE_1:
2018 print_dt_feature_1 (class, dyn->d_un.d_val);
2019 break;
2020
2021 case DT_POSFLAG_1:
2022 print_dt_posflag_1 (class, dyn->d_un.d_val);
2023 break;
2024
2025 default:
2026 printf ("%#0*" PRIx64 "\n",
2027 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
2028 break;
2029 }
2030 }
2031 }
2032
2033
2034 /* Print the dynamic segment. */
2035 static void
print_dynamic(Ebl * ebl)2036 print_dynamic (Ebl *ebl)
2037 {
2038 for (size_t i = 0; i < phnum; ++i)
2039 {
2040 GElf_Phdr phdr_mem;
2041 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
2042
2043 if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
2044 {
2045 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
2046 GElf_Shdr shdr_mem;
2047 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2048 if ((use_dynamic_segment && phdr != NULL)
2049 || (shdr != NULL && shdr->sh_type == SHT_DYNAMIC))
2050 handle_dynamic (ebl, scn, shdr, phdr);
2051 break;
2052 }
2053 }
2054 }
2055
2056
2057 /* Print relocations. */
2058 static void
print_relocs(Ebl * ebl,Dwfl_Module * mod,GElf_Ehdr * ehdr)2059 print_relocs (Ebl *ebl, Dwfl_Module *mod, GElf_Ehdr *ehdr)
2060 {
2061 /* Find all relocation sections and handle them. */
2062 Elf_Scn *scn = NULL;
2063
2064 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2065 {
2066 /* Handle the section if it is a symbol table. */
2067 GElf_Shdr shdr_mem;
2068 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2069
2070 if (likely (shdr != NULL))
2071 {
2072 if (shdr->sh_type == SHT_REL)
2073 handle_relocs_rel (ebl, ehdr, scn, shdr);
2074 else if (shdr->sh_type == SHT_RELA)
2075 handle_relocs_rela (ebl, ehdr, scn, shdr);
2076 else if (shdr->sh_type == SHT_RELR)
2077 handle_relocs_relr (ebl, mod, scn, shdr);
2078 }
2079 }
2080 }
2081
2082
2083 /* Handle a relocation section. */
2084 static void
handle_relocs_rel(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)2085 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2086 {
2087 int class = gelf_getclass (ebl->elf);
2088 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
2089 int nentries = shdr->sh_size / sh_entsize;
2090
2091 /* Get the data of the section. */
2092 Elf_Data *data = elf_getdata (scn, NULL);
2093 if (data == NULL)
2094 return;
2095
2096 /* Get the symbol table information. */
2097 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2098 GElf_Shdr symshdr_mem;
2099 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2100 Elf_Data *symdata = elf_getdata (symscn, NULL);
2101
2102 /* Get the section header of the section the relocations are for. */
2103 GElf_Shdr destshdr_mem;
2104 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2105 &destshdr_mem);
2106
2107 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2108 {
2109 printf (_("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2110 shdr->sh_offset);
2111 return;
2112 }
2113
2114 /* Search for the optional extended section index table. */
2115 Elf_Data *xndxdata = NULL;
2116 int xndxscnidx = elf_scnshndx (scn);
2117 if (unlikely (xndxscnidx > 0))
2118 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2119
2120 /* Get the section header string table index. */
2121 size_t shstrndx;
2122 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2123 error_exit (0, _("cannot get section header string table index"));
2124
2125 if (shdr->sh_info != 0)
2126 printf (ngettext ("\
2127 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2128 "\
2129 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2130 nentries),
2131 elf_ndxscn (scn),
2132 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2133 (unsigned int) shdr->sh_info,
2134 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2135 shdr->sh_offset,
2136 nentries);
2137 else
2138 /* The .rel.dyn section does not refer to a specific section but
2139 instead of section index zero. Do not try to print a section
2140 name. */
2141 printf (ngettext ("\
2142 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2143 "\
2144 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2145 nentries),
2146 (unsigned int) elf_ndxscn (scn),
2147 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2148 shdr->sh_offset,
2149 nentries);
2150 fputs_unlocked (class == ELFCLASS32
2151 ? _("\
2152 Offset Type Value Name\n")
2153 : _("\
2154 Offset Type Value Name\n"),
2155 stdout);
2156
2157 int is_statically_linked = 0;
2158 for (int cnt = 0; cnt < nentries; ++cnt)
2159 {
2160 GElf_Rel relmem;
2161 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
2162 if (likely (rel != NULL))
2163 {
2164 char buf[128];
2165 GElf_Sym symmem;
2166 Elf32_Word xndx;
2167 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2168 GELF_R_SYM (rel->r_info),
2169 &symmem, &xndx);
2170 if (unlikely (sym == NULL))
2171 {
2172 /* As a special case we have to handle relocations in static
2173 executables. This only happens for IRELATIVE relocations
2174 (so far). There is no symbol table. */
2175 if (is_statically_linked == 0)
2176 {
2177 /* Find the program header and look for a PT_INTERP entry. */
2178 is_statically_linked = -1;
2179 if (ehdr->e_type == ET_EXEC)
2180 {
2181 is_statically_linked = 1;
2182
2183 for (size_t inner = 0; inner < phnum; ++inner)
2184 {
2185 GElf_Phdr phdr_mem;
2186 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2187 &phdr_mem);
2188 if (phdr != NULL && phdr->p_type == PT_INTERP)
2189 {
2190 is_statically_linked = -1;
2191 break;
2192 }
2193 }
2194 }
2195 }
2196
2197 if (is_statically_linked > 0 && shdr->sh_link == 0)
2198 printf ("\
2199 %#0*" PRIx64 " %-20s %*s %s\n",
2200 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2201 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2202 /* Avoid the leading R_ which isn't carrying any
2203 information. */
2204 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2205 buf, sizeof (buf)) + 2
2206 : _("<INVALID RELOC>"),
2207 class == ELFCLASS32 ? 10 : 18, "",
2208 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2209 else
2210 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
2211 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2212 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2213 /* Avoid the leading R_ which isn't carrying any
2214 information. */
2215 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2216 buf, sizeof (buf)) + 2
2217 : _("<INVALID RELOC>"),
2218 _("INVALID SYMBOL"),
2219 (long int) GELF_R_SYM (rel->r_info));
2220 }
2221 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2222 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
2223 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2224 likely (ebl_reloc_type_check (ebl,
2225 GELF_R_TYPE (rel->r_info)))
2226 /* Avoid the leading R_ which isn't carrying any
2227 information. */
2228 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2229 buf, sizeof (buf)) + 2
2230 : _("<INVALID RELOC>"),
2231 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2232 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2233 else
2234 {
2235 /* This is a relocation against a STT_SECTION symbol. */
2236 GElf_Shdr secshdr_mem;
2237 GElf_Shdr *secshdr;
2238 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2239 sym->st_shndx == SHN_XINDEX
2240 ? xndx : sym->st_shndx),
2241 &secshdr_mem);
2242
2243 if (unlikely (secshdr == NULL))
2244 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
2245 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2246 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2247 /* Avoid the leading R_ which isn't carrying any
2248 information. */
2249 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2250 buf, sizeof (buf)) + 2
2251 : _("<INVALID RELOC>"),
2252 _("INVALID SECTION"),
2253 (long int) (sym->st_shndx == SHN_XINDEX
2254 ? xndx : sym->st_shndx));
2255 else
2256 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
2257 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2258 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2259 /* Avoid the leading R_ which isn't carrying any
2260 information. */
2261 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2262 buf, sizeof (buf)) + 2
2263 : _("<INVALID RELOC>"),
2264 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2265 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2266 }
2267 }
2268 }
2269 }
2270
2271
2272 /* Handle a relocation section. */
2273 static void
handle_relocs_rela(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)2274 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2275 {
2276 int class = gelf_getclass (ebl->elf);
2277 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
2278 int nentries = shdr->sh_size / sh_entsize;
2279
2280 /* Get the data of the section. */
2281 Elf_Data *data = elf_getdata (scn, NULL);
2282 if (data == NULL)
2283 return;
2284
2285 /* Get the symbol table information. */
2286 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2287 GElf_Shdr symshdr_mem;
2288 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2289 Elf_Data *symdata = elf_getdata (symscn, NULL);
2290
2291 /* Get the section header of the section the relocations are for. */
2292 GElf_Shdr destshdr_mem;
2293 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2294 &destshdr_mem);
2295
2296 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2297 {
2298 printf (_("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2299 shdr->sh_offset);
2300 return;
2301 }
2302
2303 /* Search for the optional extended section index table. */
2304 Elf_Data *xndxdata = NULL;
2305 int xndxscnidx = elf_scnshndx (scn);
2306 if (unlikely (xndxscnidx > 0))
2307 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2308
2309 /* Get the section header string table index. */
2310 size_t shstrndx;
2311 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2312 error_exit (0, _("cannot get section header string table index"));
2313
2314 if (shdr->sh_info != 0)
2315 printf (ngettext ("\
2316 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2317 "\
2318 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2319 nentries),
2320 elf_ndxscn (scn),
2321 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2322 (unsigned int) shdr->sh_info,
2323 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2324 shdr->sh_offset,
2325 nentries);
2326 else
2327 /* The .rela.dyn section does not refer to a specific section but
2328 instead of section index zero. Do not try to print a section
2329 name. */
2330 printf (ngettext ("\
2331 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2332 "\
2333 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2334 nentries),
2335 (unsigned int) elf_ndxscn (scn),
2336 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2337 shdr->sh_offset,
2338 nentries);
2339 fputs_unlocked (class == ELFCLASS32
2340 ? _("\
2341 Offset Type Value Addend Name\n")
2342 : _("\
2343 Offset Type Value Addend Name\n"),
2344 stdout);
2345
2346 int is_statically_linked = 0;
2347 for (int cnt = 0; cnt < nentries; ++cnt)
2348 {
2349 GElf_Rela relmem;
2350 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2351 if (likely (rel != NULL))
2352 {
2353 char buf[64];
2354 GElf_Sym symmem;
2355 Elf32_Word xndx;
2356 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2357 GELF_R_SYM (rel->r_info),
2358 &symmem, &xndx);
2359
2360 if (unlikely (sym == NULL))
2361 {
2362 /* As a special case we have to handle relocations in static
2363 executables. This only happens for IRELATIVE relocations
2364 (so far). There is no symbol table. */
2365 if (is_statically_linked == 0)
2366 {
2367 /* Find the program header and look for a PT_INTERP entry. */
2368 is_statically_linked = -1;
2369 if (ehdr->e_type == ET_EXEC)
2370 {
2371 is_statically_linked = 1;
2372
2373 for (size_t inner = 0; inner < phnum; ++inner)
2374 {
2375 GElf_Phdr phdr_mem;
2376 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2377 &phdr_mem);
2378 if (phdr != NULL && phdr->p_type == PT_INTERP)
2379 {
2380 is_statically_linked = -1;
2381 break;
2382 }
2383 }
2384 }
2385 }
2386
2387 if (is_statically_linked > 0 && shdr->sh_link == 0)
2388 printf ("\
2389 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
2390 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2391 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2392 /* Avoid the leading R_ which isn't carrying any
2393 information. */
2394 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2395 buf, sizeof (buf)) + 2
2396 : _("<INVALID RELOC>"),
2397 class == ELFCLASS32 ? 10 : 18, "",
2398 rel->r_addend,
2399 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2400 else
2401 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2402 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2403 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2404 /* Avoid the leading R_ which isn't carrying any
2405 information. */
2406 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2407 buf, sizeof (buf)) + 2
2408 : _("<INVALID RELOC>"),
2409 _("INVALID SYMBOL"),
2410 (long int) GELF_R_SYM (rel->r_info));
2411 }
2412 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2413 printf ("\
2414 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2415 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2416 likely (ebl_reloc_type_check (ebl,
2417 GELF_R_TYPE (rel->r_info)))
2418 /* Avoid the leading R_ which isn't carrying any
2419 information. */
2420 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2421 buf, sizeof (buf)) + 2
2422 : _("<INVALID RELOC>"),
2423 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2424 rel->r_addend,
2425 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2426 else
2427 {
2428 /* This is a relocation against a STT_SECTION symbol. */
2429 GElf_Shdr secshdr_mem;
2430 GElf_Shdr *secshdr;
2431 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2432 sym->st_shndx == SHN_XINDEX
2433 ? xndx : sym->st_shndx),
2434 &secshdr_mem);
2435
2436 if (unlikely (secshdr == NULL))
2437 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2438 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2439 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2440 /* Avoid the leading R_ which isn't carrying any
2441 information. */
2442 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2443 buf, sizeof (buf)) + 2
2444 : _("<INVALID RELOC>"),
2445 _("INVALID SECTION"),
2446 (long int) (sym->st_shndx == SHN_XINDEX
2447 ? xndx : sym->st_shndx));
2448 else
2449 printf ("\
2450 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2451 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2452 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2453 /* Avoid the leading R_ which isn't carrying any
2454 information. */
2455 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2456 buf, sizeof (buf)) + 2
2457 : _("<INVALID RELOC>"),
2458 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2459 rel->r_addend,
2460 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2461 }
2462 }
2463 }
2464 }
2465
2466 /* Handle a relocation section. */
2467 static void
handle_relocs_relr(Ebl * ebl,Dwfl_Module * mod,Elf_Scn * scn,GElf_Shdr * shdr)2468 handle_relocs_relr (Ebl *ebl, Dwfl_Module *mod, Elf_Scn *scn, GElf_Shdr *shdr)
2469 {
2470 int class = gelf_getclass (ebl->elf);
2471 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELR, 1, EV_CURRENT);
2472 int nentries = shdr->sh_size / sh_entsize;
2473
2474 /* Get the data of the section. */
2475 Elf_Data *data = elf_getdata (scn, NULL);
2476 if (data == NULL)
2477 return;
2478
2479 /* Get the section header string table index. */
2480 size_t shstrndx;
2481 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2482 error_exit (0, _("cannot get section header string table index"));
2483
2484 /* A .relr.dyn section does not refer to a specific section. */
2485 printf (ngettext ("\
2486 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2487 "\
2488 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2489 nentries),
2490 (unsigned int) elf_ndxscn (scn),
2491 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2492 shdr->sh_offset,
2493 nentries);
2494
2495 if (class == ELFCLASS32)
2496 {
2497 uint32_t base = 0;
2498 for (int cnt = 0; cnt < nentries; ++cnt)
2499 {
2500 Elf32_Word *words = data->d_buf;
2501 Elf32_Word entry = words[cnt];
2502
2503 /* Just the raw entries? */
2504 if (print_unresolved_addresses)
2505 printf (" %#010" PRIx32 "%s\n", entry,
2506 (entry & 1) == 0 ? " *" : "");
2507 else
2508 {
2509 /* A real address, also sets base. */
2510 if ((entry & 1) == 0)
2511 {
2512 printf (" ");
2513 print_dwarf_addr (mod, 4, entry, entry);
2514 printf (" *\n");
2515
2516 base = entry + 4;
2517 }
2518 else
2519 {
2520 /* Untangle address from base and bits. */
2521 uint32_t addr;
2522 for (addr = base; (entry >>= 1) != 0; addr += 4)
2523 if ((entry & 1) != 0)
2524 {
2525 printf (" ");
2526 print_dwarf_addr (mod, 4, addr, addr);
2527 printf ("\n");
2528 }
2529 base += 4 * (4 * 8 - 1);
2530 }
2531 }
2532 }
2533 }
2534 else
2535 {
2536 uint64_t base = 0;
2537 for (int cnt = 0; cnt < nentries; ++cnt)
2538 {
2539 Elf64_Xword *xwords = data->d_buf;
2540 Elf64_Xword entry = xwords[cnt];
2541
2542 /* Just the raw entries? */
2543 if (print_unresolved_addresses)
2544 printf (" %#018" PRIx64 "%s\n", entry,
2545 (entry & 1) == 0 ? " *" : "");
2546 else
2547 {
2548 /* A real address, also sets base. */
2549 if ((entry & 1) == 0)
2550 {
2551 printf (" ");
2552 print_dwarf_addr (mod, 8, entry, entry);
2553 printf (" *\n");
2554
2555 base = entry + 8;
2556 }
2557 else
2558 {
2559 /* Untangle address from base and bits. */
2560 uint64_t addr;
2561 for (addr = base; (entry >>= 1) != 0; addr += 8)
2562 if ((entry & 1) != 0)
2563 {
2564 printf (" ");
2565 print_dwarf_addr (mod, 8, addr, addr);
2566 printf ("\n");
2567 }
2568 base += 8 * (8 * 8 - 1);
2569 }
2570 }
2571 }
2572 }
2573 }
2574
2575 /* Print the program header. Return true if a symtab is printed,
2576 false otherwise. */
2577 static bool
print_symtab(Ebl * ebl,int type)2578 print_symtab (Ebl *ebl, int type)
2579 {
2580 /* Use the dynamic section info to display symbol tables. */
2581 if (use_dynamic_segment && type == SHT_DYNSYM)
2582 return handle_dynamic_symtab(ebl);
2583
2584 /* Find the symbol table(s). For this we have to search through the
2585 section table. */
2586 Elf_Scn *scn = NULL;
2587 bool symtab_printed = false;
2588
2589 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2590 {
2591 /* Handle the section if it is a symbol table. */
2592 GElf_Shdr shdr_mem;
2593 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2594
2595 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2596 {
2597 if (symbol_table_section != NULL)
2598 {
2599 /* Get the section header string table index. */
2600 size_t shstrndx;
2601 const char *sname;
2602 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2603 error_exit (0,
2604 _("cannot get section header string table index"));
2605 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
2606 if (sname == NULL || strcmp (sname, symbol_table_section) != 0)
2607 continue;
2608 }
2609
2610 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
2611 {
2612 if (elf_compress (scn, 0, 0) < 0)
2613 printf ("WARNING: %s [%zd]\n",
2614 _("Couldn't uncompress section"),
2615 elf_ndxscn (scn));
2616 shdr = gelf_getshdr (scn, &shdr_mem);
2617 if (unlikely (shdr == NULL))
2618 error_exit (0,
2619 _("cannot get section [%zd] header: %s"),
2620 elf_ndxscn (scn), elf_errmsg (-1));
2621 }
2622 symtab_printed = handle_symtab (ebl, scn, shdr);
2623 }
2624 }
2625
2626 return symtab_printed;
2627 }
2628
2629
2630 static void
process_symtab(Ebl * ebl,unsigned int nsyms,Elf64_Word idx,Elf32_Word verneed_stridx,Elf32_Word verdef_stridx,Elf_Data * symdata,Elf_Data * versym_data,Elf_Data * symstr_data,Elf_Data * verneed_data,Elf_Data * verdef_data,Elf_Data * xndx_data)2631 process_symtab (Ebl *ebl, unsigned int nsyms, Elf64_Word idx,
2632 Elf32_Word verneed_stridx, Elf32_Word verdef_stridx,
2633 Elf_Data *symdata, Elf_Data *versym_data,
2634 Elf_Data *symstr_data, Elf_Data *verneed_data,
2635 Elf_Data *verdef_data, Elf_Data *xndx_data)
2636 {
2637 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2638 {
2639 char typebuf[64];
2640 char bindbuf[64];
2641 char scnbuf[64];
2642 Elf32_Word xndx;
2643 GElf_Sym sym_mem;
2644 GElf_Sym *sym
2645 = gelf_getsymshndx (symdata, xndx_data, cnt, &sym_mem, &xndx);
2646
2647 if (unlikely (sym == NULL))
2648 continue;
2649
2650 /* Determine the real section index. */
2651 if (likely (sym->st_shndx != SHN_XINDEX))
2652 xndx = sym->st_shndx;
2653
2654 printf (_ ("\
2655 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2656 cnt, gelf_getclass (ebl->elf) == ELFCLASS32 ? 8 : 16,
2657 sym->st_value, sym->st_size,
2658 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), typebuf,
2659 sizeof (typebuf)),
2660 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2661 bindbuf, sizeof (bindbuf)),
2662 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2663 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2664 sizeof (scnbuf), NULL, shnum),
2665 use_dynamic_segment == true
2666 ? (char *)symstr_data->d_buf + sym->st_name
2667 : elf_strptr (ebl->elf, idx, sym->st_name));
2668
2669 if (versym_data != NULL)
2670 {
2671 /* Get the version information. */
2672 GElf_Versym versym_mem;
2673 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2674
2675 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2676 {
2677 bool is_nobits = false;
2678 bool check_def = xndx != SHN_UNDEF;
2679
2680 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2681 {
2682 GElf_Shdr symshdr_mem;
2683 GElf_Shdr *symshdr = gelf_getshdr (
2684 elf_getscn (ebl->elf, xndx), &symshdr_mem);
2685
2686 is_nobits
2687 = (symshdr != NULL && symshdr->sh_type == SHT_NOBITS);
2688 }
2689
2690 if (is_nobits || !check_def)
2691 {
2692 /* We must test both. */
2693 GElf_Vernaux vernaux_mem;
2694 GElf_Vernaux *vernaux = NULL;
2695 size_t vn_offset = 0;
2696
2697 GElf_Verneed verneed_mem;
2698 GElf_Verneed *verneed
2699 = gelf_getverneed (verneed_data, 0, &verneed_mem);
2700 while (verneed != NULL)
2701 {
2702 size_t vna_offset = vn_offset;
2703
2704 vernaux = gelf_getvernaux (verneed_data,
2705 vna_offset += verneed->vn_aux,
2706 &vernaux_mem);
2707 while (vernaux != NULL && vernaux->vna_other != *versym
2708 && vernaux->vna_next != 0
2709 && (verneed_data->d_size - vna_offset
2710 >= vernaux->vna_next))
2711 {
2712 /* Update the offset. */
2713 vna_offset += vernaux->vna_next;
2714
2715 vernaux = (vernaux->vna_next == 0
2716 ? NULL
2717 : gelf_getvernaux (verneed_data,
2718 vna_offset,
2719 &vernaux_mem));
2720 }
2721
2722 /* Check whether we found the version. */
2723 if (vernaux != NULL && vernaux->vna_other == *versym)
2724 /* Found it. */
2725 break;
2726
2727 if (verneed_data->d_size - vn_offset < verneed->vn_next)
2728 break;
2729
2730 vn_offset += verneed->vn_next;
2731 verneed
2732 = (verneed->vn_next == 0
2733 ? NULL
2734 : gelf_getverneed (verneed_data, vn_offset,
2735 &verneed_mem));
2736 }
2737
2738 if (vernaux != NULL && vernaux->vna_other == *versym)
2739 {
2740 printf ("@%s (%u)",
2741 use_dynamic_segment == true
2742 ? (char *)symstr_data->d_buf
2743 + vernaux->vna_name
2744 : elf_strptr (ebl->elf, verneed_stridx,
2745 vernaux->vna_name),
2746 (unsigned int)vernaux->vna_other);
2747 check_def = 0;
2748 }
2749 else if (unlikely (!is_nobits))
2750 error (0, 0, _ ("bad dynamic symbol"));
2751 else
2752 check_def = 1;
2753 }
2754
2755 if (check_def && *versym != 0x8001)
2756 {
2757 /* We must test both. */
2758 size_t vd_offset = 0;
2759
2760 GElf_Verdef verdef_mem;
2761 GElf_Verdef *verdef
2762 = gelf_getverdef (verdef_data, 0, &verdef_mem);
2763 while (verdef != NULL)
2764 {
2765 if (verdef->vd_ndx == (*versym & 0x7fff))
2766 /* Found the definition. */
2767 break;
2768
2769 if (verdef_data->d_size - vd_offset < verdef->vd_next)
2770 break;
2771
2772 vd_offset += verdef->vd_next;
2773 verdef = (verdef->vd_next == 0
2774 ? NULL
2775 : gelf_getverdef (verdef_data, vd_offset,
2776 &verdef_mem));
2777 }
2778
2779 if (verdef != NULL)
2780 {
2781 GElf_Verdaux verdaux_mem;
2782 GElf_Verdaux *verdaux = gelf_getverdaux (
2783 verdef_data, vd_offset + verdef->vd_aux,
2784 &verdaux_mem);
2785
2786 if (verdaux != NULL)
2787 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2788 use_dynamic_segment == true
2789 ? (char *)symstr_data->d_buf
2790 + verdaux->vda_name
2791 : elf_strptr (ebl->elf, verdef_stridx,
2792 verdaux->vda_name));
2793 }
2794 }
2795 }
2796 }
2797
2798 putchar_unlocked ('\n');
2799 }
2800 }
2801
2802
2803 static bool
handle_symtab(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2804 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2805 {
2806 Elf_Data *versym_data = NULL;
2807 Elf_Data *verneed_data = NULL;
2808 Elf_Data *verdef_data = NULL;
2809 Elf_Data *xndx_data = NULL;
2810 int class = gelf_getclass (ebl->elf);
2811 Elf32_Word verneed_stridx = 0;
2812 Elf32_Word verdef_stridx = 0;
2813
2814 /* Get the data of the section. */
2815 Elf_Data *data = elf_getdata (scn, NULL);
2816 if (data == NULL)
2817 return false;
2818
2819 /* Find out whether we have other sections we might need. */
2820 Elf_Scn *runscn = NULL;
2821 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2822 {
2823 GElf_Shdr runshdr_mem;
2824 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2825
2826 if (likely (runshdr != NULL))
2827 {
2828 if (runshdr->sh_type == SHT_GNU_versym
2829 && runshdr->sh_link == elf_ndxscn (scn))
2830 /* Bingo, found the version information. Now get the data. */
2831 versym_data = elf_getdata (runscn, NULL);
2832 else if (runshdr->sh_type == SHT_GNU_verneed)
2833 {
2834 /* This is the information about the needed versions. */
2835 verneed_data = elf_getdata (runscn, NULL);
2836 verneed_stridx = runshdr->sh_link;
2837 }
2838 else if (runshdr->sh_type == SHT_GNU_verdef)
2839 {
2840 /* This is the information about the defined versions. */
2841 verdef_data = elf_getdata (runscn, NULL);
2842 verdef_stridx = runshdr->sh_link;
2843 }
2844 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2845 && runshdr->sh_link == elf_ndxscn (scn))
2846 /* Extended section index. */
2847 xndx_data = elf_getdata (runscn, NULL);
2848 }
2849 }
2850
2851 /* Get the section header string table index. */
2852 size_t shstrndx;
2853 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2854 error_exit (0, _("cannot get section header string table index"));
2855
2856 GElf_Shdr glink_mem;
2857 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2858 &glink_mem);
2859 if (glink == NULL)
2860 error_exit (0, _("invalid sh_link value in section %zu"),
2861 elf_ndxscn (scn));
2862
2863 /* Now we can compute the number of entries in the section. */
2864 unsigned int nsyms = data->d_size / (class == ELFCLASS32
2865 ? sizeof (Elf32_Sym)
2866 : sizeof (Elf64_Sym));
2867
2868 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2869 "\nSymbol table [%2u] '%s' contains %u entries:\n",
2870 nsyms),
2871 (unsigned int) elf_ndxscn (scn),
2872 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2873 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
2874 " %lu local symbols String table: [%2u] '%s'\n",
2875 shdr->sh_info),
2876 (unsigned long int) shdr->sh_info,
2877 (unsigned int) shdr->sh_link,
2878 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2879
2880 fputs_unlocked (class == ELFCLASS32
2881 ? _("\
2882 Num: Value Size Type Bind Vis Ndx Name\n")
2883 : _("\
2884 Num: Value Size Type Bind Vis Ndx Name\n"),
2885 stdout);
2886
2887 process_symtab(ebl, nsyms, shdr->sh_link, verneed_stridx, verdef_stridx,
2888 data, versym_data, NULL, verneed_data, verdef_data, xndx_data);
2889 return true;
2890 }
2891
2892
2893 static bool
handle_dynamic_symtab(Ebl * ebl)2894 handle_dynamic_symtab (Ebl *ebl)
2895 {
2896 GElf_Phdr phdr_mem;
2897 GElf_Phdr *phdr = NULL;
2898 /* phnum is a static variable which was already fetched in function
2899 process_elf_file. */
2900 for (size_t i = 0; i < phnum; ++i)
2901 {
2902 phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
2903 if (phdr->p_type == PT_DYNAMIC)
2904 break;
2905 }
2906 if (phdr == NULL)
2907 return false;
2908
2909 GElf_Addr addrs[i_max] = {
2910 0,
2911 };
2912 GElf_Off offs[i_max] = {
2913 0,
2914 };
2915 get_dynscn_addrs (ebl->elf, phdr, addrs);
2916 find_offsets (ebl->elf, 0, i_max, addrs, offs);
2917
2918 size_t syments = 0;
2919
2920 GElf_Ehdr ehdr_mem;
2921 GElf_Ehdr *ehdr = gelf_getehdr (ebl->elf, &ehdr_mem);
2922
2923 if (offs[i_hash] != 0)
2924 {
2925 /* In the original format, .hash says the size of .dynsym. */
2926
2927 size_t entsz = SH_ENTSIZE_HASH (ehdr);
2928 Elf_Data *data
2929 = elf_getdata_rawchunk (ebl->elf, offs[i_hash] + entsz, entsz,
2930 (entsz == 4 ? ELF_T_WORD : ELF_T_XWORD));
2931 if (data != NULL)
2932 syments = (entsz == 4 ? *(const GElf_Word *)data->d_buf
2933 : *(const GElf_Xword *)data->d_buf);
2934 }
2935 if (offs[i_gnu_hash] != 0 && syments == 0)
2936 {
2937 /* In the new format, we can derive it with some work. */
2938
2939 const struct
2940 {
2941 Elf32_Word nbuckets;
2942 Elf32_Word symndx;
2943 Elf32_Word maskwords;
2944 Elf32_Word shift2;
2945 } * header;
2946
2947 Elf_Data *data = elf_getdata_rawchunk (ebl->elf, offs[i_gnu_hash],
2948 sizeof *header, ELF_T_WORD);
2949 if (data != NULL)
2950 {
2951 header = data->d_buf;
2952 Elf32_Word nbuckets = header->nbuckets;
2953 Elf32_Word symndx = header->symndx;
2954 GElf_Off buckets_at
2955 = (offs[i_gnu_hash] + sizeof *header
2956 + (gelf_getclass (ebl->elf) * sizeof (Elf32_Word)
2957 * header->maskwords));
2958
2959 // elf_getdata_rawchunk takes a size_t, make sure it
2960 // doesn't overflow.
2961 #if SIZE_MAX <= UINT32_MAX
2962 if (nbuckets > SIZE_MAX / sizeof (Elf32_Word))
2963 data = NULL;
2964 else
2965 #endif
2966 data = elf_getdata_rawchunk (ebl->elf, buckets_at,
2967 nbuckets * sizeof (Elf32_Word),
2968 ELF_T_WORD);
2969 if (data != NULL && symndx < nbuckets)
2970 {
2971 const Elf32_Word *const buckets = data->d_buf;
2972 Elf32_Word maxndx = symndx;
2973 for (Elf32_Word bucket = 0; bucket < nbuckets; ++bucket)
2974 if (buckets[bucket] > maxndx)
2975 maxndx = buckets[bucket];
2976
2977 GElf_Off hasharr_at
2978 = (buckets_at + nbuckets * sizeof (Elf32_Word));
2979 hasharr_at += (maxndx - symndx) * sizeof (Elf32_Word);
2980 do
2981 {
2982 data = elf_getdata_rawchunk (
2983 ebl->elf, hasharr_at, sizeof (Elf32_Word), ELF_T_WORD);
2984 if (data != NULL && (*(const Elf32_Word *)data->d_buf & 1u))
2985 {
2986 syments = maxndx + 1;
2987 break;
2988 }
2989 ++maxndx;
2990 hasharr_at += sizeof (Elf32_Word);
2991 }
2992 while (data != NULL);
2993 }
2994 }
2995 }
2996 if (offs[i_strtab] > offs[i_symtab] && syments == 0)
2997 syments = ((offs[i_strtab] - offs[i_symtab])
2998 / gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT));
2999
3000 if (syments <= 0 || offs[i_strtab] == 0 || offs[i_symtab] == 0)
3001 {
3002 error_exit (0, _ ("Dynamic symbol information is not available for "
3003 "displaying symbols."));
3004 }
3005
3006 /* All the data chunk initializaion. */
3007 Elf_Data *symdata = NULL;
3008 Elf_Data *symstrdata = NULL;
3009 Elf_Data *versym_data = NULL;
3010 Elf_Data *verdef_data = NULL;
3011 Elf_Data *verneed_data = NULL;
3012
3013 symdata = elf_getdata_rawchunk (
3014 ebl->elf, offs[i_symtab],
3015 gelf_fsize (ebl->elf, ELF_T_SYM, syments, EV_CURRENT), ELF_T_SYM);
3016 symstrdata = elf_getdata_rawchunk (ebl->elf, offs[i_strtab], addrs[i_strsz],
3017 ELF_T_BYTE);
3018 versym_data = elf_getdata_rawchunk (
3019 ebl->elf, offs[i_versym], syments * sizeof (Elf64_Half), ELF_T_HALF);
3020
3021 /* Get the verneed_data without vernaux. */
3022 verneed_data = elf_getdata_rawchunk (
3023 ebl->elf, offs[i_verneed], addrs[i_verneednum] * sizeof (Elf64_Verneed),
3024 ELF_T_VNEED);
3025 size_t vernauxnum = 0;
3026 size_t vn_next_offset = 0;
3027
3028 for (size_t i = 0; i < addrs[i_verneednum]; i++)
3029 {
3030 GElf_Verneed *verneed
3031 = (GElf_Verneed *)(verneed_data->d_buf + vn_next_offset);
3032 vernauxnum += verneed->vn_cnt;
3033 vn_next_offset += verneed->vn_next;
3034 }
3035
3036 /* Update the verneed_data to include the vernaux. */
3037 verneed_data = elf_getdata_rawchunk (
3038 ebl->elf, offs[i_verneed],
3039 (addrs[i_verneednum] + vernauxnum) * sizeof (GElf_Verneed), ELF_T_VNEED);
3040
3041 /* Get the verdef_data without verdaux. */
3042 verdef_data = elf_getdata_rawchunk (
3043 ebl->elf, offs[i_verdef], addrs[i_verdefnum] * sizeof (Elf64_Verdef),
3044 ELF_T_VDEF);
3045 size_t verdauxnum = 0;
3046 size_t vd_next_offset = 0;
3047
3048 for (size_t i = 0; i < addrs[i_verdefnum]; i++)
3049 {
3050 GElf_Verdef *verdef
3051 = (GElf_Verdef *)(verdef_data->d_buf + vd_next_offset);
3052 verdauxnum += verdef->vd_cnt;
3053 vd_next_offset += verdef->vd_next;
3054 }
3055
3056 /* Update the verdef_data to include the verdaux. */
3057 verdef_data = elf_getdata_rawchunk (
3058 ebl->elf, offs[i_verdef],
3059 (addrs[i_verdefnum] + verdauxnum) * sizeof (GElf_Verdef), ELF_T_VDEF);
3060
3061 unsigned int nsyms = (unsigned int)syments;
3062 process_symtab (ebl, nsyms, 0, 0, 0, symdata, versym_data, symstrdata,
3063 verneed_data, verdef_data, NULL);
3064 return true;
3065 }
3066
3067
3068 /* Print version information. */
3069 static void
print_verinfo(Ebl * ebl)3070 print_verinfo (Ebl *ebl)
3071 {
3072 /* Find the version information sections. For this we have to
3073 search through the section table. */
3074 Elf_Scn *scn = NULL;
3075
3076 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3077 {
3078 /* Handle the section if it is part of the versioning handling. */
3079 GElf_Shdr shdr_mem;
3080 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3081
3082 if (likely (shdr != NULL))
3083 {
3084 if (shdr->sh_type == SHT_GNU_verneed)
3085 handle_verneed (ebl, scn, shdr);
3086 else if (shdr->sh_type == SHT_GNU_verdef)
3087 handle_verdef (ebl, scn, shdr);
3088 else if (shdr->sh_type == SHT_GNU_versym)
3089 handle_versym (ebl, scn, shdr);
3090 }
3091 }
3092 }
3093
3094
3095 static const char *
get_ver_flags(unsigned int flags)3096 get_ver_flags (unsigned int flags)
3097 {
3098 static char buf[32];
3099 char *endp;
3100
3101 if (flags == 0)
3102 return _("none");
3103
3104 if (flags & VER_FLG_BASE)
3105 endp = stpcpy (buf, "BASE ");
3106 else
3107 endp = buf;
3108
3109 if (flags & VER_FLG_WEAK)
3110 {
3111 if (endp != buf)
3112 endp = stpcpy (endp, "| ");
3113
3114 endp = stpcpy (endp, "WEAK ");
3115 }
3116
3117 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
3118 {
3119 strncpy (endp, _("| <unknown>"), buf + sizeof (buf) - endp);
3120 buf[sizeof (buf) - 1] = '\0';
3121 }
3122
3123 return buf;
3124 }
3125
3126
3127 static void
handle_verneed(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)3128 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
3129 {
3130 int class = gelf_getclass (ebl->elf);
3131
3132 /* Get the data of the section. */
3133 Elf_Data *data = elf_getdata (scn, NULL);
3134 if (data == NULL)
3135 return;
3136
3137 /* Get the section header string table index. */
3138 size_t shstrndx;
3139 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3140 error_exit (0, _("cannot get section header string table index"));
3141
3142 GElf_Shdr glink_mem;
3143 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
3144 &glink_mem);
3145 if (glink == NULL)
3146 error_exit (0, _("invalid sh_link value in section %zu"),
3147 elf_ndxscn (scn));
3148
3149 printf (ngettext ("\
3150 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
3151 "\
3152 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
3153 shdr->sh_info),
3154 (unsigned int) elf_ndxscn (scn),
3155 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
3156 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
3157 shdr->sh_offset,
3158 (unsigned int) shdr->sh_link,
3159 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3160
3161 unsigned int offset = 0;
3162 for (int cnt = shdr->sh_info; --cnt >= 0; )
3163 {
3164 /* Get the data at the next offset. */
3165 GElf_Verneed needmem;
3166 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
3167 if (unlikely (need == NULL))
3168 break;
3169
3170 printf (_(" %#06x: Version: %hu File: %s Cnt: %hu\n"),
3171 offset, (unsigned short int) need->vn_version,
3172 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
3173 (unsigned short int) need->vn_cnt);
3174
3175 unsigned int auxoffset = offset + need->vn_aux;
3176 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
3177 {
3178 GElf_Vernaux auxmem;
3179 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
3180 if (unlikely (aux == NULL))
3181 break;
3182
3183 printf (_(" %#06x: Name: %s Flags: %s Version: %hu\n"),
3184 auxoffset,
3185 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
3186 get_ver_flags (aux->vna_flags),
3187 (unsigned short int) aux->vna_other);
3188
3189 if (aux->vna_next == 0)
3190 break;
3191
3192 auxoffset += aux->vna_next;
3193 }
3194
3195 /* Find the next offset. */
3196 if (need->vn_next == 0)
3197 break;
3198
3199 offset += need->vn_next;
3200 }
3201 }
3202
3203
3204 static void
handle_verdef(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)3205 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
3206 {
3207 /* Get the data of the section. */
3208 Elf_Data *data = elf_getdata (scn, NULL);
3209 if (data == NULL)
3210 return;
3211
3212 /* Get the section header string table index. */
3213 size_t shstrndx;
3214 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3215 error_exit (0, _("cannot get section header string table index"));
3216
3217 GElf_Shdr glink_mem;
3218 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
3219 &glink_mem);
3220 if (glink == NULL)
3221 error_exit (0, _("invalid sh_link value in section %zu"),
3222 elf_ndxscn (scn));
3223
3224 int class = gelf_getclass (ebl->elf);
3225 printf (ngettext ("\
3226 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
3227 "\
3228 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
3229 shdr->sh_info),
3230 (unsigned int) elf_ndxscn (scn),
3231 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3232 shdr->sh_info,
3233 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
3234 shdr->sh_offset,
3235 (unsigned int) shdr->sh_link,
3236 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3237
3238 unsigned int offset = 0;
3239 for (int cnt = shdr->sh_info; --cnt >= 0; )
3240 {
3241 /* Get the data at the next offset. */
3242 GElf_Verdef defmem;
3243 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
3244 if (unlikely (def == NULL))
3245 break;
3246
3247 unsigned int auxoffset = offset + def->vd_aux;
3248 GElf_Verdaux auxmem;
3249 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
3250 if (unlikely (aux == NULL))
3251 break;
3252
3253 printf (_("\
3254 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
3255 offset, def->vd_version,
3256 get_ver_flags (def->vd_flags),
3257 def->vd_ndx,
3258 def->vd_cnt,
3259 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
3260
3261 auxoffset += aux->vda_next;
3262 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
3263 {
3264 aux = gelf_getverdaux (data, auxoffset, &auxmem);
3265 if (unlikely (aux == NULL))
3266 break;
3267
3268 printf (_(" %#06x: Parent %d: %s\n"),
3269 auxoffset, cnt2,
3270 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
3271
3272 if (aux->vda_next == 0)
3273 break;
3274
3275 auxoffset += aux->vda_next;
3276 }
3277
3278 /* Find the next offset. */
3279 if (def->vd_next == 0)
3280 break;
3281 offset += def->vd_next;
3282 }
3283 }
3284
3285
3286 static void
handle_versym(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)3287 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
3288 {
3289 int class = gelf_getclass (ebl->elf);
3290 const char **vername;
3291 const char **filename;
3292
3293 /* Get the data of the section. */
3294 Elf_Data *data = elf_getdata (scn, NULL);
3295 if (data == NULL)
3296 return;
3297
3298 /* Get the section header string table index. */
3299 size_t shstrndx;
3300 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3301 error_exit (0, _("cannot get section header string table index"));
3302
3303 /* We have to find the version definition section and extract the
3304 version names. */
3305 Elf_Scn *defscn = NULL;
3306 Elf_Scn *needscn = NULL;
3307
3308 Elf_Scn *verscn = NULL;
3309 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
3310 {
3311 GElf_Shdr vershdr_mem;
3312 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
3313
3314 if (likely (vershdr != NULL))
3315 {
3316 if (vershdr->sh_type == SHT_GNU_verdef)
3317 defscn = verscn;
3318 else if (vershdr->sh_type == SHT_GNU_verneed)
3319 needscn = verscn;
3320 }
3321 }
3322
3323 size_t nvername;
3324 if (defscn != NULL || needscn != NULL)
3325 {
3326 /* We have a version information (better should have). Now get
3327 the version names. First find the maximum version number. */
3328 nvername = 0;
3329 if (defscn != NULL)
3330 {
3331 /* Run through the version definitions and find the highest
3332 index. */
3333 unsigned int offset = 0;
3334 Elf_Data *defdata;
3335 GElf_Shdr defshdrmem;
3336 GElf_Shdr *defshdr;
3337
3338 defdata = elf_getdata (defscn, NULL);
3339 if (unlikely (defdata == NULL))
3340 return;
3341
3342 defshdr = gelf_getshdr (defscn, &defshdrmem);
3343 if (unlikely (defshdr == NULL))
3344 return;
3345
3346 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
3347 {
3348 GElf_Verdef defmem;
3349 GElf_Verdef *def;
3350
3351 /* Get the data at the next offset. */
3352 def = gelf_getverdef (defdata, offset, &defmem);
3353 if (unlikely (def == NULL))
3354 break;
3355
3356 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
3357
3358 if (def->vd_next == 0)
3359 break;
3360 offset += def->vd_next;
3361 }
3362 }
3363 if (needscn != NULL)
3364 {
3365 unsigned int offset = 0;
3366 Elf_Data *needdata;
3367 GElf_Shdr needshdrmem;
3368 GElf_Shdr *needshdr;
3369
3370 needdata = elf_getdata (needscn, NULL);
3371 if (unlikely (needdata == NULL))
3372 return;
3373
3374 needshdr = gelf_getshdr (needscn, &needshdrmem);
3375 if (unlikely (needshdr == NULL))
3376 return;
3377
3378 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
3379 {
3380 GElf_Verneed needmem;
3381 GElf_Verneed *need;
3382 unsigned int auxoffset;
3383 int cnt2;
3384
3385 /* Get the data at the next offset. */
3386 need = gelf_getverneed (needdata, offset, &needmem);
3387 if (unlikely (need == NULL))
3388 break;
3389
3390 /* Run through the auxiliary entries. */
3391 auxoffset = offset + need->vn_aux;
3392 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
3393 {
3394 GElf_Vernaux auxmem;
3395 GElf_Vernaux *aux;
3396
3397 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
3398 if (unlikely (aux == NULL))
3399 break;
3400
3401 nvername = MAX (nvername,
3402 (size_t) (aux->vna_other & 0x7fff));
3403
3404 if (aux->vna_next == 0)
3405 break;
3406 auxoffset += aux->vna_next;
3407 }
3408
3409 if (need->vn_next == 0)
3410 break;
3411 offset += need->vn_next;
3412 }
3413 }
3414
3415 /* This is the number of versions we know about. */
3416 ++nvername;
3417
3418 /* Allocate the array. */
3419 vername = (const char **) alloca (nvername * sizeof (const char *));
3420 memset(vername, 0, nvername * sizeof (const char *));
3421 filename = (const char **) alloca (nvername * sizeof (const char *));
3422 memset(filename, 0, nvername * sizeof (const char *));
3423
3424 /* Run through the data structures again and collect the strings. */
3425 if (defscn != NULL)
3426 {
3427 /* Run through the version definitions and find the highest
3428 index. */
3429 unsigned int offset = 0;
3430 Elf_Data *defdata;
3431 GElf_Shdr defshdrmem;
3432 GElf_Shdr *defshdr;
3433
3434 defdata = elf_getdata (defscn, NULL);
3435 if (unlikely (defdata == NULL))
3436 return;
3437
3438 defshdr = gelf_getshdr (defscn, &defshdrmem);
3439 if (unlikely (defshdr == NULL))
3440 return;
3441
3442 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
3443 {
3444
3445 /* Get the data at the next offset. */
3446 GElf_Verdef defmem;
3447 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
3448 if (unlikely (def == NULL))
3449 break;
3450
3451 GElf_Verdaux auxmem;
3452 GElf_Verdaux *aux = gelf_getverdaux (defdata,
3453 offset + def->vd_aux,
3454 &auxmem);
3455 if (unlikely (aux == NULL))
3456 break;
3457
3458 vername[def->vd_ndx & 0x7fff]
3459 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
3460 filename[def->vd_ndx & 0x7fff] = NULL;
3461
3462 if (def->vd_next == 0)
3463 break;
3464 offset += def->vd_next;
3465 }
3466 }
3467 if (needscn != NULL)
3468 {
3469 unsigned int offset = 0;
3470
3471 Elf_Data *needdata = elf_getdata (needscn, NULL);
3472 GElf_Shdr needshdrmem;
3473 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
3474 if (unlikely (needdata == NULL || needshdr == NULL))
3475 return;
3476
3477 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
3478 {
3479 /* Get the data at the next offset. */
3480 GElf_Verneed needmem;
3481 GElf_Verneed *need = gelf_getverneed (needdata, offset,
3482 &needmem);
3483 if (unlikely (need == NULL))
3484 break;
3485
3486 /* Run through the auxiliary entries. */
3487 unsigned int auxoffset = offset + need->vn_aux;
3488 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
3489 {
3490 GElf_Vernaux auxmem;
3491 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
3492 &auxmem);
3493 if (unlikely (aux == NULL))
3494 break;
3495
3496 vername[aux->vna_other & 0x7fff]
3497 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
3498 filename[aux->vna_other & 0x7fff]
3499 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
3500
3501 if (aux->vna_next == 0)
3502 break;
3503 auxoffset += aux->vna_next;
3504 }
3505
3506 if (need->vn_next == 0)
3507 break;
3508 offset += need->vn_next;
3509 }
3510 }
3511 }
3512 else
3513 {
3514 vername = NULL;
3515 nvername = 1;
3516 filename = NULL;
3517 }
3518
3519 GElf_Shdr glink_mem;
3520 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
3521 &glink_mem);
3522 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
3523 if (glink == NULL)
3524 error_exit (0, _("invalid sh_link value in section %zu"),
3525 elf_ndxscn (scn));
3526
3527 /* Print the header. */
3528 printf (ngettext ("\
3529 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
3530 "\
3531 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
3532 shdr->sh_size / sh_entsize),
3533 (unsigned int) elf_ndxscn (scn),
3534 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3535 (int) (shdr->sh_size / sh_entsize),
3536 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
3537 shdr->sh_offset,
3538 (unsigned int) shdr->sh_link,
3539 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3540
3541 /* Now we can finally look at the actual contents of this section. */
3542 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
3543 {
3544 if (cnt % 2 == 0)
3545 printf ("\n %4d:", cnt);
3546
3547 GElf_Versym symmem;
3548 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
3549 if (sym == NULL)
3550 break;
3551
3552 switch (*sym)
3553 {
3554 ssize_t n;
3555 case 0:
3556 fputs_unlocked (_(" 0 *local* "),
3557 stdout);
3558 break;
3559
3560 case 1:
3561 fputs_unlocked (_(" 1 *global* "),
3562 stdout);
3563 break;
3564
3565 default:
3566 n = printf ("%4d%c%s",
3567 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
3568 (vername != NULL
3569 && (unsigned int) (*sym & 0x7fff) < nvername)
3570 ? vername[*sym & 0x7fff] : "???");
3571 if ((unsigned int) (*sym & 0x7fff) < nvername
3572 && filename != NULL && filename[*sym & 0x7fff] != NULL)
3573 n += printf ("(%s)", filename[*sym & 0x7fff]);
3574 printf ("%*s", MAX (0, 33 - (int) n), " ");
3575 break;
3576 }
3577 }
3578 putchar_unlocked ('\n');
3579 }
3580
3581
3582 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)3583 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
3584 uint_fast32_t maxlength, Elf32_Word nbucket,
3585 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
3586 {
3587 uint32_t *counts = xcalloc (maxlength + 1, sizeof (uint32_t));
3588
3589 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3590 ++counts[lengths[cnt]];
3591
3592 GElf_Shdr glink_mem;
3593 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
3594 shdr->sh_link),
3595 &glink_mem);
3596 if (glink == NULL)
3597 {
3598 error (0, 0, _("invalid sh_link value in section %zu"),
3599 elf_ndxscn (scn));
3600 return;
3601 }
3602
3603 printf (ngettext ("\
3604 \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",
3605 "\
3606 \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",
3607 nbucket),
3608 (unsigned int) elf_ndxscn (scn),
3609 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3610 (int) nbucket,
3611 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
3612 shdr->sh_addr,
3613 shdr->sh_offset,
3614 (unsigned int) shdr->sh_link,
3615 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3616
3617 if (extrastr != NULL)
3618 fputs (extrastr, stdout);
3619
3620 if (likely (nbucket > 0))
3621 {
3622 uint64_t success = 0;
3623
3624 /* xgettext:no-c-format */
3625 fputs_unlocked (_("\
3626 Length Number % of total Coverage\n"), stdout);
3627 printf (_(" 0 %6" PRIu32 " %5.1f%%\n"),
3628 counts[0], (counts[0] * 100.0) / nbucket);
3629
3630 uint64_t nzero_counts = 0;
3631 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3632 {
3633 nzero_counts += counts[cnt] * cnt;
3634 printf (_("\
3635 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
3636 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
3637 (nzero_counts * 100.0) / nsyms);
3638 }
3639
3640 Elf32_Word acc = 0;
3641 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3642 {
3643 acc += cnt;
3644 success += counts[cnt] * acc;
3645 }
3646
3647 printf (_("\
3648 Average number of tests: successful lookup: %f\n\
3649 unsuccessful lookup: %f\n"),
3650 (double) success / (double) nzero_counts,
3651 (double) nzero_counts / (double) nbucket);
3652 }
3653
3654 free (counts);
3655 }
3656
3657
3658 /* This function handles the traditional System V-style hash table format. */
3659 static void
handle_sysv_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3660 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3661 {
3662 Elf_Data *data = elf_getdata (scn, NULL);
3663 if (unlikely (data == NULL))
3664 {
3665 error (0, 0, _("cannot get data for section %d: %s"),
3666 (int) elf_ndxscn (scn), elf_errmsg (-1));
3667 return;
3668 }
3669
3670 if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
3671 {
3672 invalid_data:
3673 error (0, 0, _("invalid data in sysv.hash section %d"),
3674 (int) elf_ndxscn (scn));
3675 return;
3676 }
3677
3678 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3679 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
3680
3681 uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
3682 if (used_buf > data->d_size)
3683 goto invalid_data;
3684
3685 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
3686 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
3687
3688 uint32_t *lengths = xcalloc (nbucket, sizeof (uint32_t));
3689
3690 uint_fast32_t maxlength = 0;
3691 uint_fast32_t nsyms = 0;
3692 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3693 {
3694 Elf32_Word inner = bucket[cnt];
3695 Elf32_Word chain_len = 0;
3696 while (inner > 0 && inner < nchain)
3697 {
3698 ++nsyms;
3699 ++chain_len;
3700 if (chain_len > nchain)
3701 {
3702 error (0, 0, _("invalid chain in sysv.hash section %d"),
3703 (int) elf_ndxscn (scn));
3704 free (lengths);
3705 return;
3706 }
3707 if (maxlength < ++lengths[cnt])
3708 ++maxlength;
3709
3710 inner = chain[inner];
3711 }
3712 }
3713
3714 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3715 lengths, NULL);
3716
3717 free (lengths);
3718 }
3719
3720
3721 /* This function handles the incorrect, System V-style hash table
3722 format some 64-bit architectures use. */
3723 static void
handle_sysv_hash64(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3724 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3725 {
3726 Elf_Data *data = elf_getdata (scn, NULL);
3727 if (unlikely (data == NULL))
3728 {
3729 error (0, 0, _("cannot get data for section %d: %s"),
3730 (int) elf_ndxscn (scn), elf_errmsg (-1));
3731 return;
3732 }
3733
3734 if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3735 {
3736 invalid_data:
3737 error (0, 0, _("invalid data in sysv.hash64 section %d"),
3738 (int) elf_ndxscn (scn));
3739 return;
3740 }
3741
3742 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3743 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3744
3745 uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
3746 if (maxwords < 2
3747 || maxwords - 2 < nbucket
3748 || maxwords - 2 - nbucket < nchain)
3749 goto invalid_data;
3750
3751 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3752 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3753
3754 uint32_t *lengths = xcalloc (nbucket, sizeof (uint32_t));
3755
3756 uint_fast32_t maxlength = 0;
3757 uint_fast32_t nsyms = 0;
3758 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3759 {
3760 Elf64_Xword inner = bucket[cnt];
3761 Elf64_Xword chain_len = 0;
3762 while (inner > 0 && inner < nchain)
3763 {
3764 ++nsyms;
3765 ++chain_len;
3766 if (chain_len > nchain)
3767 {
3768 error (0, 0, _("invalid chain in sysv.hash64 section %d"),
3769 (int) elf_ndxscn (scn));
3770 free (lengths);
3771 return;
3772 }
3773 if (maxlength < ++lengths[cnt])
3774 ++maxlength;
3775
3776 inner = chain[inner];
3777 }
3778 }
3779
3780 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3781 lengths, NULL);
3782
3783 free (lengths);
3784 }
3785
3786
3787 /* This function handles the GNU-style hash table format. */
3788 static void
handle_gnu_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3789 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3790 {
3791 uint32_t *lengths = NULL;
3792 Elf_Data *data = elf_getdata (scn, NULL);
3793 if (unlikely (data == NULL))
3794 {
3795 error (0, 0, _("cannot get data for section %d: %s"),
3796 (int) elf_ndxscn (scn), elf_errmsg (-1));
3797 return;
3798 }
3799
3800 if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3801 {
3802 invalid_data:
3803 free (lengths);
3804 error (0, 0, _("invalid data in gnu.hash section %d"),
3805 (int) elf_ndxscn (scn));
3806 return;
3807 }
3808
3809 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3810 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3811
3812 /* Next comes the size of the bitmap. It's measured in words for
3813 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3814 64 bit archs. There is always a bloom filter present, so zero is
3815 an invalid value. */
3816 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3817 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3818 bitmask_words *= 2;
3819
3820 if (bitmask_words == 0)
3821 goto invalid_data;
3822
3823 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3824
3825 /* Is there still room for the sym chain?
3826 Use uint64_t calculation to prevent 32bit overflow. */
3827 uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3828 uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3829 if (used_buf > data->d_size)
3830 goto invalid_data;
3831
3832 lengths = xcalloc (nbucket, sizeof (uint32_t));
3833
3834 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3835 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3836 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3837 + nbucket];
3838
3839 /* Compute distribution of chain lengths. */
3840 uint_fast32_t maxlength = 0;
3841 uint_fast32_t nsyms = 0;
3842 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3843 if (bucket[cnt] != 0)
3844 {
3845 Elf32_Word inner = bucket[cnt] - symbias;
3846 do
3847 {
3848 ++nsyms;
3849 if (maxlength < ++lengths[cnt])
3850 ++maxlength;
3851 if (inner >= max_nsyms)
3852 goto invalid_data;
3853 }
3854 while ((chain[inner++] & 1) == 0);
3855 }
3856
3857 /* Count bits in bitmask. */
3858 uint_fast32_t nbits = 0;
3859 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3860 {
3861 uint_fast32_t word = bitmask[cnt];
3862
3863 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3864 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3865 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3866 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3867 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3868 }
3869
3870 char *str = xasprintf (_("\
3871 Symbol Bias: %u\n\
3872 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3873 (unsigned int) symbias,
3874 bitmask_words * sizeof (Elf32_Word),
3875 ((nbits * 100 + 50)
3876 / (uint_fast32_t) (bitmask_words
3877 * sizeof (Elf32_Word) * 8)),
3878 (unsigned int) shift);
3879
3880 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3881 lengths, str);
3882
3883 free (str);
3884 free (lengths);
3885 }
3886
3887
3888 /* Find the symbol table(s). For this we have to search through the
3889 section table. */
3890 static void
handle_hash(Ebl * ebl)3891 handle_hash (Ebl *ebl)
3892 {
3893 /* Get the section header string table index. */
3894 size_t shstrndx;
3895 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3896 error_exit (0, _("cannot get section header string table index"));
3897
3898 Elf_Scn *scn = NULL;
3899 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3900 {
3901 /* Handle the section if it is a symbol table. */
3902 GElf_Shdr shdr_mem;
3903 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3904
3905 if (likely (shdr != NULL))
3906 {
3907 if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH)
3908 && (shdr->sh_flags & SHF_COMPRESSED) != 0)
3909 {
3910 if (elf_compress (scn, 0, 0) < 0)
3911 printf ("WARNING: %s [%zd]\n",
3912 _("Couldn't uncompress section"),
3913 elf_ndxscn (scn));
3914 shdr = gelf_getshdr (scn, &shdr_mem);
3915 if (unlikely (shdr == NULL))
3916 error_exit (0, _("cannot get section [%zd] header: %s"),
3917 elf_ndxscn (scn), elf_errmsg (-1));
3918 }
3919
3920 if (shdr->sh_type == SHT_HASH)
3921 {
3922 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3923 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3924 else
3925 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3926 }
3927 else if (shdr->sh_type == SHT_GNU_HASH)
3928 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3929 }
3930 }
3931 }
3932
3933
3934 static void
print_liblist(Ebl * ebl)3935 print_liblist (Ebl *ebl)
3936 {
3937 /* Find the library list sections. For this we have to search
3938 through the section table. */
3939 Elf_Scn *scn = NULL;
3940
3941 /* Get the section header string table index. */
3942 size_t shstrndx;
3943 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3944 error_exit (0, _("cannot get section header string table index"));
3945
3946 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3947 {
3948 GElf_Shdr shdr_mem;
3949 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3950
3951 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3952 {
3953 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3954 int nentries = shdr->sh_size / sh_entsize;
3955 printf (ngettext ("\
3956 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3957 "\
3958 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3959 nentries),
3960 elf_ndxscn (scn),
3961 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3962 shdr->sh_offset,
3963 nentries);
3964
3965 Elf_Data *data = elf_getdata (scn, NULL);
3966 if (data == NULL)
3967 return;
3968
3969 puts (_("\
3970 Library Time Stamp Checksum Version Flags"));
3971
3972 for (int cnt = 0; cnt < nentries; ++cnt)
3973 {
3974 GElf_Lib lib_mem;
3975 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3976 if (unlikely (lib == NULL))
3977 continue;
3978
3979 time_t t = (time_t) lib->l_time_stamp;
3980 struct tm *tm = gmtime (&t);
3981 if (unlikely (tm == NULL))
3982 continue;
3983
3984 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3985 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3986 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3987 tm->tm_hour, tm->tm_min, tm->tm_sec,
3988 (unsigned int) lib->l_checksum,
3989 (unsigned int) lib->l_version,
3990 (unsigned int) lib->l_flags);
3991 }
3992 }
3993 }
3994 }
3995
3996 static inline size_t
left(Elf_Data * data,const unsigned char * p)3997 left (Elf_Data *data,
3998 const unsigned char *p)
3999 {
4000 return (const unsigned char *) data->d_buf + data->d_size - p;
4001 }
4002
4003 static void
print_attributes(Ebl * ebl,const GElf_Ehdr * ehdr)4004 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
4005 {
4006 /* Find the object attributes sections. For this we have to search
4007 through the section table. */
4008 Elf_Scn *scn = NULL;
4009
4010 /* Get the section header string table index. */
4011 size_t shstrndx;
4012 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
4013 error_exit (0, _("cannot get section header string table index"));
4014
4015 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
4016 {
4017 GElf_Shdr shdr_mem;
4018 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
4019
4020 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
4021 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
4022 || ehdr->e_machine != EM_ARM)
4023 && (shdr->sh_type != SHT_CSKY_ATTRIBUTES
4024 || ehdr->e_machine != EM_CSKY)
4025 && (shdr->sh_type != SHT_RISCV_ATTRIBUTES
4026 || ehdr->e_machine != EM_RISCV)))
4027 continue;
4028
4029 printf (_("\
4030 \nObject attributes section [%2zu] '%s' of %" PRIu64
4031 " bytes at offset %#0" PRIx64 ":\n"),
4032 elf_ndxscn (scn),
4033 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
4034 shdr->sh_size, shdr->sh_offset);
4035
4036 Elf_Data *data = elf_rawdata (scn, NULL);
4037 if (unlikely (data == NULL || data->d_size == 0))
4038 return;
4039
4040 const unsigned char *p = data->d_buf;
4041
4042 /* There is only one 'version', A. */
4043 if (unlikely (*p++ != 'A'))
4044 return;
4045
4046 fputs_unlocked (_(" Owner Size\n"), stdout);
4047
4048 /* Loop over the sections. */
4049 while (left (data, p) >= 4)
4050 {
4051 /* Section length. */
4052 uint32_t len;
4053 memcpy (&len, p, sizeof len);
4054
4055 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
4056 CONVERT (len);
4057
4058 if (unlikely (len > left (data, p)))
4059 break;
4060
4061 /* Section vendor name. */
4062 const unsigned char *name = p + sizeof len;
4063 p += len;
4064
4065 unsigned const char *q = memchr (name, '\0', len);
4066 if (unlikely (q == NULL))
4067 break;
4068 ++q;
4069
4070 printf (_(" %-13s %4" PRIu32 "\n"), name, len);
4071
4072 bool gnu_vendor = (q - name == sizeof "gnu"
4073 && !memcmp (name, "gnu", sizeof "gnu"));
4074
4075 /* Loop over subsections. */
4076 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
4077 || gnu_vendor)
4078 while (q < p)
4079 {
4080 const unsigned char *const sub = q;
4081
4082 unsigned int subsection_tag;
4083 get_uleb128 (subsection_tag, q, p);
4084 if (unlikely (q >= p))
4085 break;
4086
4087 uint32_t subsection_len;
4088 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
4089 break;
4090
4091 memcpy (&subsection_len, q, sizeof subsection_len);
4092
4093 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
4094 CONVERT (subsection_len);
4095
4096 /* Don't overflow, ptrdiff_t might be 32bits, but signed. */
4097 if (unlikely (subsection_len == 0
4098 || subsection_len >= (uint32_t) PTRDIFF_MAX
4099 || p - sub < (ptrdiff_t) subsection_len))
4100 break;
4101
4102 const unsigned char *r = q + sizeof subsection_len;
4103 q = sub + subsection_len;
4104
4105 switch (subsection_tag)
4106 {
4107 default:
4108 /* Unknown subsection, print and skip. */
4109 printf (_(" %-4u %12" PRIu32 "\n"),
4110 subsection_tag, subsection_len);
4111 break;
4112
4113 case 1: /* Tag_File */
4114 printf (_(" File: %11" PRIu32 "\n"),
4115 subsection_len);
4116
4117 while (r < q)
4118 {
4119 unsigned int tag;
4120 get_uleb128 (tag, r, q);
4121 if (unlikely (r >= q))
4122 break;
4123
4124 /* GNU style tags have either a uleb128 value,
4125 when lowest bit is not set, or a string
4126 when the lowest bit is set.
4127 "compatibility" (32) is special. It has
4128 both a string and a uleb128 value. For
4129 non-gnu we assume 6 till 31 only take ints.
4130 XXX see arm backend, do we need a separate
4131 hook? */
4132 uint64_t value = 0;
4133 const char *string = NULL;
4134 if (tag == 32 || (tag & 1) == 0
4135 || (! gnu_vendor && (tag > 5 && tag < 32)))
4136 {
4137 // Note r >= q check above.
4138 get_uleb128 (value, r, q);
4139 if (r > q)
4140 break;
4141 }
4142 if (tag == 32
4143 || ((tag & 1) != 0
4144 && (gnu_vendor
4145 || (! gnu_vendor && tag > 32)))
4146 || (! gnu_vendor && tag > 3 && tag < 6))
4147 {
4148 string = (const char *) r;
4149 r = memchr (r, '\0', q - r);
4150 if (r == NULL)
4151 break;
4152 ++r;
4153 }
4154
4155 const char *tag_name = NULL;
4156 const char *value_name = NULL;
4157 ebl_check_object_attribute (ebl, (const char *) name,
4158 tag, value,
4159 &tag_name, &value_name);
4160
4161 if (tag_name != NULL)
4162 {
4163 if (tag == 32)
4164 printf (_(" %s: %" PRId64 ", %s\n"),
4165 tag_name, value, string);
4166 else if (string == NULL && value_name == NULL)
4167 printf (_(" %s: %" PRId64 "\n"),
4168 tag_name, value);
4169 else
4170 printf (_(" %s: %s\n"),
4171 tag_name, string ?: value_name);
4172 }
4173 else
4174 {
4175 /* For "gnu" vendor 32 "compatibility" has
4176 already been handled above. */
4177 assert (tag != 32
4178 || strcmp ((const char *) name, "gnu"));
4179 if (string == NULL)
4180 printf (_(" %u: %" PRId64 "\n"),
4181 tag, value);
4182 else
4183 printf (_(" %u: %s\n"),
4184 tag, string);
4185 }
4186 }
4187 }
4188 }
4189 }
4190 }
4191 }
4192
4193 /* Returns either the (relocated) data from the Dwarf, or tries to get
4194 the "raw" (uncompressed) data from the Elf section. Produces a
4195 warning if the data cannot be found (or decompressed). */
4196 static Elf_Data *
get_debug_elf_data(Dwarf * dbg,Ebl * ebl,int idx,Elf_Scn * scn)4197 get_debug_elf_data (Dwarf *dbg, Ebl *ebl, int idx, Elf_Scn *scn)
4198 {
4199 /* We prefer to get the section data from the Dwarf because that
4200 might have been relocated already. Note this is subtly wrong if
4201 there are multiple sections with the same .debug name. */
4202 if (dbg->sectiondata[idx] != NULL)
4203 return dbg->sectiondata[idx];
4204
4205 GElf_Shdr shdr_mem;
4206 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
4207 if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
4208 {
4209 if (elf_compress (scn, 0, 0) < 0)
4210 {
4211 error (0, 0, "%s [%zd] '%s'\n",
4212 _("Couldn't uncompress section"),
4213 elf_ndxscn (scn), section_name (ebl, shdr));
4214 return NULL;
4215 }
4216 }
4217
4218 Elf_Data *data = elf_getdata (scn, NULL);
4219 if (data == NULL)
4220 error (0, 0, "%s [%zd] '%s': %s\n",
4221 _("Couldn't get data from section"),
4222 elf_ndxscn (scn), section_name (ebl, shdr), elf_errmsg (-1));
4223
4224 return elf_getdata (scn, NULL);
4225 }
4226
4227 static void
print_dwarf_addr(Dwfl_Module * dwflmod,int address_size,Dwarf_Addr address,Dwarf_Addr raw)4228 print_dwarf_addr (Dwfl_Module *dwflmod,
4229 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
4230 {
4231 /* See if there is a name we can give for this address. */
4232 GElf_Sym sym;
4233 GElf_Off off = 0;
4234 const char *name = (print_address_names && ! print_unresolved_addresses)
4235 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
4236 : NULL;
4237
4238 const char *scn;
4239 if (print_unresolved_addresses)
4240 {
4241 address = raw;
4242 scn = NULL;
4243 }
4244 else
4245 {
4246 /* Relativize the address. */
4247 int n = dwfl_module_relocations (dwflmod);
4248 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
4249
4250 /* In an ET_REL file there is a section name to refer to. */
4251 scn = (i < 0 ? NULL
4252 : dwfl_module_relocation_info (dwflmod, i, NULL));
4253 }
4254
4255 if ((name != NULL
4256 ? (off != 0
4257 ? (scn != NULL
4258 ? (address_size == 0
4259 ? printf ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">",
4260 scn, address, name, off)
4261 : printf ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">",
4262 scn, 2 + address_size * 2, address,
4263 name, off))
4264 : (address_size == 0
4265 ? printf ("%#" PRIx64 " <%s+%#" PRIx64 ">",
4266 address, name, off)
4267 : printf ("%#0*" PRIx64 " <%s+%#" PRIx64 ">",
4268 2 + address_size * 2, address,
4269 name, off)))
4270 : (scn != NULL
4271 ? (address_size == 0
4272 ? printf ("%s+%#" PRIx64 " <%s>", scn, address, name)
4273 : printf ("%s+%#0*" PRIx64 " <%s>",
4274 scn, 2 + address_size * 2, address, name))
4275 : (address_size == 0
4276 ? printf ("%#" PRIx64 " <%s>", address, name)
4277 : printf ("%#0*" PRIx64 " <%s>",
4278 2 + address_size * 2, address, name))))
4279 : (scn != NULL
4280 ? (address_size == 0
4281 ? printf ("%s+%#" PRIx64, scn, address)
4282 : printf ("%s+%#0*" PRIx64, scn, 2 + address_size * 2, address))
4283 : (address_size == 0
4284 ? printf ("%#" PRIx64, address)
4285 : printf ("%#0*" PRIx64, 2 + address_size * 2, address)))) < 0)
4286 error_exit (0, _("sprintf failure"));
4287 }
4288
4289
4290 static const char *
dwarf_tag_string(unsigned int tag)4291 dwarf_tag_string (unsigned int tag)
4292 {
4293 switch (tag)
4294 {
4295 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
4296 DWARF_ALL_KNOWN_DW_TAG
4297 #undef DWARF_ONE_KNOWN_DW_TAG
4298 default:
4299 return NULL;
4300 }
4301 }
4302
4303
4304 static const char *
dwarf_attr_string(unsigned int attrnum)4305 dwarf_attr_string (unsigned int attrnum)
4306 {
4307 switch (attrnum)
4308 {
4309 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
4310 DWARF_ALL_KNOWN_DW_AT
4311 #undef DWARF_ONE_KNOWN_DW_AT
4312 default:
4313 return NULL;
4314 }
4315 }
4316
4317
4318 static const char *
dwarf_form_string(unsigned int form)4319 dwarf_form_string (unsigned int form)
4320 {
4321 switch (form)
4322 {
4323 #define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
4324 DWARF_ALL_KNOWN_DW_FORM
4325 #undef DWARF_ONE_KNOWN_DW_FORM
4326 default:
4327 return NULL;
4328 }
4329 }
4330
4331
4332 static const char *
dwarf_lang_string(unsigned int lang)4333 dwarf_lang_string (unsigned int lang)
4334 {
4335 switch (lang)
4336 {
4337 #define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
4338 DWARF_ALL_KNOWN_DW_LANG
4339 #undef DWARF_ONE_KNOWN_DW_LANG
4340 default:
4341 return NULL;
4342 }
4343 }
4344
4345
4346 static const char *
dwarf_inline_string(unsigned int code)4347 dwarf_inline_string (unsigned int code)
4348 {
4349 static const char *const known[] =
4350 {
4351 #define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
4352 DWARF_ALL_KNOWN_DW_INL
4353 #undef DWARF_ONE_KNOWN_DW_INL
4354 };
4355
4356 if (likely (code < sizeof (known) / sizeof (known[0])))
4357 return known[code];
4358
4359 return NULL;
4360 }
4361
4362
4363 static const char *
dwarf_encoding_string(unsigned int code)4364 dwarf_encoding_string (unsigned int code)
4365 {
4366 static const char *const known[] =
4367 {
4368 #define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
4369 DWARF_ALL_KNOWN_DW_ATE
4370 #undef DWARF_ONE_KNOWN_DW_ATE
4371 };
4372
4373 if (likely (code < sizeof (known) / sizeof (known[0])))
4374 return known[code];
4375
4376 return NULL;
4377 }
4378
4379
4380 static const char *
dwarf_access_string(unsigned int code)4381 dwarf_access_string (unsigned int code)
4382 {
4383 static const char *const known[] =
4384 {
4385 #define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
4386 DWARF_ALL_KNOWN_DW_ACCESS
4387 #undef DWARF_ONE_KNOWN_DW_ACCESS
4388 };
4389
4390 if (likely (code < sizeof (known) / sizeof (known[0])))
4391 return known[code];
4392
4393 return NULL;
4394 }
4395
4396
4397 static const char *
dwarf_defaulted_string(unsigned int code)4398 dwarf_defaulted_string (unsigned int code)
4399 {
4400 static const char *const known[] =
4401 {
4402 #define DWARF_ONE_KNOWN_DW_DEFAULTED(NAME, CODE) [CODE] = #NAME,
4403 DWARF_ALL_KNOWN_DW_DEFAULTED
4404 #undef DWARF_ONE_KNOWN_DW_DEFAULTED
4405 };
4406
4407 if (likely (code < sizeof (known) / sizeof (known[0])))
4408 return known[code];
4409
4410 return NULL;
4411 }
4412
4413
4414 static const char *
dwarf_visibility_string(unsigned int code)4415 dwarf_visibility_string (unsigned int code)
4416 {
4417 static const char *const known[] =
4418 {
4419 #define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
4420 DWARF_ALL_KNOWN_DW_VIS
4421 #undef DWARF_ONE_KNOWN_DW_VIS
4422 };
4423
4424 if (likely (code < sizeof (known) / sizeof (known[0])))
4425 return known[code];
4426
4427 return NULL;
4428 }
4429
4430
4431 static const char *
dwarf_virtuality_string(unsigned int code)4432 dwarf_virtuality_string (unsigned int code)
4433 {
4434 static const char *const known[] =
4435 {
4436 #define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
4437 DWARF_ALL_KNOWN_DW_VIRTUALITY
4438 #undef DWARF_ONE_KNOWN_DW_VIRTUALITY
4439 };
4440
4441 if (likely (code < sizeof (known) / sizeof (known[0])))
4442 return known[code];
4443
4444 return NULL;
4445 }
4446
4447
4448 static const char *
dwarf_identifier_case_string(unsigned int code)4449 dwarf_identifier_case_string (unsigned int code)
4450 {
4451 static const char *const known[] =
4452 {
4453 #define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
4454 DWARF_ALL_KNOWN_DW_ID
4455 #undef DWARF_ONE_KNOWN_DW_ID
4456 };
4457
4458 if (likely (code < sizeof (known) / sizeof (known[0])))
4459 return known[code];
4460
4461 return NULL;
4462 }
4463
4464
4465 static const char *
dwarf_calling_convention_string(unsigned int code)4466 dwarf_calling_convention_string (unsigned int code)
4467 {
4468 static const char *const known[] =
4469 {
4470 #define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
4471 DWARF_ALL_KNOWN_DW_CC
4472 #undef DWARF_ONE_KNOWN_DW_CC
4473 };
4474
4475 if (likely (code < sizeof (known) / sizeof (known[0])))
4476 return known[code];
4477
4478 return NULL;
4479 }
4480
4481
4482 static const char *
dwarf_ordering_string(unsigned int code)4483 dwarf_ordering_string (unsigned int code)
4484 {
4485 static const char *const known[] =
4486 {
4487 #define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
4488 DWARF_ALL_KNOWN_DW_ORD
4489 #undef DWARF_ONE_KNOWN_DW_ORD
4490 };
4491
4492 if (likely (code < sizeof (known) / sizeof (known[0])))
4493 return known[code];
4494
4495 return NULL;
4496 }
4497
4498
4499 static const char *
dwarf_discr_list_string(unsigned int code)4500 dwarf_discr_list_string (unsigned int code)
4501 {
4502 static const char *const known[] =
4503 {
4504 #define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
4505 DWARF_ALL_KNOWN_DW_DSC
4506 #undef DWARF_ONE_KNOWN_DW_DSC
4507 };
4508
4509 if (likely (code < sizeof (known) / sizeof (known[0])))
4510 return known[code];
4511
4512 return NULL;
4513 }
4514
4515
4516 static const char *
dwarf_locexpr_opcode_string(unsigned int code)4517 dwarf_locexpr_opcode_string (unsigned int code)
4518 {
4519 static const char *const known[] =
4520 {
4521 /* Normally we can't afford building huge table of 64K entries,
4522 most of them zero, just because there are a couple defined
4523 values at the far end. In case of opcodes, it's OK. */
4524 #define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
4525 DWARF_ALL_KNOWN_DW_OP
4526 #undef DWARF_ONE_KNOWN_DW_OP
4527 };
4528
4529 if (likely (code < sizeof (known) / sizeof (known[0])))
4530 return known[code];
4531
4532 return NULL;
4533 }
4534
4535
4536 static const char *
dwarf_unit_string(unsigned int type)4537 dwarf_unit_string (unsigned int type)
4538 {
4539 switch (type)
4540 {
4541 #define DWARF_ONE_KNOWN_DW_UT(NAME, CODE) case CODE: return #NAME;
4542 DWARF_ALL_KNOWN_DW_UT
4543 #undef DWARF_ONE_KNOWN_DW_UT
4544 default:
4545 return NULL;
4546 }
4547 }
4548
4549
4550 static const char *
dwarf_range_list_encoding_string(unsigned int kind)4551 dwarf_range_list_encoding_string (unsigned int kind)
4552 {
4553 switch (kind)
4554 {
4555 #define DWARF_ONE_KNOWN_DW_RLE(NAME, CODE) case CODE: return #NAME;
4556 DWARF_ALL_KNOWN_DW_RLE
4557 #undef DWARF_ONE_KNOWN_DW_RLE
4558 default:
4559 return NULL;
4560 }
4561 }
4562
4563
4564 static const char *
dwarf_loc_list_encoding_string(unsigned int kind)4565 dwarf_loc_list_encoding_string (unsigned int kind)
4566 {
4567 switch (kind)
4568 {
4569 #define DWARF_ONE_KNOWN_DW_LLE(NAME, CODE) case CODE: return #NAME;
4570 DWARF_ALL_KNOWN_DW_LLE
4571 #undef DWARF_ONE_KNOWN_DW_LLE
4572 /* DW_LLE_GNU_view_pair is special/incompatible with default codes. */
4573 case DW_LLE_GNU_view_pair: return "GNU_view_pair";
4574 default:
4575 return NULL;
4576 }
4577 }
4578
4579
4580 static const char *
dwarf_line_content_description_string(unsigned int kind)4581 dwarf_line_content_description_string (unsigned int kind)
4582 {
4583 switch (kind)
4584 {
4585 #define DWARF_ONE_KNOWN_DW_LNCT(NAME, CODE) case CODE: return #NAME;
4586 DWARF_ALL_KNOWN_DW_LNCT
4587 #undef DWARF_ONE_KNOWN_DW_LNCT
4588 default:
4589 return NULL;
4590 }
4591 }
4592
4593
4594 /* Used by all dwarf_foo_name functions. */
4595 static const char *
string_or_unknown(const char * known,unsigned int code,unsigned int lo_user,unsigned int hi_user,bool print_unknown_num)4596 string_or_unknown (const char *known, unsigned int code,
4597 unsigned int lo_user, unsigned int hi_user,
4598 bool print_unknown_num)
4599 {
4600 static char unknown_buf[20];
4601
4602 if (likely (known != NULL))
4603 return known;
4604
4605 if (lo_user != 0 && code >= lo_user && code <= hi_user)
4606 {
4607 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
4608 code - lo_user);
4609 return unknown_buf;
4610 }
4611
4612 if (print_unknown_num)
4613 {
4614 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
4615 return unknown_buf;
4616 }
4617
4618 return "???";
4619 }
4620
4621
4622 static const char *
dwarf_tag_name(unsigned int tag)4623 dwarf_tag_name (unsigned int tag)
4624 {
4625 const char *ret = dwarf_tag_string (tag);
4626 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
4627 }
4628
4629 static const char *
dwarf_attr_name(unsigned int attr)4630 dwarf_attr_name (unsigned int attr)
4631 {
4632 const char *ret = dwarf_attr_string (attr);
4633 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
4634 }
4635
4636
4637 static const char *
dwarf_form_name(unsigned int form)4638 dwarf_form_name (unsigned int form)
4639 {
4640 const char *ret = dwarf_form_string (form);
4641 return string_or_unknown (ret, form, 0, 0, true);
4642 }
4643
4644
4645 static const char *
dwarf_lang_name(unsigned int lang)4646 dwarf_lang_name (unsigned int lang)
4647 {
4648 const char *ret = dwarf_lang_string (lang);
4649 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
4650 }
4651
4652
4653 static const char *
dwarf_inline_name(unsigned int code)4654 dwarf_inline_name (unsigned int code)
4655 {
4656 const char *ret = dwarf_inline_string (code);
4657 return string_or_unknown (ret, code, 0, 0, false);
4658 }
4659
4660
4661 static const char *
dwarf_encoding_name(unsigned int code)4662 dwarf_encoding_name (unsigned int code)
4663 {
4664 const char *ret = dwarf_encoding_string (code);
4665 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
4666 }
4667
4668
4669 static const char *
dwarf_access_name(unsigned int code)4670 dwarf_access_name (unsigned int code)
4671 {
4672 const char *ret = dwarf_access_string (code);
4673 return string_or_unknown (ret, code, 0, 0, false);
4674 }
4675
4676
4677 static const char *
dwarf_defaulted_name(unsigned int code)4678 dwarf_defaulted_name (unsigned int code)
4679 {
4680 const char *ret = dwarf_defaulted_string (code);
4681 return string_or_unknown (ret, code, 0, 0, false);
4682 }
4683
4684
4685 static const char *
dwarf_visibility_name(unsigned int code)4686 dwarf_visibility_name (unsigned int code)
4687 {
4688 const char *ret = dwarf_visibility_string (code);
4689 return string_or_unknown (ret, code, 0, 0, false);
4690 }
4691
4692
4693 static const char *
dwarf_virtuality_name(unsigned int code)4694 dwarf_virtuality_name (unsigned int code)
4695 {
4696 const char *ret = dwarf_virtuality_string (code);
4697 return string_or_unknown (ret, code, 0, 0, false);
4698 }
4699
4700
4701 static const char *
dwarf_identifier_case_name(unsigned int code)4702 dwarf_identifier_case_name (unsigned int code)
4703 {
4704 const char *ret = dwarf_identifier_case_string (code);
4705 return string_or_unknown (ret, code, 0, 0, false);
4706 }
4707
4708
4709 static const char *
dwarf_calling_convention_name(unsigned int code)4710 dwarf_calling_convention_name (unsigned int code)
4711 {
4712 const char *ret = dwarf_calling_convention_string (code);
4713 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
4714 }
4715
4716
4717 static const char *
dwarf_ordering_name(unsigned int code)4718 dwarf_ordering_name (unsigned int code)
4719 {
4720 const char *ret = dwarf_ordering_string (code);
4721 return string_or_unknown (ret, code, 0, 0, false);
4722 }
4723
4724
4725 static const char *
dwarf_discr_list_name(unsigned int code)4726 dwarf_discr_list_name (unsigned int code)
4727 {
4728 const char *ret = dwarf_discr_list_string (code);
4729 return string_or_unknown (ret, code, 0, 0, false);
4730 }
4731
4732
4733 static const char *
dwarf_unit_name(unsigned int type)4734 dwarf_unit_name (unsigned int type)
4735 {
4736 const char *ret = dwarf_unit_string (type);
4737 return string_or_unknown (ret, type, DW_UT_lo_user, DW_UT_hi_user, true);
4738 }
4739
4740
4741 static const char *
dwarf_range_list_encoding_name(unsigned int kind)4742 dwarf_range_list_encoding_name (unsigned int kind)
4743 {
4744 const char *ret = dwarf_range_list_encoding_string (kind);
4745 return string_or_unknown (ret, kind, 0, 0, false);
4746 }
4747
4748
4749 static const char *
dwarf_loc_list_encoding_name(unsigned int kind)4750 dwarf_loc_list_encoding_name (unsigned int kind)
4751 {
4752 const char *ret = dwarf_loc_list_encoding_string (kind);
4753 return string_or_unknown (ret, kind, 0, 0, false);
4754 }
4755
4756
4757 static const char *
dwarf_line_content_description_name(unsigned int kind)4758 dwarf_line_content_description_name (unsigned int kind)
4759 {
4760 const char *ret = dwarf_line_content_description_string (kind);
4761 return string_or_unknown (ret, kind, DW_LNCT_lo_user, DW_LNCT_hi_user,
4762 false);
4763 }
4764
4765
4766 static void
print_block(size_t n,const void * block)4767 print_block (size_t n, const void *block)
4768 {
4769 if (n == 0)
4770 puts (_("empty block"));
4771 else
4772 {
4773 printf (_("%zu byte block:"), n);
4774 const unsigned char *data = block;
4775 do
4776 printf (" %02x", *data++);
4777 while (--n > 0);
4778 putchar ('\n');
4779 }
4780 }
4781
4782 static void
print_bytes(size_t n,const unsigned char * bytes)4783 print_bytes (size_t n, const unsigned char *bytes)
4784 {
4785 while (n-- > 0)
4786 {
4787 printf ("%02x", *bytes++);
4788 if (n > 0)
4789 printf (" ");
4790 }
4791 }
4792
4793 static int
get_indexed_addr(Dwarf_CU * cu,Dwarf_Word idx,Dwarf_Addr * addr)4794 get_indexed_addr (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
4795 {
4796 if (cu == NULL)
4797 return -1;
4798
4799 Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
4800 if (debug_addr == NULL)
4801 return -1;
4802
4803 Dwarf_Off base = __libdw_cu_addr_base (cu);
4804 Dwarf_Word off = idx * cu->address_size;
4805 if (base > debug_addr->d_size
4806 || off > debug_addr->d_size - base
4807 || cu->address_size > debug_addr->d_size - base - off)
4808 return -1;
4809
4810 const unsigned char *addrp = debug_addr->d_buf + base + off;
4811 if (cu->address_size == 4)
4812 *addr = read_4ubyte_unaligned (cu->dbg, addrp);
4813 else
4814 *addr = read_8ubyte_unaligned (cu->dbg, addrp);
4815
4816 return 0;
4817 }
4818
4819 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)4820 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
4821 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
4822 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
4823 {
4824 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
4825
4826 if (len == 0)
4827 {
4828 printf ("%*s(empty)\n", indent, "");
4829 return;
4830 }
4831
4832 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
4833 #define CONSUME(n) NEED (n); else len -= (n)
4834
4835 Dwarf_Word offset = 0;
4836 while (len-- > 0)
4837 {
4838 uint_fast8_t op = *data++;
4839
4840 const char *op_name = dwarf_locexpr_opcode_string (op);
4841 if (unlikely (op_name == NULL))
4842 {
4843 static char buf[20];
4844 if (op >= DW_OP_lo_user)
4845 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
4846 else
4847 snprintf (buf, sizeof buf, "??? (%#x)", op);
4848 op_name = buf;
4849 }
4850
4851 switch (op)
4852 {
4853 case DW_OP_addr:;
4854 /* Address operand. */
4855 Dwarf_Word addr;
4856 NEED (addrsize);
4857 if (addrsize == 4)
4858 addr = read_4ubyte_unaligned (dbg, data);
4859 else if (addrsize == 8)
4860 addr = read_8ubyte_unaligned (dbg, data);
4861 else
4862 goto invalid;
4863 data += addrsize;
4864 CONSUME (addrsize);
4865
4866 printf ("%*s[%2" PRIuMAX "] %s ",
4867 indent, "", (uintmax_t) offset, op_name);
4868 print_dwarf_addr (dwflmod, 0, addr, addr);
4869 printf ("\n");
4870
4871 offset += 1 + addrsize;
4872 break;
4873
4874 case DW_OP_call_ref:
4875 case DW_OP_GNU_variable_value:
4876 /* Offset operand. */
4877 if (ref_size != 4 && ref_size != 8)
4878 goto invalid; /* Cannot be used in CFA. */
4879 NEED (ref_size);
4880 if (ref_size == 4)
4881 addr = read_4ubyte_unaligned (dbg, data);
4882 else
4883 addr = read_8ubyte_unaligned (dbg, data);
4884 data += ref_size;
4885 CONSUME (ref_size);
4886 /* addr is a DIE offset, so format it as one. */
4887 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4888 indent, "", (uintmax_t) offset,
4889 op_name, (uintmax_t) addr);
4890 offset += 1 + ref_size;
4891 break;
4892
4893 case DW_OP_deref_size:
4894 case DW_OP_xderef_size:
4895 case DW_OP_pick:
4896 case DW_OP_const1u:
4897 // XXX value might be modified by relocation
4898 NEED (1);
4899 printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 "\n",
4900 indent, "", (uintmax_t) offset,
4901 op_name, *((uint8_t *) data));
4902 ++data;
4903 --len;
4904 offset += 2;
4905 break;
4906
4907 case DW_OP_const2u:
4908 NEED (2);
4909 // XXX value might be modified by relocation
4910 printf ("%*s[%2" PRIuMAX "] %s %" PRIu16 "\n",
4911 indent, "", (uintmax_t) offset,
4912 op_name, read_2ubyte_unaligned (dbg, data));
4913 CONSUME (2);
4914 data += 2;
4915 offset += 3;
4916 break;
4917
4918 case DW_OP_const4u:
4919 NEED (4);
4920 // XXX value might be modified by relocation
4921 printf ("%*s[%2" PRIuMAX "] %s %" PRIu32 "\n",
4922 indent, "", (uintmax_t) offset,
4923 op_name, read_4ubyte_unaligned (dbg, data));
4924 CONSUME (4);
4925 data += 4;
4926 offset += 5;
4927 break;
4928
4929 case DW_OP_const8u:
4930 NEED (8);
4931 // XXX value might be modified by relocation
4932 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4933 indent, "", (uintmax_t) offset,
4934 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4935 CONSUME (8);
4936 data += 8;
4937 offset += 9;
4938 break;
4939
4940 case DW_OP_const1s:
4941 NEED (1);
4942 // XXX value might be modified by relocation
4943 printf ("%*s[%2" PRIuMAX "] %s %" PRId8 "\n",
4944 indent, "", (uintmax_t) offset,
4945 op_name, *((int8_t *) data));
4946 ++data;
4947 --len;
4948 offset += 2;
4949 break;
4950
4951 case DW_OP_const2s:
4952 NEED (2);
4953 // XXX value might be modified by relocation
4954 printf ("%*s[%2" PRIuMAX "] %s %" PRId16 "\n",
4955 indent, "", (uintmax_t) offset,
4956 op_name, read_2sbyte_unaligned (dbg, data));
4957 CONSUME (2);
4958 data += 2;
4959 offset += 3;
4960 break;
4961
4962 case DW_OP_const4s:
4963 NEED (4);
4964 // XXX value might be modified by relocation
4965 printf ("%*s[%2" PRIuMAX "] %s %" PRId32 "\n",
4966 indent, "", (uintmax_t) offset,
4967 op_name, read_4sbyte_unaligned (dbg, data));
4968 CONSUME (4);
4969 data += 4;
4970 offset += 5;
4971 break;
4972
4973 case DW_OP_const8s:
4974 NEED (8);
4975 // XXX value might be modified by relocation
4976 printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4977 indent, "", (uintmax_t) offset,
4978 op_name, read_8sbyte_unaligned (dbg, data));
4979 CONSUME (8);
4980 data += 8;
4981 offset += 9;
4982 break;
4983
4984 case DW_OP_piece:
4985 case DW_OP_regx:
4986 case DW_OP_plus_uconst:
4987 case DW_OP_constu:;
4988 const unsigned char *start = data;
4989 uint64_t uleb;
4990 NEED (1);
4991 get_uleb128 (uleb, data, data + len);
4992 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4993 indent, "", (uintmax_t) offset, op_name, uleb);
4994 CONSUME (data - start);
4995 offset += 1 + (data - start);
4996 break;
4997
4998 case DW_OP_addrx:
4999 case DW_OP_GNU_addr_index:
5000 case DW_OP_constx:
5001 case DW_OP_GNU_const_index:;
5002 start = data;
5003 NEED (1);
5004 get_uleb128 (uleb, data, data + len);
5005 printf ("%*s[%2" PRIuMAX "] %s [%" PRIu64 "] ",
5006 indent, "", (uintmax_t) offset, op_name, uleb);
5007 CONSUME (data - start);
5008 offset += 1 + (data - start);
5009 if (get_indexed_addr (cu, uleb, &addr) != 0)
5010 printf ("???\n");
5011 else
5012 {
5013 print_dwarf_addr (dwflmod, 0, addr, addr);
5014 printf ("\n");
5015 }
5016 break;
5017
5018 case DW_OP_bit_piece:
5019 start = data;
5020 uint64_t uleb2;
5021 NEED (1);
5022 get_uleb128 (uleb, data, data + len);
5023 NEED (1);
5024 get_uleb128 (uleb2, data, data + len);
5025 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
5026 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
5027 CONSUME (data - start);
5028 offset += 1 + (data - start);
5029 break;
5030
5031 case DW_OP_fbreg:
5032 case DW_OP_breg0 ... DW_OP_breg31:
5033 case DW_OP_consts:
5034 start = data;
5035 int64_t sleb;
5036 NEED (1);
5037 get_sleb128 (sleb, data, data + len);
5038 printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
5039 indent, "", (uintmax_t) offset, op_name, sleb);
5040 CONSUME (data - start);
5041 offset += 1 + (data - start);
5042 break;
5043
5044 case DW_OP_bregx:
5045 start = data;
5046 NEED (1);
5047 get_uleb128 (uleb, data, data + len);
5048 NEED (1);
5049 get_sleb128 (sleb, data, data + len);
5050 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
5051 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
5052 CONSUME (data - start);
5053 offset += 1 + (data - start);
5054 break;
5055
5056 case DW_OP_call2:
5057 NEED (2);
5058 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx16 "]\n",
5059 indent, "", (uintmax_t) offset, op_name,
5060 read_2ubyte_unaligned (dbg, data));
5061 CONSUME (2);
5062 data += 2;
5063 offset += 3;
5064 break;
5065
5066 case DW_OP_call4:
5067 NEED (4);
5068 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx32 "]\n",
5069 indent, "", (uintmax_t) offset, op_name,
5070 read_4ubyte_unaligned (dbg, data));
5071 CONSUME (4);
5072 data += 4;
5073 offset += 5;
5074 break;
5075
5076 case DW_OP_skip:
5077 case DW_OP_bra:
5078 NEED (2);
5079 printf ("%*s[%2" PRIuMAX "] %s %" PRIuMAX "\n",
5080 indent, "", (uintmax_t) offset, op_name,
5081 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
5082 CONSUME (2);
5083 data += 2;
5084 offset += 3;
5085 break;
5086
5087 case DW_OP_implicit_value:
5088 start = data;
5089 NEED (1);
5090 get_uleb128 (uleb, data, data + len);
5091 printf ("%*s[%2" PRIuMAX "] %s: ",
5092 indent, "", (uintmax_t) offset, op_name);
5093 NEED (uleb);
5094 print_block (uleb, data);
5095 data += uleb;
5096 CONSUME (data - start);
5097 offset += 1 + (data - start);
5098 break;
5099
5100 case DW_OP_implicit_pointer:
5101 case DW_OP_GNU_implicit_pointer:
5102 /* DIE offset operand. */
5103 start = data;
5104 NEED (ref_size);
5105 if (ref_size != 4 && ref_size != 8)
5106 goto invalid; /* Cannot be used in CFA. */
5107 if (ref_size == 4)
5108 addr = read_4ubyte_unaligned (dbg, data);
5109 else
5110 addr = read_8ubyte_unaligned (dbg, data);
5111 data += ref_size;
5112 /* Byte offset operand. */
5113 NEED (1);
5114 get_sleb128 (sleb, data, data + len);
5115
5116 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
5117 indent, "", (intmax_t) offset,
5118 op_name, (uintmax_t) addr, sleb);
5119 CONSUME (data - start);
5120 offset += 1 + (data - start);
5121 break;
5122
5123 case DW_OP_entry_value:
5124 case DW_OP_GNU_entry_value:
5125 /* Size plus expression block. */
5126 start = data;
5127 NEED (1);
5128 get_uleb128 (uleb, data, data + len);
5129 printf ("%*s[%2" PRIuMAX "] %s:\n",
5130 indent, "", (uintmax_t) offset, op_name);
5131 NEED (uleb);
5132 print_ops (dwflmod, dbg, indent + 5, indent + 5, vers,
5133 addrsize, offset_size, cu, uleb, data);
5134 data += uleb;
5135 CONSUME (data - start);
5136 offset += 1 + (data - start);
5137 break;
5138
5139 case DW_OP_const_type:
5140 case DW_OP_GNU_const_type:
5141 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
5142 unsigned size plus block. */
5143 start = data;
5144 NEED (1);
5145 get_uleb128 (uleb, data, data + len);
5146 if (! print_unresolved_addresses && cu != NULL)
5147 uleb += cu->start;
5148 NEED (1);
5149 uint8_t usize = *(uint8_t *) data++;
5150 NEED (usize);
5151 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] ",
5152 indent, "", (uintmax_t) offset, op_name, uleb);
5153 print_block (usize, data);
5154 data += usize;
5155 CONSUME (data - start);
5156 offset += 1 + (data - start);
5157 break;
5158
5159 case DW_OP_regval_type:
5160 case DW_OP_GNU_regval_type:
5161 /* uleb128 register number, uleb128 CU relative
5162 DW_TAG_base_type DIE offset. */
5163 start = data;
5164 NEED (1);
5165 get_uleb128 (uleb, data, data + len);
5166 NEED (1);
5167 get_uleb128 (uleb2, data, data + len);
5168 if (! print_unresolved_addresses && cu != NULL)
5169 uleb2 += cu->start;
5170 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
5171 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
5172 CONSUME (data - start);
5173 offset += 1 + (data - start);
5174 break;
5175
5176 case DW_OP_deref_type:
5177 case DW_OP_GNU_deref_type:
5178 /* 1-byte unsigned size of value, uleb128 CU relative
5179 DW_TAG_base_type DIE offset. */
5180 start = data;
5181 NEED (1);
5182 usize = *(uint8_t *) data++;
5183 NEED (1);
5184 get_uleb128 (uleb, data, data + len);
5185 if (! print_unresolved_addresses && cu != NULL)
5186 uleb += cu->start;
5187 printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
5188 indent, "", (uintmax_t) offset,
5189 op_name, usize, uleb);
5190 CONSUME (data - start);
5191 offset += 1 + (data - start);
5192 break;
5193
5194 case DW_OP_xderef_type:
5195 /* 1-byte unsigned size of value, uleb128 base_type DIE offset. */
5196 start = data;
5197 NEED (1);
5198 usize = *(uint8_t *) data++;
5199 NEED (1);
5200 get_uleb128 (uleb, data, data + len);
5201 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
5202 indent, "", (uintmax_t) offset,
5203 op_name, usize, uleb);
5204 CONSUME (data - start);
5205 offset += 1 + (data - start);
5206 break;
5207
5208 case DW_OP_convert:
5209 case DW_OP_GNU_convert:
5210 case DW_OP_reinterpret:
5211 case DW_OP_GNU_reinterpret:
5212 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
5213 for conversion to untyped. */
5214 start = data;
5215 NEED (1);
5216 get_uleb128 (uleb, data, data + len);
5217 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
5218 uleb += cu->start;
5219 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
5220 indent, "", (uintmax_t) offset, op_name, uleb);
5221 CONSUME (data - start);
5222 offset += 1 + (data - start);
5223 break;
5224
5225 case DW_OP_GNU_parameter_ref:
5226 /* 4 byte CU relative reference to the abstract optimized away
5227 DW_TAG_formal_parameter. */
5228 NEED (4);
5229 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
5230 if (! print_unresolved_addresses && cu != NULL)
5231 param_off += cu->start;
5232 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
5233 indent, "", (uintmax_t) offset, op_name, param_off);
5234 CONSUME (4);
5235 data += 4;
5236 offset += 5;
5237 break;
5238
5239 default:
5240 /* No Operand. */
5241 printf ("%*s[%2" PRIuMAX "] %s\n",
5242 indent, "", (uintmax_t) offset, op_name);
5243 ++offset;
5244 break;
5245 }
5246
5247 indent = indentrest;
5248 continue;
5249
5250 invalid:
5251 printf (_("%*s[%2" PRIuMAX "] %s <TRUNCATED>\n"),
5252 indent, "", (uintmax_t) offset, op_name);
5253 break;
5254 }
5255 }
5256
5257
5258 /* Turn the addresses into file offsets by using the phdrs. */
5259 static void
find_offsets(Elf * elf,GElf_Addr main_bias,size_t n,GElf_Addr addrs[n],GElf_Off offs[n])5260 find_offsets(Elf *elf, GElf_Addr main_bias, size_t n,
5261 GElf_Addr addrs[n], GElf_Off offs[n])
5262 {
5263 size_t unsolved = n;
5264 for (size_t i = 0; i < phnum; ++i) {
5265 GElf_Phdr phdr_mem;
5266 GElf_Phdr *phdr = gelf_getphdr(elf, i, &phdr_mem);
5267 if (phdr != NULL && phdr->p_type == PT_LOAD && phdr->p_memsz > 0)
5268 for (size_t j = 0; j < n; ++j)
5269 if (offs[j] == 0 && addrs[j] >= phdr->p_vaddr + main_bias &&
5270 addrs[j] - (phdr->p_vaddr + main_bias) < phdr->p_filesz) {
5271 offs[j] = addrs[j] - (phdr->p_vaddr + main_bias) + phdr->p_offset;
5272 if (--unsolved == 0)
5273 break;
5274 }
5275 }
5276 }
5277
5278 /* The dynamic segment (type PT_DYNAMIC), contains the .dynamic section.
5279 And .dynamic section contains an array of the dynamic structures.
5280 We use the array to get:
5281 DT_STRTAB: the address of the string table
5282 DT_SYMTAB: the address of the symbol table
5283 DT_STRSZ: the size, in bytes, of the string table
5284 ... */
5285 static void
get_dynscn_addrs(Elf * elf,GElf_Phdr * phdr,GElf_Addr addrs[i_max])5286 get_dynscn_addrs(Elf *elf, GElf_Phdr *phdr, GElf_Addr addrs[i_max])
5287 {
5288 Elf_Data *data = elf_getdata_rawchunk(
5289 elf, phdr->p_offset, phdr->p_filesz, ELF_T_DYN);
5290
5291 int dyn_idx = 0;
5292 for (;; ++dyn_idx) {
5293 GElf_Dyn dyn_mem;
5294 GElf_Dyn *dyn = gelf_getdyn(data, dyn_idx, &dyn_mem);
5295 /* DT_NULL Marks end of dynamic section. */
5296 if (dyn == NULL || dyn->d_tag == DT_NULL)
5297 break;
5298
5299 switch (dyn->d_tag) {
5300 case DT_SYMTAB:
5301 addrs[i_symtab] = dyn->d_un.d_ptr;
5302 break;
5303
5304 case DT_HASH:
5305 addrs[i_hash] = dyn->d_un.d_ptr;
5306 break;
5307
5308 case DT_GNU_HASH:
5309 addrs[i_gnu_hash] = dyn->d_un.d_ptr;
5310 break;
5311
5312 case DT_STRTAB:
5313 addrs[i_strtab] = dyn->d_un.d_ptr;
5314 break;
5315
5316 case DT_VERSYM:
5317 addrs[i_versym] = dyn->d_un.d_ptr;
5318 break;
5319
5320 case DT_VERDEF:
5321 addrs[i_verdef] = dyn->d_un.d_ptr;
5322 break;
5323
5324 case DT_VERDEFNUM:
5325 addrs[i_verdefnum] = dyn->d_un.d_val;
5326 break;
5327
5328 case DT_VERNEED:
5329 addrs[i_verneed] = dyn->d_un.d_ptr;
5330 break;
5331
5332 case DT_VERNEEDNUM:
5333 addrs[i_verneednum] = dyn->d_un.d_val;
5334 break;
5335
5336 case DT_STRSZ:
5337 addrs[i_strsz] = dyn->d_un.d_val;
5338 break;
5339
5340 case DT_SYMTAB_SHNDX:
5341 addrs[i_symtab_shndx] = dyn->d_un.d_ptr;
5342 break;
5343 }
5344 }
5345 }
5346
5347
5348 /* Use dynamic segment to get data for the string table section. */
5349 static Elf_Data *
get_dynscn_strtab(Elf * elf,GElf_Phdr * phdr)5350 get_dynscn_strtab(Elf *elf, GElf_Phdr *phdr)
5351 {
5352 Elf_Data *strtab_data;
5353 GElf_Addr addrs[i_max] = {0,};
5354 GElf_Off offs[i_max] = {0,};
5355 get_dynscn_addrs(elf, phdr, addrs);
5356 find_offsets(elf, 0, i_max, addrs, offs);
5357 strtab_data = elf_getdata_rawchunk(
5358 elf, offs[i_strtab], addrs[i_strsz], ELF_T_BYTE);
5359 return strtab_data;
5360 }
5361
5362
5363 struct listptr
5364 {
5365 Dwarf_Off offset:(64 - 3);
5366 bool addr64:1;
5367 bool dwarf64:1;
5368 bool warned:1;
5369 struct Dwarf_CU *cu;
5370 unsigned int attr;
5371 };
5372
5373 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
5374 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
5375
5376 static Dwarf_Addr
cudie_base(Dwarf_Die * cudie)5377 cudie_base (Dwarf_Die *cudie)
5378 {
5379 Dwarf_Addr base;
5380 /* Find the base address of the compilation unit. It will normally
5381 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
5382 address could be overridden by DW_AT_entry_pc. It's been
5383 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
5384 compilation units with discontinuous ranges. */
5385 if (unlikely (dwarf_lowpc (cudie, &base) != 0))
5386 {
5387 Dwarf_Attribute attr_mem;
5388 if (dwarf_formaddr (dwarf_attr (cudie, DW_AT_entry_pc, &attr_mem),
5389 &base) != 0)
5390 base = 0;
5391 }
5392 return base;
5393 }
5394
5395 static Dwarf_Addr
listptr_base(struct listptr * p)5396 listptr_base (struct listptr *p)
5397 {
5398 Dwarf_Die cu = CUDIE (p->cu);
5399 return cudie_base (&cu);
5400 }
5401
5402 /* To store the name used in compare_listptr */
5403 static const char *sort_listptr_name;
5404
5405 static int
compare_listptr(const void * a,const void * b)5406 compare_listptr (const void *a, const void *b)
5407 {
5408 const char *name = sort_listptr_name;
5409 struct listptr *p1 = (void *) a;
5410 struct listptr *p2 = (void *) b;
5411
5412 if (p1->offset < p2->offset)
5413 return -1;
5414 if (p1->offset > p2->offset)
5415 return 1;
5416
5417 if (!p1->warned && !p2->warned)
5418 {
5419 if (p1->addr64 != p2->addr64)
5420 {
5421 p1->warned = p2->warned = true;
5422 error (0, 0,
5423 _("%s %#" PRIx64 " used with different address sizes"),
5424 name, (uint64_t) p1->offset);
5425 }
5426 if (p1->dwarf64 != p2->dwarf64)
5427 {
5428 p1->warned = p2->warned = true;
5429 error (0, 0,
5430 _("%s %#" PRIx64 " used with different offset sizes"),
5431 name, (uint64_t) p1->offset);
5432 }
5433 if (listptr_base (p1) != listptr_base (p2))
5434 {
5435 p1->warned = p2->warned = true;
5436 error (0, 0,
5437 _("%s %#" PRIx64 " used with different base addresses"),
5438 name, (uint64_t) p1->offset);
5439 }
5440 if (p1->attr != p2 ->attr)
5441 {
5442 p1->warned = p2->warned = true;
5443 error (0, 0,
5444 _("%s %#" PRIx64
5445 " used with different attribute %s and %s"),
5446 name, (uint64_t) p1->offset, dwarf_attr_name (p1->attr),
5447 dwarf_attr_name (p2->attr));
5448 }
5449 }
5450
5451 return 0;
5452 }
5453
5454 struct listptr_table
5455 {
5456 size_t n;
5457 size_t alloc;
5458 struct listptr *table;
5459 };
5460
5461 static struct listptr_table known_locsptr;
5462 static struct listptr_table known_loclistsptr;
5463 static struct listptr_table known_rangelistptr;
5464 static struct listptr_table known_rnglistptr;
5465 static struct listptr_table known_addrbases;
5466 static struct listptr_table known_stroffbases;
5467
5468 static void
reset_listptr(struct listptr_table * table)5469 reset_listptr (struct listptr_table *table)
5470 {
5471 free (table->table);
5472 table->table = NULL;
5473 table->n = table->alloc = 0;
5474 }
5475
5476 /* Returns false if offset doesn't fit. See struct listptr. */
5477 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)5478 notice_listptr (enum section_e section, struct listptr_table *table,
5479 uint_fast8_t address_size, uint_fast8_t offset_size,
5480 struct Dwarf_CU *cu, Dwarf_Off offset, unsigned int attr)
5481 {
5482 if (print_debug_sections & section)
5483 {
5484 if (table->n == table->alloc)
5485 {
5486 if (table->alloc == 0)
5487 table->alloc = 128;
5488 else
5489 table->alloc *= 2;
5490 table->table = xrealloc (table->table,
5491 table->alloc * sizeof table->table[0]);
5492 }
5493
5494 struct listptr *p = &table->table[table->n++];
5495
5496 *p = (struct listptr)
5497 {
5498 .addr64 = address_size == 8,
5499 .dwarf64 = offset_size == 8,
5500 .offset = offset,
5501 .cu = cu,
5502 .attr = attr
5503 };
5504
5505 if (p->offset != offset)
5506 {
5507 table->n--;
5508 return false;
5509 }
5510 }
5511 return true;
5512 }
5513
5514 static void
sort_listptr(struct listptr_table * table,const char * name)5515 sort_listptr (struct listptr_table *table, const char *name)
5516 {
5517 if (table->n > 0)
5518 {
5519 sort_listptr_name = name;
5520 qsort (table->table, table->n, sizeof table->table[0],
5521 &compare_listptr);
5522 }
5523 }
5524
5525 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)5526 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
5527 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
5528 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
5529 unsigned char **readp, unsigned char *endp,
5530 unsigned int *attr)
5531 {
5532 if (table->n == 0)
5533 return false;
5534
5535 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
5536 ++*idxp;
5537
5538 struct listptr *p = &table->table[*idxp];
5539
5540 if (*idxp == table->n
5541 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
5542 {
5543 *readp = endp;
5544 printf (_(" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
5545 offset);
5546 return true;
5547 }
5548
5549 if (p->offset != (Dwarf_Off) offset)
5550 {
5551 *readp += p->offset - offset;
5552 printf (_(" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
5553 offset, (Dwarf_Off) p->offset - offset);
5554 return true;
5555 }
5556
5557 if (address_sizep != NULL)
5558 *address_sizep = listptr_address_size (p);
5559 if (offset_sizep != NULL)
5560 *offset_sizep = listptr_offset_size (p);
5561 if (base != NULL)
5562 *base = listptr_base (p);
5563 if (cu != NULL)
5564 *cu = p->cu;
5565 if (attr != NULL)
5566 *attr = p->attr;
5567
5568 return false;
5569 }
5570
5571 static Dwarf_Off
next_listptr_offset(struct listptr_table * table,size_t * idxp,Dwarf_Off off)5572 next_listptr_offset (struct listptr_table *table, size_t *idxp, Dwarf_Off off)
5573 {
5574 /* Note that multiple attributes could in theory point to the same loclist
5575 offset, so make sure we pick one that is bigger than the current one.
5576 The table is sorted on offset. */
5577 if (*idxp < table->n)
5578 {
5579 while (++*idxp < table->n)
5580 {
5581 Dwarf_Off next = table->table[*idxp].offset;
5582 if (next > off)
5583 return next;
5584 }
5585 }
5586 return 0;
5587 }
5588
5589 /* Returns the listptr associated with the given index, or NULL. */
5590 static struct listptr *
get_listptr(struct listptr_table * table,size_t idx)5591 get_listptr (struct listptr_table *table, size_t idx)
5592 {
5593 if (idx >= table->n)
5594 return NULL;
5595 return &table->table[idx];
5596 }
5597
5598 /* Returns the next index, base address and CU associated with the
5599 list unit offsets. If there is none false is returned, otherwise
5600 true. Assumes the table has been sorted. */
5601 static bool
listptr_cu(struct listptr_table * table,size_t * idxp,Dwarf_Off start,Dwarf_Off end,Dwarf_Addr * base,struct Dwarf_CU ** cu)5602 listptr_cu (struct listptr_table *table, size_t *idxp,
5603 Dwarf_Off start, Dwarf_Off end,
5604 Dwarf_Addr *base, struct Dwarf_CU **cu)
5605 {
5606 while (*idxp < table->n
5607 && table->table[*idxp].offset < start)
5608 ++*idxp;
5609
5610 if (*idxp < table->n
5611 && table->table[*idxp].offset >= start
5612 && table->table[*idxp].offset < end)
5613 {
5614 struct listptr *p = &table->table[*idxp];
5615 *base = listptr_base (p);
5616 *cu = p->cu;
5617 return true;
5618 }
5619
5620 return false;
5621 }
5622
5623 /* Returns the next index with the current CU for the given attribute.
5624 If there is none false is returned, otherwise true. Assumes the
5625 table has been sorted. */
5626 static bool
listptr_attr(struct listptr_table * table,size_t idxp,Dwarf_Off offset,unsigned int attr)5627 listptr_attr (struct listptr_table *table, size_t idxp,
5628 Dwarf_Off offset, unsigned int attr)
5629 {
5630 struct listptr *listptr;
5631 do
5632 {
5633 listptr = get_listptr (table, idxp);
5634 if (listptr == NULL)
5635 return false;
5636
5637 if (listptr->offset == offset && listptr->attr == attr)
5638 return true;
5639
5640 idxp++;
5641 }
5642 while (listptr->offset <= offset);
5643
5644 return false;
5645 }
5646
5647 static void
print_debug_abbrev_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5648 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5649 Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
5650 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5651 {
5652 Elf_Data *elf_data = get_debug_elf_data (dbg, ebl, IDX_debug_abbrev, scn);
5653 if (elf_data == NULL)
5654 return;
5655
5656 const size_t sh_size = elf_data->d_size;
5657
5658 printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
5659 " [ Code]\n"),
5660 elf_ndxscn (scn), section_name (ebl, shdr),
5661 (uint64_t) shdr->sh_offset);
5662
5663 Dwarf_Off offset = 0;
5664 while (offset < sh_size)
5665 {
5666 printf (_("\nAbbreviation section at offset %" PRIu64 ":\n"),
5667 offset);
5668
5669 while (1)
5670 {
5671 size_t length;
5672 Dwarf_Abbrev abbrev;
5673
5674 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
5675 if (res != 0)
5676 {
5677 if (unlikely (res < 0))
5678 {
5679 printf (_("\
5680 *** error while reading abbreviation: %s\n"),
5681 dwarf_errmsg (-1));
5682 return;
5683 }
5684
5685 /* This is the NUL byte at the end of the section. */
5686 ++offset;
5687 break;
5688 }
5689
5690 /* We know these calls can never fail. */
5691 unsigned int code = dwarf_getabbrevcode (&abbrev);
5692 unsigned int tag = dwarf_getabbrevtag (&abbrev);
5693 int has_children = dwarf_abbrevhaschildren (&abbrev);
5694
5695 printf (_(" [%5u] offset: %" PRId64
5696 ", children: %s, tag: %s\n"),
5697 code, (int64_t) offset,
5698 has_children ? yes_str : no_str,
5699 dwarf_tag_name (tag));
5700
5701 size_t cnt = 0;
5702 unsigned int name;
5703 unsigned int form;
5704 Dwarf_Sword data;
5705 Dwarf_Off enoffset;
5706 while (dwarf_getabbrevattr_data (&abbrev, cnt, &name, &form,
5707 &data, &enoffset) == 0)
5708 {
5709 printf (" attr: %s, form: %s",
5710 dwarf_attr_name (name), dwarf_form_name (form));
5711 if (form == DW_FORM_implicit_const)
5712 printf (" (%" PRId64 ")", data);
5713 printf (", offset: %#" PRIx64 "\n", (uint64_t) enoffset);
5714 ++cnt;
5715 }
5716
5717 offset += length;
5718 }
5719 }
5720 }
5721
5722
5723 static void
print_debug_addr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5724 print_debug_addr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5725 Ebl *ebl, GElf_Ehdr *ehdr,
5726 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5727 {
5728 Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_addr, scn);
5729 if (data == NULL)
5730 return;
5731
5732 printf (_("\
5733 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5734 elf_ndxscn (scn), section_name (ebl, shdr),
5735 (uint64_t) shdr->sh_offset);
5736
5737 if (shdr->sh_size == 0)
5738 return;
5739
5740 size_t idx = 0;
5741 sort_listptr (&known_addrbases, "addr_base");
5742
5743 const unsigned char *start = (const unsigned char *) data->d_buf;
5744 const unsigned char *readp = start;
5745 const unsigned char *readendp = ((const unsigned char *) data->d_buf
5746 + data->d_size);
5747
5748 while (readp < readendp)
5749 {
5750 /* We cannot really know whether or not there is an header. The
5751 DebugFission extension to DWARF4 doesn't add one. The DWARF5
5752 .debug_addr variant does. Whether or not we have an header,
5753 DW_AT_[GNU_]addr_base points at "index 0". So if the current
5754 offset equals the CU addr_base then we can just start
5755 printing addresses. If there is no CU with an exact match
5756 then we'll try to parse the header first. */
5757 Dwarf_Off off = (Dwarf_Off) (readp
5758 - (const unsigned char *) data->d_buf);
5759
5760 printf ("Table at offset %" PRIx64 " ", off);
5761
5762 struct listptr *listptr = get_listptr (&known_addrbases, idx++);
5763 const unsigned char *next_unitp;
5764
5765 uint64_t unit_length;
5766 uint16_t version;
5767 uint8_t address_size;
5768 uint8_t segment_size;
5769 if (listptr == NULL)
5770 {
5771 error (0, 0, "Warning: No CU references .debug_addr after %" PRIx64,
5772 off);
5773
5774 /* We will have to assume it is just addresses to the end... */
5775 address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5776 next_unitp = readendp;
5777 printf ("Unknown CU:\n");
5778 }
5779 else
5780 {
5781 Dwarf_Die cudie;
5782 if (dwarf_cu_die (listptr->cu, &cudie,
5783 NULL, NULL, NULL, NULL,
5784 NULL, NULL) == NULL)
5785 printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
5786 else
5787 printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
5788
5789 if (listptr->offset == off)
5790 {
5791 address_size = listptr_address_size (listptr);
5792 segment_size = 0;
5793 version = 4;
5794
5795 /* The addresses start here, but where do they end? */
5796 listptr = get_listptr (&known_addrbases, idx);
5797 if (listptr == NULL)
5798 next_unitp = readendp;
5799 else if (listptr->cu->version < 5)
5800 {
5801 next_unitp = start + listptr->offset;
5802 if (listptr->offset < off || listptr->offset > data->d_size)
5803 {
5804 error (0, 0,
5805 "Warning: Bad address base for next unit at %"
5806 PRIx64, off);
5807 next_unitp = readendp;
5808 }
5809 }
5810 else
5811 {
5812 /* Tricky, we don't have a header for this unit, but
5813 there is one for the next. We will have to
5814 "guess" how big it is and subtract it from the
5815 offset (because that points after the header). */
5816 unsigned int offset_size = listptr_offset_size (listptr);
5817 Dwarf_Off next_off = (listptr->offset
5818 - (offset_size == 4 ? 4 : 12) /* len */
5819 - 2 /* version */
5820 - 1 /* address size */
5821 - 1); /* segment selector size */
5822 next_unitp = start + next_off;
5823 if (next_off < off || next_off > data->d_size)
5824 {
5825 error (0, 0,
5826 "Warning: Couldn't calculate .debug_addr "
5827 " unit length at %" PRIx64, off);
5828 next_unitp = readendp;
5829 }
5830 }
5831 unit_length = (uint64_t) (next_unitp - readp);
5832
5833 /* Pretend we have a header. */
5834 printf ("\n");
5835 printf (_(" Length: %8" PRIu64 "\n"),
5836 unit_length);
5837 printf (_(" DWARF version: %8" PRIu16 "\n"), version);
5838 printf (_(" Address size: %8" PRIu64 "\n"),
5839 (uint64_t) address_size);
5840 printf (_(" Segment size: %8" PRIu64 "\n"),
5841 (uint64_t) segment_size);
5842 printf ("\n");
5843 }
5844 else
5845 {
5846 /* OK, we have to parse an header first. */
5847 unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5848 if (unlikely (unit_length == 0xffffffff))
5849 {
5850 if (unlikely (readp > readendp - 8))
5851 {
5852 invalid_data:
5853 error (0, 0, "Invalid data");
5854 return;
5855 }
5856 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5857 }
5858 printf ("\n");
5859 printf (_(" Length: %8" PRIu64 "\n"),
5860 unit_length);
5861
5862 /* We need at least 2-bytes (version) + 1-byte
5863 (addr_size) + 1-byte (segment_size) = 4 bytes to
5864 complete the header. And this unit cannot go beyond
5865 the section data. */
5866 if (readp > readendp - 4
5867 || unit_length < 4
5868 || unit_length > (uint64_t) (readendp - readp))
5869 goto invalid_data;
5870
5871 next_unitp = readp + unit_length;
5872
5873 version = read_2ubyte_unaligned_inc (dbg, readp);
5874 printf (_(" DWARF version: %8" PRIu16 "\n"), version);
5875
5876 if (version != 5)
5877 {
5878 error (0, 0, _("Unknown version"));
5879 goto next_unit;
5880 }
5881
5882 address_size = *readp++;
5883 printf (_(" Address size: %8" PRIu64 "\n"),
5884 (uint64_t) address_size);
5885
5886 if (address_size != 4 && address_size != 8)
5887 {
5888 error (0, 0, _("unsupported address size"));
5889 goto next_unit;
5890 }
5891
5892 segment_size = *readp++;
5893 printf (_(" Segment size: %8" PRIu64 "\n"),
5894 (uint64_t) segment_size);
5895 printf ("\n");
5896
5897 if (segment_size != 0)
5898 {
5899 error (0, 0, _("unsupported segment size"));
5900 goto next_unit;
5901 }
5902
5903 if (listptr->offset != (Dwarf_Off) (readp - start))
5904 {
5905 error (0, 0, "Address index doesn't start after header");
5906 goto next_unit;
5907 }
5908 }
5909 }
5910
5911 int digits = 1;
5912 size_t addresses = (next_unitp - readp) / address_size;
5913 while (addresses >= 10)
5914 {
5915 ++digits;
5916 addresses /= 10;
5917 }
5918
5919 unsigned int uidx = 0;
5920 size_t index_offset = readp - (const unsigned char *) data->d_buf;
5921 printf (" Addresses start at offset 0x%zx:\n", index_offset);
5922 while (readp <= next_unitp - address_size)
5923 {
5924 Dwarf_Addr addr = read_addr_unaligned_inc (address_size, dbg,
5925 readp);
5926 printf (" [%*u] ", digits, uidx++);
5927 print_dwarf_addr (dwflmod, address_size, addr, addr);
5928 printf ("\n");
5929 }
5930 printf ("\n");
5931
5932 if (readp != next_unitp)
5933 error (0, 0, "extra %zd bytes at end of unit",
5934 (size_t) (next_unitp - readp));
5935
5936 next_unit:
5937 readp = next_unitp;
5938 }
5939 }
5940
5941 /* Print content of DWARF .debug_aranges section. We fortunately do
5942 not have to know a bit about the structure of the section, libdwarf
5943 takes care of it. */
5944 static void
print_decoded_aranges_section(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5945 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5946 GElf_Shdr *shdr, Dwarf *dbg)
5947 {
5948 Dwarf_Aranges *aranges;
5949 size_t cnt;
5950 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
5951 {
5952 error (0, 0, _("cannot get .debug_aranges content: %s"),
5953 dwarf_errmsg (-1));
5954 return;
5955 }
5956
5957 GElf_Shdr glink_mem;
5958 GElf_Shdr *glink;
5959 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
5960 if (glink == NULL)
5961 {
5962 error (0, 0, _("invalid sh_link value in section %zu"),
5963 elf_ndxscn (scn));
5964 return;
5965 }
5966
5967 printf (ngettext ("\
5968 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
5969 "\
5970 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
5971 cnt),
5972 elf_ndxscn (scn), section_name (ebl, shdr),
5973 (uint64_t) shdr->sh_offset, cnt);
5974
5975 /* Compute floor(log16(cnt)). */
5976 size_t tmp = cnt;
5977 int digits = 1;
5978 while (tmp >= 16)
5979 {
5980 ++digits;
5981 tmp >>= 4;
5982 }
5983
5984 for (size_t n = 0; n < cnt; ++n)
5985 {
5986 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
5987 if (unlikely (runp == NULL))
5988 {
5989 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
5990 return;
5991 }
5992
5993 Dwarf_Addr start;
5994 Dwarf_Word length;
5995 Dwarf_Off offset;
5996
5997 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
5998 printf (_(" [%*zu] ???\n"), digits, n);
5999 else
6000 printf (_(" [%*zu] start: %0#*" PRIx64
6001 ", length: %5" PRIu64 ", CU DIE offset: %6"
6002 PRId64 "\n"),
6003 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
6004 (uint64_t) start, (uint64_t) length, (int64_t) offset);
6005 }
6006 }
6007
6008
6009 /* Print content of DWARF .debug_aranges section. */
6010 static void
print_debug_aranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6011 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
6012 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
6013 GElf_Shdr *shdr, Dwarf *dbg)
6014 {
6015 if (decodedaranges)
6016 {
6017 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
6018 return;
6019 }
6020
6021 Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_aranges, scn);
6022 if (data == NULL)
6023 return;
6024
6025 printf (_("\
6026 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6027 elf_ndxscn (scn), section_name (ebl, shdr),
6028 (uint64_t) shdr->sh_offset);
6029
6030 const unsigned char *readp = data->d_buf;
6031 const unsigned char *readendp = readp + data->d_size;
6032
6033 while (readp < readendp)
6034 {
6035 const unsigned char *hdrstart = readp;
6036 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
6037
6038 printf (_("\nTable at offset %zu:\n"), start_offset);
6039 if (readp + 4 > readendp)
6040 {
6041 invalid_data:
6042 error (0, 0, _("invalid data in section [%zu] '%s'"),
6043 elf_ndxscn (scn), section_name (ebl, shdr));
6044 return;
6045 }
6046
6047 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
6048 unsigned int length_bytes = 4;
6049 if (length == DWARF3_LENGTH_64_BIT)
6050 {
6051 if (readp + 8 > readendp)
6052 goto invalid_data;
6053 length = read_8ubyte_unaligned_inc (dbg, readp);
6054 length_bytes = 8;
6055 }
6056
6057 const unsigned char *nexthdr = readp + length;
6058 printf (_("\n Length: %6" PRIu64 "\n"),
6059 (uint64_t) length);
6060
6061 if (unlikely (length > (size_t) (readendp - readp)))
6062 goto invalid_data;
6063
6064 if (length == 0)
6065 continue;
6066
6067 if (readp + 2 > readendp)
6068 goto invalid_data;
6069 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
6070 printf (_(" DWARF version: %6" PRIuFAST16 "\n"),
6071 version);
6072 if (version != 2)
6073 {
6074 error (0, 0, _("unsupported aranges version"));
6075 goto next_table;
6076 }
6077
6078 Dwarf_Word offset;
6079 if (readp + length_bytes > readendp)
6080 goto invalid_data;
6081 if (length_bytes == 8)
6082 offset = read_8ubyte_unaligned_inc (dbg, readp);
6083 else
6084 offset = read_4ubyte_unaligned_inc (dbg, readp);
6085 printf (_(" CU offset: %6" PRIx64 "\n"),
6086 (uint64_t) offset);
6087
6088 if (readp + 1 > readendp)
6089 goto invalid_data;
6090 unsigned int address_size = *readp++;
6091 printf (_(" Address size: %6" PRIu64 "\n"),
6092 (uint64_t) address_size);
6093 if (address_size != 4 && address_size != 8)
6094 {
6095 error (0, 0, _("unsupported address size"));
6096 goto next_table;
6097 }
6098
6099 if (readp + 1 > readendp)
6100 goto invalid_data;
6101 unsigned int segment_size = *readp++;
6102 printf (_(" Segment size: %6" PRIu64 "\n\n"),
6103 (uint64_t) segment_size);
6104 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
6105 {
6106 error (0, 0, _("unsupported segment size"));
6107 goto next_table;
6108 }
6109
6110 /* Round the address to the next multiple of 2*address_size. */
6111 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
6112 % (2 * address_size));
6113
6114 while (readp < nexthdr)
6115 {
6116 Dwarf_Word range_address;
6117 Dwarf_Word range_length;
6118 Dwarf_Word segment = 0;
6119 if (readp + 2 * address_size + segment_size > readendp)
6120 goto invalid_data;
6121 if (address_size == 4)
6122 {
6123 range_address = read_4ubyte_unaligned_inc (dbg, readp);
6124 range_length = read_4ubyte_unaligned_inc (dbg, readp);
6125 }
6126 else
6127 {
6128 range_address = read_8ubyte_unaligned_inc (dbg, readp);
6129 range_length = read_8ubyte_unaligned_inc (dbg, readp);
6130 }
6131
6132 if (segment_size == 4)
6133 segment = read_4ubyte_unaligned_inc (dbg, readp);
6134 else if (segment_size == 8)
6135 segment = read_8ubyte_unaligned_inc (dbg, readp);
6136
6137 if (range_address == 0 && range_length == 0 && segment == 0)
6138 break;
6139
6140 printf (" ");
6141 print_dwarf_addr (dwflmod, address_size, range_address,
6142 range_address);
6143 printf ("..");
6144 print_dwarf_addr (dwflmod, address_size,
6145 range_address + range_length - 1,
6146 range_length);
6147 if (segment_size != 0)
6148 printf (" (%" PRIx64 ")\n", (uint64_t) segment);
6149 else
6150 printf ("\n");
6151 }
6152
6153 next_table:
6154 if (readp != nexthdr)
6155 {
6156 size_t padding = nexthdr - readp;
6157 printf (_(" %zu padding bytes\n"), padding);
6158 readp = nexthdr;
6159 }
6160 }
6161 }
6162
6163
6164 static bool is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu);
6165
6166 /* Returns true and sets cu and cu_base if the given Dwarf is a split
6167 DWARF (.dwo) file. */
6168 static bool
split_dwarf_cu_base(Dwarf * dbg,Dwarf_CU ** cu,Dwarf_Addr * cu_base)6169 split_dwarf_cu_base (Dwarf *dbg, Dwarf_CU **cu, Dwarf_Addr *cu_base)
6170 {
6171 uint64_t id;
6172 if (is_split_dwarf (dbg, &id, cu))
6173 {
6174 Dwarf_Die cudie;
6175 if (dwarf_cu_info (*cu, NULL, NULL, &cudie, NULL, NULL, NULL, NULL) == 0)
6176 {
6177 *cu_base = cudie_base (&cudie);
6178 return true;
6179 }
6180 }
6181 return false;
6182 }
6183
6184 /* Print content of DWARF .debug_rnglists section. */
6185 static void
print_debug_rnglists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6186 print_debug_rnglists_section (Dwfl_Module *dwflmod,
6187 Ebl *ebl,
6188 GElf_Ehdr *ehdr __attribute__ ((unused)),
6189 Elf_Scn *scn, GElf_Shdr *shdr,
6190 Dwarf *dbg __attribute__((unused)))
6191 {
6192 Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_rnglists, scn);
6193 if (data == NULL)
6194 return;
6195
6196 printf (_("\
6197 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6198 elf_ndxscn (scn), section_name (ebl, shdr),
6199 (uint64_t) shdr->sh_offset);
6200
6201 /* For the listptr to get the base address/CU. */
6202 sort_listptr (&known_rnglistptr, "rnglistptr");
6203 size_t listptr_idx = 0;
6204
6205 const unsigned char *readp = data->d_buf;
6206 const unsigned char *const dataend = ((unsigned char *) data->d_buf
6207 + data->d_size);
6208 while (readp < dataend)
6209 {
6210 if (unlikely (readp > dataend - 4))
6211 {
6212 invalid_data:
6213 error (0, 0, _("invalid data in section [%zu] '%s'"),
6214 elf_ndxscn (scn), section_name (ebl, shdr));
6215 return;
6216 }
6217
6218 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6219 printf (_("Table at Offset 0x%" PRIx64 ":\n\n"),
6220 (uint64_t) offset);
6221
6222 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
6223 unsigned int offset_size = 4;
6224 if (unlikely (unit_length == 0xffffffff))
6225 {
6226 if (unlikely (readp > dataend - 8))
6227 goto invalid_data;
6228
6229 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
6230 offset_size = 8;
6231 }
6232 printf (_(" Length: %8" PRIu64 "\n"), unit_length);
6233
6234 /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
6235 bytes to complete the header. And this unit cannot go beyond
6236 the section data. */
6237 if (readp > dataend - 8
6238 || unit_length < 8
6239 || unit_length > (uint64_t) (dataend - readp))
6240 goto invalid_data;
6241
6242 const unsigned char *nexthdr = readp + unit_length;
6243
6244 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
6245 printf (_(" DWARF version: %8" PRIu16 "\n"), version);
6246
6247 if (version != 5)
6248 {
6249 error (0, 0, _("Unknown version"));
6250 goto next_table;
6251 }
6252
6253 uint8_t address_size = *readp++;
6254 printf (_(" Address size: %8" PRIu64 "\n"),
6255 (uint64_t) address_size);
6256
6257 if (address_size != 4 && address_size != 8)
6258 {
6259 error (0, 0, _("unsupported address size"));
6260 goto next_table;
6261 }
6262
6263 uint8_t segment_size = *readp++;
6264 printf (_(" Segment size: %8" PRIu64 "\n"),
6265 (uint64_t) segment_size);
6266
6267 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
6268 {
6269 error (0, 0, _("unsupported segment size"));
6270 goto next_table;
6271 }
6272
6273 uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
6274 printf (_(" Offset entries: %8" PRIu64 "\n"),
6275 (uint64_t) offset_entry_count);
6276
6277 /* We need the CU that uses this unit to get the initial base address. */
6278 Dwarf_Addr cu_base = 0;
6279 struct Dwarf_CU *cu = NULL;
6280 if (listptr_cu (&known_rnglistptr, &listptr_idx,
6281 (Dwarf_Off) offset,
6282 (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
6283 &cu_base, &cu)
6284 || split_dwarf_cu_base (dbg, &cu, &cu_base))
6285 {
6286 Dwarf_Die cudie;
6287 if (dwarf_cu_die (cu, &cudie,
6288 NULL, NULL, NULL, NULL,
6289 NULL, NULL) == NULL)
6290 printf (_(" Unknown CU base: "));
6291 else
6292 printf (_(" CU [%6" PRIx64 "] base: "),
6293 dwarf_dieoffset (&cudie));
6294 print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
6295 printf ("\n");
6296 }
6297 else
6298 printf (_(" Not associated with a CU.\n"));
6299
6300 printf ("\n");
6301
6302 const unsigned char *offset_array_start = readp;
6303 if (offset_entry_count > 0)
6304 {
6305 uint64_t max_entries = (unit_length - 8) / offset_size;
6306 if (offset_entry_count > max_entries)
6307 {
6308 error (0, 0,
6309 _("too many offset entries for unit length"));
6310 offset_entry_count = max_entries;
6311 }
6312
6313 printf (_(" Offsets starting at 0x%" PRIx64 ":\n"),
6314 (uint64_t) (offset_array_start
6315 - (unsigned char *) data->d_buf));
6316 for (uint32_t idx = 0; idx < offset_entry_count; idx++)
6317 {
6318 printf (" [%6" PRIu32 "] ", idx);
6319 if (offset_size == 4)
6320 {
6321 uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
6322 printf ("0x%" PRIx32 "\n", off);
6323 }
6324 else
6325 {
6326 uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
6327 printf ("0x%" PRIx64 "\n", off);
6328 }
6329 }
6330 printf ("\n");
6331 }
6332
6333 Dwarf_Addr base = cu_base;
6334 bool start_of_list = true;
6335 while (readp < nexthdr)
6336 {
6337 uint8_t kind = *readp++;
6338 uint64_t op1, op2;
6339
6340 /* Skip padding. */
6341 if (start_of_list && kind == DW_RLE_end_of_list)
6342 continue;
6343
6344 if (start_of_list)
6345 {
6346 base = cu_base;
6347 printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
6348 (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
6349 (uint64_t) (readp - offset_array_start - 1));
6350 start_of_list = false;
6351 }
6352
6353 printf (" %s", dwarf_range_list_encoding_name (kind));
6354 switch (kind)
6355 {
6356 case DW_RLE_end_of_list:
6357 start_of_list = true;
6358 printf ("\n\n");
6359 break;
6360
6361 case DW_RLE_base_addressx:
6362 if ((uint64_t) (nexthdr - readp) < 1)
6363 {
6364 invalid_range:
6365 error (0, 0, _("invalid range list data"));
6366 goto next_table;
6367 }
6368 get_uleb128 (op1, readp, nexthdr);
6369 printf (" %" PRIx64 "\n", op1);
6370 if (! print_unresolved_addresses)
6371 {
6372 Dwarf_Addr addr;
6373 if (get_indexed_addr (cu, op1, &addr) != 0)
6374 printf (" ???\n");
6375 else
6376 {
6377 printf (" ");
6378 print_dwarf_addr (dwflmod, address_size, addr, addr);
6379 printf ("\n");
6380 }
6381 }
6382 break;
6383
6384 case DW_RLE_startx_endx:
6385 if ((uint64_t) (nexthdr - readp) < 1)
6386 goto invalid_range;
6387 get_uleb128 (op1, readp, nexthdr);
6388 if ((uint64_t) (nexthdr - readp) < 1)
6389 goto invalid_range;
6390 get_uleb128 (op2, readp, nexthdr);
6391 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
6392 if (! print_unresolved_addresses)
6393 {
6394 Dwarf_Addr addr1;
6395 Dwarf_Addr addr2;
6396 if (get_indexed_addr (cu, op1, &addr1) != 0
6397 || get_indexed_addr (cu, op2, &addr2) != 0)
6398 {
6399 printf (" ???..\n");
6400 printf (" ???\n");
6401 }
6402 else
6403 {
6404 printf (" ");
6405 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
6406 printf ("..\n ");
6407 print_dwarf_addr (dwflmod, address_size,
6408 addr2 - 1, addr2);
6409 printf ("\n");
6410 }
6411 }
6412 break;
6413
6414 case DW_RLE_startx_length:
6415 if ((uint64_t) (nexthdr - readp) < 1)
6416 goto invalid_range;
6417 get_uleb128 (op1, readp, nexthdr);
6418 if ((uint64_t) (nexthdr - readp) < 1)
6419 goto invalid_range;
6420 get_uleb128 (op2, readp, nexthdr);
6421 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
6422 if (! print_unresolved_addresses)
6423 {
6424 Dwarf_Addr addr1;
6425 Dwarf_Addr addr2;
6426 if (get_indexed_addr (cu, op1, &addr1) != 0)
6427 {
6428 printf (" ???..\n");
6429 printf (" ???\n");
6430 }
6431 else
6432 {
6433 addr2 = addr1 + op2;
6434 printf (" ");
6435 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
6436 printf ("..\n ");
6437 print_dwarf_addr (dwflmod, address_size,
6438 addr2 - 1, addr2);
6439 printf ("\n");
6440 }
6441 }
6442 break;
6443
6444 case DW_RLE_offset_pair:
6445 if ((uint64_t) (nexthdr - readp) < 1)
6446 goto invalid_range;
6447 get_uleb128 (op1, readp, nexthdr);
6448 if ((uint64_t) (nexthdr - readp) < 1)
6449 goto invalid_range;
6450 get_uleb128 (op2, readp, nexthdr);
6451 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
6452 if (! print_unresolved_addresses)
6453 {
6454 op1 += base;
6455 op2 += base;
6456 printf (" ");
6457 print_dwarf_addr (dwflmod, address_size, op1, op1);
6458 printf ("..\n ");
6459 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
6460 printf ("\n");
6461 }
6462 break;
6463
6464 case DW_RLE_base_address:
6465 if (address_size == 4)
6466 {
6467 if ((uint64_t) (nexthdr - readp) < 4)
6468 goto invalid_range;
6469 op1 = read_4ubyte_unaligned_inc (dbg, readp);
6470 }
6471 else
6472 {
6473 if ((uint64_t) (nexthdr - readp) < 8)
6474 goto invalid_range;
6475 op1 = read_8ubyte_unaligned_inc (dbg, readp);
6476 }
6477 base = op1;
6478 printf (" 0x%" PRIx64 "\n", base);
6479 if (! print_unresolved_addresses)
6480 {
6481 printf (" ");
6482 print_dwarf_addr (dwflmod, address_size, base, base);
6483 printf ("\n");
6484 }
6485 break;
6486
6487 case DW_RLE_start_end:
6488 if (address_size == 4)
6489 {
6490 if ((uint64_t) (nexthdr - readp) < 8)
6491 goto invalid_range;
6492 op1 = read_4ubyte_unaligned_inc (dbg, readp);
6493 op2 = read_4ubyte_unaligned_inc (dbg, readp);
6494 }
6495 else
6496 {
6497 if ((uint64_t) (nexthdr - readp) < 16)
6498 goto invalid_range;
6499 op1 = read_8ubyte_unaligned_inc (dbg, readp);
6500 op2 = read_8ubyte_unaligned_inc (dbg, readp);
6501 }
6502 printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
6503 if (! print_unresolved_addresses)
6504 {
6505 printf (" ");
6506 print_dwarf_addr (dwflmod, address_size, op1, op1);
6507 printf ("..\n ");
6508 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
6509 printf ("\n");
6510 }
6511 break;
6512
6513 case DW_RLE_start_length:
6514 if (address_size == 4)
6515 {
6516 if ((uint64_t) (nexthdr - readp) < 4)
6517 goto invalid_range;
6518 op1 = read_4ubyte_unaligned_inc (dbg, readp);
6519 }
6520 else
6521 {
6522 if ((uint64_t) (nexthdr - readp) < 8)
6523 goto invalid_range;
6524 op1 = read_8ubyte_unaligned_inc (dbg, readp);
6525 }
6526 if ((uint64_t) (nexthdr - readp) < 1)
6527 goto invalid_range;
6528 get_uleb128 (op2, readp, nexthdr);
6529 printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
6530 if (! print_unresolved_addresses)
6531 {
6532 op2 = op1 + op2;
6533 printf (" ");
6534 print_dwarf_addr (dwflmod, address_size, op1, op1);
6535 printf ("..\n ");
6536 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
6537 printf ("\n");
6538 }
6539 break;
6540
6541 default:
6542 goto invalid_range;
6543 }
6544 }
6545
6546 next_table:
6547 if (readp != nexthdr)
6548 {
6549 size_t padding = nexthdr - readp;
6550 printf (_(" %zu padding bytes\n\n"), padding);
6551 readp = nexthdr;
6552 }
6553 }
6554 }
6555
6556 /* Print content of DWARF .debug_ranges section. */
6557 static void
print_debug_ranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6558 print_debug_ranges_section (Dwfl_Module *dwflmod,
6559 Ebl *ebl, GElf_Ehdr *ehdr,
6560 Elf_Scn *scn, GElf_Shdr *shdr,
6561 Dwarf *dbg)
6562 {
6563 Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_ranges, scn);
6564 if (data == NULL)
6565 return;
6566
6567 printf (_("\
6568 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6569 elf_ndxscn (scn), section_name (ebl, shdr),
6570 (uint64_t) shdr->sh_offset);
6571
6572 sort_listptr (&known_rangelistptr, "rangelistptr");
6573 size_t listptr_idx = 0;
6574
6575 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6576
6577 bool first = true;
6578 Dwarf_Addr base = 0;
6579 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
6580 unsigned char *readp = data->d_buf;
6581 Dwarf_CU *last_cu = NULL;
6582 while (readp < endp)
6583 {
6584 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6585 Dwarf_CU *cu = last_cu;
6586
6587 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
6588 &address_size, NULL, &base, &cu,
6589 offset, &readp, endp, NULL))
6590 continue;
6591
6592 if (last_cu != cu)
6593 {
6594 Dwarf_Die cudie;
6595 if (dwarf_cu_die (cu, &cudie,
6596 NULL, NULL, NULL, NULL,
6597 NULL, NULL) == NULL)
6598 printf (_("\n Unknown CU base: "));
6599 else
6600 printf (_("\n CU [%6" PRIx64 "] base: "),
6601 dwarf_dieoffset (&cudie));
6602 print_dwarf_addr (dwflmod, address_size, base, base);
6603 printf ("\n");
6604 }
6605 last_cu = cu;
6606
6607 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
6608 {
6609 printf (_(" [%6tx] <INVALID DATA>\n"), offset);
6610 break;
6611 }
6612
6613 Dwarf_Addr begin;
6614 Dwarf_Addr end;
6615 if (address_size == 8)
6616 {
6617 begin = read_8ubyte_unaligned_inc (dbg, readp);
6618 end = read_8ubyte_unaligned_inc (dbg, readp);
6619 }
6620 else
6621 {
6622 begin = read_4ubyte_unaligned_inc (dbg, readp);
6623 end = read_4ubyte_unaligned_inc (dbg, readp);
6624 if (begin == (Dwarf_Addr) (uint32_t) -1)
6625 begin = (Dwarf_Addr) -1l;
6626 }
6627
6628 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
6629 {
6630 if (first)
6631 printf (" [%6tx] ", offset);
6632 else
6633 printf (" ");
6634 puts (_("base address"));
6635 printf (" ");
6636 print_dwarf_addr (dwflmod, address_size, end, end);
6637 printf ("\n");
6638 base = end;
6639 first = false;
6640 }
6641 else if (begin == 0 && end == 0) /* End of list entry. */
6642 {
6643 if (first)
6644 printf (_(" [%6tx] empty list\n"), offset);
6645 first = true;
6646 }
6647 else
6648 {
6649 /* We have an address range entry. */
6650 if (first) /* First address range entry in a list. */
6651 printf (" [%6tx] ", offset);
6652 else
6653 printf (" ");
6654
6655 printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
6656 if (! print_unresolved_addresses)
6657 {
6658 printf (" ");
6659 print_dwarf_addr (dwflmod, address_size, base + begin,
6660 base + begin);
6661 printf ("..\n ");
6662 print_dwarf_addr (dwflmod, address_size,
6663 base + end - 1, base + end);
6664 printf ("\n");
6665 }
6666
6667 first = false;
6668 }
6669 }
6670 }
6671
6672 #define REGNAMESZ 16
6673 static const char *
register_info(Ebl * ebl,unsigned int regno,const Ebl_Register_Location * loc,char name[REGNAMESZ],int * bits,int * type)6674 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
6675 char name[REGNAMESZ], int *bits, int *type)
6676 {
6677 const char *set;
6678 const char *pfx;
6679 int ignore;
6680 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
6681 bits ?: &ignore, type ?: &ignore);
6682 if (n <= 0)
6683 {
6684 if (loc != NULL)
6685 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
6686 else
6687 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
6688 if (bits != NULL)
6689 *bits = loc != NULL ? loc->bits : 0;
6690 if (type != NULL)
6691 *type = DW_ATE_unsigned;
6692 set = "??? unrecognized";
6693 }
6694 else
6695 {
6696 if (bits != NULL && *bits <= 0)
6697 *bits = loc != NULL ? loc->bits : 0;
6698 if (type != NULL && *type == DW_ATE_void)
6699 *type = DW_ATE_unsigned;
6700
6701 }
6702 return set;
6703 }
6704
6705 static const unsigned char *
read_encoded(unsigned int encoding,const unsigned char * readp,const unsigned char * const endp,uint64_t * res,Dwarf * dbg)6706 read_encoded (unsigned int encoding, const unsigned char *readp,
6707 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
6708 {
6709 if ((encoding & 0xf) == DW_EH_PE_absptr)
6710 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
6711 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
6712
6713 switch (encoding & 0xf)
6714 {
6715 case DW_EH_PE_uleb128:
6716 if (readp >= endp)
6717 goto invalid;
6718 get_uleb128 (*res, readp, endp);
6719 break;
6720 case DW_EH_PE_sleb128:
6721 if (readp >= endp)
6722 goto invalid;
6723 get_sleb128 (*res, readp, endp);
6724 break;
6725 case DW_EH_PE_udata2:
6726 if (readp + 2 > endp)
6727 goto invalid;
6728 *res = read_2ubyte_unaligned_inc (dbg, readp);
6729 break;
6730 case DW_EH_PE_udata4:
6731 if (readp + 4 > endp)
6732 goto invalid;
6733 *res = read_4ubyte_unaligned_inc (dbg, readp);
6734 break;
6735 case DW_EH_PE_udata8:
6736 if (readp + 8 > endp)
6737 goto invalid;
6738 *res = read_8ubyte_unaligned_inc (dbg, readp);
6739 break;
6740 case DW_EH_PE_sdata2:
6741 if (readp + 2 > endp)
6742 goto invalid;
6743 *res = read_2sbyte_unaligned_inc (dbg, readp);
6744 break;
6745 case DW_EH_PE_sdata4:
6746 if (readp + 4 > endp)
6747 goto invalid;
6748 *res = read_4sbyte_unaligned_inc (dbg, readp);
6749 break;
6750 case DW_EH_PE_sdata8:
6751 if (readp + 8 > endp)
6752 goto invalid;
6753 *res = read_8sbyte_unaligned_inc (dbg, readp);
6754 break;
6755 default:
6756 invalid:
6757 error (1, 0,
6758 _("invalid encoding"));
6759 }
6760
6761 return readp;
6762 }
6763
6764 static const char *
regname(Ebl * ebl,unsigned int regno,char * regnamebuf)6765 regname (Ebl *ebl, unsigned int regno, char *regnamebuf)
6766 {
6767 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
6768
6769 return regnamebuf;
6770 }
6771
6772 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)6773 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
6774 Dwarf_Word vma_base, unsigned int code_align,
6775 int data_align,
6776 unsigned int version, unsigned int ptr_size,
6777 unsigned int encoding,
6778 Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, Dwarf *dbg)
6779 {
6780 char regnamebuf[REGNAMESZ];
6781
6782 puts ("\n Program:");
6783 Dwarf_Word pc = vma_base;
6784 while (readp < endp)
6785 {
6786 unsigned int opcode = *readp++;
6787
6788 if (opcode < DW_CFA_advance_loc)
6789 /* Extended opcode. */
6790 switch (opcode)
6791 {
6792 uint64_t op1;
6793 int64_t sop1;
6794 uint64_t op2;
6795 int64_t sop2;
6796
6797 case DW_CFA_nop:
6798 puts (" nop");
6799 break;
6800 case DW_CFA_set_loc:
6801 if ((uint64_t) (endp - readp) < 1)
6802 goto invalid;
6803 readp = read_encoded (encoding, readp, endp, &op1, dbg);
6804 printf (" set_loc %#" PRIx64 " to %#" PRIx64 "\n",
6805 op1, pc = vma_base + op1);
6806 break;
6807 case DW_CFA_advance_loc1:
6808 if ((uint64_t) (endp - readp) < 1)
6809 goto invalid;
6810 printf (" advance_loc1 %u to %#" PRIx64 "\n",
6811 *readp, pc += *readp * code_align);
6812 ++readp;
6813 break;
6814 case DW_CFA_advance_loc2:
6815 if ((uint64_t) (endp - readp) < 2)
6816 goto invalid;
6817 op1 = read_2ubyte_unaligned_inc (dbg, readp);
6818 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
6819 op1, pc += op1 * code_align);
6820 break;
6821 case DW_CFA_advance_loc4:
6822 if ((uint64_t) (endp - readp) < 4)
6823 goto invalid;
6824 op1 = read_4ubyte_unaligned_inc (dbg, readp);
6825 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
6826 op1, pc += op1 * code_align);
6827 break;
6828 case DW_CFA_offset_extended:
6829 if ((uint64_t) (endp - readp) < 1)
6830 goto invalid;
6831 get_uleb128 (op1, readp, endp);
6832 if ((uint64_t) (endp - readp) < 1)
6833 goto invalid;
6834 get_uleb128 (op2, readp, endp);
6835 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
6836 "\n",
6837 op1, regname (ebl, op1, regnamebuf), op2 * data_align);
6838 break;
6839 case DW_CFA_restore_extended:
6840 if ((uint64_t) (endp - readp) < 1)
6841 goto invalid;
6842 get_uleb128 (op1, readp, endp);
6843 printf (" restore_extended r%" PRIu64 " (%s)\n",
6844 op1, regname (ebl, op1, regnamebuf));
6845 break;
6846 case DW_CFA_undefined:
6847 if ((uint64_t) (endp - readp) < 1)
6848 goto invalid;
6849 get_uleb128 (op1, readp, endp);
6850 printf (" undefined r%" PRIu64 " (%s)\n", op1,
6851 regname (ebl, op1, regnamebuf));
6852 break;
6853 case DW_CFA_same_value:
6854 if ((uint64_t) (endp - readp) < 1)
6855 goto invalid;
6856 get_uleb128 (op1, readp, endp);
6857 printf (" same_value r%" PRIu64 " (%s)\n", op1,
6858 regname (ebl, op1, regnamebuf));
6859 break;
6860 case DW_CFA_register:
6861 if ((uint64_t) (endp - readp) < 1)
6862 goto invalid;
6863 get_uleb128 (op1, readp, endp);
6864 if ((uint64_t) (endp - readp) < 1)
6865 goto invalid;
6866 get_uleb128 (op2, readp, endp);
6867 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
6868 op1, regname (ebl, op1, regnamebuf), op2,
6869 regname (ebl, op2, regnamebuf));
6870 break;
6871 case DW_CFA_remember_state:
6872 puts (" remember_state");
6873 break;
6874 case DW_CFA_restore_state:
6875 puts (" restore_state");
6876 break;
6877 case DW_CFA_def_cfa:
6878 if ((uint64_t) (endp - readp) < 1)
6879 goto invalid;
6880 get_uleb128 (op1, readp, endp);
6881 if ((uint64_t) (endp - readp) < 1)
6882 goto invalid;
6883 get_uleb128 (op2, readp, endp);
6884 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
6885 op1, regname (ebl, op1, regnamebuf), op2);
6886 break;
6887 case DW_CFA_def_cfa_register:
6888 if ((uint64_t) (endp - readp) < 1)
6889 goto invalid;
6890 get_uleb128 (op1, readp, endp);
6891 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
6892 op1, regname (ebl, op1, regnamebuf));
6893 break;
6894 case DW_CFA_def_cfa_offset:
6895 if ((uint64_t) (endp - readp) < 1)
6896 goto invalid;
6897 get_uleb128 (op1, readp, endp);
6898 printf (" def_cfa_offset %" PRIu64 "\n", op1);
6899 break;
6900 case DW_CFA_def_cfa_expression:
6901 if ((uint64_t) (endp - readp) < 1)
6902 goto invalid;
6903 get_uleb128 (op1, readp, endp); /* Length of DW_FORM_block. */
6904 printf (" def_cfa_expression %" PRIu64 "\n", op1);
6905 if ((uint64_t) (endp - readp) < op1)
6906 {
6907 invalid:
6908 fputs (_(" <INVALID DATA>\n"), stdout);
6909 return;
6910 }
6911 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6912 op1, readp);
6913 readp += op1;
6914 break;
6915 case DW_CFA_expression:
6916 if ((uint64_t) (endp - readp) < 1)
6917 goto invalid;
6918 get_uleb128 (op1, readp, endp);
6919 if ((uint64_t) (endp - readp) < 1)
6920 goto invalid;
6921 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
6922 printf (" expression r%" PRIu64 " (%s) \n",
6923 op1, regname (ebl, op1, regnamebuf));
6924 if ((uint64_t) (endp - readp) < op2)
6925 goto invalid;
6926 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6927 op2, readp);
6928 readp += op2;
6929 break;
6930 case DW_CFA_offset_extended_sf:
6931 if ((uint64_t) (endp - readp) < 1)
6932 goto invalid;
6933 get_uleb128 (op1, readp, endp);
6934 if ((uint64_t) (endp - readp) < 1)
6935 goto invalid;
6936 get_sleb128 (sop2, readp, endp);
6937 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
6938 PRId64 "\n",
6939 op1, regname (ebl, op1, regnamebuf), sop2 * data_align);
6940 break;
6941 case DW_CFA_def_cfa_sf:
6942 if ((uint64_t) (endp - readp) < 1)
6943 goto invalid;
6944 get_uleb128 (op1, readp, endp);
6945 if ((uint64_t) (endp - readp) < 1)
6946 goto invalid;
6947 get_sleb128 (sop2, readp, endp);
6948 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
6949 op1, regname (ebl, op1, regnamebuf), sop2 * data_align);
6950 break;
6951 case DW_CFA_def_cfa_offset_sf:
6952 if ((uint64_t) (endp - readp) < 1)
6953 goto invalid;
6954 get_sleb128 (sop1, readp, endp);
6955 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
6956 break;
6957 case DW_CFA_val_offset:
6958 if ((uint64_t) (endp - readp) < 1)
6959 goto invalid;
6960 get_uleb128 (op1, readp, endp);
6961 if ((uint64_t) (endp - readp) < 1)
6962 goto invalid;
6963 get_uleb128 (op2, readp, endp);
6964 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
6965 op1, op2 * data_align);
6966 break;
6967 case DW_CFA_val_offset_sf:
6968 if ((uint64_t) (endp - readp) < 1)
6969 goto invalid;
6970 get_uleb128 (op1, readp, endp);
6971 if ((uint64_t) (endp - readp) < 1)
6972 goto invalid;
6973 get_sleb128 (sop2, readp, endp);
6974 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
6975 op1, sop2 * data_align);
6976 break;
6977 case DW_CFA_val_expression:
6978 if ((uint64_t) (endp - readp) < 1)
6979 goto invalid;
6980 get_uleb128 (op1, readp, endp);
6981 if ((uint64_t) (endp - readp) < 1)
6982 goto invalid;
6983 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
6984 printf (" val_expression r%" PRIu64 " (%s)\n",
6985 op1, regname (ebl, op1, regnamebuf));
6986 if ((uint64_t) (endp - readp) < op2)
6987 goto invalid;
6988 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
6989 NULL, op2, readp);
6990 readp += op2;
6991 break;
6992 case DW_CFA_MIPS_advance_loc8:
6993 if ((uint64_t) (endp - readp) < 8)
6994 goto invalid;
6995 op1 = read_8ubyte_unaligned_inc (dbg, readp);
6996 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
6997 op1, pc += op1 * code_align);
6998 break;
6999 case DW_CFA_GNU_window_save: /* DW_CFA_AARCH64_negate_ra_state */
7000 if (ehdr->e_machine == EM_AARCH64)
7001 puts (" AARCH64_negate_ra_state");
7002 else
7003 puts (" GNU_window_save");
7004 break;
7005 case DW_CFA_GNU_args_size:
7006 if ((uint64_t) (endp - readp) < 1)
7007 goto invalid;
7008 get_uleb128 (op1, readp, endp);
7009 printf (" args_size %" PRIu64 "\n", op1);
7010 break;
7011 default:
7012 printf (" ??? (%u)\n", opcode);
7013 break;
7014 }
7015 else if (opcode < DW_CFA_offset)
7016 printf (" advance_loc %u to %#" PRIx64 "\n",
7017 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
7018 else if (opcode < DW_CFA_restore)
7019 {
7020 uint64_t offset;
7021 if ((uint64_t) (endp - readp) < 1)
7022 goto invalid;
7023 get_uleb128 (offset, readp, endp);
7024 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
7025 opcode & 0x3f, regname (ebl, opcode & 0x3f, regnamebuf),
7026 offset * data_align);
7027 }
7028 else
7029 printf (" restore r%u (%s)\n",
7030 opcode & 0x3f, regname (ebl, opcode & 0x3f, regnamebuf));
7031 }
7032 }
7033
7034
7035 static unsigned int
encoded_ptr_size(int encoding,unsigned int ptr_size)7036 encoded_ptr_size (int encoding, unsigned int ptr_size)
7037 {
7038 switch (encoding & 7)
7039 {
7040 case DW_EH_PE_udata4:
7041 return 4;
7042 case DW_EH_PE_udata8:
7043 return 8;
7044 case 0:
7045 return ptr_size;
7046 }
7047
7048 fprintf (stderr, "Unsupported pointer encoding: %#x, "
7049 "assuming pointer size of %d.\n", encoding, ptr_size);
7050 return ptr_size;
7051 }
7052
7053
7054 static unsigned int
print_encoding(unsigned int val)7055 print_encoding (unsigned int val)
7056 {
7057 switch (val & 0xf)
7058 {
7059 case DW_EH_PE_absptr:
7060 fputs ("absptr", stdout);
7061 break;
7062 case DW_EH_PE_uleb128:
7063 fputs ("uleb128", stdout);
7064 break;
7065 case DW_EH_PE_udata2:
7066 fputs ("udata2", stdout);
7067 break;
7068 case DW_EH_PE_udata4:
7069 fputs ("udata4", stdout);
7070 break;
7071 case DW_EH_PE_udata8:
7072 fputs ("udata8", stdout);
7073 break;
7074 case DW_EH_PE_sleb128:
7075 fputs ("sleb128", stdout);
7076 break;
7077 case DW_EH_PE_sdata2:
7078 fputs ("sdata2", stdout);
7079 break;
7080 case DW_EH_PE_sdata4:
7081 fputs ("sdata4", stdout);
7082 break;
7083 case DW_EH_PE_sdata8:
7084 fputs ("sdata8", stdout);
7085 break;
7086 default:
7087 /* We did not use any of the bits after all. */
7088 return val;
7089 }
7090
7091 return val & ~0xf;
7092 }
7093
7094
7095 static unsigned int
print_relinfo(unsigned int val)7096 print_relinfo (unsigned int val)
7097 {
7098 switch (val & 0x70)
7099 {
7100 case DW_EH_PE_pcrel:
7101 fputs ("pcrel", stdout);
7102 break;
7103 case DW_EH_PE_textrel:
7104 fputs ("textrel", stdout);
7105 break;
7106 case DW_EH_PE_datarel:
7107 fputs ("datarel", stdout);
7108 break;
7109 case DW_EH_PE_funcrel:
7110 fputs ("funcrel", stdout);
7111 break;
7112 case DW_EH_PE_aligned:
7113 fputs ("aligned", stdout);
7114 break;
7115 default:
7116 return val;
7117 }
7118
7119 return val & ~0x70;
7120 }
7121
7122
7123 static void
print_encoding_base(const char * pfx,unsigned int fde_encoding)7124 print_encoding_base (const char *pfx, unsigned int fde_encoding)
7125 {
7126 printf ("(%s", pfx);
7127
7128 if (fde_encoding == DW_EH_PE_omit)
7129 puts ("omit)");
7130 else
7131 {
7132 unsigned int w = fde_encoding;
7133
7134 w = print_encoding (w);
7135
7136 if (w & 0x70)
7137 {
7138 if (w != fde_encoding)
7139 fputc_unlocked (' ', stdout);
7140
7141 w = print_relinfo (w);
7142 }
7143
7144 if (w != 0)
7145 printf ("%s%x", w != fde_encoding ? " " : "", w);
7146
7147 puts (")");
7148 }
7149 }
7150
7151
7152 static void
print_debug_frame_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7153 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7154 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7155 {
7156 size_t shstrndx;
7157 /* We know this call will succeed since it did in the caller. */
7158 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
7159 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
7160
7161 /* Needed if we find PC-relative addresses. */
7162 GElf_Addr bias;
7163 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
7164 {
7165 error (0, 0, _("cannot get ELF: %s"), dwfl_errmsg (-1));
7166 return;
7167 }
7168
7169 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
7170 Elf_Data *data;
7171 if (is_eh_frame)
7172 {
7173 data = elf_rawdata (scn, NULL);
7174 if (data == NULL)
7175 {
7176 error (0, 0, _("cannot get %s content: %s"),
7177 scnname, elf_errmsg (-1));
7178 return;
7179 }
7180 }
7181 else
7182 {
7183 data = get_debug_elf_data (dbg, ebl, IDX_debug_frame, scn);
7184 if (data == NULL)
7185 return;
7186 }
7187
7188 if (is_eh_frame)
7189 printf (_("\
7190 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7191 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
7192 else
7193 printf (_("\
7194 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7195 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
7196
7197 struct cieinfo
7198 {
7199 ptrdiff_t cie_offset;
7200 const char *augmentation;
7201 unsigned int code_alignment_factor;
7202 unsigned int data_alignment_factor;
7203 uint8_t address_size;
7204 uint8_t fde_encoding;
7205 uint8_t lsda_encoding;
7206 struct cieinfo *next;
7207 } *cies = NULL;
7208
7209 const unsigned char *readp = data->d_buf;
7210 const unsigned char *const dataend = ((unsigned char *) data->d_buf
7211 + data->d_size);
7212 while (readp < dataend)
7213 {
7214 if (unlikely (readp + 4 > dataend))
7215 {
7216 invalid_data:
7217 error (0, 0, _("invalid data in section [%zu] '%s'"),
7218 elf_ndxscn (scn), scnname);
7219 return;
7220 }
7221
7222 /* At the beginning there must be a CIE. There can be multiple,
7223 hence we test tis in a loop. */
7224 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
7225
7226 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
7227 unsigned int length = 4;
7228 if (unlikely (unit_length == 0xffffffff))
7229 {
7230 if (unlikely (readp + 8 > dataend))
7231 goto invalid_data;
7232
7233 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
7234 length = 8;
7235 }
7236
7237 if (unlikely (unit_length == 0))
7238 {
7239 printf (_("\n [%6tx] Zero terminator\n"), offset);
7240 continue;
7241 }
7242
7243 Dwarf_Word maxsize = dataend - readp;
7244 if (unlikely (unit_length > maxsize))
7245 goto invalid_data;
7246
7247 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
7248
7249 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
7250 const unsigned char *const cieend = readp + unit_length;
7251 if (unlikely (cieend > dataend))
7252 goto invalid_data;
7253
7254 Dwarf_Off cie_id;
7255 if (length == 4)
7256 {
7257 if (unlikely (cieend - readp < 4))
7258 goto invalid_data;
7259 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
7260 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
7261 cie_id = DW_CIE_ID_64;
7262 }
7263 else
7264 {
7265 if (unlikely (cieend - readp < 8))
7266 goto invalid_data;
7267 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
7268 }
7269
7270 uint_fast8_t version = 2;
7271 unsigned int code_alignment_factor;
7272 int data_alignment_factor;
7273 unsigned int fde_encoding = 0;
7274 unsigned int lsda_encoding = 0;
7275 Dwarf_Word initial_location = 0;
7276 Dwarf_Word vma_base = 0;
7277
7278 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
7279 {
7280 if (unlikely (cieend - readp < 2))
7281 goto invalid_data;
7282 version = *readp++;
7283 const char *const augmentation = (const char *) readp;
7284 readp = memchr (readp, '\0', cieend - readp);
7285 if (unlikely (readp == NULL))
7286 goto invalid_data;
7287 ++readp;
7288
7289 uint_fast8_t segment_size = 0;
7290 if (version >= 4)
7291 {
7292 if (cieend - readp < 5)
7293 goto invalid_data;
7294 ptr_size = *readp++;
7295 segment_size = *readp++;
7296 }
7297
7298 if (cieend - readp < 1)
7299 goto invalid_data;
7300 get_uleb128 (code_alignment_factor, readp, cieend);
7301 if (cieend - readp < 1)
7302 goto invalid_data;
7303 get_sleb128 (data_alignment_factor, readp, cieend);
7304
7305 /* In some variant for unwind data there is another field. */
7306 if (strcmp (augmentation, "eh") == 0)
7307 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
7308
7309 unsigned int return_address_register;
7310 if (cieend - readp < 1)
7311 goto invalid_data;
7312 if (unlikely (version == 1))
7313 return_address_register = *readp++;
7314 else
7315 get_uleb128 (return_address_register, readp, cieend);
7316
7317 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
7318 " CIE_id: %" PRIu64 "\n"
7319 " version: %u\n"
7320 " augmentation: \"%s\"\n",
7321 offset, (uint64_t) unit_length, (uint64_t) cie_id,
7322 version, augmentation);
7323 if (version >= 4)
7324 printf (" address_size: %u\n"
7325 " segment_size: %u\n",
7326 ptr_size, segment_size);
7327 printf (" code_alignment_factor: %u\n"
7328 " data_alignment_factor: %d\n"
7329 " return_address_register: %u\n",
7330 code_alignment_factor,
7331 data_alignment_factor, return_address_register);
7332
7333 if (augmentation[0] == 'z')
7334 {
7335 if (cieend - readp < 1)
7336 goto invalid_data;
7337
7338 unsigned int augmentationlen;
7339 get_uleb128 (augmentationlen, readp, cieend);
7340
7341 if (augmentationlen > (size_t) (cieend - readp))
7342 {
7343 error (0, 0, _("invalid augmentation length"));
7344 readp = cieend;
7345 continue;
7346 }
7347
7348 const char *hdr = "Augmentation data:";
7349 const char *cp = augmentation + 1;
7350 while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
7351 {
7352 printf (" %-26s%#x ", hdr, *readp);
7353 hdr = "";
7354
7355 if (*cp == 'R')
7356 {
7357 fde_encoding = *readp++;
7358 print_encoding_base (_("FDE address encoding: "),
7359 fde_encoding);
7360 }
7361 else if (*cp == 'L')
7362 {
7363 lsda_encoding = *readp++;
7364 print_encoding_base (_("LSDA pointer encoding: "),
7365 lsda_encoding);
7366 }
7367 else if (*cp == 'P')
7368 {
7369 /* Personality. This field usually has a relocation
7370 attached pointing to __gcc_personality_v0. */
7371 const unsigned char *startp = readp;
7372 unsigned int encoding = *readp++;
7373 uint64_t val = 0;
7374 readp = read_encoded (encoding, readp,
7375 readp - 1 + augmentationlen,
7376 &val, dbg);
7377
7378 while (++startp < readp)
7379 printf ("%#x ", *startp);
7380
7381 putchar ('(');
7382 print_encoding (encoding);
7383 putchar (' ');
7384 switch (encoding & 0xf)
7385 {
7386 case DW_EH_PE_sleb128:
7387 case DW_EH_PE_sdata2:
7388 case DW_EH_PE_sdata4:
7389 printf ("%" PRId64 ")\n", val);
7390 break;
7391 default:
7392 printf ("%#" PRIx64 ")\n", val);
7393 break;
7394 }
7395 }
7396 else
7397 printf ("(%x)\n", *readp++);
7398
7399 ++cp;
7400 }
7401 }
7402
7403 if (likely (ptr_size == 4 || ptr_size == 8))
7404 {
7405 struct cieinfo *newp = alloca (sizeof (*newp));
7406 newp->cie_offset = offset;
7407 newp->augmentation = augmentation;
7408 newp->fde_encoding = fde_encoding;
7409 newp->lsda_encoding = lsda_encoding;
7410 newp->address_size = ptr_size;
7411 newp->code_alignment_factor = code_alignment_factor;
7412 newp->data_alignment_factor = data_alignment_factor;
7413 newp->next = cies;
7414 cies = newp;
7415 }
7416 }
7417 else
7418 {
7419 struct cieinfo *cie = cies;
7420 while (cie != NULL)
7421 if (is_eh_frame
7422 ? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
7423 : cie_id == (Dwarf_Off) cie->cie_offset)
7424 break;
7425 else
7426 cie = cie->next;
7427 if (unlikely (cie == NULL))
7428 {
7429 puts ("invalid CIE reference in FDE");
7430 return;
7431 }
7432
7433 /* Initialize from CIE data. */
7434 fde_encoding = cie->fde_encoding;
7435 lsda_encoding = cie->lsda_encoding;
7436 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
7437 code_alignment_factor = cie->code_alignment_factor;
7438 data_alignment_factor = cie->data_alignment_factor;
7439
7440 const unsigned char *base = readp;
7441 // XXX There are sometimes relocations for this value
7442 initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
7443 Dwarf_Word address_range
7444 = read_addr_unaligned_inc (ptr_size, dbg, readp);
7445
7446 /* pcrel for an FDE address is relative to the runtime
7447 address of the start_address field itself. Sign extend
7448 if necessary to make sure the calculation is done on the
7449 full 64 bit address even when initial_location only holds
7450 the lower 32 bits. */
7451 Dwarf_Addr pc_start = initial_location;
7452 if (ptr_size == 4)
7453 pc_start = (uint64_t) (int32_t) pc_start;
7454 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
7455 pc_start += ((uint64_t) shdr->sh_addr
7456 + (base - (const unsigned char *) data->d_buf)
7457 - bias);
7458
7459 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
7460 " CIE_pointer: %" PRIu64 "\n"
7461 " initial_location: ",
7462 offset, (uint64_t) unit_length,
7463 cie->cie_offset, (uint64_t) cie_id);
7464 print_dwarf_addr (dwflmod, cie->address_size,
7465 pc_start, initial_location);
7466 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
7467 {
7468 vma_base = (((uint64_t) shdr->sh_offset
7469 + (base - (const unsigned char *) data->d_buf)
7470 + (uint64_t) initial_location)
7471 & (ptr_size == 4
7472 ? UINT64_C (0xffffffff)
7473 : UINT64_C (0xffffffffffffffff)));
7474 printf (_(" (offset: %#" PRIx64 ")"),
7475 (uint64_t) vma_base);
7476 }
7477
7478 printf ("\n address_range: %#" PRIx64,
7479 (uint64_t) address_range);
7480 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
7481 printf (_(" (end offset: %#" PRIx64 ")"),
7482 ((uint64_t) vma_base + (uint64_t) address_range)
7483 & (ptr_size == 4
7484 ? UINT64_C (0xffffffff)
7485 : UINT64_C (0xffffffffffffffff)));
7486 putchar ('\n');
7487
7488 if (cie->augmentation[0] == 'z')
7489 {
7490 unsigned int augmentationlen;
7491 if (cieend - readp < 1)
7492 goto invalid_data;
7493 get_uleb128 (augmentationlen, readp, cieend);
7494
7495 if (augmentationlen > (size_t) (cieend - readp))
7496 {
7497 error (0, 0, _("invalid augmentation length"));
7498 readp = cieend;
7499 continue;
7500 }
7501
7502 if (augmentationlen > 0)
7503 {
7504 const char *hdr = "Augmentation data:";
7505 const char *cp = cie->augmentation + 1;
7506 unsigned int u = 0;
7507 while (*cp != '\0'
7508 && cp < cie->augmentation + augmentationlen + 1)
7509 {
7510 if (*cp == 'L')
7511 {
7512 uint64_t lsda_pointer;
7513 const unsigned char *p
7514 = read_encoded (lsda_encoding, &readp[u],
7515 &readp[augmentationlen],
7516 &lsda_pointer, dbg);
7517 u = p - readp;
7518 printf (_("\
7519 %-26sLSDA pointer: %#" PRIx64 "\n"),
7520 hdr, lsda_pointer);
7521 hdr = "";
7522 }
7523 ++cp;
7524 }
7525
7526 while (u < augmentationlen)
7527 {
7528 printf (" %-26s%#x\n", hdr, readp[u++]);
7529 hdr = "";
7530 }
7531 }
7532
7533 readp += augmentationlen;
7534 }
7535 }
7536
7537 /* Handle the initialization instructions. */
7538 if (ptr_size != 4 && ptr_size !=8)
7539 printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
7540 else
7541 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
7542 data_alignment_factor, version, ptr_size,
7543 fde_encoding, dwflmod, ebl, ehdr, dbg);
7544 readp = cieend;
7545 }
7546 }
7547
7548
7549 /* Returns the signedness (or false if it cannot be determined) and
7550 the byte size (or zero if it cannot be gotten) of the given DIE
7551 DW_AT_type attribute. Uses dwarf_peel_type and dwarf_aggregate_size. */
7552 static void
die_type_sign_bytes(Dwarf_Die * die,bool * is_signed,int * bytes)7553 die_type_sign_bytes (Dwarf_Die *die, bool *is_signed, int *bytes)
7554 {
7555 Dwarf_Attribute attr;
7556 Dwarf_Die type;
7557
7558 *bytes = 0;
7559 *is_signed = false;
7560
7561 if (dwarf_peel_type (dwarf_formref_die (dwarf_attr_integrate (die,
7562 DW_AT_type,
7563 &attr), &type),
7564 &type) == 0)
7565 {
7566 Dwarf_Word val;
7567 *is_signed = (dwarf_formudata (dwarf_attr (&type, DW_AT_encoding,
7568 &attr), &val) == 0
7569 && (val == DW_ATE_signed || val == DW_ATE_signed_char));
7570
7571 if (dwarf_aggregate_size (&type, &val) == 0)
7572 *bytes = val;
7573 }
7574 }
7575
7576 struct attrcb_args
7577 {
7578 Dwfl_Module *dwflmod;
7579 Dwarf *dbg;
7580 Dwarf_Die *dies;
7581 int level;
7582 bool silent;
7583 bool is_split;
7584 unsigned int version;
7585 unsigned int addrsize;
7586 unsigned int offset_size;
7587 struct Dwarf_CU *cu;
7588 };
7589
7590
7591 static int
attr_callback(Dwarf_Attribute * attrp,void * arg)7592 attr_callback (Dwarf_Attribute *attrp, void *arg)
7593 {
7594 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
7595 const int level = cbargs->level;
7596 Dwarf_Die *die = &cbargs->dies[level];
7597 bool is_split = cbargs->is_split;
7598
7599 unsigned int attr = dwarf_whatattr (attrp);
7600 if (unlikely (attr == 0))
7601 {
7602 if (!cbargs->silent)
7603 error (0, 0, _("DIE [%" PRIx64 "] "
7604 "cannot get attribute code: %s"),
7605 dwarf_dieoffset (die), dwarf_errmsg (-1));
7606 return DWARF_CB_ABORT;
7607 }
7608
7609 unsigned int form = dwarf_whatform (attrp);
7610 if (unlikely (form == 0))
7611 {
7612 if (!cbargs->silent)
7613 error (0, 0, _("DIE [%" PRIx64 "] "
7614 "cannot get attribute form: %s"),
7615 dwarf_dieoffset (die), dwarf_errmsg (-1));
7616 return DWARF_CB_ABORT;
7617 }
7618
7619 switch (form)
7620 {
7621 case DW_FORM_addr:
7622 case DW_FORM_addrx:
7623 case DW_FORM_addrx1:
7624 case DW_FORM_addrx2:
7625 case DW_FORM_addrx3:
7626 case DW_FORM_addrx4:
7627 case DW_FORM_GNU_addr_index:
7628 if (!cbargs->silent)
7629 {
7630 Dwarf_Addr addr;
7631 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
7632 {
7633 attrval_out:
7634 if (!cbargs->silent)
7635 error (0, 0, _("DIE [%" PRIx64 "] "
7636 "cannot get attribute '%s' (%s) value: "
7637 "%s"),
7638 dwarf_dieoffset (die),
7639 dwarf_attr_name (attr),
7640 dwarf_form_name (form),
7641 dwarf_errmsg (-1));
7642 /* Don't ABORT, it might be other attributes can be resolved. */
7643 return DWARF_CB_OK;
7644 }
7645 if (form != DW_FORM_addr )
7646 {
7647 Dwarf_Word word;
7648 if (dwarf_formudata (attrp, &word) != 0)
7649 goto attrval_out;
7650 printf (" %*s%-20s (%s) [%" PRIx64 "] ",
7651 (int) (level * 2), "", dwarf_attr_name (attr),
7652 dwarf_form_name (form), word);
7653 }
7654 else
7655 printf (" %*s%-20s (%s) ",
7656 (int) (level * 2), "", dwarf_attr_name (attr),
7657 dwarf_form_name (form));
7658 print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr, addr);
7659 printf ("\n");
7660 }
7661 break;
7662
7663 case DW_FORM_indirect:
7664 case DW_FORM_strp:
7665 case DW_FORM_line_strp:
7666 case DW_FORM_strx:
7667 case DW_FORM_strx1:
7668 case DW_FORM_strx2:
7669 case DW_FORM_strx3:
7670 case DW_FORM_strx4:
7671 case DW_FORM_string:
7672 case DW_FORM_GNU_strp_alt:
7673 case DW_FORM_GNU_str_index:
7674 if (cbargs->silent)
7675 break;
7676 const char *str = dwarf_formstring (attrp);
7677 if (unlikely (str == NULL))
7678 goto attrval_out;
7679 printf (" %*s%-20s (%s) \"%s\"\n",
7680 (int) (level * 2), "", dwarf_attr_name (attr),
7681 dwarf_form_name (form), str);
7682 break;
7683
7684 case DW_FORM_ref_addr:
7685 case DW_FORM_ref_udata:
7686 case DW_FORM_ref8:
7687 case DW_FORM_ref4:
7688 case DW_FORM_ref2:
7689 case DW_FORM_ref1:
7690 case DW_FORM_GNU_ref_alt:
7691 case DW_FORM_ref_sup4:
7692 case DW_FORM_ref_sup8:
7693 if (cbargs->silent)
7694 break;
7695 Dwarf_Die ref;
7696 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
7697 goto attrval_out;
7698
7699 printf (" %*s%-20s (%s) ",
7700 (int) (level * 2), "", dwarf_attr_name (attr),
7701 dwarf_form_name (form));
7702 if (is_split)
7703 printf ("{%6" PRIxMAX "}\n", (uintmax_t) dwarf_dieoffset (&ref));
7704 else
7705 printf ("[%6" PRIxMAX "]\n", (uintmax_t) dwarf_dieoffset (&ref));
7706 break;
7707
7708 case DW_FORM_ref_sig8:
7709 if (cbargs->silent)
7710 break;
7711 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
7712 (int) (level * 2), "", dwarf_attr_name (attr),
7713 dwarf_form_name (form),
7714 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
7715 break;
7716
7717 case DW_FORM_sec_offset:
7718 case DW_FORM_rnglistx:
7719 case DW_FORM_loclistx:
7720 case DW_FORM_implicit_const:
7721 case DW_FORM_udata:
7722 case DW_FORM_sdata:
7723 case DW_FORM_data8: /* Note no data16 here, we see that as block. */
7724 case DW_FORM_data4:
7725 case DW_FORM_data2:
7726 case DW_FORM_data1:;
7727 Dwarf_Word num;
7728 if (unlikely (dwarf_formudata (attrp, &num) != 0))
7729 goto attrval_out;
7730
7731 const char *valuestr = NULL;
7732 bool as_hex_id = false;
7733 switch (attr)
7734 {
7735 /* This case can take either a constant or a loclistptr. */
7736 case DW_AT_data_member_location:
7737 if (form != DW_FORM_sec_offset
7738 && (cbargs->version >= 4
7739 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
7740 {
7741 if (!cbargs->silent)
7742 printf (" %*s%-20s (%s) %" PRIuMAX "\n",
7743 (int) (level * 2), "", dwarf_attr_name (attr),
7744 dwarf_form_name (form), (uintmax_t) num);
7745 return DWARF_CB_OK;
7746 }
7747 FALLTHROUGH;
7748
7749 /* These cases always take a loclist[ptr] and no constant. */
7750 case DW_AT_location:
7751 case DW_AT_data_location:
7752 case DW_AT_vtable_elem_location:
7753 case DW_AT_string_length:
7754 case DW_AT_use_location:
7755 case DW_AT_frame_base:
7756 case DW_AT_return_addr:
7757 case DW_AT_static_link:
7758 case DW_AT_segment:
7759 case DW_AT_GNU_call_site_value:
7760 case DW_AT_GNU_call_site_data_value:
7761 case DW_AT_GNU_call_site_target:
7762 case DW_AT_GNU_call_site_target_clobbered:
7763 case DW_AT_GNU_locviews:
7764 {
7765 bool nlpt;
7766 if (cbargs->cu->version < 5)
7767 {
7768 if (! cbargs->is_split)
7769 {
7770 nlpt = notice_listptr (section_loc, &known_locsptr,
7771 cbargs->addrsize,
7772 cbargs->offset_size,
7773 cbargs->cu, num, attr);
7774 }
7775 else
7776 nlpt = true;
7777 }
7778 else
7779 {
7780 /* Only register for a real section offset. Otherwise
7781 it is a DW_FORM_loclistx which is just an index
7782 number and we should already have registered the
7783 section offset for the index when we saw the
7784 DW_AT_loclists_base CU attribute. */
7785 if (form == DW_FORM_sec_offset)
7786 nlpt = notice_listptr (section_loc, &known_loclistsptr,
7787 cbargs->addrsize, cbargs->offset_size,
7788 cbargs->cu, num, attr);
7789 else
7790 nlpt = true;
7791
7792 }
7793
7794 if (!cbargs->silent)
7795 {
7796 if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7797 printf (" %*s%-20s (%s) location list [%6"
7798 PRIxMAX "]%s\n",
7799 (int) (level * 2), "", dwarf_attr_name (attr),
7800 dwarf_form_name (form), (uintmax_t) num,
7801 nlpt ? "" : " <WARNING offset too big>");
7802 else
7803 printf (" %*s%-20s (%s) location index [%6"
7804 PRIxMAX "]\n",
7805 (int) (level * 2), "", dwarf_attr_name (attr),
7806 dwarf_form_name (form), (uintmax_t) num);
7807 }
7808 }
7809 return DWARF_CB_OK;
7810
7811 case DW_AT_loclists_base:
7812 {
7813 bool nlpt = notice_listptr (section_loc, &known_loclistsptr,
7814 cbargs->addrsize, cbargs->offset_size,
7815 cbargs->cu, num, attr);
7816
7817 if (!cbargs->silent)
7818 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
7819 (int) (level * 2), "", dwarf_attr_name (attr),
7820 dwarf_form_name (form), (uintmax_t) num,
7821 nlpt ? "" : " <WARNING offset too big>");
7822 }
7823 return DWARF_CB_OK;
7824
7825 case DW_AT_ranges:
7826 case DW_AT_start_scope:
7827 {
7828 bool nlpt;
7829 if (cbargs->cu->version < 5)
7830 nlpt = notice_listptr (section_ranges, &known_rangelistptr,
7831 cbargs->addrsize, cbargs->offset_size,
7832 cbargs->cu, num, attr);
7833 else
7834 {
7835 /* Only register for a real section offset. Otherwise
7836 it is a DW_FORM_rangelistx which is just an index
7837 number and we should already have registered the
7838 section offset for the index when we saw the
7839 DW_AT_rnglists_base CU attribute. */
7840 if (form == DW_FORM_sec_offset)
7841 nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7842 cbargs->addrsize, cbargs->offset_size,
7843 cbargs->cu, num, attr);
7844 else
7845 nlpt = true;
7846 }
7847
7848 if (!cbargs->silent)
7849 {
7850 if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7851 printf (" %*s%-20s (%s) range list [%6"
7852 PRIxMAX "]%s\n",
7853 (int) (level * 2), "", dwarf_attr_name (attr),
7854 dwarf_form_name (form), (uintmax_t) num,
7855 nlpt ? "" : " <WARNING offset too big>");
7856 else
7857 printf (" %*s%-20s (%s) range index [%6"
7858 PRIxMAX "]\n",
7859 (int) (level * 2), "", dwarf_attr_name (attr),
7860 dwarf_form_name (form), (uintmax_t) num);
7861 }
7862 }
7863 return DWARF_CB_OK;
7864
7865 case DW_AT_rnglists_base:
7866 {
7867 bool nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7868 cbargs->addrsize, cbargs->offset_size,
7869 cbargs->cu, num, attr);
7870 if (!cbargs->silent)
7871 printf (" %*s%-20s (%s) range list [%6"
7872 PRIxMAX "]%s\n",
7873 (int) (level * 2), "", dwarf_attr_name (attr),
7874 dwarf_form_name (form), (uintmax_t) num,
7875 nlpt ? "" : " <WARNING offset too big>");
7876 }
7877 return DWARF_CB_OK;
7878
7879 case DW_AT_addr_base:
7880 case DW_AT_GNU_addr_base:
7881 {
7882 bool addrbase = notice_listptr (section_addr, &known_addrbases,
7883 cbargs->addrsize,
7884 cbargs->offset_size,
7885 cbargs->cu, num, attr);
7886 if (!cbargs->silent)
7887 printf (" %*s%-20s (%s) address base [%6"
7888 PRIxMAX "]%s\n",
7889 (int) (level * 2), "", dwarf_attr_name (attr),
7890 dwarf_form_name (form), (uintmax_t) num,
7891 addrbase ? "" : " <WARNING offset too big>");
7892 }
7893 return DWARF_CB_OK;
7894
7895 case DW_AT_str_offsets_base:
7896 {
7897 bool stroffbase = notice_listptr (section_str, &known_stroffbases,
7898 cbargs->addrsize,
7899 cbargs->offset_size,
7900 cbargs->cu, num, attr);
7901 if (!cbargs->silent)
7902 printf (" %*s%-20s (%s) str offsets base [%6"
7903 PRIxMAX "]%s\n",
7904 (int) (level * 2), "", dwarf_attr_name (attr),
7905 dwarf_form_name (form), (uintmax_t) num,
7906 stroffbase ? "" : " <WARNING offset too big>");
7907 }
7908 return DWARF_CB_OK;
7909
7910 case DW_AT_language:
7911 valuestr = dwarf_lang_name (num);
7912 break;
7913 case DW_AT_encoding:
7914 valuestr = dwarf_encoding_name (num);
7915 break;
7916 case DW_AT_accessibility:
7917 valuestr = dwarf_access_name (num);
7918 break;
7919 case DW_AT_defaulted:
7920 valuestr = dwarf_defaulted_name (num);
7921 break;
7922 case DW_AT_visibility:
7923 valuestr = dwarf_visibility_name (num);
7924 break;
7925 case DW_AT_virtuality:
7926 valuestr = dwarf_virtuality_name (num);
7927 break;
7928 case DW_AT_identifier_case:
7929 valuestr = dwarf_identifier_case_name (num);
7930 break;
7931 case DW_AT_calling_convention:
7932 valuestr = dwarf_calling_convention_name (num);
7933 break;
7934 case DW_AT_inline:
7935 valuestr = dwarf_inline_name (num);
7936 break;
7937 case DW_AT_ordering:
7938 valuestr = dwarf_ordering_name (num);
7939 break;
7940 case DW_AT_decl_file:
7941 case DW_AT_call_file:
7942 {
7943 if (cbargs->silent)
7944 break;
7945
7946 /* Try to get the actual file, the current interface only
7947 gives us full paths, but we only want to show the file
7948 name for now. */
7949 Dwarf_Die cudie;
7950 if (dwarf_cu_die (cbargs->cu, &cudie,
7951 NULL, NULL, NULL, NULL, NULL, NULL) != NULL)
7952 {
7953 Dwarf_Files *files;
7954 size_t nfiles;
7955 if (dwarf_getsrcfiles (&cudie, &files, &nfiles) == 0)
7956 {
7957 valuestr = dwarf_filesrc (files, num, NULL, NULL);
7958 if (valuestr != NULL)
7959 {
7960 char *filename = strrchr (valuestr, '/');
7961 if (filename != NULL)
7962 valuestr = filename + 1;
7963 }
7964 else
7965 error (0, 0, _("invalid file (%" PRId64 "): %s"),
7966 num, dwarf_errmsg (-1));
7967 }
7968 else
7969 error (0, 0, _("no srcfiles for CU [%" PRIx64 "]"),
7970 dwarf_dieoffset (&cudie));
7971 }
7972 else
7973 error (0, 0, _("couldn't get DWARF CU: %s"),
7974 dwarf_errmsg (-1));
7975 if (valuestr == NULL)
7976 valuestr = "???";
7977 }
7978 break;
7979 case DW_AT_GNU_dwo_id:
7980 as_hex_id = true;
7981 break;
7982
7983 default:
7984 /* Nothing. */
7985 break;
7986 }
7987
7988 if (cbargs->silent)
7989 break;
7990
7991 /* When highpc is in constant form it is relative to lowpc.
7992 In that case also show the address. */
7993 Dwarf_Addr highpc;
7994 if (attr == DW_AT_high_pc && dwarf_highpc (die, &highpc) == 0)
7995 {
7996 printf (" %*s%-20s (%s) %" PRIuMAX " (",
7997 (int) (level * 2), "", dwarf_attr_name (attr),
7998 dwarf_form_name (form), (uintmax_t) num);
7999 print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, highpc, highpc);
8000 printf (")\n");
8001 }
8002 else
8003 {
8004 if (as_hex_id)
8005 {
8006 printf (" %*s%-20s (%s) 0x%.16" PRIx64 "\n",
8007 (int) (level * 2), "", dwarf_attr_name (attr),
8008 dwarf_form_name (form), num);
8009 }
8010 else
8011 {
8012 Dwarf_Sword snum = 0;
8013 bool is_signed;
8014 int bytes = 0;
8015 if (attr == DW_AT_const_value)
8016 die_type_sign_bytes (die, &is_signed, &bytes);
8017 else
8018 is_signed = (form == DW_FORM_sdata
8019 || form == DW_FORM_implicit_const);
8020
8021 if (is_signed)
8022 if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
8023 goto attrval_out;
8024
8025 if (valuestr == NULL)
8026 {
8027 printf (" %*s%-20s (%s) ",
8028 (int) (level * 2), "", dwarf_attr_name (attr),
8029 dwarf_form_name (form));
8030 }
8031 else
8032 {
8033 printf (" %*s%-20s (%s) %s (",
8034 (int) (level * 2), "", dwarf_attr_name (attr),
8035 dwarf_form_name (form), valuestr);
8036 }
8037
8038 switch (bytes)
8039 {
8040 case 1:
8041 if (is_signed)
8042 printf ("%" PRId8, (int8_t) snum);
8043 else
8044 printf ("%" PRIu8, (uint8_t) num);
8045 break;
8046
8047 case 2:
8048 if (is_signed)
8049 printf ("%" PRId16, (int16_t) snum);
8050 else
8051 printf ("%" PRIu16, (uint16_t) num);
8052 break;
8053
8054 case 4:
8055 if (is_signed)
8056 printf ("%" PRId32, (int32_t) snum);
8057 else
8058 printf ("%" PRIu32, (uint32_t) num);
8059 break;
8060
8061 case 8:
8062 if (is_signed)
8063 printf ("%" PRId64, (int64_t) snum);
8064 else
8065 printf ("%" PRIu64, (uint64_t) num);
8066 break;
8067
8068 default:
8069 if (is_signed)
8070 printf ("%" PRIdMAX, (intmax_t) snum);
8071 else
8072 printf ("%" PRIuMAX, (uintmax_t) num);
8073 break;
8074 }
8075
8076 /* Make clear if we switched from a signed encoding to
8077 an unsigned value. */
8078 if (attr == DW_AT_const_value
8079 && (form == DW_FORM_sdata || form == DW_FORM_implicit_const)
8080 && !is_signed)
8081 printf (" (%" PRIdMAX ")", (intmax_t) num);
8082
8083 if (valuestr == NULL)
8084 printf ("\n");
8085 else
8086 printf (")\n");
8087 }
8088 }
8089 break;
8090
8091 case DW_FORM_flag:
8092 if (cbargs->silent)
8093 break;
8094 bool flag;
8095 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
8096 goto attrval_out;
8097
8098 printf (" %*s%-20s (%s) %s\n",
8099 (int) (level * 2), "", dwarf_attr_name (attr),
8100 dwarf_form_name (form), flag ? yes_str : no_str);
8101 break;
8102
8103 case DW_FORM_flag_present:
8104 if (cbargs->silent)
8105 break;
8106 printf (" %*s%-20s (%s) %s\n",
8107 (int) (level * 2), "", dwarf_attr_name (attr),
8108 dwarf_form_name (form), yes_str);
8109 break;
8110
8111 case DW_FORM_exprloc:
8112 case DW_FORM_block4:
8113 case DW_FORM_block2:
8114 case DW_FORM_block1:
8115 case DW_FORM_block:
8116 case DW_FORM_data16: /* DWARF5 calls this a constant class. */
8117 if (cbargs->silent)
8118 break;
8119 Dwarf_Block block;
8120 if (unlikely (dwarf_formblock (attrp, &block) != 0))
8121 goto attrval_out;
8122
8123 printf (" %*s%-20s (%s) ",
8124 (int) (level * 2), "", dwarf_attr_name (attr),
8125 dwarf_form_name (form));
8126
8127 switch (attr)
8128 {
8129 default:
8130 if (form != DW_FORM_exprloc)
8131 {
8132 print_block (block.length, block.data);
8133 break;
8134 }
8135 FALLTHROUGH;
8136
8137 case DW_AT_location:
8138 case DW_AT_data_location:
8139 case DW_AT_data_member_location:
8140 case DW_AT_vtable_elem_location:
8141 case DW_AT_string_length:
8142 case DW_AT_use_location:
8143 case DW_AT_frame_base:
8144 case DW_AT_return_addr:
8145 case DW_AT_static_link:
8146 case DW_AT_allocated:
8147 case DW_AT_associated:
8148 case DW_AT_bit_size:
8149 case DW_AT_bit_offset:
8150 case DW_AT_bit_stride:
8151 case DW_AT_byte_size:
8152 case DW_AT_byte_stride:
8153 case DW_AT_count:
8154 case DW_AT_lower_bound:
8155 case DW_AT_upper_bound:
8156 case DW_AT_GNU_call_site_value:
8157 case DW_AT_GNU_call_site_data_value:
8158 case DW_AT_GNU_call_site_target:
8159 case DW_AT_GNU_call_site_target_clobbered:
8160 if (form == DW_FORM_exprloc
8161 || (form != DW_FORM_data16
8162 && attrp->cu->version < 4)) /* blocks were expressions. */
8163 {
8164 putchar ('\n');
8165 print_ops (cbargs->dwflmod, cbargs->dbg,
8166 12 + level * 2, 12 + level * 2,
8167 cbargs->version, cbargs->addrsize, cbargs->offset_size,
8168 attrp->cu, block.length, block.data);
8169 }
8170 else
8171 print_block (block.length, block.data);
8172 break;
8173
8174 case DW_AT_discr_list:
8175 if (block.length == 0)
8176 puts ("<default>");
8177 else if (form != DW_FORM_data16)
8178 {
8179 const unsigned char *readp = block.data;
8180 const unsigned char *readendp = readp + block.length;
8181
8182 /* See if we are dealing with a signed or unsigned
8183 values. If the parent of this variant DIE is a
8184 variant_part then it will either have a discriminant
8185 which points to the member which type is the
8186 discriminant type. Or the variant_part itself has a
8187 type representing the discriminant. */
8188 bool is_signed = false;
8189 if (level > 0)
8190 {
8191 Dwarf_Die *parent = &cbargs->dies[level - 1];
8192 if (dwarf_tag (die) == DW_TAG_variant
8193 && dwarf_tag (parent) == DW_TAG_variant_part)
8194 {
8195 Dwarf_Die member;
8196 Dwarf_Attribute discr_attr;
8197 int bytes;
8198 if (dwarf_formref_die (dwarf_attr (parent,
8199 DW_AT_discr,
8200 &discr_attr),
8201 &member) != NULL)
8202 die_type_sign_bytes (&member, &is_signed, &bytes);
8203 else
8204 die_type_sign_bytes (parent, &is_signed, &bytes);
8205 }
8206 }
8207 while (readp < readendp)
8208 {
8209 int d = (int) *readp++;
8210 printf ("%s ", dwarf_discr_list_name (d));
8211 if (readp >= readendp)
8212 goto attrval_out;
8213
8214 Dwarf_Word val;
8215 Dwarf_Sword sval;
8216 if (d == DW_DSC_label)
8217 {
8218 if (is_signed)
8219 {
8220 get_sleb128 (sval, readp, readendp);
8221 printf ("%" PRId64 "", sval);
8222 }
8223 else
8224 {
8225 get_uleb128 (val, readp, readendp);
8226 printf ("%" PRIu64 "", val);
8227 }
8228 }
8229 else if (d == DW_DSC_range)
8230 {
8231 if (is_signed)
8232 {
8233 get_sleb128 (sval, readp, readendp);
8234 printf ("%" PRId64 "..", sval);
8235 if (readp >= readendp)
8236 goto attrval_out;
8237 get_sleb128 (sval, readp, readendp);
8238 printf ("%" PRId64 "", sval);
8239 }
8240 else
8241 {
8242 get_uleb128 (val, readp, readendp);
8243 printf ("%" PRIu64 "..", val);
8244 if (readp >= readendp)
8245 goto attrval_out;
8246 get_uleb128 (val, readp, readendp);
8247 printf ("%" PRIu64 "", val);
8248 }
8249 }
8250 else
8251 {
8252 print_block (readendp - readp, readp);
8253 break;
8254 }
8255 if (readp < readendp)
8256 printf (", ");
8257 }
8258 putchar ('\n');
8259 }
8260 else
8261 print_block (block.length, block.data);
8262 break;
8263 }
8264 break;
8265
8266 default:
8267 if (cbargs->silent)
8268 break;
8269 printf (" %*s%-20s (%s) ???\n",
8270 (int) (level * 2), "", dwarf_attr_name (attr),
8271 dwarf_form_name (form));
8272 break;
8273 }
8274
8275 return DWARF_CB_OK;
8276 }
8277
8278 static void
print_debug_units(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg,bool debug_types)8279 print_debug_units (Dwfl_Module *dwflmod,
8280 Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
8281 Elf_Scn *scn, GElf_Shdr *shdr,
8282 Dwarf *dbg, bool debug_types)
8283 {
8284 const bool silent = !(print_debug_sections & section_info) && !debug_types;
8285 const char *secname = section_name (ebl, shdr);
8286
8287 /* Check section actually exists. */
8288 if (!silent)
8289 if (get_debug_elf_data (dbg, ebl,
8290 debug_types ? IDX_debug_types : IDX_debug_info,
8291 scn) == NULL)
8292 return;
8293
8294 if (!silent)
8295 printf (_("\
8296 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
8297 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
8298
8299 /* If the section is empty we don't have to do anything. */
8300 if (!silent && shdr->sh_size == 0)
8301 return;
8302
8303 int maxdies = 20;
8304 Dwarf_Die *dies = xmalloc (maxdies * sizeof (Dwarf_Die));
8305
8306 /* New compilation unit. */
8307 Dwarf_Half version;
8308
8309 Dwarf_Die result;
8310 Dwarf_Off abbroffset;
8311 uint8_t addrsize;
8312 uint8_t offsize;
8313 uint64_t unit_id;
8314 Dwarf_Off subdie_off;
8315
8316 int unit_res;
8317 Dwarf_CU *cu;
8318 Dwarf_CU cu_mem;
8319 uint8_t unit_type;
8320 Dwarf_Die cudie;
8321
8322 /* We cheat a little because we want to see only the CUs from .debug_info
8323 or .debug_types. We know the Dwarf_CU struct layout. Set it up at
8324 the end of .debug_info if we want .debug_types only. Check the returned
8325 Dwarf_CU is still in the expected section. */
8326 if (debug_types)
8327 {
8328 cu_mem.dbg = dbg;
8329 cu_mem.end = dbg->sectiondata[IDX_debug_info]->d_size;
8330 cu_mem.sec_idx = IDX_debug_info;
8331 cu = &cu_mem;
8332 }
8333 else
8334 cu = NULL;
8335
8336 next_cu:
8337 unit_res = dwarf_get_units (dbg, cu, &cu, &version, &unit_type,
8338 &cudie, NULL);
8339 if (unit_res == 1)
8340 goto do_return;
8341
8342 if (unit_res == -1)
8343 {
8344 if (!silent)
8345 error (0, 0, _("cannot get next unit: %s"), dwarf_errmsg (-1));
8346 goto do_return;
8347 }
8348
8349 if (cu->sec_idx != (size_t) (debug_types ? IDX_debug_types : IDX_debug_info))
8350 goto do_return;
8351
8352 dwarf_cu_die (cu, &result, NULL, &abbroffset, &addrsize, &offsize,
8353 &unit_id, &subdie_off);
8354
8355 if (!silent)
8356 {
8357 Dwarf_Off offset = cu->start;
8358 if (debug_types && version < 5)
8359 {
8360 Dwarf_Die typedie;
8361 Dwarf_Off dieoffset;
8362 dieoffset = dwarf_dieoffset (dwarf_offdie_types (dbg, cu->start
8363 + subdie_off,
8364 &typedie));
8365 printf (_(" Type unit at offset %" PRIu64 ":\n"
8366 " Version: %" PRIu16
8367 ", Abbreviation section offset: %" PRIu64
8368 ", Address size: %" PRIu8
8369 ", Offset size: %" PRIu8
8370 "\n Type signature: %#" PRIx64
8371 ", Type offset: %#" PRIx64 " [%" PRIx64 "]\n"),
8372 (uint64_t) offset, version, abbroffset, addrsize, offsize,
8373 unit_id, (uint64_t) subdie_off, dieoffset);
8374 }
8375 else
8376 {
8377 printf (_(" Compilation unit at offset %" PRIu64 ":\n"
8378 " Version: %" PRIu16
8379 ", Abbreviation section offset: %" PRIu64
8380 ", Address size: %" PRIu8
8381 ", Offset size: %" PRIu8 "\n"),
8382 (uint64_t) offset, version, abbroffset, addrsize, offsize);
8383
8384 if (version >= 5 || (unit_type != DW_UT_compile
8385 && unit_type != DW_UT_partial))
8386 {
8387 printf (_(" Unit type: %s (%" PRIu8 ")"),
8388 dwarf_unit_name (unit_type), unit_type);
8389 if (unit_type == DW_UT_type
8390 || unit_type == DW_UT_skeleton
8391 || unit_type == DW_UT_split_compile
8392 || unit_type == DW_UT_split_type)
8393 printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
8394 if (unit_type == DW_UT_type
8395 || unit_type == DW_UT_split_type)
8396 {
8397 Dwarf_Die typedie;
8398 Dwarf_Off dieoffset;
8399 dwarf_cu_info (cu, NULL, NULL, NULL, &typedie,
8400 NULL, NULL, NULL);
8401 dieoffset = dwarf_dieoffset (&typedie);
8402 printf (", Unit DIE off: %#" PRIx64 " [%" PRIx64 "]",
8403 subdie_off, dieoffset);
8404 }
8405 printf ("\n");
8406 }
8407 }
8408 }
8409
8410 if (version < 2 || version > 5
8411 || unit_type < DW_UT_compile || unit_type > DW_UT_split_type)
8412 {
8413 if (!silent)
8414 error (0, 0, _("unknown version (%d) or unit type (%d)"),
8415 version, unit_type);
8416 goto next_cu;
8417 }
8418
8419 struct attrcb_args args =
8420 {
8421 .dwflmod = dwflmod,
8422 .silent = silent,
8423 .version = version,
8424 .addrsize = addrsize,
8425 .offset_size = offsize
8426 };
8427
8428 bool is_split = false;
8429 int level = 0;
8430 dies[0] = cudie;
8431 args.cu = dies[0].cu;
8432 args.dbg = dbg;
8433 args.is_split = is_split;
8434
8435 /* We might return here again for the split CU subdie. */
8436 do_cu:
8437 do
8438 {
8439 Dwarf_Off offset = dwarf_dieoffset (&dies[level]);
8440 if (unlikely (offset == (Dwarf_Off) -1))
8441 {
8442 if (!silent)
8443 error (0, 0, _("cannot get DIE offset: %s"),
8444 dwarf_errmsg (-1));
8445 goto do_return;
8446 }
8447
8448 int tag = dwarf_tag (&dies[level]);
8449 if (unlikely (tag == DW_TAG_invalid))
8450 {
8451 if (!silent)
8452 error (0, 0, _("cannot get tag of DIE at offset [%" PRIx64
8453 "] in section '%s': %s"),
8454 (uint64_t) offset, secname, dwarf_errmsg (-1));
8455 goto do_return;
8456 }
8457
8458 if (!silent)
8459 {
8460 unsigned int code = dwarf_getabbrevcode (dies[level].abbrev);
8461 if (is_split)
8462 printf (" {%6" PRIx64 "} ", (uint64_t) offset);
8463 else
8464 printf (" [%6" PRIx64 "] ", (uint64_t) offset);
8465 printf ("%*s%-20s abbrev: %u\n", (int) (level * 2), "",
8466 dwarf_tag_name (tag), code);
8467 }
8468
8469 /* Print the attribute values. */
8470 args.level = level;
8471 args.dies = dies;
8472 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
8473
8474 /* Make room for the next level's DIE. */
8475 if (level + 1 == maxdies)
8476 dies = xrealloc (dies, (maxdies += 10) * sizeof (Dwarf_Die));
8477
8478 int res = dwarf_child (&dies[level], &dies[level + 1]);
8479 if (res > 0)
8480 {
8481 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
8482 if (level-- == 0)
8483 break;
8484
8485 if (unlikely (res == -1))
8486 {
8487 if (!silent)
8488 error (0, 0, _("cannot get next DIE: %s\n"),
8489 dwarf_errmsg (-1));
8490 goto do_return;
8491 }
8492 }
8493 else if (unlikely (res < 0))
8494 {
8495 if (!silent)
8496 error (0, 0, _("cannot get next DIE: %s"),
8497 dwarf_errmsg (-1));
8498 goto do_return;
8499 }
8500 else
8501 ++level;
8502 }
8503 while (level >= 0);
8504
8505 /* We might want to show the split compile unit if this was a skeleton.
8506 We need to scan it if we are requesting printing .debug_ranges for
8507 DWARF4 since GNU DebugFission uses "offsets" into the main ranges
8508 section. */
8509 if (unit_type == DW_UT_skeleton
8510 && ((!silent && show_split_units)
8511 || (version < 5 && (print_debug_sections & section_ranges) != 0)))
8512 {
8513 Dwarf_Die subdie;
8514 if (dwarf_cu_info (cu, NULL, NULL, NULL, &subdie, NULL, NULL, NULL) != 0
8515 || dwarf_tag (&subdie) == DW_TAG_invalid)
8516 {
8517 if (!silent)
8518 {
8519 Dwarf_Attribute dwo_at;
8520 const char *dwo_name =
8521 (dwarf_formstring (dwarf_attr (&cudie, DW_AT_dwo_name,
8522 &dwo_at))
8523 ?: (dwarf_formstring (dwarf_attr (&cudie, DW_AT_GNU_dwo_name,
8524 &dwo_at))
8525 ?: "<unknown>"));
8526 fprintf (stderr,
8527 "Could not find split unit '%s', id: %" PRIx64 "\n",
8528 dwo_name, unit_id);
8529 }
8530 }
8531 else
8532 {
8533 Dwarf_CU *split_cu = subdie.cu;
8534 dwarf_cu_die (split_cu, &result, NULL, &abbroffset,
8535 &addrsize, &offsize, &unit_id, &subdie_off);
8536 Dwarf_Off offset = cu->start;
8537
8538 if (!silent)
8539 {
8540 printf (_(" Split compilation unit at offset %"
8541 PRIu64 ":\n"
8542 " Version: %" PRIu16
8543 ", Abbreviation section offset: %" PRIu64
8544 ", Address size: %" PRIu8
8545 ", Offset size: %" PRIu8 "\n"),
8546 (uint64_t) offset, version, abbroffset,
8547 addrsize, offsize);
8548 printf (_(" Unit type: %s (%" PRIu8 ")"),
8549 dwarf_unit_name (unit_type), unit_type);
8550 printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
8551 printf ("\n");
8552 }
8553
8554 unit_type = DW_UT_split_compile;
8555 is_split = true;
8556 level = 0;
8557 dies[0] = subdie;
8558 args.cu = dies[0].cu;
8559 args.dbg = split_cu->dbg;
8560 args.is_split = is_split;
8561 goto do_cu;
8562 }
8563 }
8564
8565 /* And again... */
8566 goto next_cu;
8567
8568 do_return:
8569 free (dies);
8570 }
8571
8572 static void
print_debug_info_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8573 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8574 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8575 {
8576 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
8577 }
8578
8579 static void
print_debug_types_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8580 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8581 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8582 {
8583 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
8584 }
8585
8586
8587 static void
print_decoded_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8588 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
8589 GElf_Ehdr *ehdr __attribute__ ((unused)),
8590 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8591 {
8592 printf (_("\
8593 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
8594 elf_ndxscn (scn), section_name (ebl, shdr),
8595 (uint64_t) shdr->sh_offset);
8596
8597 size_t address_size
8598 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
8599
8600 Dwarf_Lines *lines;
8601 size_t nlines;
8602 Dwarf_Off off, next_off = 0;
8603 Dwarf_CU *cu = NULL;
8604 while (dwarf_next_lines (dbg, off = next_off, &next_off, &cu, NULL, NULL,
8605 &lines, &nlines) == 0)
8606 {
8607 Dwarf_Die cudie;
8608 if (cu != NULL && dwarf_cu_info (cu, NULL, NULL, &cudie,
8609 NULL, NULL, NULL, NULL) == 0)
8610 printf (" CU [%" PRIx64 "] %s\n",
8611 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8612 else
8613 {
8614 /* DWARF5 lines can be independent of any CU, but they probably
8615 are used by some CU. Determine the CU this block is for. */
8616 Dwarf_Off cuoffset;
8617 Dwarf_Off ncuoffset = 0;
8618 size_t hsize;
8619 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
8620 NULL, NULL, NULL) == 0)
8621 {
8622 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
8623 continue;
8624 Dwarf_Attribute stmt_list;
8625 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
8626 continue;
8627 Dwarf_Word lineoff;
8628 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
8629 continue;
8630 if (lineoff == off)
8631 {
8632 /* Found the CU. */
8633 cu = cudie.cu;
8634 break;
8635 }
8636 }
8637
8638 if (cu != NULL)
8639 printf (" CU [%" PRIx64 "] %s\n",
8640 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
8641 else
8642 printf (" No CU\n");
8643 }
8644
8645 printf (" line:col SBPE* disc isa op address"
8646 " (Statement Block Prologue Epilogue *End)\n");
8647 const char *last_file = "";
8648 for (size_t n = 0; n < nlines; n++)
8649 {
8650 Dwarf_Line *line = dwarf_onesrcline (lines, n);
8651 if (line == NULL)
8652 {
8653 printf (" dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
8654 continue;
8655 }
8656 Dwarf_Word mtime, length;
8657 const char *file = dwarf_linesrc (line, &mtime, &length);
8658 if (file == NULL)
8659 {
8660 printf (" <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
8661 last_file = "";
8662 }
8663 else if (strcmp (last_file, file) != 0)
8664 {
8665 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
8666 file, mtime, length);
8667 last_file = file;
8668 }
8669
8670 int lineno, colno;
8671 bool statement, endseq, block, prologue_end, epilogue_begin;
8672 unsigned int lineop, isa, disc;
8673 Dwarf_Addr address;
8674 dwarf_lineaddr (line, &address);
8675 dwarf_lineno (line, &lineno);
8676 dwarf_linecol (line, &colno);
8677 dwarf_lineop_index (line, &lineop);
8678 dwarf_linebeginstatement (line, &statement);
8679 dwarf_lineendsequence (line, &endseq);
8680 dwarf_lineblock (line, &block);
8681 dwarf_lineprologueend (line, &prologue_end);
8682 dwarf_lineepiloguebegin (line, &epilogue_begin);
8683 dwarf_lineisa (line, &isa);
8684 dwarf_linediscriminator (line, &disc);
8685
8686 /* End sequence is special, it is one byte past. */
8687 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d ",
8688 lineno, colno,
8689 (statement ? 'S' : ' '),
8690 (block ? 'B' : ' '),
8691 (prologue_end ? 'P' : ' '),
8692 (epilogue_begin ? 'E' : ' '),
8693 (endseq ? '*' : ' '),
8694 disc, isa, lineop);
8695 print_dwarf_addr (dwflmod, address_size,
8696 address - (endseq ? 1 : 0), address);
8697 printf ("\n");
8698
8699 if (endseq)
8700 printf("\n");
8701 }
8702 }
8703 }
8704
8705
8706 /* Print the value of a form.
8707 Returns new value of readp, or readendp on failure. */
8708 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)8709 print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
8710 const unsigned char *readendp, unsigned int offset_len,
8711 Dwarf_Off str_offsets_base)
8712 {
8713 Dwarf_Word val;
8714 unsigned char *endp;
8715 Elf_Data *data;
8716 char *str;
8717 switch (form)
8718 {
8719 case DW_FORM_data1:
8720 if (readendp - readp < 1)
8721 {
8722 invalid_data:
8723 error (0, 0, "invalid data");
8724 return readendp;
8725 }
8726 val = *readp++;
8727 printf (" %" PRIx8, (unsigned int) val);
8728 break;
8729
8730 case DW_FORM_data2:
8731 if (readendp - readp < 2)
8732 goto invalid_data;
8733 val = read_2ubyte_unaligned_inc (dbg, readp);
8734 printf(" %" PRIx16, (unsigned int) val);
8735 break;
8736
8737 case DW_FORM_data4:
8738 if (readendp - readp < 4)
8739 goto invalid_data;
8740 val = read_4ubyte_unaligned_inc (dbg, readp);
8741 printf (" %" PRIx32, (unsigned int) val);
8742 break;
8743
8744 case DW_FORM_data8:
8745 if (readendp - readp < 8)
8746 goto invalid_data;
8747 val = read_8ubyte_unaligned_inc (dbg, readp);
8748 printf (" %" PRIx64, val);
8749 break;
8750
8751 case DW_FORM_sdata:
8752 if (readendp - readp < 1)
8753 goto invalid_data;
8754 get_sleb128 (val, readp, readendp);
8755 printf (" %" PRIx64, val);
8756 break;
8757
8758 case DW_FORM_udata:
8759 if (readendp - readp < 1)
8760 goto invalid_data;
8761 get_uleb128 (val, readp, readendp);
8762 printf (" %" PRIx64, val);
8763 break;
8764
8765 case DW_FORM_block:
8766 if (readendp - readp < 1)
8767 goto invalid_data;
8768 get_uleb128 (val, readp, readendp);
8769 if ((size_t) (readendp - readp) < val)
8770 goto invalid_data;
8771 print_bytes (val, readp);
8772 readp += val;
8773 break;
8774
8775 case DW_FORM_block1:
8776 if (readendp - readp < 1)
8777 goto invalid_data;
8778 val = *readp++;
8779 if ((size_t) (readendp - readp) < val)
8780 goto invalid_data;
8781 print_bytes (val, readp);
8782 readp += val;
8783 break;
8784
8785 case DW_FORM_block2:
8786 if (readendp - readp < 2)
8787 goto invalid_data;
8788 val = read_2ubyte_unaligned_inc (dbg, readp);
8789 if ((size_t) (readendp - readp) < val)
8790 goto invalid_data;
8791 print_bytes (val, readp);
8792 readp += val;
8793 break;
8794
8795 case DW_FORM_block4:
8796 if (readendp - readp < 4)
8797 goto invalid_data;
8798 val = read_4ubyte_unaligned_inc (dbg, readp);
8799 if ((size_t) (readendp - readp) < val)
8800 goto invalid_data;
8801 print_bytes (val, readp);
8802 readp += val;
8803 break;
8804
8805 case DW_FORM_data16:
8806 if (readendp - readp < 16)
8807 goto invalid_data;
8808 print_bytes (16, readp);
8809 readp += 16;
8810 break;
8811
8812 case DW_FORM_flag:
8813 if (readendp - readp < 1)
8814 goto invalid_data;
8815 val = *readp++;
8816 printf ("%s", val != 0 ? yes_str : no_str);
8817 break;
8818
8819 case DW_FORM_string:
8820 endp = memchr (readp, '\0', readendp - readp);
8821 if (endp == NULL)
8822 goto invalid_data;
8823 printf ("%s", readp);
8824 readp = endp + 1;
8825 break;
8826
8827 case DW_FORM_strp:
8828 case DW_FORM_line_strp:
8829 case DW_FORM_strp_sup:
8830 if ((size_t) (readendp - readp) < offset_len)
8831 goto invalid_data;
8832 if (offset_len == 8)
8833 val = read_8ubyte_unaligned_inc (dbg, readp);
8834 else
8835 val = read_4ubyte_unaligned_inc (dbg, readp);
8836 if (form == DW_FORM_strp)
8837 data = dbg->sectiondata[IDX_debug_str];
8838 else if (form == DW_FORM_line_strp)
8839 data = dbg->sectiondata[IDX_debug_line_str];
8840 else /* form == DW_FORM_strp_sup */
8841 {
8842 Dwarf *alt = dwarf_getalt (dbg);
8843 data = alt != NULL ? alt->sectiondata[IDX_debug_str] : NULL;
8844 }
8845 if (data == NULL || val >= data->d_size
8846 || memchr (data->d_buf + val, '\0', data->d_size - val) == NULL)
8847 str = "???";
8848 else
8849 str = (char *) data->d_buf + val;
8850 printf ("%s (%" PRIu64 ")", str, val);
8851 break;
8852
8853 case DW_FORM_sec_offset:
8854 if ((size_t) (readendp - readp) < offset_len)
8855 goto invalid_data;
8856 if (offset_len == 8)
8857 val = read_8ubyte_unaligned_inc (dbg, readp);
8858 else
8859 val = read_4ubyte_unaligned_inc (dbg, readp);
8860 printf ("[%" PRIx64 "]", val);
8861 break;
8862
8863 case DW_FORM_strx:
8864 case DW_FORM_GNU_str_index:
8865 if (readendp - readp < 1)
8866 goto invalid_data;
8867 get_uleb128 (val, readp, readendp);
8868 strx_val:
8869 data = dbg->sectiondata[IDX_debug_str_offsets];
8870 if (data == NULL
8871 || data->d_size - str_offsets_base < val)
8872 str = "???";
8873 else
8874 {
8875 const unsigned char *strreadp = data->d_buf + str_offsets_base + val;
8876 const unsigned char *strreadendp = data->d_buf + data->d_size;
8877 if ((size_t) (strreadendp - strreadp) < offset_len)
8878 str = "???";
8879 else
8880 {
8881 Dwarf_Off idx;
8882 if (offset_len == 8)
8883 idx = read_8ubyte_unaligned (dbg, strreadp);
8884 else
8885 idx = read_4ubyte_unaligned (dbg, strreadp);
8886
8887 data = dbg->sectiondata[IDX_debug_str];
8888 if (data == NULL || idx >= data->d_size
8889 || memchr (data->d_buf + idx, '\0',
8890 data->d_size - idx) == NULL)
8891 str = "???";
8892 else
8893 str = (char *) data->d_buf + idx;
8894 }
8895 }
8896 printf ("%s (%" PRIu64 ")", str, val);
8897 break;
8898
8899 case DW_FORM_strx1:
8900 if (readendp - readp < 1)
8901 goto invalid_data;
8902 val = *readp++;
8903 goto strx_val;
8904
8905 case DW_FORM_strx2:
8906 if (readendp - readp < 2)
8907 goto invalid_data;
8908 val = read_2ubyte_unaligned_inc (dbg, readp);
8909 goto strx_val;
8910
8911 case DW_FORM_strx3:
8912 if (readendp - readp < 3)
8913 goto invalid_data;
8914 val = read_3ubyte_unaligned_inc (dbg, readp);
8915 goto strx_val;
8916
8917 case DW_FORM_strx4:
8918 if (readendp - readp < 4)
8919 goto invalid_data;
8920 val = read_4ubyte_unaligned_inc (dbg, readp);
8921 goto strx_val;
8922
8923 default:
8924 error (0, 0, _("unknown form: %s"), dwarf_form_name (form));
8925 return readendp;
8926 }
8927
8928 return readp;
8929 }
8930
8931 /* Only used via run_advance_pc() macro */
8932 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)8933 run_advance_pc (unsigned int op_advance,
8934 unsigned int minimum_instr_len,
8935 unsigned int max_ops_per_instr,
8936 unsigned int *op_addr_advance,
8937 Dwarf_Word *address,
8938 unsigned int *op_index)
8939 {
8940 const unsigned int advanced_op_index = (*op_index) + op_advance;
8941
8942 *op_addr_advance = minimum_instr_len * (advanced_op_index
8943 / max_ops_per_instr);
8944 *address = *address + *op_addr_advance;
8945 *op_index = advanced_op_index % max_ops_per_instr;
8946 }
8947
8948 static void
print_debug_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8949 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8950 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8951 {
8952 if (decodedline)
8953 {
8954 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
8955 return;
8956 }
8957
8958 Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_line, scn);
8959 if (data == NULL)
8960 return;
8961
8962 printf (_("\
8963 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
8964 elf_ndxscn (scn), section_name (ebl, shdr),
8965 (uint64_t) shdr->sh_offset);
8966
8967 if (shdr->sh_size == 0)
8968 return;
8969
8970 /* There is no functionality in libdw to read the information in the
8971 way it is represented here. Hardcode the decoder. */
8972
8973 const unsigned char *linep = (const unsigned char *) data->d_buf;
8974 const unsigned char *lineendp;
8975
8976 while (linep
8977 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
8978 {
8979 size_t start_offset = linep - (const unsigned char *) data->d_buf;
8980
8981 printf (_("\nTable at offset %zu:\n"), start_offset);
8982
8983 if (unlikely (linep + 4 > lineendp))
8984 goto invalid_data;
8985 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
8986 unsigned int length = 4;
8987 if (unlikely (unit_length == 0xffffffff))
8988 {
8989 if (unlikely (linep + 8 > lineendp))
8990 {
8991 invalid_data:
8992 error (0, 0, _("invalid data in section [%zu] '%s'"),
8993 elf_ndxscn (scn), section_name (ebl, shdr));
8994 return;
8995 }
8996 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
8997 length = 8;
8998 }
8999
9000 /* Check whether we have enough room in the section. */
9001 if (unlikely (unit_length > (size_t) (lineendp - linep)))
9002 goto invalid_data;
9003 lineendp = linep + unit_length;
9004
9005 /* The next element of the header is the version identifier. */
9006 if ((size_t) (lineendp - linep) < 2)
9007 goto invalid_data;
9008 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
9009
9010 size_t address_size
9011 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
9012 unsigned char segment_selector_size = 0;
9013 if (version > 4)
9014 {
9015 if ((size_t) (lineendp - linep) < 2)
9016 goto invalid_data;
9017 address_size = *linep++;
9018 segment_selector_size = *linep++;
9019 }
9020
9021 /* Next comes the header length. */
9022 Dwarf_Word header_length;
9023 if (length == 4)
9024 {
9025 if ((size_t) (lineendp - linep) < 4)
9026 goto invalid_data;
9027 header_length = read_4ubyte_unaligned_inc (dbg, linep);
9028 }
9029 else
9030 {
9031 if ((size_t) (lineendp - linep) < 8)
9032 goto invalid_data;
9033 header_length = read_8ubyte_unaligned_inc (dbg, linep);
9034 }
9035
9036 const unsigned char *header_start = linep;
9037
9038 /* Next the minimum instruction length. */
9039 if ((size_t) (lineendp - linep) < 1)
9040 goto invalid_data;
9041 uint_fast8_t minimum_instr_len = *linep++;
9042
9043 /* Next the maximum operations per instruction, in version 4 format. */
9044 uint_fast8_t max_ops_per_instr;
9045 if (version < 4)
9046 max_ops_per_instr = 1;
9047 else
9048 {
9049 if ((size_t) (lineendp - linep) < 1)
9050 goto invalid_data;
9051 max_ops_per_instr = *linep++;
9052 }
9053
9054 /* We need at least 4 more bytes. */
9055 if ((size_t) (lineendp - linep) < 4)
9056 goto invalid_data;
9057
9058 /* Then the flag determining the default value of the is_stmt
9059 register. */
9060 uint_fast8_t default_is_stmt = *linep++;
9061
9062 /* Now the line base. */
9063 int_fast8_t line_base = *linep++;
9064
9065 /* And the line range. */
9066 uint_fast8_t line_range = *linep++;
9067
9068 /* The opcode base. */
9069 uint_fast8_t opcode_base = *linep++;
9070
9071 /* Print what we got so far. */
9072 printf (_("\n"
9073 " Length: %" PRIu64 "\n"
9074 " DWARF version: %" PRIuFAST16 "\n"
9075 " Prologue length: %" PRIu64 "\n"
9076 " Address size: %zd\n"
9077 " Segment selector size: %zd\n"
9078 " Min instruction length: %" PRIuFAST8 "\n"
9079 " Max operations per instruction: %" PRIuFAST8 "\n"
9080 " Initial value if 'is_stmt': %" PRIuFAST8 "\n"
9081 " Line base: %" PRIdFAST8 "\n"
9082 " Line range: %" PRIuFAST8 "\n"
9083 " Opcode base: %" PRIuFAST8 "\n"
9084 "\n"
9085 "Opcodes:\n"),
9086 (uint64_t) unit_length, version, (uint64_t) header_length,
9087 address_size, (size_t) segment_selector_size,
9088 minimum_instr_len, max_ops_per_instr,
9089 default_is_stmt, line_base,
9090 line_range, opcode_base);
9091
9092 if (version < 2 || version > 5)
9093 {
9094 error (0, 0, _("cannot handle .debug_line version: %u\n"),
9095 (unsigned int) version);
9096 linep = lineendp;
9097 continue;
9098 }
9099
9100 if (address_size != 4 && address_size != 8)
9101 {
9102 error (0, 0, _("cannot handle address size: %u\n"),
9103 (unsigned int) address_size);
9104 linep = lineendp;
9105 continue;
9106 }
9107
9108 if (segment_selector_size != 0)
9109 {
9110 error (0, 0, _("cannot handle segment selector size: %u\n"),
9111 (unsigned int) segment_selector_size);
9112 linep = lineendp;
9113 continue;
9114 }
9115
9116 if (unlikely (linep + opcode_base - 1 >= lineendp))
9117 {
9118 invalid_unit:
9119 error (0, 0,
9120 _("invalid data at offset %tu in section [%zu] '%s'"),
9121 linep - (const unsigned char *) data->d_buf,
9122 elf_ndxscn (scn), section_name (ebl, shdr));
9123 linep = lineendp;
9124 continue;
9125 }
9126 int opcode_base_l10 = 1;
9127 unsigned int tmp = opcode_base;
9128 while (tmp > 10)
9129 {
9130 tmp /= 10;
9131 ++opcode_base_l10;
9132 }
9133 const uint8_t *standard_opcode_lengths = linep - 1;
9134 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
9135 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
9136 " [%*" PRIuFAST8 "] %hhu arguments\n",
9137 (int) linep[cnt - 1]),
9138 opcode_base_l10, cnt, linep[cnt - 1]);
9139 linep += opcode_base - 1;
9140
9141 if (unlikely (linep >= lineendp))
9142 goto invalid_unit;
9143
9144 Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, NULL);
9145
9146 puts (_("\nDirectory table:"));
9147 if (version > 4)
9148 {
9149 struct encpair { uint16_t desc; uint16_t form; };
9150 struct encpair enc[256];
9151
9152 printf (_(" ["));
9153 if ((size_t) (lineendp - linep) < 1)
9154 goto invalid_data;
9155 unsigned char directory_entry_format_count = *linep++;
9156 for (int i = 0; i < directory_entry_format_count; i++)
9157 {
9158 uint16_t desc, form;
9159 if ((size_t) (lineendp - linep) < 1)
9160 goto invalid_data;
9161 get_uleb128 (desc, linep, lineendp);
9162 if ((size_t) (lineendp - linep) < 1)
9163 goto invalid_data;
9164 get_uleb128 (form, linep, lineendp);
9165
9166 enc[i].desc = desc;
9167 enc[i].form = form;
9168
9169 printf ("%s(%s)",
9170 dwarf_line_content_description_name (desc),
9171 dwarf_form_name (form));
9172 if (i + 1 < directory_entry_format_count)
9173 printf (", ");
9174 }
9175 printf ("]\n");
9176
9177 uint64_t directories_count;
9178 if ((size_t) (lineendp - linep) < 1)
9179 goto invalid_data;
9180 get_uleb128 (directories_count, linep, lineendp);
9181
9182 if (directory_entry_format_count == 0
9183 && directories_count != 0)
9184 goto invalid_data;
9185
9186 for (uint64_t i = 0; i < directories_count; i++)
9187 {
9188 printf (" %-5" PRIu64 " ", i);
9189 for (int j = 0; j < directory_entry_format_count; j++)
9190 {
9191 linep = print_form_data (dbg, enc[j].form,
9192 linep, lineendp, length,
9193 str_offsets_base);
9194 if (j + 1 < directory_entry_format_count)
9195 printf (", ");
9196 }
9197 printf ("\n");
9198 if (linep >= lineendp)
9199 goto invalid_unit;
9200 }
9201 }
9202 else
9203 {
9204 while (linep < lineendp && *linep != 0)
9205 {
9206 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
9207 if (unlikely (endp == NULL))
9208 goto invalid_unit;
9209
9210 printf (" %s\n", (char *) linep);
9211
9212 linep = endp + 1;
9213 }
9214 if (linep >= lineendp || *linep != 0)
9215 goto invalid_unit;
9216 /* Skip the final NUL byte. */
9217 ++linep;
9218 }
9219
9220 if (unlikely (linep >= lineendp))
9221 goto invalid_unit;
9222
9223 puts (_("\nFile name table:"));
9224 if (version > 4)
9225 {
9226 struct encpair { uint16_t desc; uint16_t form; };
9227 struct encpair enc[256];
9228
9229 printf (_(" ["));
9230 if ((size_t) (lineendp - linep) < 1)
9231 goto invalid_data;
9232 unsigned char file_name_format_count = *linep++;
9233 for (int i = 0; i < file_name_format_count; i++)
9234 {
9235 uint64_t desc, form;
9236 if ((size_t) (lineendp - linep) < 1)
9237 goto invalid_data;
9238 get_uleb128 (desc, linep, lineendp);
9239 if ((size_t) (lineendp - linep) < 1)
9240 goto invalid_data;
9241 get_uleb128 (form, linep, lineendp);
9242
9243 if (! libdw_valid_user_form (form))
9244 goto invalid_data;
9245
9246 enc[i].desc = desc;
9247 enc[i].form = form;
9248
9249 printf ("%s(%s)",
9250 dwarf_line_content_description_name (desc),
9251 dwarf_form_name (form));
9252 if (i + 1 < file_name_format_count)
9253 printf (", ");
9254 }
9255 printf ("]\n");
9256
9257 uint64_t file_name_count;
9258 if ((size_t) (lineendp - linep) < 1)
9259 goto invalid_data;
9260 get_uleb128 (file_name_count, linep, lineendp);
9261
9262 if (file_name_format_count == 0
9263 && file_name_count != 0)
9264 goto invalid_data;
9265
9266 for (uint64_t i = 0; i < file_name_count; i++)
9267 {
9268 printf (" %-5" PRIu64 " ", i);
9269 for (int j = 0; j < file_name_format_count; j++)
9270 {
9271 linep = print_form_data (dbg, enc[j].form,
9272 linep, lineendp, length,
9273 str_offsets_base);
9274 if (j + 1 < file_name_format_count)
9275 printf (", ");
9276 }
9277 printf ("\n");
9278 if (linep > lineendp)
9279 goto invalid_unit;
9280 }
9281 }
9282 else
9283 {
9284 puts (_(" Entry Dir Time Size Name"));
9285 for (unsigned int cnt = 1; linep < lineendp && *linep != 0; ++cnt)
9286 {
9287 /* First comes the file name. */
9288 char *fname = (char *) linep;
9289 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
9290 if (unlikely (endp == NULL))
9291 goto invalid_unit;
9292 linep = endp + 1;
9293
9294 /* Then the index. */
9295 unsigned int diridx;
9296 if (lineendp - linep < 1)
9297 goto invalid_unit;
9298 get_uleb128 (diridx, linep, lineendp);
9299
9300 /* Next comes the modification time. */
9301 unsigned int mtime;
9302 if (lineendp - linep < 1)
9303 goto invalid_unit;
9304 get_uleb128 (mtime, linep, lineendp);
9305
9306 /* Finally the length of the file. */
9307 unsigned int fsize;
9308 if (lineendp - linep < 1)
9309 goto invalid_unit;
9310 get_uleb128 (fsize, linep, lineendp);
9311
9312 printf (" %-5u %-5u %-9u %-9u %s\n",
9313 cnt, diridx, mtime, fsize, fname);
9314 }
9315 if (linep >= lineendp || *linep != '\0')
9316 goto invalid_unit;
9317 /* Skip the final NUL byte. */
9318 ++linep;
9319 }
9320
9321 unsigned int debug_str_offset = 0;
9322 if (unlikely (linep == header_start + header_length - 4))
9323 {
9324 /* CUBINs contain an unsigned 4-byte offset */
9325 debug_str_offset = read_4ubyte_unaligned_inc (dbg, linep);
9326 }
9327
9328 if (linep == lineendp)
9329 {
9330 puts (_("\nNo line number statements."));
9331 continue;
9332 }
9333
9334 puts (_("\nLine number statements:"));
9335 Dwarf_Word address = 0;
9336 unsigned int op_index = 0;
9337 size_t line = 1;
9338 uint_fast8_t is_stmt = default_is_stmt;
9339
9340 /* Apply the "operation advance" from a special opcode
9341 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
9342 unsigned int op_addr_advance;
9343 #define advance_pc(op_advance) run_advance_pc(op_advance, minimum_instr_len, \
9344 max_ops_per_instr, &op_addr_advance, &address, &op_index)
9345
9346 if (max_ops_per_instr == 0)
9347 {
9348 error (0, 0,
9349 _("invalid maximum operations per instruction is zero"));
9350 linep = lineendp;
9351 continue;
9352 }
9353
9354 while (linep < lineendp)
9355 {
9356 size_t offset = linep - (const unsigned char *) data->d_buf;
9357 unsigned int u128;
9358 int s128;
9359
9360 /* Read the opcode. */
9361 unsigned int opcode = *linep++;
9362
9363 printf (" [%6" PRIx64 "]", (uint64_t)offset);
9364 /* Is this a special opcode? */
9365 if (likely (opcode >= opcode_base))
9366 {
9367 if (unlikely (line_range == 0))
9368 goto invalid_unit;
9369
9370 /* Yes. Handling this is quite easy since the opcode value
9371 is computed with
9372
9373 opcode = (desired line increment - line_base)
9374 + (line_range * address advance) + opcode_base
9375 */
9376 int line_increment = (line_base
9377 + (opcode - opcode_base) % line_range);
9378
9379 /* Perform the increments. */
9380 line += line_increment;
9381 advance_pc ((opcode - opcode_base) / line_range);
9382
9383 printf (_(" special opcode %u: address+%u = "),
9384 opcode, op_addr_advance);
9385 print_dwarf_addr (dwflmod, 0, address, address);
9386 if (op_index > 0)
9387 printf (_(", op_index = %u, line%+d = %zu\n"),
9388 op_index, line_increment, line);
9389 else
9390 printf (_(", line%+d = %zu\n"),
9391 line_increment, line);
9392 }
9393 else if (opcode == 0)
9394 {
9395 /* This an extended opcode. */
9396 if (unlikely (linep + 2 > lineendp))
9397 goto invalid_unit;
9398
9399 /* The length. */
9400 unsigned int len = *linep++;
9401
9402 if (unlikely (linep + len > lineendp))
9403 goto invalid_unit;
9404
9405 /* The sub-opcode. */
9406 opcode = *linep++;
9407
9408 printf (_(" extended opcode %u: "), opcode);
9409
9410 switch (opcode)
9411 {
9412 case DW_LNE_end_sequence:
9413 puts (_(" end of sequence"));
9414
9415 /* Reset the registers we care about. */
9416 address = 0;
9417 op_index = 0;
9418 line = 1;
9419 is_stmt = default_is_stmt;
9420 break;
9421
9422 case DW_LNE_set_address:
9423 op_index = 0;
9424 if (unlikely ((size_t) (lineendp - linep) < address_size))
9425 goto invalid_unit;
9426 if (address_size == 4)
9427 address = read_4ubyte_unaligned_inc (dbg, linep);
9428 else
9429 address = read_8ubyte_unaligned_inc (dbg, linep);
9430 {
9431 printf (_(" set address to "));
9432 print_dwarf_addr (dwflmod, 0, address, address);
9433 printf ("\n");
9434 }
9435 break;
9436
9437 case DW_LNE_define_file:
9438 {
9439 char *fname = (char *) linep;
9440 unsigned char *endp = memchr (linep, '\0',
9441 lineendp - linep);
9442 if (unlikely (endp == NULL))
9443 goto invalid_unit;
9444 linep = endp + 1;
9445
9446 unsigned int diridx;
9447 if (lineendp - linep < 1)
9448 goto invalid_unit;
9449 get_uleb128 (diridx, linep, lineendp);
9450 Dwarf_Word mtime;
9451 if (lineendp - linep < 1)
9452 goto invalid_unit;
9453 get_uleb128 (mtime, linep, lineendp);
9454 Dwarf_Word filelength;
9455 if (lineendp - linep < 1)
9456 goto invalid_unit;
9457 get_uleb128 (filelength, linep, lineendp);
9458
9459 printf (_("\
9460 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
9461 diridx, (uint64_t) mtime, (uint64_t) filelength,
9462 fname);
9463 }
9464 break;
9465
9466 case DW_LNE_set_discriminator:
9467 /* Takes one ULEB128 parameter, the discriminator. */
9468 if (unlikely (standard_opcode_lengths[opcode] != 1
9469 || lineendp - linep < 1))
9470 goto invalid_unit;
9471
9472 get_uleb128 (u128, linep, lineendp);
9473 printf (_(" set discriminator to %u\n"), u128);
9474 break;
9475
9476 case DW_LNE_NVIDIA_inlined_call:
9477 {
9478 if (unlikely (linep >= lineendp))
9479 goto invalid_data;
9480
9481 unsigned int context;
9482 get_uleb128 (context, linep, lineendp);
9483
9484 if (unlikely (linep >= lineendp))
9485 goto invalid_data;
9486
9487 unsigned int function_name;
9488 get_uleb128 (function_name, linep, lineendp);
9489 function_name += debug_str_offset;
9490
9491 Elf_Data *str_data = dbg->sectiondata[IDX_debug_str];
9492 char *function_str;
9493 if (str_data == NULL || function_name >= str_data->d_size
9494 || memchr (str_data->d_buf + function_name, '\0',
9495 str_data->d_size - function_name) == NULL)
9496 function_str = "???";
9497 else
9498 function_str = (char *) str_data->d_buf + function_name;
9499
9500 printf (_(" set inlined context %u,"
9501 " function name %s (0x%x)\n"),
9502 context, function_str, function_name);
9503 break;
9504 }
9505
9506 case DW_LNE_NVIDIA_set_function_name:
9507 {
9508 if (unlikely (linep >= lineendp))
9509 goto invalid_data;
9510
9511 unsigned int function_name;
9512 get_uleb128 (function_name, linep, lineendp);
9513 function_name += debug_str_offset;
9514
9515 Elf_Data *str_data = dbg->sectiondata[IDX_debug_str];
9516 char *function_str;
9517 if (str_data == NULL || function_name >= str_data->d_size
9518 || memchr (str_data->d_buf + function_name, '\0',
9519 str_data->d_size - function_name) == NULL)
9520 function_str = "???";
9521 else
9522 function_str = (char *) str_data->d_buf + function_name;
9523
9524 printf (_(" set function name %s (0x%x)\n"),
9525 function_str, function_name);
9526 }
9527 break;
9528
9529 default:
9530 /* Unknown, ignore it. */
9531 puts (_(" unknown opcode"));
9532 linep += len - 1;
9533 break;
9534 }
9535 }
9536 else if (opcode <= DW_LNS_set_isa)
9537 {
9538 /* This is a known standard opcode. */
9539 switch (opcode)
9540 {
9541 case DW_LNS_copy:
9542 /* Takes no argument. */
9543 puts (_(" copy"));
9544 break;
9545
9546 case DW_LNS_advance_pc:
9547 /* Takes one uleb128 parameter which is added to the
9548 address. */
9549 if (lineendp - linep < 1)
9550 goto invalid_unit;
9551 get_uleb128 (u128, linep, lineendp);
9552 advance_pc (u128);
9553 {
9554 printf (_(" advance address by %u to "),
9555 op_addr_advance);
9556 print_dwarf_addr (dwflmod, 0, address, address);
9557 if (op_index > 0)
9558 printf (_(", op_index to %u"), op_index);
9559 printf ("\n");
9560 }
9561 break;
9562
9563 case DW_LNS_advance_line:
9564 /* Takes one sleb128 parameter which is added to the
9565 line. */
9566 if (lineendp - linep < 1)
9567 goto invalid_unit;
9568 get_sleb128 (s128, linep, lineendp);
9569 line += s128;
9570 printf (_("\
9571 advance line by constant %d to %" PRId64 "\n"),
9572 s128, (int64_t) line);
9573 break;
9574
9575 case DW_LNS_set_file:
9576 /* Takes one uleb128 parameter which is stored in file. */
9577 if (lineendp - linep < 1)
9578 goto invalid_unit;
9579 get_uleb128 (u128, linep, lineendp);
9580 printf (_(" set file to %" PRIu64 "\n"),
9581 (uint64_t) u128);
9582 break;
9583
9584 case DW_LNS_set_column:
9585 /* Takes one uleb128 parameter which is stored in column. */
9586 if (unlikely (standard_opcode_lengths[opcode] != 1
9587 || lineendp - linep < 1))
9588 goto invalid_unit;
9589
9590 get_uleb128 (u128, linep, lineendp);
9591 printf (_(" set column to %" PRIu64 "\n"),
9592 (uint64_t) u128);
9593 break;
9594
9595 case DW_LNS_negate_stmt:
9596 /* Takes no argument. */
9597 is_stmt = 1 - is_stmt;
9598 printf (_(" set '%s' to %" PRIuFAST8 "\n"),
9599 "is_stmt", is_stmt);
9600 break;
9601
9602 case DW_LNS_set_basic_block:
9603 /* Takes no argument. */
9604 puts (_(" set basic block flag"));
9605 break;
9606
9607 case DW_LNS_const_add_pc:
9608 /* Takes no argument. */
9609
9610 if (unlikely (line_range == 0))
9611 goto invalid_unit;
9612
9613 advance_pc ((255 - opcode_base) / line_range);
9614 {
9615 printf (_(" advance address by constant %u to "),
9616 op_addr_advance);
9617 print_dwarf_addr (dwflmod, 0, address, address);
9618 if (op_index > 0)
9619 printf (_(", op_index to %u"), op_index);
9620 printf ("\n");
9621 }
9622 break;
9623
9624 case DW_LNS_fixed_advance_pc:
9625 /* Takes one 16 bit parameter which is added to the
9626 address. */
9627 if (unlikely (standard_opcode_lengths[opcode] != 1
9628 || lineendp - linep < 2))
9629 goto invalid_unit;
9630
9631 u128 = read_2ubyte_unaligned_inc (dbg, linep);
9632 address += u128;
9633 op_index = 0;
9634 {
9635 printf (_("\
9636 advance address by fixed value %u to \n"),
9637 u128);
9638 print_dwarf_addr (dwflmod, 0, address, address);
9639 printf ("\n");
9640 }
9641 break;
9642
9643 case DW_LNS_set_prologue_end:
9644 /* Takes no argument. */
9645 puts (_(" set prologue end flag"));
9646 break;
9647
9648 case DW_LNS_set_epilogue_begin:
9649 /* Takes no argument. */
9650 puts (_(" set epilogue begin flag"));
9651 break;
9652
9653 case DW_LNS_set_isa:
9654 /* Takes one uleb128 parameter which is stored in isa. */
9655 if (unlikely (standard_opcode_lengths[opcode] != 1
9656 || lineendp - linep < 1))
9657 goto invalid_unit;
9658
9659 get_uleb128 (u128, linep, lineendp);
9660 printf (_(" set isa to %u\n"), u128);
9661 break;
9662 }
9663 }
9664 else
9665 {
9666 /* This is a new opcode the generator but not we know about.
9667 Read the parameters associated with it but then discard
9668 everything. Read all the parameters for this opcode. */
9669 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
9670 " unknown opcode with %" PRIu8 " parameters:",
9671 standard_opcode_lengths[opcode]),
9672 standard_opcode_lengths[opcode]);
9673 for (int n = standard_opcode_lengths[opcode];
9674 n > 0 && linep < lineendp; --n)
9675 {
9676 get_uleb128 (u128, linep, lineendp);
9677 if (n != standard_opcode_lengths[opcode])
9678 putc_unlocked (',', stdout);
9679 printf (" %u", u128);
9680 }
9681
9682 /* Next round, ignore this opcode. */
9683 continue;
9684 }
9685 }
9686 }
9687
9688 /* There must only be one data block. */
9689 assert (elf_getdata (scn, data) == NULL);
9690 }
9691
9692
9693 static void
print_debug_loclists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9694 print_debug_loclists_section (Dwfl_Module *dwflmod,
9695 Ebl *ebl,
9696 GElf_Ehdr *ehdr __attribute__ ((unused)),
9697 Elf_Scn *scn, GElf_Shdr *shdr,
9698 Dwarf *dbg)
9699 {
9700 Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_loclists, scn);
9701 if (data == NULL)
9702 return;
9703
9704 printf (_("\
9705 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9706 elf_ndxscn (scn), section_name (ebl, shdr),
9707 (uint64_t) shdr->sh_offset);
9708
9709 /* For the listptr to get the base address/CU. */
9710 sort_listptr (&known_loclistsptr, "loclistsptr");
9711 size_t listptr_idx = 0;
9712
9713 const unsigned char *readp = data->d_buf;
9714 const unsigned char *const dataend = ((unsigned char *) data->d_buf
9715 + data->d_size);
9716 while (readp < dataend)
9717 {
9718 if (unlikely (readp > dataend - 4))
9719 {
9720 invalid_data:
9721 error (0, 0, _("invalid data in section [%zu] '%s'"),
9722 elf_ndxscn (scn), section_name (ebl, shdr));
9723 return;
9724 }
9725
9726 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9727 printf (_("Table at Offset 0x%" PRIx64 ":\n\n"),
9728 (uint64_t) offset);
9729
9730 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
9731 unsigned int offset_size = 4;
9732 if (unlikely (unit_length == 0xffffffff))
9733 {
9734 if (unlikely (readp > dataend - 8))
9735 goto invalid_data;
9736
9737 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
9738 offset_size = 8;
9739 }
9740 printf (_(" Length: %8" PRIu64 "\n"), unit_length);
9741
9742 /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
9743 bytes to complete the header. And this unit cannot go beyond
9744 the section data. */
9745 if (readp > dataend - 8
9746 || unit_length < 8
9747 || unit_length > (uint64_t) (dataend - readp))
9748 goto invalid_data;
9749
9750 const unsigned char *nexthdr = readp + unit_length;
9751
9752 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
9753 printf (_(" DWARF version: %8" PRIu16 "\n"), version);
9754
9755 if (version != 5)
9756 {
9757 error (0, 0, _("Unknown version"));
9758 goto next_table;
9759 }
9760
9761 uint8_t address_size = *readp++;
9762 printf (_(" Address size: %8" PRIu64 "\n"),
9763 (uint64_t) address_size);
9764
9765 if (address_size != 4 && address_size != 8)
9766 {
9767 error (0, 0, _("unsupported address size"));
9768 goto next_table;
9769 }
9770
9771 uint8_t segment_size = *readp++;
9772 printf (_(" Segment size: %8" PRIu64 "\n"),
9773 (uint64_t) segment_size);
9774
9775 if (segment_size != 0)
9776 {
9777 error (0, 0, _("unsupported segment size"));
9778 goto next_table;
9779 }
9780
9781 uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
9782 printf (_(" Offset entries: %8" PRIu64 "\n"),
9783 (uint64_t) offset_entry_count);
9784
9785 /* We need the CU that uses this unit to get the initial base address. */
9786 Dwarf_Addr cu_base = 0;
9787 struct Dwarf_CU *cu = NULL;
9788 if (listptr_cu (&known_loclistsptr, &listptr_idx,
9789 (Dwarf_Off) offset,
9790 (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
9791 &cu_base, &cu)
9792 || split_dwarf_cu_base (dbg, &cu, &cu_base))
9793 {
9794 Dwarf_Die cudie;
9795 if (dwarf_cu_die (cu, &cudie,
9796 NULL, NULL, NULL, NULL,
9797 NULL, NULL) == NULL)
9798 printf (_(" Unknown CU base: "));
9799 else
9800 printf (_(" CU [%6" PRIx64 "] base: "),
9801 dwarf_dieoffset (&cudie));
9802 print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
9803 printf ("\n");
9804 }
9805 else
9806 printf (_(" Not associated with a CU.\n"));
9807
9808 printf ("\n");
9809
9810 const unsigned char *offset_array_start = readp;
9811 if (offset_entry_count > 0)
9812 {
9813 uint64_t max_entries = (unit_length - 8) / offset_size;
9814 if (offset_entry_count > max_entries)
9815 {
9816 error (0, 0,
9817 _("too many offset entries for unit length"));
9818 offset_entry_count = max_entries;
9819 }
9820
9821 printf (_(" Offsets starting at 0x%" PRIx64 ":\n"),
9822 (uint64_t) (offset_array_start
9823 - (unsigned char *) data->d_buf));
9824 for (uint32_t idx = 0; idx < offset_entry_count; idx++)
9825 {
9826 printf (" [%6" PRIu32 "] ", idx);
9827 if (offset_size == 4)
9828 {
9829 uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
9830 printf ("0x%" PRIx32 "\n", off);
9831 }
9832 else
9833 {
9834 uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
9835 printf ("0x%" PRIx64 "\n", off);
9836 }
9837 }
9838 printf ("\n");
9839 }
9840
9841 Dwarf_Addr base = cu_base;
9842 bool start_of_list = true;
9843 while (readp < nexthdr)
9844 {
9845 Dwarf_Off off = (Dwarf_Off) (readp - (unsigned char *) data->d_buf);
9846 if (listptr_attr (&known_loclistsptr, listptr_idx, off,
9847 DW_AT_GNU_locviews))
9848 {
9849 Dwarf_Off next_off = next_listptr_offset (&known_loclistsptr,
9850 &listptr_idx, off);
9851 const unsigned char *locp = readp;
9852 const unsigned char *locendp;
9853 if (next_off == 0
9854 || next_off > (size_t) (nexthdr - ((const unsigned char *)
9855 data->d_buf)))
9856 locendp = nexthdr;
9857 else
9858 locendp = (const unsigned char *) data->d_buf + next_off;
9859
9860 printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9861 (uint64_t) (readp - (unsigned char *) data->d_buf),
9862 (uint64_t) (readp - offset_array_start));
9863
9864 while (locp < locendp)
9865 {
9866 uint64_t v1, v2;
9867 get_uleb128 (v1, locp, locendp);
9868 if (locp >= locendp)
9869 {
9870 printf (_(" <INVALID DATA>\n"));
9871 break;
9872 }
9873 get_uleb128 (v2, locp, locendp);
9874 printf (" view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
9875 }
9876
9877 printf ("\n");
9878 readp = (unsigned char *) locendp;
9879 continue;
9880 }
9881
9882 uint8_t kind = *readp++;
9883 uint64_t op1, op2, len;
9884
9885 /* Skip padding. */
9886 if (start_of_list && kind == DW_LLE_end_of_list)
9887 continue;
9888
9889 if (start_of_list)
9890 {
9891 base = cu_base;
9892 printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9893 (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
9894 (uint64_t) (readp - offset_array_start - 1));
9895 start_of_list = false;
9896 }
9897
9898 printf (" %s", dwarf_loc_list_encoding_name (kind));
9899 switch (kind)
9900 {
9901 case DW_LLE_end_of_list:
9902 start_of_list = true;
9903 printf ("\n\n");
9904 break;
9905
9906 case DW_LLE_base_addressx:
9907 if ((uint64_t) (nexthdr - readp) < 1)
9908 {
9909 invalid_entry:
9910 error (0, 0, _("invalid loclists data"));
9911 goto next_table;
9912 }
9913 get_uleb128 (op1, readp, nexthdr);
9914 printf (" %" PRIx64 "\n", op1);
9915 if (! print_unresolved_addresses)
9916 {
9917 Dwarf_Addr addr;
9918 if (get_indexed_addr (cu, op1, &addr) != 0)
9919 printf (" ???\n");
9920 else
9921 {
9922 printf (" ");
9923 print_dwarf_addr (dwflmod, address_size, addr, addr);
9924 printf ("\n");
9925 }
9926 }
9927 break;
9928
9929 case DW_LLE_startx_endx:
9930 if ((uint64_t) (nexthdr - readp) < 1)
9931 goto invalid_entry;
9932 get_uleb128 (op1, readp, nexthdr);
9933 if ((uint64_t) (nexthdr - readp) < 1)
9934 goto invalid_entry;
9935 get_uleb128 (op2, readp, nexthdr);
9936 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9937 if (! print_unresolved_addresses)
9938 {
9939 Dwarf_Addr addr1;
9940 Dwarf_Addr addr2;
9941 if (get_indexed_addr (cu, op1, &addr1) != 0
9942 || get_indexed_addr (cu, op2, &addr2) != 0)
9943 {
9944 printf (" ???..\n");
9945 printf (" ???\n");
9946 }
9947 else
9948 {
9949 printf (" ");
9950 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9951 printf ("..\n ");
9952 print_dwarf_addr (dwflmod, address_size,
9953 addr2 - 1, addr2);
9954 printf ("\n");
9955 }
9956 }
9957 if ((uint64_t) (nexthdr - readp) < 1)
9958 goto invalid_entry;
9959 get_uleb128 (len, readp, nexthdr);
9960 if ((uint64_t) (nexthdr - readp) < len)
9961 goto invalid_entry;
9962 print_ops (dwflmod, dbg, 8, 8, version,
9963 address_size, offset_size, cu, len, readp);
9964 readp += len;
9965 break;
9966
9967 case DW_LLE_startx_length:
9968 if ((uint64_t) (nexthdr - readp) < 1)
9969 goto invalid_entry;
9970 get_uleb128 (op1, readp, nexthdr);
9971 if ((uint64_t) (nexthdr - readp) < 1)
9972 goto invalid_entry;
9973 get_uleb128 (op2, readp, nexthdr);
9974 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9975 if (! print_unresolved_addresses)
9976 {
9977 Dwarf_Addr addr1;
9978 Dwarf_Addr addr2;
9979 if (get_indexed_addr (cu, op1, &addr1) != 0)
9980 {
9981 printf (" ???..\n");
9982 printf (" ???\n");
9983 }
9984 else
9985 {
9986 addr2 = addr1 + op2;
9987 printf (" ");
9988 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9989 printf ("..\n ");
9990 print_dwarf_addr (dwflmod, address_size,
9991 addr2 - 1, addr2);
9992 printf ("\n");
9993 }
9994 }
9995 if ((uint64_t) (nexthdr - readp) < 1)
9996 goto invalid_entry;
9997 get_uleb128 (len, readp, nexthdr);
9998 if ((uint64_t) (nexthdr - readp) < len)
9999 goto invalid_entry;
10000 print_ops (dwflmod, dbg, 8, 8, version,
10001 address_size, offset_size, cu, len, readp);
10002 readp += len;
10003 break;
10004
10005 case DW_LLE_offset_pair:
10006 if ((uint64_t) (nexthdr - readp) < 1)
10007 goto invalid_entry;
10008 get_uleb128 (op1, readp, nexthdr);
10009 if ((uint64_t) (nexthdr - readp) < 1)
10010 goto invalid_entry;
10011 get_uleb128 (op2, readp, nexthdr);
10012 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
10013 if (! print_unresolved_addresses)
10014 {
10015 op1 += base;
10016 op2 += base;
10017 printf (" ");
10018 print_dwarf_addr (dwflmod, address_size, op1, op1);
10019 printf ("..\n ");
10020 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
10021 printf ("\n");
10022 }
10023 if ((uint64_t) (nexthdr - readp) < 1)
10024 goto invalid_entry;
10025 get_uleb128 (len, readp, nexthdr);
10026 if ((uint64_t) (nexthdr - readp) < len)
10027 goto invalid_entry;
10028 print_ops (dwflmod, dbg, 8, 8, version,
10029 address_size, offset_size, cu, len, readp);
10030 readp += len;
10031 break;
10032
10033 case DW_LLE_default_location:
10034 if ((uint64_t) (nexthdr - readp) < 1)
10035 goto invalid_entry;
10036 get_uleb128 (len, readp, nexthdr);
10037 if ((uint64_t) (nexthdr - readp) < len)
10038 goto invalid_entry;
10039 print_ops (dwflmod, dbg, 8, 8, version,
10040 address_size, offset_size, cu, len, readp);
10041 readp += len;
10042 break;
10043
10044 case DW_LLE_base_address:
10045 if (address_size == 4)
10046 {
10047 if ((uint64_t) (nexthdr - readp) < 4)
10048 goto invalid_entry;
10049 op1 = read_4ubyte_unaligned_inc (dbg, readp);
10050 }
10051 else
10052 {
10053 if ((uint64_t) (nexthdr - readp) < 8)
10054 goto invalid_entry;
10055 op1 = read_8ubyte_unaligned_inc (dbg, readp);
10056 }
10057 base = op1;
10058 printf (" 0x%" PRIx64 "\n", base);
10059 if (! print_unresolved_addresses)
10060 {
10061 printf (" ");
10062 print_dwarf_addr (dwflmod, address_size, base, base);
10063 printf ("\n");
10064 }
10065 break;
10066
10067 case DW_LLE_start_end:
10068 if (address_size == 4)
10069 {
10070 if ((uint64_t) (nexthdr - readp) < 8)
10071 goto invalid_entry;
10072 op1 = read_4ubyte_unaligned_inc (dbg, readp);
10073 op2 = read_4ubyte_unaligned_inc (dbg, readp);
10074 }
10075 else
10076 {
10077 if ((uint64_t) (nexthdr - readp) < 16)
10078 goto invalid_entry;
10079 op1 = read_8ubyte_unaligned_inc (dbg, readp);
10080 op2 = read_8ubyte_unaligned_inc (dbg, readp);
10081 }
10082 printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
10083 if (! print_unresolved_addresses)
10084 {
10085 printf (" ");
10086 print_dwarf_addr (dwflmod, address_size, op1, op1);
10087 printf ("..\n ");
10088 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
10089 printf ("\n");
10090 }
10091 if ((uint64_t) (nexthdr - readp) < 1)
10092 goto invalid_entry;
10093 get_uleb128 (len, readp, nexthdr);
10094 if ((uint64_t) (nexthdr - readp) < len)
10095 goto invalid_entry;
10096 print_ops (dwflmod, dbg, 8, 8, version,
10097 address_size, offset_size, cu, len, readp);
10098 readp += len;
10099 break;
10100
10101 case DW_LLE_start_length:
10102 if (address_size == 4)
10103 {
10104 if ((uint64_t) (nexthdr - readp) < 4)
10105 goto invalid_entry;
10106 op1 = read_4ubyte_unaligned_inc (dbg, readp);
10107 }
10108 else
10109 {
10110 if ((uint64_t) (nexthdr - readp) < 8)
10111 goto invalid_entry;
10112 op1 = read_8ubyte_unaligned_inc (dbg, readp);
10113 }
10114 if ((uint64_t) (nexthdr - readp) < 1)
10115 goto invalid_entry;
10116 get_uleb128 (op2, readp, nexthdr);
10117 printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
10118 if (! print_unresolved_addresses)
10119 {
10120 op2 = op1 + op2;
10121 printf (" ");
10122 print_dwarf_addr (dwflmod, address_size, op1, op1);
10123 printf ("..\n ");
10124 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
10125 printf ("\n");
10126 }
10127 if ((uint64_t) (nexthdr - readp) < 1)
10128 goto invalid_entry;
10129 get_uleb128 (len, readp, nexthdr);
10130 if ((uint64_t) (nexthdr - readp) < len)
10131 goto invalid_entry;
10132 print_ops (dwflmod, dbg, 8, 8, version,
10133 address_size, offset_size, cu, len, readp);
10134 readp += len;
10135 break;
10136
10137 case DW_LLE_GNU_view_pair:
10138 if ((uint64_t) (nexthdr - readp) < 1)
10139 goto invalid_entry;
10140 get_uleb128 (op1, readp, nexthdr);
10141 if ((uint64_t) (nexthdr - readp) < 1)
10142 goto invalid_entry;
10143 get_uleb128 (op2, readp, nexthdr);
10144 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
10145 break;
10146
10147 default:
10148 goto invalid_entry;
10149 }
10150 }
10151
10152 next_table:
10153 if (readp != nexthdr)
10154 {
10155 size_t padding = nexthdr - readp;
10156 printf (_(" %zu padding bytes\n\n"), padding);
10157 readp = nexthdr;
10158 }
10159 }
10160 }
10161
10162
10163 static void
print_debug_loc_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10164 print_debug_loc_section (Dwfl_Module *dwflmod,
10165 Ebl *ebl, GElf_Ehdr *ehdr,
10166 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10167 {
10168 Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_loc, scn);
10169 if (data == NULL)
10170 return;
10171
10172 printf (_("\
10173 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10174 elf_ndxscn (scn), section_name (ebl, shdr),
10175 (uint64_t) shdr->sh_offset);
10176
10177 sort_listptr (&known_locsptr, "loclistptr");
10178 size_t listptr_idx = 0;
10179
10180 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
10181 uint_fast8_t offset_size = 4;
10182
10183 bool first = true;
10184 Dwarf_Addr base = 0;
10185 unsigned char *readp = data->d_buf;
10186 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
10187 Dwarf_CU *last_cu = NULL;
10188 while (readp < endp)
10189 {
10190 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
10191 Dwarf_CU *cu = last_cu;
10192 unsigned int attr = 0;
10193
10194 if (first && skip_listptr_hole (&known_locsptr, &listptr_idx,
10195 &address_size, &offset_size, &base,
10196 &cu, offset, &readp, endp, &attr))
10197 continue;
10198
10199 if (last_cu != cu)
10200 {
10201 Dwarf_Die cudie;
10202 if (dwarf_cu_die (cu, &cudie,
10203 NULL, NULL, NULL, NULL,
10204 NULL, NULL) == NULL)
10205 printf (_("\n Unknown CU base: "));
10206 else
10207 printf (_("\n CU [%6" PRIx64 "] base: "),
10208 dwarf_dieoffset (&cudie));
10209 print_dwarf_addr (dwflmod, address_size, base, base);
10210 printf ("\n");
10211 }
10212 last_cu = cu;
10213
10214 if (attr == DW_AT_GNU_locviews)
10215 {
10216 Dwarf_Off next_off = next_listptr_offset (&known_locsptr,
10217 &listptr_idx, offset);
10218 const unsigned char *locp = readp;
10219 const unsigned char *locendp;
10220 if (next_off == 0
10221 || next_off > (size_t) (endp
10222 - (const unsigned char *) data->d_buf))
10223 locendp = endp;
10224 else
10225 locendp = (const unsigned char *) data->d_buf + next_off;
10226
10227 while (locp < locendp)
10228 {
10229 uint64_t v1, v2;
10230 get_uleb128 (v1, locp, locendp);
10231 if (locp >= locendp)
10232 {
10233 printf (_(" [%6tx] <INVALID DATA>\n"), offset);
10234 break;
10235 }
10236 get_uleb128 (v2, locp, locendp);
10237 if (first) /* First view pair in a list. */
10238 printf (" [%6tx] ", offset);
10239 else
10240 printf (" ");
10241 printf ("view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
10242 first = false;
10243 }
10244
10245 first = true;
10246 readp = (unsigned char *) locendp;
10247 continue;
10248 }
10249
10250 /* GNU DebugFission encoded addresses as addrx. */
10251 bool is_debugfission = ((cu != NULL
10252 || split_dwarf_cu_base (dbg, &cu, &base))
10253 && (cu->version < 5
10254 && cu->unit_type == DW_UT_split_compile));
10255 if (!is_debugfission
10256 && unlikely (data->d_size - offset < (size_t) address_size * 2))
10257 {
10258 invalid_data:
10259 printf (_(" [%6tx] <INVALID DATA>\n"), offset);
10260 break;
10261 }
10262
10263 Dwarf_Addr begin;
10264 Dwarf_Addr end;
10265 bool use_base = true;
10266 if (is_debugfission)
10267 {
10268 const unsigned char *locp = readp;
10269 const unsigned char *locendp = readp + data->d_size;
10270 if (locp >= locendp)
10271 goto invalid_data;
10272
10273 Dwarf_Word idx;
10274 unsigned char code = *locp++;
10275 switch (code)
10276 {
10277 case DW_LLE_GNU_end_of_list_entry:
10278 begin = 0;
10279 end = 0;
10280 break;
10281
10282 case DW_LLE_GNU_base_address_selection_entry:
10283 if (locp >= locendp)
10284 goto invalid_data;
10285 begin = (Dwarf_Addr) -1;
10286 get_uleb128 (idx, locp, locendp);
10287 if (get_indexed_addr (cu, idx, &end) != 0)
10288 end = idx; /* ... */
10289 break;
10290
10291 case DW_LLE_GNU_start_end_entry:
10292 if (locp >= locendp)
10293 goto invalid_data;
10294 get_uleb128 (idx, locp, locendp);
10295 if (get_indexed_addr (cu, idx, &begin) != 0)
10296 begin = idx; /* ... */
10297 if (locp >= locendp)
10298 goto invalid_data;
10299 get_uleb128 (idx, locp, locendp);
10300 if (get_indexed_addr (cu, idx, &end) != 0)
10301 end = idx; /* ... */
10302 use_base = false;
10303 break;
10304
10305 case DW_LLE_GNU_start_length_entry:
10306 if (locp >= locendp)
10307 goto invalid_data;
10308 get_uleb128 (idx, locp, locendp);
10309 if (get_indexed_addr (cu, idx, &begin) != 0)
10310 begin = idx; /* ... */
10311 if (locendp - locp < 4)
10312 goto invalid_data;
10313 end = read_4ubyte_unaligned_inc (dbg, locp);
10314 end += begin;
10315 use_base = false;
10316 break;
10317
10318 default:
10319 goto invalid_data;
10320 }
10321
10322 readp = (unsigned char *) locp;
10323 }
10324 else if (address_size == 8)
10325 {
10326 begin = read_8ubyte_unaligned_inc (dbg, readp);
10327 end = read_8ubyte_unaligned_inc (dbg, readp);
10328 }
10329 else
10330 {
10331 begin = read_4ubyte_unaligned_inc (dbg, readp);
10332 end = read_4ubyte_unaligned_inc (dbg, readp);
10333 if (begin == (Dwarf_Addr) (uint32_t) -1)
10334 begin = (Dwarf_Addr) -1l;
10335 }
10336
10337 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
10338 {
10339 if (first)
10340 printf (" [%6tx] ", offset);
10341 else
10342 printf (" ");
10343 puts (_("base address"));
10344 printf (" ");
10345 print_dwarf_addr (dwflmod, address_size, end, end);
10346 printf ("\n");
10347 base = end;
10348 first = false;
10349 }
10350 else if (begin == 0 && end == 0) /* End of list entry. */
10351 {
10352 if (first)
10353 printf (_(" [%6tx] empty list\n"), offset);
10354 first = true;
10355 }
10356 else
10357 {
10358 /* We have a location expression entry. */
10359 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
10360
10361 if (first) /* First entry in a list. */
10362 printf (" [%6tx] ", offset);
10363 else
10364 printf (" ");
10365
10366 printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
10367 if (! print_unresolved_addresses)
10368 {
10369 Dwarf_Addr dab = use_base ? base + begin : begin;
10370 Dwarf_Addr dae = use_base ? base + end : end;
10371 printf (" ");
10372 print_dwarf_addr (dwflmod, address_size, dab, dab);
10373 printf ("..\n ");
10374 print_dwarf_addr (dwflmod, address_size, dae - 1, dae);
10375 printf ("\n");
10376 }
10377
10378 if (endp - readp <= (ptrdiff_t) len)
10379 {
10380 fputs (_(" <INVALID DATA>\n"), stdout);
10381 break;
10382 }
10383
10384 print_ops (dwflmod, dbg, 11, 11,
10385 cu != NULL ? cu->version : 3,
10386 address_size, offset_size, cu, len, readp);
10387
10388 first = false;
10389 readp += len;
10390 }
10391 }
10392 }
10393
10394 struct mac_culist
10395 {
10396 Dwarf_Die die;
10397 Dwarf_Off offset;
10398 Dwarf_Files *files;
10399 struct mac_culist *next;
10400 };
10401
10402
10403 static int
mac_compare(const void * p1,const void * p2)10404 mac_compare (const void *p1, const void *p2)
10405 {
10406 struct mac_culist *m1 = (struct mac_culist *) p1;
10407 struct mac_culist *m2 = (struct mac_culist *) p2;
10408
10409 if (m1->offset < m2->offset)
10410 return -1;
10411 if (m1->offset > m2->offset)
10412 return 1;
10413 return 0;
10414 }
10415
10416
10417 static void
print_debug_macinfo_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10418 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10419 Ebl *ebl,
10420 GElf_Ehdr *ehdr __attribute__ ((unused)),
10421 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10422 {
10423 Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_macinfo, scn);
10424 if (data == NULL)
10425 return;
10426
10427 printf (_("\
10428 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10429 elf_ndxscn (scn), section_name (ebl, shdr),
10430 (uint64_t) shdr->sh_offset);
10431 putc_unlocked ('\n', stdout);
10432
10433 /* There is no function in libdw to iterate over the raw content of
10434 the section but it is easy enough to do. */
10435
10436 /* Get the source file information for all CUs. */
10437 Dwarf_Off offset;
10438 Dwarf_Off ncu = 0;
10439 size_t hsize;
10440 struct mac_culist *culist = NULL;
10441 size_t nculist = 0;
10442 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
10443 {
10444 Dwarf_Die cudie;
10445 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
10446 continue;
10447
10448 Dwarf_Attribute attr;
10449 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
10450 continue;
10451
10452 Dwarf_Word macoff;
10453 if (dwarf_formudata (&attr, &macoff) != 0)
10454 continue;
10455
10456 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
10457 newp->die = cudie;
10458 newp->offset = macoff;
10459 newp->files = NULL;
10460 newp->next = culist;
10461 culist = newp;
10462 ++nculist;
10463 }
10464
10465 /* Convert the list into an array for easier consumption. */
10466 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
10467 * sizeof (*cus));
10468 /* Add sentinel. */
10469 cus[nculist].offset = data->d_size;
10470 cus[nculist].files = (Dwarf_Files *) -1l;
10471 if (nculist > 0)
10472 {
10473 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
10474 {
10475 assert (cnt < nculist);
10476 cus[cnt] = *culist;
10477 culist = culist->next;
10478 }
10479
10480 /* Sort the array according to the offset in the .debug_macinfo
10481 section. Note we keep the sentinel at the end. */
10482 qsort (cus, nculist, sizeof (*cus), mac_compare);
10483 }
10484
10485 const unsigned char *readp = (const unsigned char *) data->d_buf;
10486 const unsigned char *readendp = readp + data->d_size;
10487 int level = 1;
10488
10489 while (readp < readendp)
10490 {
10491 unsigned int opcode = *readp++;
10492 unsigned int u128;
10493 unsigned int u128_2;
10494 const unsigned char *endp;
10495
10496 switch (opcode)
10497 {
10498 case DW_MACINFO_define:
10499 case DW_MACINFO_undef:
10500 case DW_MACINFO_vendor_ext:
10501 /* For the first two opcodes the parameters are
10502 line, string
10503 For the latter
10504 number, string.
10505 We can treat these cases together. */
10506 get_uleb128 (u128, readp, readendp);
10507
10508 endp = memchr (readp, '\0', readendp - readp);
10509 if (unlikely (endp == NULL))
10510 {
10511 printf (_("\
10512 %*s*** non-terminated string at end of section"),
10513 level, "");
10514 return;
10515 }
10516
10517 if (opcode == DW_MACINFO_define)
10518 printf ("%*s#define %s, line %u\n",
10519 level, "", (char *) readp, u128);
10520 else if (opcode == DW_MACINFO_undef)
10521 printf ("%*s#undef %s, line %u\n",
10522 level, "", (char *) readp, u128);
10523 else
10524 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
10525
10526 readp = endp + 1;
10527 break;
10528
10529 case DW_MACINFO_start_file:
10530 /* The two parameters are line and file index, in this order. */
10531 get_uleb128 (u128, readp, readendp);
10532 if (readendp - readp < 1)
10533 {
10534 printf (_("\
10535 %*s*** missing DW_MACINFO_start_file argument at end of section"),
10536 level, "");
10537 return;
10538 }
10539 get_uleb128 (u128_2, readp, readendp);
10540
10541 /* Find the CU DIE for this file. */
10542 size_t macoff = readp - (const unsigned char *) data->d_buf;
10543 const char *fname = "???";
10544 if (macoff >= cus[0].offset && cus[0].offset != data->d_size)
10545 {
10546 while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
10547 ++cus;
10548
10549 if (cus[0].files == NULL
10550 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
10551 cus[0].files = (Dwarf_Files *) -1l;
10552
10553 if (cus[0].files != (Dwarf_Files *) -1l)
10554 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
10555 ?: "???");
10556 }
10557
10558 printf ("%*sstart_file %u, [%u] %s\n",
10559 level, "", u128, u128_2, fname);
10560 ++level;
10561 break;
10562
10563 case DW_MACINFO_end_file:
10564 --level;
10565 printf ("%*send_file\n", level, "");
10566 /* Nothing more to do. */
10567 break;
10568
10569 default:
10570 // XXX gcc seems to generate files with a trailing zero.
10571 if (unlikely (opcode != 0 || readp != readendp))
10572 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
10573 break;
10574 }
10575 }
10576 }
10577
10578
10579 static void
print_debug_macro_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10580 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10581 Ebl *ebl,
10582 GElf_Ehdr *ehdr __attribute__ ((unused)),
10583 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10584 {
10585 Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_macro, scn);
10586 if (data == NULL)
10587 return;
10588
10589 printf (_("\
10590 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10591 elf_ndxscn (scn), section_name (ebl, shdr),
10592 (uint64_t) shdr->sh_offset);
10593 putc_unlocked ('\n', stdout);
10594
10595 /* Get the source file information for all CUs. Uses same
10596 datastructure as macinfo. But uses offset field to directly
10597 match .debug_line offset. And just stored in a list. */
10598 Dwarf_Off offset;
10599 Dwarf_Off ncu = 0;
10600 size_t hsize;
10601 struct mac_culist *culist = NULL;
10602 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
10603 {
10604 Dwarf_Die cudie;
10605 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
10606 continue;
10607
10608 Dwarf_Attribute attr;
10609 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
10610 continue;
10611
10612 Dwarf_Word lineoff;
10613 if (dwarf_formudata (&attr, &lineoff) != 0)
10614 continue;
10615
10616 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
10617 newp->die = cudie;
10618 newp->offset = lineoff;
10619 newp->files = NULL;
10620 newp->next = culist;
10621 culist = newp;
10622 }
10623
10624 const unsigned char *readp = (const unsigned char *) data->d_buf;
10625 const unsigned char *readendp = readp + data->d_size;
10626
10627 while (readp < readendp)
10628 {
10629 printf (_(" Offset: 0x%" PRIx64 "\n"),
10630 (uint64_t) (readp - (const unsigned char *) data->d_buf));
10631
10632 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
10633 // optional vendor extension macro entry table.
10634 if (readp + 2 > readendp)
10635 {
10636 invalid_data:
10637 error (0, 0, _("invalid data"));
10638 return;
10639 }
10640 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
10641 printf (_(" Version: %" PRIu16 "\n"), vers);
10642
10643 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
10644 // 5 when it gets standardized.
10645 if (vers != 4 && vers != 5)
10646 {
10647 printf (_(" unknown version, cannot parse section\n"));
10648 return;
10649 }
10650
10651 if (readp + 1 > readendp)
10652 goto invalid_data;
10653 const unsigned char flag = *readp++;
10654 printf (_(" Flag: 0x%" PRIx8), flag);
10655 if (flag != 0)
10656 {
10657 printf (" (");
10658 if ((flag & 0x01) != 0)
10659 {
10660 printf ("offset_size");
10661 if ((flag & 0xFE) != 0)
10662 printf (", ");
10663 }
10664 if ((flag & 0x02) != 0)
10665 {
10666 printf ("debug_line_offset");
10667 if ((flag & 0xFC) != 0)
10668 printf (", ");
10669 }
10670 if ((flag & 0x04) != 0)
10671 {
10672 printf ("operands_table");
10673 if ((flag & 0xF8) != 0)
10674 printf (", ");
10675 }
10676 if ((flag & 0xF8) != 0)
10677 printf ("unknown");
10678 printf (")");
10679 }
10680 printf ("\n");
10681
10682 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
10683 printf (_(" Offset length: %" PRIu8 "\n"), offset_len);
10684 Dwarf_Off line_offset = -1;
10685 if (flag & 0x02)
10686 {
10687 if (offset_len == 8)
10688 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
10689 else
10690 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
10691 printf (_(" .debug_line offset: 0x%" PRIx64 "\n"),
10692 line_offset);
10693 }
10694
10695 struct mac_culist *cu = NULL;
10696 if (line_offset != (Dwarf_Off) -1)
10697 {
10698 cu = culist;
10699 while (cu != NULL && line_offset != cu->offset)
10700 cu = cu->next;
10701 }
10702
10703 Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, (cu != NULL
10704 ? cu->die.cu
10705 : NULL));
10706
10707 const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user + 1];
10708 memset (vendor, 0, sizeof vendor);
10709 if (flag & 0x04)
10710 {
10711 // 1 byte length, for each item, 1 byte opcode, uleb128 number
10712 // of arguments, for each argument 1 byte form code.
10713 if (readp + 1 > readendp)
10714 goto invalid_data;
10715 unsigned int tlen = *readp++;
10716 printf (_(" extension opcode table, %" PRIu8 " items:\n"),
10717 tlen);
10718 for (unsigned int i = 0; i < tlen; i++)
10719 {
10720 if (readp + 1 > readendp)
10721 goto invalid_data;
10722 unsigned int opcode = *readp++;
10723 printf (_(" [%" PRIx8 "]"), opcode);
10724 if (opcode < DW_MACRO_lo_user
10725 || opcode > DW_MACRO_hi_user)
10726 goto invalid_data;
10727 // Record the start of description for this vendor opcode.
10728 // uleb128 nr args, 1 byte per arg form.
10729 vendor[opcode - DW_MACRO_lo_user] = readp;
10730 if (readp + 1 > readendp)
10731 goto invalid_data;
10732 unsigned int args = *readp++;
10733 if (args > 0)
10734 {
10735 printf (_(" %" PRIu8 " arguments:"), args);
10736 while (args > 0)
10737 {
10738 if (readp + 1 > readendp)
10739 goto invalid_data;
10740 unsigned int form = *readp++;
10741 printf (" %s", dwarf_form_name (form));
10742 if (! libdw_valid_user_form (form))
10743 goto invalid_data;
10744 args--;
10745 if (args > 0)
10746 putchar_unlocked (',');
10747 }
10748 }
10749 else
10750 printf (_(" no arguments."));
10751 putchar_unlocked ('\n');
10752 }
10753 }
10754 putchar_unlocked ('\n');
10755
10756 int level = 1;
10757 if (readp + 1 > readendp)
10758 goto invalid_data;
10759 unsigned int opcode = *readp++;
10760 while (opcode != 0)
10761 {
10762 unsigned int u128;
10763 unsigned int u128_2;
10764 const unsigned char *endp;
10765 uint64_t off;
10766
10767 switch (opcode)
10768 {
10769 case DW_MACRO_start_file:
10770 get_uleb128 (u128, readp, readendp);
10771 if (readp >= readendp)
10772 goto invalid_data;
10773 get_uleb128 (u128_2, readp, readendp);
10774
10775 /* Find the CU DIE that matches this line offset. */
10776 const char *fname = "???";
10777 if (cu != NULL)
10778 {
10779 if (cu->files == NULL
10780 && dwarf_getsrcfiles (&cu->die, &cu->files,
10781 NULL) != 0)
10782 cu->files = (Dwarf_Files *) -1l;
10783
10784 if (cu->files != (Dwarf_Files *) -1l)
10785 fname = (dwarf_filesrc (cu->files, u128_2,
10786 NULL, NULL) ?: "???");
10787 }
10788 printf ("%*sstart_file %u, [%u] %s\n",
10789 level, "", u128, u128_2, fname);
10790 ++level;
10791 break;
10792
10793 case DW_MACRO_end_file:
10794 --level;
10795 printf ("%*send_file\n", level, "");
10796 break;
10797
10798 case DW_MACRO_define:
10799 get_uleb128 (u128, readp, readendp);
10800 endp = memchr (readp, '\0', readendp - readp);
10801 if (endp == NULL)
10802 goto invalid_data;
10803 printf ("%*s#define %s, line %u\n",
10804 level, "", readp, u128);
10805 readp = endp + 1;
10806 break;
10807
10808 case DW_MACRO_undef:
10809 get_uleb128 (u128, readp, readendp);
10810 endp = memchr (readp, '\0', readendp - readp);
10811 if (endp == NULL)
10812 goto invalid_data;
10813 printf ("%*s#undef %s, line %u\n",
10814 level, "", readp, u128);
10815 readp = endp + 1;
10816 break;
10817
10818 case DW_MACRO_define_strp:
10819 get_uleb128 (u128, readp, readendp);
10820 if (readp + offset_len > readendp)
10821 goto invalid_data;
10822 if (offset_len == 8)
10823 off = read_8ubyte_unaligned_inc (dbg, readp);
10824 else
10825 off = read_4ubyte_unaligned_inc (dbg, readp);
10826 printf ("%*s#define %s, line %u (indirect)\n",
10827 level, "", dwarf_getstring (dbg, off, NULL), u128);
10828 break;
10829
10830 case DW_MACRO_undef_strp:
10831 get_uleb128 (u128, readp, readendp);
10832 if (readp + offset_len > readendp)
10833 goto invalid_data;
10834 if (offset_len == 8)
10835 off = read_8ubyte_unaligned_inc (dbg, readp);
10836 else
10837 off = read_4ubyte_unaligned_inc (dbg, readp);
10838 printf ("%*s#undef %s, line %u (indirect)\n",
10839 level, "", dwarf_getstring (dbg, off, NULL), u128);
10840 break;
10841
10842 case DW_MACRO_import:
10843 if (readp + offset_len > readendp)
10844 goto invalid_data;
10845 if (offset_len == 8)
10846 off = read_8ubyte_unaligned_inc (dbg, readp);
10847 else
10848 off = read_4ubyte_unaligned_inc (dbg, readp);
10849 printf ("%*s#include offset 0x%" PRIx64 "\n",
10850 level, "", off);
10851 break;
10852
10853 case DW_MACRO_define_sup:
10854 get_uleb128 (u128, readp, readendp);
10855 if (readp + offset_len > readendp)
10856 goto invalid_data;
10857 printf ("%*s#define ", level, "");
10858 readp = print_form_data (dbg, DW_FORM_strp_sup,
10859 readp, readendp, offset_len,
10860 str_offsets_base);
10861 printf (", line %u (sup)\n", u128);
10862 break;
10863
10864 case DW_MACRO_undef_sup:
10865 get_uleb128 (u128, readp, readendp);
10866 if (readp + offset_len > readendp)
10867 goto invalid_data;
10868 printf ("%*s#undef ", level, "");
10869 readp = print_form_data (dbg, DW_FORM_strp_sup,
10870 readp, readendp, offset_len,
10871 str_offsets_base);
10872 printf (", line %u (sup)\n", u128);
10873 break;
10874
10875 case DW_MACRO_import_sup:
10876 if (readp + offset_len > readendp)
10877 goto invalid_data;
10878 if (offset_len == 8)
10879 off = read_8ubyte_unaligned_inc (dbg, readp);
10880 else
10881 off = read_4ubyte_unaligned_inc (dbg, readp);
10882 // XXX Needs support for reading from supplementary object file.
10883 printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
10884 level, "", off);
10885 break;
10886
10887 case DW_MACRO_define_strx:
10888 get_uleb128 (u128, readp, readendp);
10889 if (readp + offset_len > readendp)
10890 goto invalid_data;
10891 printf ("%*s#define ", level, "");
10892 readp = print_form_data (dbg, DW_FORM_strx,
10893 readp, readendp, offset_len,
10894 str_offsets_base);
10895 printf (", line %u (strx)\n", u128);
10896 break;
10897
10898 case DW_MACRO_undef_strx:
10899 get_uleb128 (u128, readp, readendp);
10900 if (readp + offset_len > readendp)
10901 goto invalid_data;
10902 printf ("%*s#undef ", level, "");
10903 readp = print_form_data (dbg, DW_FORM_strx,
10904 readp, readendp, offset_len,
10905 str_offsets_base);
10906 printf (", line %u (strx)\n", u128);
10907 break;
10908
10909 default:
10910 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
10911 if (opcode < DW_MACRO_lo_user
10912 || opcode > DW_MACRO_lo_user
10913 || vendor[opcode - DW_MACRO_lo_user] == NULL)
10914 goto invalid_data;
10915
10916 const unsigned char *op_desc;
10917 op_desc = vendor[opcode - DW_MACRO_lo_user];
10918
10919 // Just skip the arguments, we cannot really interpret them,
10920 // but print as much as we can.
10921 unsigned int args = *op_desc++;
10922 while (args > 0 && readp < readendp)
10923 {
10924 unsigned int form = *op_desc++;
10925 readp = print_form_data (dbg, form, readp, readendp,
10926 offset_len, str_offsets_base);
10927 args--;
10928 if (args > 0)
10929 printf (", ");
10930 }
10931 putchar_unlocked ('\n');
10932 }
10933
10934 if (readp + 1 > readendp)
10935 goto invalid_data;
10936 opcode = *readp++;
10937 if (opcode == 0)
10938 putchar_unlocked ('\n');
10939 }
10940 }
10941 }
10942
10943
10944 /* Callback for printing global names. */
10945 static int
print_pubnames(Dwarf * dbg,Dwarf_Global * global,void * arg)10946 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
10947 void *arg)
10948 {
10949 int *np = (int *) arg;
10950
10951 printf (_(" [%5d] DIE offset: %6" PRId64
10952 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
10953 (*np)++, global->die_offset, global->cu_offset, global->name);
10954
10955 return 0;
10956 }
10957
10958
10959 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
10960 static void
print_debug_pubnames_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10961 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10962 Ebl *ebl,
10963 GElf_Ehdr *ehdr __attribute__ ((unused)),
10964 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10965 {
10966 /* Check section actually exists. */
10967 if (get_debug_elf_data (dbg, ebl, IDX_debug_pubnames, scn) == NULL)
10968 return;
10969
10970 printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10971 elf_ndxscn (scn), section_name (ebl, shdr),
10972 (uint64_t) shdr->sh_offset);
10973
10974 int n = 0;
10975 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
10976 }
10977
10978 /* Print the content of the DWARF string section '.debug_str'
10979 or 'debug_line_str'. */
10980 static void
print_debug_str_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10981 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10982 Ebl *ebl,
10983 GElf_Ehdr *ehdr __attribute__ ((unused)),
10984 Elf_Scn *scn, GElf_Shdr *shdr,
10985 Dwarf *dbg __attribute__ ((unused)))
10986 {
10987 const char *name = section_name (ebl, shdr);
10988 int idx = ((name != NULL && strstr (name, "debug_line_str") != NULL)
10989 ? IDX_debug_line_str : IDX_debug_str);
10990 Elf_Data *data = get_debug_elf_data (dbg, ebl, idx, scn);
10991 if (data == NULL)
10992 return;
10993
10994 const size_t sh_size = data->d_size;
10995
10996 /* Compute floor(log16(shdr->sh_size)). */
10997 GElf_Addr tmp = sh_size;
10998 int digits = 1;
10999 while (tmp >= 16)
11000 {
11001 ++digits;
11002 tmp >>= 4;
11003 }
11004 digits = MAX (4, digits);
11005
11006 printf (_("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
11007 " %*s String\n"),
11008 elf_ndxscn (scn),
11009 section_name (ebl, shdr), (uint64_t) shdr->sh_offset,
11010 /* TRANS: the debugstr| prefix makes the string unique. */
11011 digits + 2, sgettext ("debugstr|Offset"));
11012
11013 Dwarf_Off offset = 0;
11014 while (offset < sh_size)
11015 {
11016 size_t len;
11017 const char *str = (const char *) data->d_buf + offset;
11018 const char *endp = memchr (str, '\0', sh_size - offset);
11019 if (unlikely (endp == NULL))
11020 {
11021 printf (_(" *** error, missing string terminator\n"));
11022 break;
11023 }
11024
11025 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
11026 len = endp - str;
11027 offset += len + 1;
11028 }
11029 }
11030
11031 static void
print_debug_str_offsets_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)11032 print_debug_str_offsets_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
11033 Ebl *ebl,
11034 GElf_Ehdr *ehdr __attribute__ ((unused)),
11035 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
11036 {
11037 Elf_Data *data = get_debug_elf_data (dbg, ebl, IDX_debug_str_offsets, scn);
11038 if (data == NULL)
11039 return;
11040
11041 printf (_("\
11042 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
11043 elf_ndxscn (scn), section_name (ebl, shdr),
11044 (uint64_t) shdr->sh_offset);
11045
11046 if (shdr->sh_size == 0)
11047 return;
11048
11049 size_t idx = 0;
11050 sort_listptr (&known_stroffbases, "str_offsets");
11051
11052 const unsigned char *start = (const unsigned char *) data->d_buf;
11053 const unsigned char *readp = start;
11054 const unsigned char *readendp = ((const unsigned char *) data->d_buf
11055 + data->d_size);
11056
11057 while (readp < readendp)
11058 {
11059 /* Most string offset tables will have a header. For split
11060 dwarf unit GNU DebugFission didn't add one. But they were
11061 also only defined for split units (main or skeleton units
11062 didn't have indirect strings). So if we don't have a
11063 DW_AT_str_offsets_base at all and this is offset zero, then
11064 just start printing offsets immediately, if this is a .dwo
11065 section. */
11066 Dwarf_Off off = (Dwarf_Off) (readp
11067 - (const unsigned char *) data->d_buf);
11068
11069 printf ("Table at offset %" PRIx64 " ", off);
11070
11071 struct listptr *listptr = get_listptr (&known_stroffbases, idx++);
11072 const unsigned char *next_unitp = readendp;
11073 uint8_t offset_size;
11074 bool has_header;
11075 if (listptr == NULL)
11076 {
11077 /* This can happen for .dwo files. There is only an header
11078 in the case this is a version 5 split DWARF file. */
11079 Dwarf_CU *cu;
11080 uint8_t unit_type;
11081 if (dwarf_get_units (dbg, NULL, &cu, NULL, &unit_type,
11082 NULL, NULL) != 0)
11083 {
11084 error (0, 0, "Warning: Cannot find any DWARF unit.");
11085 /* Just guess some values. */
11086 has_header = false;
11087 offset_size = 4;
11088 }
11089 else if (off == 0
11090 && (unit_type == DW_UT_split_type
11091 || unit_type == DW_UT_split_compile))
11092 {
11093 has_header = cu->version > 4;
11094 offset_size = cu->offset_size;
11095 }
11096 else
11097 {
11098 error (0, 0,
11099 "Warning: No CU references .debug_str_offsets after %"
11100 PRIx64, off);
11101 has_header = cu->version > 4;
11102 offset_size = cu->offset_size;
11103 }
11104 printf ("\n");
11105 }
11106 else
11107 {
11108 /* This must be DWARF5, since GNU DebugFission didn't define
11109 DW_AT_str_offsets_base. */
11110 has_header = true;
11111
11112 Dwarf_Die cudie;
11113 if (dwarf_cu_die (listptr->cu, &cudie,
11114 NULL, NULL, NULL, NULL,
11115 NULL, NULL) == NULL)
11116 printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
11117 else
11118 printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
11119 }
11120
11121 if (has_header)
11122 {
11123 uint64_t unit_length;
11124 uint16_t version;
11125 uint16_t padding;
11126
11127 unit_length = read_4ubyte_unaligned_inc (dbg, readp);
11128 if (unlikely (unit_length == 0xffffffff))
11129 {
11130 if (unlikely (readp > readendp - 8))
11131 {
11132 invalid_data:
11133 error (0, 0, "Invalid data");
11134 return;
11135 }
11136 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
11137 offset_size = 8;
11138 }
11139 else
11140 offset_size = 4;
11141
11142 printf ("\n");
11143 printf (_(" Length: %8" PRIu64 "\n"),
11144 unit_length);
11145 printf (_(" Offset size: %8" PRIu8 "\n"),
11146 offset_size);
11147
11148 /* We need at least 2-bytes (version) + 2-bytes (padding) =
11149 4 bytes to complete the header. And this unit cannot go
11150 beyond the section data. */
11151 if (readp > readendp - 4
11152 || unit_length < 4
11153 || unit_length > (uint64_t) (readendp - readp))
11154 goto invalid_data;
11155
11156 next_unitp = readp + unit_length;
11157
11158 version = read_2ubyte_unaligned_inc (dbg, readp);
11159 printf (_(" DWARF version: %8" PRIu16 "\n"), version);
11160
11161 if (version != 5)
11162 {
11163 error (0, 0, _("Unknown version"));
11164 goto next_unit;
11165 }
11166
11167 padding = read_2ubyte_unaligned_inc (dbg, readp);
11168 printf (_(" Padding: %8" PRIx16 "\n"), padding);
11169
11170 if (listptr != NULL
11171 && listptr->offset != (Dwarf_Off) (readp - start))
11172 {
11173 error (0, 0, "String offsets index doesn't start after header");
11174 goto next_unit;
11175 }
11176
11177 printf ("\n");
11178 }
11179
11180 int digits = 1;
11181 size_t offsets = (next_unitp - readp) / offset_size;
11182 while (offsets >= 10)
11183 {
11184 ++digits;
11185 offsets /= 10;
11186 }
11187
11188 unsigned int uidx = 0;
11189 size_t index_offset = readp - (const unsigned char *) data->d_buf;
11190 printf (" Offsets start at 0x%zx:\n", index_offset);
11191 while (readp <= next_unitp - offset_size)
11192 {
11193 Dwarf_Word offset;
11194 if (offset_size == 4)
11195 offset = read_4ubyte_unaligned_inc (dbg, readp);
11196 else
11197 offset = read_8ubyte_unaligned_inc (dbg, readp);
11198 const char *str = dwarf_getstring (dbg, offset, NULL);
11199 printf (" [%*u] [%*" PRIx64 "] \"%s\"\n",
11200 digits, uidx++, (int) offset_size * 2, offset, str ?: "???");
11201 }
11202 printf ("\n");
11203
11204 if (readp != next_unitp)
11205 error (0, 0, "extra %zd bytes at end of unit",
11206 (size_t) (next_unitp - readp));
11207
11208 next_unit:
11209 readp = next_unitp;
11210 }
11211 }
11212
11213
11214 /* Print the content of the call frame search table section
11215 '.eh_frame_hdr'. */
11216 static void
print_debug_frame_hdr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)11217 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
11218 Ebl *ebl __attribute__ ((unused)),
11219 GElf_Ehdr *ehdr __attribute__ ((unused)),
11220 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
11221 {
11222 printf (_("\
11223 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
11224 elf_ndxscn (scn));
11225
11226 Elf_Data *data = elf_rawdata (scn, NULL);
11227
11228 if (unlikely (data == NULL))
11229 {
11230 error (0, 0, _("cannot get %s content: %s"),
11231 ".eh_frame_hdr", elf_errmsg (-1));
11232 return;
11233 }
11234
11235 const unsigned char *readp = data->d_buf;
11236 const unsigned char *const dataend = ((unsigned char *) data->d_buf
11237 + data->d_size);
11238
11239 if (unlikely (readp + 4 > dataend))
11240 {
11241 invalid_data:
11242 error (0, 0, _("invalid data"));
11243 return;
11244 }
11245
11246 unsigned int version = *readp++;
11247 unsigned int eh_frame_ptr_enc = *readp++;
11248 unsigned int fde_count_enc = *readp++;
11249 unsigned int table_enc = *readp++;
11250
11251 printf (" version: %u\n"
11252 " eh_frame_ptr_enc: %#x ",
11253 version, eh_frame_ptr_enc);
11254 print_encoding_base ("", eh_frame_ptr_enc);
11255 printf (" fde_count_enc: %#x ", fde_count_enc);
11256 print_encoding_base ("", fde_count_enc);
11257 printf (" table_enc: %#x ", table_enc);
11258 print_encoding_base ("", table_enc);
11259
11260 uint64_t eh_frame_ptr = 0;
11261 if (eh_frame_ptr_enc != DW_EH_PE_omit)
11262 {
11263 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
11264 dbg);
11265 if (unlikely (readp == NULL))
11266 goto invalid_data;
11267
11268 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
11269 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
11270 printf (" (offset: %#" PRIx64 ")",
11271 /* +4 because of the 4 byte header of the section. */
11272 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
11273
11274 putchar_unlocked ('\n');
11275 }
11276
11277 uint64_t fde_count = 0;
11278 if (fde_count_enc != DW_EH_PE_omit)
11279 {
11280 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
11281 if (unlikely (readp == NULL))
11282 goto invalid_data;
11283
11284 printf (" fde_count: %" PRIu64 "\n", fde_count);
11285 }
11286
11287 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
11288 return;
11289
11290 puts (" Table:");
11291
11292 /* Optimize for the most common case. */
11293 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
11294 while (fde_count > 0 && readp + 8 <= dataend)
11295 {
11296 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
11297 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
11298 + (int64_t) initial_location);
11299 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
11300 // XXX Possibly print symbol name or section offset for initial_offset
11301 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
11302 " fde=[%6" PRIx64 "]\n",
11303 initial_location, initial_offset,
11304 address, address - (eh_frame_ptr + 4));
11305 }
11306 else
11307 while (0 && readp < dataend)
11308 {
11309
11310 }
11311 }
11312
11313
11314 /* Print the content of the exception handling table section
11315 '.eh_frame_hdr'. */
11316 static void
print_debug_exception_table(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)11317 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
11318 Ebl *ebl __attribute__ ((unused)),
11319 GElf_Ehdr *ehdr __attribute__ ((unused)),
11320 Elf_Scn *scn,
11321 GElf_Shdr *shdr __attribute__ ((unused)),
11322 Dwarf *dbg __attribute__ ((unused)))
11323 {
11324 printf (_("\
11325 \nException handling table section [%2zu] '.gcc_except_table':\n"),
11326 elf_ndxscn (scn));
11327
11328 Elf_Data *data = elf_rawdata (scn, NULL);
11329
11330 if (unlikely (data == NULL))
11331 {
11332 error (0, 0, _("cannot get %s content: %s"),
11333 ".gcc_except_table", elf_errmsg (-1));
11334 return;
11335 }
11336
11337 const unsigned char *readp = data->d_buf;
11338 const unsigned char *const dataend = readp + data->d_size;
11339
11340 if (unlikely (readp + 1 > dataend))
11341 {
11342 invalid_data:
11343 error (0, 0, _("invalid data"));
11344 return;
11345 }
11346 unsigned int lpstart_encoding = *readp++;
11347 printf (_(" LPStart encoding: %#x "), lpstart_encoding);
11348 print_encoding_base ("", lpstart_encoding);
11349 if (lpstart_encoding != DW_EH_PE_omit)
11350 {
11351 uint64_t lpstart;
11352 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
11353 printf (" LPStart: %#" PRIx64 "\n", lpstart);
11354 }
11355
11356 if (unlikely (readp + 1 > dataend))
11357 goto invalid_data;
11358 unsigned int ttype_encoding = *readp++;
11359 printf (_(" TType encoding: %#x "), ttype_encoding);
11360 print_encoding_base ("", ttype_encoding);
11361 const unsigned char *ttype_base = NULL;
11362 if (ttype_encoding != DW_EH_PE_omit)
11363 {
11364 unsigned int ttype_base_offset;
11365 if (readp >= dataend)
11366 goto invalid_data;
11367 get_uleb128 (ttype_base_offset, readp, dataend);
11368 printf (" TType base offset: %#x\n", ttype_base_offset);
11369 if ((size_t) (dataend - readp) > ttype_base_offset)
11370 ttype_base = readp + ttype_base_offset;
11371 }
11372
11373 if (unlikely (readp + 1 > dataend))
11374 goto invalid_data;
11375 unsigned int call_site_encoding = *readp++;
11376 printf (_(" Call site encoding: %#x "), call_site_encoding);
11377 print_encoding_base ("", call_site_encoding);
11378 unsigned int call_site_table_len;
11379 if (readp >= dataend)
11380 goto invalid_data;
11381 get_uleb128 (call_site_table_len, readp, dataend);
11382
11383 const unsigned char *const action_table = readp + call_site_table_len;
11384 if (unlikely (action_table > dataend))
11385 goto invalid_data;
11386 unsigned int u = 0;
11387 unsigned int max_action = 0;
11388 while (readp < action_table)
11389 {
11390 if (u == 0)
11391 puts (_("\n Call site table:"));
11392
11393 uint64_t call_site_start;
11394 readp = read_encoded (call_site_encoding, readp, dataend,
11395 &call_site_start, dbg);
11396 uint64_t call_site_length;
11397 readp = read_encoded (call_site_encoding, readp, dataend,
11398 &call_site_length, dbg);
11399 uint64_t landing_pad;
11400 readp = read_encoded (call_site_encoding, readp, dataend,
11401 &landing_pad, dbg);
11402 unsigned int action;
11403 if (readp >= dataend)
11404 goto invalid_data;
11405 get_uleb128 (action, readp, dataend);
11406 max_action = MAX (action, max_action);
11407 printf (_(" [%4u] Call site start: %#" PRIx64 "\n"
11408 " Call site length: %" PRIu64 "\n"
11409 " Landing pad: %#" PRIx64 "\n"
11410 " Action: %u\n"),
11411 u++, call_site_start, call_site_length, landing_pad, action);
11412 }
11413 if (readp != action_table)
11414 goto invalid_data;
11415
11416 unsigned int max_ar_filter = 0;
11417 if (max_action > 0)
11418 {
11419 puts ("\n Action table:");
11420
11421 size_t maxdata = (size_t) (dataend - action_table);
11422 if (max_action > maxdata || maxdata - max_action < 1)
11423 {
11424 invalid_action_table:
11425 fputs (_(" <INVALID DATA>\n"), stdout);
11426 return;
11427 }
11428
11429 const unsigned char *const action_table_end
11430 = action_table + max_action + 1;
11431
11432 u = 0;
11433 do
11434 {
11435 int ar_filter;
11436 get_sleb128 (ar_filter, readp, action_table_end);
11437 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
11438 max_ar_filter = ar_filter;
11439 int ar_disp;
11440 if (readp >= action_table_end)
11441 goto invalid_action_table;
11442 get_sleb128 (ar_disp, readp, action_table_end);
11443
11444 printf (" [%4u] ar_filter: % d\n"
11445 " ar_disp: % -5d",
11446 u, ar_filter, ar_disp);
11447 if (abs (ar_disp) & 1)
11448 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
11449 else if (ar_disp != 0)
11450 puts (" -> ???");
11451 else
11452 putchar_unlocked ('\n');
11453 ++u;
11454 }
11455 while (readp < action_table_end);
11456 }
11457
11458 if (max_ar_filter > 0 && ttype_base != NULL)
11459 {
11460 unsigned char dsize;
11461 puts ("\n TType table:");
11462
11463 // XXX Not *4, size of encoding;
11464 switch (ttype_encoding & 7)
11465 {
11466 case DW_EH_PE_udata2:
11467 case DW_EH_PE_sdata2:
11468 dsize = 2;
11469 break;
11470 case DW_EH_PE_udata4:
11471 case DW_EH_PE_sdata4:
11472 dsize = 4;
11473 break;
11474 case DW_EH_PE_udata8:
11475 case DW_EH_PE_sdata8:
11476 dsize = 8;
11477 break;
11478 default:
11479 dsize = 0;
11480 error (1, 0, _("invalid TType encoding"));
11481 }
11482
11483 if (max_ar_filter
11484 > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
11485 goto invalid_data;
11486
11487 readp = ttype_base - max_ar_filter * dsize;
11488 do
11489 {
11490 uint64_t ttype;
11491 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
11492 dbg);
11493 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
11494 }
11495 while (readp < ttype_base);
11496 }
11497 }
11498
11499 /* Print the content of the '.gdb_index' section.
11500 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
11501 */
11502 static void
print_gdb_index_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)11503 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl,
11504 GElf_Ehdr *ehdr __attribute__ ((unused)),
11505 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
11506 {
11507 printf (_("\nGDB section [%2zu] '%s' at offset %#" PRIx64
11508 " contains %" PRId64 " bytes :\n"),
11509 elf_ndxscn (scn), section_name (ebl, shdr),
11510 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
11511
11512 Elf_Data *data = elf_rawdata (scn, NULL);
11513
11514 if (unlikely (data == NULL))
11515 {
11516 error (0, 0, _("cannot get %s content: %s"),
11517 ".gdb_index", elf_errmsg (-1));
11518 return;
11519 }
11520
11521 // .gdb_index is always in little endian.
11522 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
11523 dbg = &dummy_dbg;
11524
11525 const unsigned char *readp = data->d_buf;
11526 const unsigned char *const dataend = readp + data->d_size;
11527
11528 if (unlikely (readp + 4 > dataend))
11529 {
11530 invalid_data:
11531 error (0, 0, _("invalid data"));
11532 return;
11533 }
11534
11535 int32_t vers = read_4ubyte_unaligned (dbg, readp);
11536 printf (_(" Version: %" PRId32 "\n"), vers);
11537
11538 // The only difference between version 4 and version 5 is the
11539 // hash used for generating the table. Version 6 contains symbols
11540 // for inlined functions, older versions didn't. Version 7 adds
11541 // symbol kinds. Version 8 just indicates that it correctly includes
11542 // TUs for symbols. Version 9 adds shortcut table for information
11543 // regarding the main function.
11544 if (vers < 4 || vers > 9)
11545 {
11546 printf (_(" unknown version, cannot parse section\n"));
11547 return;
11548 }
11549
11550 readp += 4;
11551 if (unlikely (readp + 4 > dataend))
11552 goto invalid_data;
11553
11554 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
11555 printf (_(" CU offset: %#" PRIx32 "\n"), cu_off);
11556
11557 readp += 4;
11558 if (unlikely (readp + 4 > dataend))
11559 goto invalid_data;
11560
11561 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
11562 printf (_(" TU offset: %#" PRIx32 "\n"), tu_off);
11563
11564 readp += 4;
11565 if (unlikely (readp + 4 > dataend))
11566 goto invalid_data;
11567
11568 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
11569 printf (_(" address offset: %#" PRIx32 "\n"), addr_off);
11570
11571 readp += 4;
11572 if (unlikely (readp + 4 > dataend))
11573 goto invalid_data;
11574
11575 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
11576 printf (_(" symbol offset: %#" PRIx32 "\n"), sym_off);
11577
11578 readp += 4;
11579 if (unlikely (readp + 4 > dataend))
11580 goto invalid_data;
11581
11582 uint32_t shortcut_off = 0;
11583 if (vers >= 9)
11584 {
11585 shortcut_off = read_4ubyte_unaligned (dbg, readp);
11586 printf (_(" shortcut offset: %#" PRIx32 "\n"), shortcut_off);
11587
11588 readp += 4;
11589 if (unlikely (readp + 4 > dataend))
11590 goto invalid_data;
11591 }
11592
11593 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
11594 printf (_(" constant offset: %#" PRIx32 "\n"), const_off);
11595
11596 if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
11597 < const_off))
11598 goto invalid_data;
11599
11600 readp = data->d_buf + cu_off;
11601
11602 const unsigned char *nextp = data->d_buf + tu_off;
11603 if (tu_off >= data->d_size)
11604 goto invalid_data;
11605
11606 size_t cu_nr = (nextp - readp) / 16;
11607
11608 printf (_("\n CU list at offset %#" PRIx32
11609 " contains %zu entries:\n"),
11610 cu_off, cu_nr);
11611
11612 size_t n = 0;
11613 while (dataend - readp >= 16 && n < cu_nr)
11614 {
11615 uint64_t off = read_8ubyte_unaligned (dbg, readp);
11616 readp += 8;
11617
11618 uint64_t len = read_8ubyte_unaligned (dbg, readp);
11619 readp += 8;
11620
11621 printf (" [%4zu] start: %0#8" PRIx64
11622 ", length: %5" PRIu64 "\n", n, off, len);
11623 n++;
11624 }
11625
11626 readp = data->d_buf + tu_off;
11627 nextp = data->d_buf + addr_off;
11628 if (addr_off >= data->d_size)
11629 goto invalid_data;
11630
11631 size_t tu_nr = (nextp - readp) / 24;
11632
11633 printf (_("\n TU list at offset %#" PRIx32
11634 " contains %zu entries:\n"),
11635 tu_off, tu_nr);
11636
11637 n = 0;
11638 while (dataend - readp >= 24 && n < tu_nr)
11639 {
11640 uint64_t off = read_8ubyte_unaligned (dbg, readp);
11641 readp += 8;
11642
11643 uint64_t type = read_8ubyte_unaligned (dbg, readp);
11644 readp += 8;
11645
11646 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
11647 readp += 8;
11648
11649 printf (" [%4zu] CU offset: %5" PRId64
11650 ", type offset: %5" PRId64
11651 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
11652 n++;
11653 }
11654
11655 readp = data->d_buf + addr_off;
11656 nextp = data->d_buf + sym_off;
11657 if (sym_off >= data->d_size)
11658 goto invalid_data;
11659
11660 size_t addr_nr = (nextp - readp) / 20;
11661
11662 printf (_("\n Address list at offset %#" PRIx32
11663 " contains %zu entries:\n"),
11664 addr_off, addr_nr);
11665
11666 n = 0;
11667 while (dataend - readp >= 20 && n < addr_nr)
11668 {
11669 uint64_t low = read_8ubyte_unaligned (dbg, readp);
11670 readp += 8;
11671
11672 uint64_t high = read_8ubyte_unaligned (dbg, readp);
11673 readp += 8;
11674
11675 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
11676 readp += 4;
11677
11678 printf (" [%4zu] ", n);
11679 print_dwarf_addr (dwflmod, 8, low, low);
11680 printf ("..");
11681 print_dwarf_addr (dwflmod, 8, high - 1, high);
11682 printf (", CU index: %5" PRId32 "\n", idx);
11683 n++;
11684 }
11685
11686 const unsigned char *const_start = data->d_buf + const_off;
11687 if (const_off >= data->d_size)
11688 goto invalid_data;
11689
11690 const unsigned char *shortcut_start = NULL;
11691 if (vers >= 9)
11692 {
11693 if (shortcut_off >= data->d_size)
11694 goto invalid_data;
11695
11696 shortcut_start = data->d_buf + shortcut_off;
11697 nextp = shortcut_start;
11698 }
11699 else
11700 nextp = const_start;
11701
11702 readp = data->d_buf + sym_off;
11703 size_t sym_nr = (nextp - readp) / 8;
11704
11705 printf (_("\n Symbol table at offset %#" PRIx32
11706 " contains %zu slots:\n"),
11707 addr_off, sym_nr);
11708
11709 n = 0;
11710 while (dataend - readp >= 8 && n < sym_nr)
11711 {
11712 uint32_t name = read_4ubyte_unaligned (dbg, readp);
11713 readp += 4;
11714
11715 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
11716 readp += 4;
11717
11718 if (name != 0 || vector != 0)
11719 {
11720 const unsigned char *sym = const_start + name;
11721 if (unlikely ((size_t) (dataend - const_start) < name
11722 || memchr (sym, '\0', dataend - sym) == NULL))
11723 goto invalid_data;
11724
11725 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
11726
11727 const unsigned char *readcus = const_start + vector;
11728 if (unlikely ((size_t) (dataend - const_start) < vector))
11729 goto invalid_data;
11730 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
11731 while (cus--)
11732 {
11733 uint32_t cu_kind, cu, kind;
11734 bool is_static;
11735 readcus += 4;
11736 if (unlikely (readcus + 4 > dataend))
11737 goto invalid_data;
11738 cu_kind = read_4ubyte_unaligned (dbg, readcus);
11739 cu = cu_kind & ((1 << 24) - 1);
11740 kind = (cu_kind >> 28) & 7;
11741 is_static = cu_kind & (1U << 31);
11742 if (cu > cu_nr - 1)
11743 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
11744 else
11745 printf ("%" PRId32, cu);
11746 if (kind != 0)
11747 {
11748 printf (" (");
11749 switch (kind)
11750 {
11751 case 1:
11752 printf ("type");
11753 break;
11754 case 2:
11755 printf ("var");
11756 break;
11757 case 3:
11758 printf ("func");
11759 break;
11760 case 4:
11761 printf ("other");
11762 break;
11763 default:
11764 printf ("unknown-0x%" PRIx32, kind);
11765 break;
11766 }
11767 printf (":%c)", (is_static ? 'S' : 'G'));
11768 }
11769 if (cus > 0)
11770 printf (", ");
11771 }
11772 printf ("\n");
11773 }
11774 n++;
11775 }
11776
11777 if (vers < 9)
11778 return;
11779
11780 if (unlikely (shortcut_start == NULL))
11781 goto invalid_data;
11782
11783 readp = shortcut_start;
11784 nextp = const_start;
11785 size_t shortcut_nr = (nextp - readp) / 4;
11786
11787 if (unlikely (shortcut_nr != 2))
11788 goto invalid_data;
11789
11790 printf (_("\nShortcut table at offset %#" PRIx32 " contains %zu slots:\n"),
11791 shortcut_off, shortcut_nr);
11792
11793 uint32_t lang = read_4ubyte_unaligned (dbg, readp);
11794 readp += 4;
11795
11796 /* Include the hex number of LANG in the output if the language
11797 is unknown. */
11798 const char *lang_str = dwarf_lang_string (lang);
11799 lang_str = string_or_unknown (lang_str, lang, DW_LANG_lo_user,
11800 DW_LANG_hi_user, true);
11801
11802 printf (_("Language of main: %s\n"), lang_str);
11803 printf (_("Name of main: "));
11804
11805 if (lang != 0)
11806 {
11807 uint32_t name = read_4ubyte_unaligned (dbg, readp);
11808 readp += 4;
11809 const unsigned char *sym = const_start + name;
11810
11811 if (unlikely ((size_t) (dataend - const_start) < name
11812 || memchr (sym, '\0', dataend - sym) == NULL))
11813 goto invalid_data;
11814
11815 printf ("%s\n", sym);
11816 }
11817 else
11818 printf ("<unknown>\n");
11819 }
11820
11821 /* Returns true and sets split DWARF CU id if there is a split compile
11822 unit in the given Dwarf, and no non-split units are found (before it). */
11823 static bool
is_split_dwarf(Dwarf * dbg,uint64_t * id,Dwarf_CU ** split_cu)11824 is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu)
11825 {
11826 Dwarf_CU *cu = NULL;
11827 while (dwarf_get_units (dbg, cu, &cu, NULL, NULL, NULL, NULL) == 0)
11828 {
11829 uint8_t unit_type;
11830 if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11831 id, NULL, NULL) != 0)
11832 return false;
11833
11834 if (unit_type != DW_UT_split_compile && unit_type != DW_UT_split_type)
11835 return false;
11836
11837 /* We really only care about the split compile unit, the types
11838 should be fine and self sufficient. Also they don't have an
11839 id that we can match with a skeleton unit. */
11840 if (unit_type == DW_UT_split_compile)
11841 {
11842 *split_cu = cu;
11843 return true;
11844 }
11845 }
11846
11847 return false;
11848 }
11849
11850 /* Check that there is one and only one Dwfl_Module, return in arg. */
11851 static int
getone_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)11852 getone_dwflmod (Dwfl_Module *dwflmod,
11853 void **userdata __attribute__ ((unused)),
11854 const char *name __attribute__ ((unused)),
11855 Dwarf_Addr base __attribute__ ((unused)),
11856 void *arg)
11857 {
11858 Dwfl_Module **m = (Dwfl_Module **) arg;
11859 if (*m != NULL)
11860 return DWARF_CB_ABORT;
11861 *m = dwflmod;
11862 return DWARF_CB_OK;
11863 }
11864
11865 static void
print_debug(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr)11866 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
11867 {
11868 /* Used for skeleton file, if necessary for split DWARF. */
11869 Dwfl *skel_dwfl = NULL;
11870 Dwfl_Module *skel_mod = NULL;
11871 char *skel_name = NULL;
11872 Dwarf *split_dbg = NULL;
11873 Dwarf_CU *split_cu = NULL;
11874
11875 /* Before we start the real work get a debug context descriptor. */
11876 Dwarf_Addr dwbias;
11877 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
11878 Dwarf dummy_dbg =
11879 {
11880 .elf = ebl->elf,
11881 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
11882 };
11883 if (dbg == NULL)
11884 {
11885 if ((print_debug_sections & ~(section_exception|section_frame)) != 0)
11886 error (0, 0, _("cannot get debug context descriptor: %s"),
11887 dwfl_errmsg (-1));
11888 dbg = &dummy_dbg;
11889 }
11890 else
11891 {
11892 /* If we are asked about a split dwarf (.dwo) file, use the user
11893 provided, or find the corresponding skeleton file. If we got
11894 a skeleton file, replace the given dwflmod and dbg, with one
11895 derived from the skeleton file to provide enough context. */
11896 uint64_t split_id;
11897 if (is_split_dwarf (dbg, &split_id, &split_cu))
11898 {
11899 if (dwarf_skeleton != NULL)
11900 skel_name = strdup (dwarf_skeleton);
11901 else
11902 {
11903 /* Replace file.dwo with file.o and see if that matches. */
11904 const char *fname;
11905 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL,
11906 &fname, NULL);
11907 if (fname != NULL)
11908 {
11909 size_t flen = strlen (fname);
11910 if (flen > 4 && strcmp (".dwo", fname + flen - 4) == 0)
11911 {
11912 skel_name = strdup (fname);
11913 if (skel_name != NULL)
11914 {
11915 skel_name[flen - 3] = 'o';
11916 skel_name[flen - 2] = '\0';
11917 }
11918 }
11919 }
11920 }
11921
11922 if (skel_name != NULL)
11923 {
11924 int skel_fd = open (skel_name, O_RDONLY);
11925 if (skel_fd == -1)
11926 fprintf (stderr, "Warning: Couldn't open DWARF skeleton file"
11927 " '%s'\n", skel_name);
11928 else
11929 skel_dwfl = create_dwfl (skel_fd, skel_name);
11930
11931 if (skel_dwfl != NULL)
11932 {
11933 if (dwfl_getmodules (skel_dwfl, &getone_dwflmod,
11934 &skel_mod, 0) != 0)
11935 {
11936 fprintf (stderr, "Warning: Bad DWARF skeleton,"
11937 " multiple modules '%s'\n", skel_name);
11938 dwfl_end (skel_dwfl);
11939 skel_mod = NULL;
11940 }
11941 }
11942 else if (skel_fd != -1)
11943 fprintf (stderr, "Warning: Couldn't create skeleton dwfl for"
11944 " '%s': %s\n", skel_name, dwfl_errmsg (-1));
11945
11946 if (skel_mod != NULL)
11947 {
11948 Dwarf *skel_dbg = dwfl_module_getdwarf (skel_mod, &dwbias);
11949 if (skel_dbg != NULL)
11950 {
11951 /* First check the skeleton CU DIE, only fetch
11952 the split DIE if we know the id matches to
11953 not unnecessary search for any split DIEs we
11954 don't need. */
11955 Dwarf_CU *cu = NULL;
11956 while (dwarf_get_units (skel_dbg, cu, &cu,
11957 NULL, NULL, NULL, NULL) == 0)
11958 {
11959 uint8_t unit_type;
11960 uint64_t skel_id;
11961 if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11962 &skel_id, NULL, NULL) == 0
11963 && unit_type == DW_UT_skeleton
11964 && split_id == skel_id)
11965 {
11966 Dwarf_Die subdie;
11967 if (dwarf_cu_info (cu, NULL, NULL, NULL,
11968 &subdie,
11969 NULL, NULL, NULL) == 0
11970 && dwarf_tag (&subdie) != DW_TAG_invalid)
11971 {
11972 split_dbg = dwarf_cu_getdwarf (subdie.cu);
11973 if (split_dbg == NULL)
11974 fprintf (stderr,
11975 "Warning: Couldn't get split_dbg:"
11976 " %s\n", dwarf_errmsg (-1));
11977 break;
11978 }
11979 else
11980 {
11981 /* Everything matches up, but not
11982 according to libdw. Which means
11983 the user knew better. So...
11984 Terrible hack... We can never
11985 destroy the underlying dwfl
11986 because it would free the wrong
11987 Dwarfs... So we leak memory...*/
11988 if (cu->split == NULL
11989 && dwarf_skeleton != NULL)
11990 {
11991 do_not_close_dwfl = true;
11992 __libdw_link_skel_split (cu, split_cu);
11993 split_dbg = dwarf_cu_getdwarf (split_cu);
11994 break;
11995 }
11996 else
11997 fprintf (stderr, "Warning: Couldn't get"
11998 " skeleton subdie: %s\n",
11999 dwarf_errmsg (-1));
12000 }
12001 }
12002 }
12003 if (split_dbg == NULL)
12004 fprintf (stderr, "Warning: '%s' didn't contain a skeleton for split id %" PRIx64 "\n", skel_name, split_id);
12005 }
12006 else
12007 fprintf (stderr, "Warning: Couldn't get skeleton DWARF:"
12008 " %s\n", dwfl_errmsg (-1));
12009 }
12010 }
12011
12012 if (split_dbg != NULL)
12013 {
12014 dbg = split_dbg;
12015 dwflmod = skel_mod;
12016 }
12017 else if (skel_name == NULL)
12018 fprintf (stderr,
12019 "Warning: split DWARF file, but no skeleton found.\n");
12020 }
12021 else if (dwarf_skeleton != NULL)
12022 fprintf (stderr, "Warning: DWARF skeleton given,"
12023 " but not a split DWARF file\n");
12024 }
12025
12026 /* Get the section header string table index. */
12027 size_t shstrndx;
12028 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
12029 error_exit (0, _("cannot get section header string table index"));
12030
12031 /* If the .debug_info section is listed as implicitly required then
12032 we must make sure to handle it before handling any other debug
12033 section. Various other sections depend on the CU DIEs being
12034 scanned (silently) first. */
12035 bool implicit_info = (implicit_debug_sections & section_info) != 0;
12036 bool explicit_info = (print_debug_sections & section_info) != 0;
12037 if (implicit_info)
12038 {
12039 Elf_Scn *scn = NULL;
12040 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12041 {
12042 GElf_Shdr shdr_mem;
12043 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
12044
12045 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
12046 {
12047 const char *name = elf_strptr (ebl->elf, shstrndx,
12048 shdr->sh_name);
12049 if (name == NULL)
12050 continue;
12051
12052 if (strcmp (name, ".debug_info") == 0
12053 || strcmp (name, ".debug_info.dwo") == 0
12054 || strcmp (name, ".zdebug_info") == 0
12055 || strcmp (name, ".zdebug_info.dwo") == 0
12056 || strcmp (name, ".gnu.debuglto_.debug_info") == 0)
12057 {
12058 print_debug_info_section (dwflmod, ebl, ehdr,
12059 scn, shdr, dbg);
12060 break;
12061 }
12062 }
12063 }
12064 print_debug_sections &= ~section_info;
12065 implicit_debug_sections &= ~section_info;
12066 }
12067
12068 /* Look through all the sections for the debugging sections to print. */
12069 Elf_Scn *scn = NULL;
12070 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12071 {
12072 GElf_Shdr shdr_mem;
12073 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
12074
12075 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
12076 {
12077 static const struct
12078 {
12079 const char *name;
12080 enum section_e bitmask;
12081 void (*fp) (Dwfl_Module *, Ebl *,
12082 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
12083 } debug_sections[] =
12084 {
12085 #define NEW_SECTION(name) \
12086 { ".debug_" #name, section_##name, print_debug_##name##_section }
12087 NEW_SECTION (abbrev),
12088 NEW_SECTION (addr),
12089 NEW_SECTION (aranges),
12090 NEW_SECTION (frame),
12091 NEW_SECTION (info),
12092 NEW_SECTION (types),
12093 NEW_SECTION (line),
12094 NEW_SECTION (loc),
12095 /* loclists is loc for DWARF5. */
12096 { ".debug_loclists", section_loc,
12097 print_debug_loclists_section },
12098 NEW_SECTION (pubnames),
12099 NEW_SECTION (str),
12100 /* A DWARF5 specialised debug string section. */
12101 { ".debug_line_str", section_str,
12102 print_debug_str_section },
12103 /* DWARF5 string offsets table. */
12104 { ".debug_str_offsets", section_str,
12105 print_debug_str_offsets_section },
12106 NEW_SECTION (macinfo),
12107 NEW_SECTION (macro),
12108 NEW_SECTION (ranges),
12109 /* rnglists is ranges for DWARF5. */
12110 { ".debug_rnglists", section_ranges,
12111 print_debug_rnglists_section },
12112 { ".eh_frame", section_frame | section_exception,
12113 print_debug_frame_section },
12114 { ".eh_frame_hdr", section_frame | section_exception,
12115 print_debug_frame_hdr_section },
12116 { ".gcc_except_table", section_frame | section_exception,
12117 print_debug_exception_table },
12118 { ".gdb_index", section_gdb_index, print_gdb_index_section }
12119 };
12120 const int ndebug_sections = (sizeof (debug_sections)
12121 / sizeof (debug_sections[0]));
12122 const char *name = elf_strptr (ebl->elf, shstrndx,
12123 shdr->sh_name);
12124 if (name == NULL)
12125 continue;
12126
12127 int n;
12128 for (n = 0; n < ndebug_sections; ++n)
12129 {
12130 size_t dbglen = strlen (debug_sections[n].name);
12131 size_t scnlen = strlen (name);
12132 if ((strncmp (name, debug_sections[n].name, dbglen) == 0
12133 && (dbglen == scnlen
12134 || (scnlen == dbglen + 4
12135 && strstr (name, ".dwo") == name + dbglen)))
12136 || (name[0] == '.' && name[1] == 'z'
12137 && debug_sections[n].name[1] == 'd'
12138 && strncmp (&name[2], &debug_sections[n].name[1],
12139 dbglen - 1) == 0
12140 && (scnlen == dbglen + 1
12141 || (scnlen == dbglen + 5
12142 && strstr (name, ".dwo") == name + dbglen + 1)))
12143 || (scnlen > 14 /* .gnu.debuglto_ prefix. */
12144 && startswith (name, ".gnu.debuglto_")
12145 && strcmp (&name[14], debug_sections[n].name) == 0)
12146 )
12147 {
12148 if ((print_debug_sections | implicit_debug_sections)
12149 & debug_sections[n].bitmask)
12150 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
12151 break;
12152 }
12153 }
12154 }
12155 }
12156
12157 dwfl_end (skel_dwfl);
12158 free (skel_name);
12159
12160 /* Turn implicit and/or explicit back on in case we go over another file. */
12161 if (implicit_info)
12162 implicit_debug_sections |= section_info;
12163 if (explicit_info)
12164 print_debug_sections |= section_info;
12165
12166 reset_listptr (&known_locsptr);
12167 reset_listptr (&known_loclistsptr);
12168 reset_listptr (&known_rangelistptr);
12169 reset_listptr (&known_rnglistptr);
12170 reset_listptr (&known_addrbases);
12171 reset_listptr (&known_stroffbases);
12172 }
12173
12174
12175 #define ITEM_INDENT 4
12176 #define WRAP_COLUMN 75
12177
12178 /* Print "NAME: FORMAT", wrapping when output text would make the line
12179 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
12180 but this function is also used for registers which should be printed
12181 aligned. Fortunately registers output uses fixed fields width (such
12182 as %11d) for the alignment.
12183
12184 Line breaks should not depend on the particular values although that
12185 may happen in some cases of the core items. */
12186
12187 static unsigned int
12188 __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,...)12189 print_core_item (unsigned int colno, char sep, unsigned int wrap,
12190 size_t name_width, const char *name, const char *format, ...)
12191 {
12192 size_t len = strlen (name);
12193 if (name_width < len)
12194 name_width = len;
12195
12196 char *out;
12197 va_list ap;
12198 va_start (ap, format);
12199 int out_len = vasprintf (&out, format, ap);
12200 va_end (ap);
12201 if (out_len == -1)
12202 error_exit (0, _("memory exhausted"));
12203
12204 size_t n = name_width + sizeof ": " - 1 + out_len;
12205
12206 if (colno == 0)
12207 {
12208 printf ("%*s", ITEM_INDENT, "");
12209 colno = ITEM_INDENT + n;
12210 }
12211 else if (colno + 2 + n < wrap)
12212 {
12213 printf ("%c ", sep);
12214 colno += 2 + n;
12215 }
12216 else
12217 {
12218 printf ("\n%*s", ITEM_INDENT, "");
12219 colno = ITEM_INDENT + n;
12220 }
12221
12222 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
12223
12224 free (out);
12225
12226 return colno;
12227 }
12228
12229 static const void *
convert(Elf * core,Elf_Type type,uint_fast16_t count,void * value,const void * data,size_t size)12230 convert (Elf *core, Elf_Type type, uint_fast16_t count,
12231 void *value, const void *data, size_t size)
12232 {
12233 Elf_Data valuedata =
12234 {
12235 .d_type = type,
12236 .d_buf = value,
12237 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
12238 .d_version = EV_CURRENT,
12239 };
12240 Elf_Data indata =
12241 {
12242 .d_type = type,
12243 .d_buf = (void *) data,
12244 .d_size = valuedata.d_size,
12245 .d_version = EV_CURRENT,
12246 };
12247
12248 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
12249 ? elf32_xlatetom : elf64_xlatetom)
12250 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
12251 if (d == NULL)
12252 error_exit (0, _("cannot convert core note data: %s"),
12253 elf_errmsg (-1));
12254
12255 return data + indata.d_size;
12256 }
12257
12258 typedef uint8_t GElf_Byte;
12259
12260 static unsigned int
handle_core_item(Elf * core,const Ebl_Core_Item * item,const void * desc,unsigned int colno,size_t * repeated_size)12261 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
12262 unsigned int colno, size_t *repeated_size)
12263 {
12264 uint_fast16_t count = item->count ?: 1;
12265 /* Ebl_Core_Item count is always a small number.
12266 Make sure the backend didn't put in some large bogus value. */
12267 assert (count < 128);
12268
12269 #define TYPES \
12270 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
12271 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
12272 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
12273 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
12274 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
12275 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
12276
12277 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
12278 typedef union { TYPES; } value_t;
12279 void *data = alloca (count * sizeof (value_t));
12280 #undef DO_TYPE
12281
12282 #define DO_TYPE(NAME, Name, hex, dec) \
12283 GElf_##Name *value_##Name __attribute__((unused)) = data
12284 TYPES;
12285 #undef DO_TYPE
12286
12287 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
12288 size_t convsize = size;
12289 if (repeated_size != NULL)
12290 {
12291 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
12292 {
12293 data = alloca (*repeated_size);
12294 count *= *repeated_size / size;
12295 convsize = count * size;
12296 *repeated_size -= convsize;
12297 }
12298 else if (item->count != 0 || item->format != '\n')
12299 *repeated_size -= size;
12300 }
12301
12302 convert (core, item->type, count, data, desc + item->offset, convsize);
12303
12304 Elf_Type type = item->type;
12305 if (type == ELF_T_ADDR)
12306 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
12307
12308 switch (item->format)
12309 {
12310 case 'd':
12311 assert (count == 1);
12312 switch (type)
12313 {
12314 #define DO_TYPE(NAME, Name, hex, dec) \
12315 case ELF_T_##NAME: \
12316 colno = print_core_item (colno, ',', WRAP_COLUMN, \
12317 0, item->name, dec, value_##Name[0]); \
12318 break
12319 TYPES;
12320 #undef DO_TYPE
12321 default:
12322 abort ();
12323 }
12324 break;
12325
12326 case 'x':
12327 assert (count == 1);
12328 switch (type)
12329 {
12330 #define DO_TYPE(NAME, Name, hex, dec) \
12331 case ELF_T_##NAME: \
12332 colno = print_core_item (colno, ',', WRAP_COLUMN, \
12333 0, item->name, hex, value_##Name[0]); \
12334 break
12335 TYPES;
12336 #undef DO_TYPE
12337 default:
12338 abort ();
12339 }
12340 break;
12341
12342 case 'b':
12343 case 'B':
12344 assert (size % sizeof (unsigned int) == 0);
12345 unsigned int nbits = count * size * 8;
12346 unsigned int pop = 0;
12347 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
12348 pop += __builtin_popcount (*i);
12349 bool negate = pop > nbits / 2;
12350 const unsigned int bias = item->format == 'b';
12351
12352 {
12353 char printed[(negate ? nbits - pop : pop) * 16 + 1];
12354 char *p = printed;
12355 *p = '\0';
12356
12357 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
12358 {
12359 assert (size == sizeof (unsigned int) * 2);
12360 for (unsigned int *i = data;
12361 (void *) i < data + count * size; i += 2)
12362 {
12363 unsigned int w = i[1];
12364 i[1] = i[0];
12365 i[0] = w;
12366 }
12367 }
12368
12369 unsigned int lastbit = 0;
12370 unsigned int run = 0;
12371 for (const unsigned int *i = data;
12372 (void *) i < data + count * size; ++i)
12373 {
12374 unsigned int bit = ((void *) i - data) * 8;
12375 unsigned int w = negate ? ~*i : *i;
12376 while (w != 0)
12377 {
12378 /* Note that a right shift equal to (or greater than)
12379 the number of bits of w is undefined behaviour. In
12380 particular when the least significant bit is bit 32
12381 (w = 0x8000000) then w >>= n is undefined. So
12382 explicitly handle that case separately. */
12383 unsigned int n = ffs (w);
12384 if (n < sizeof (w) * 8)
12385 w >>= n;
12386 else
12387 w = 0;
12388 bit += n;
12389
12390 if (lastbit != 0 && lastbit + 1 == bit)
12391 ++run;
12392 else
12393 {
12394 if (lastbit == 0)
12395 p += sprintf (p, "%u", bit - bias);
12396 else if (run == 0)
12397 p += sprintf (p, ",%u", bit - bias);
12398 else
12399 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
12400 run = 0;
12401 }
12402
12403 lastbit = bit;
12404 }
12405 }
12406 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
12407 p += sprintf (p, "-%u", lastbit - bias);
12408
12409 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
12410 negate ? "~<%s>" : "<%s>", printed);
12411 }
12412 break;
12413
12414 case 'T':
12415 case (char) ('T'|0x80):
12416 assert (count == 2);
12417 Dwarf_Word sec;
12418 Dwarf_Word usec;
12419 switch (type)
12420 {
12421 #define DO_TYPE(NAME, Name, hex, dec) \
12422 case ELF_T_##NAME: \
12423 sec = value_##Name[0]; \
12424 usec = value_##Name[1]; \
12425 break
12426 TYPES;
12427 #undef DO_TYPE
12428 default:
12429 abort ();
12430 }
12431 if (unlikely (item->format == (char) ('T'|0x80)))
12432 {
12433 /* This is a hack for an ill-considered 64-bit ABI where
12434 tv_usec is actually a 32-bit field with 32 bits of padding
12435 rounding out struct timeval. We've already converted it as
12436 a 64-bit field. For little-endian, this just means the
12437 high half is the padding; it's presumably zero, but should
12438 be ignored anyway. For big-endian, it means the 32-bit
12439 field went into the high half of USEC. */
12440 GElf_Ehdr ehdr_mem;
12441 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
12442 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
12443 usec >>= 32;
12444 else
12445 usec &= UINT32_MAX;
12446 }
12447 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
12448 "%" PRIu64 ".%.6" PRIu64, sec, usec);
12449 break;
12450
12451 case 'c':
12452 assert (count == 1);
12453 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
12454 "%c", value_Byte[0]);
12455 break;
12456
12457 case 's':
12458 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
12459 "%.*s", (int) count, value_Byte);
12460 break;
12461
12462 case '\n':
12463 /* This is a list of strings separated by '\n'. */
12464 assert (item->count == 0);
12465 assert (repeated_size != NULL);
12466 assert (item->name == NULL);
12467 if (unlikely (item->offset >= *repeated_size))
12468 break;
12469
12470 const char *s = desc + item->offset;
12471 size = *repeated_size - item->offset;
12472 *repeated_size = 0;
12473 while (size > 0)
12474 {
12475 const char *eol = memchr (s, '\n', size);
12476 int len = size;
12477 if (eol != NULL)
12478 len = eol - s;
12479 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
12480 if (eol == NULL)
12481 break;
12482 size -= eol + 1 - s;
12483 s = eol + 1;
12484 }
12485
12486 colno = WRAP_COLUMN;
12487 break;
12488
12489 case 'h':
12490 break;
12491
12492 default:
12493 error (0, 0, "XXX not handling format '%c' for %s",
12494 item->format, item->name);
12495 break;
12496 }
12497
12498 #undef TYPES
12499
12500 return colno;
12501 }
12502
12503
12504 /* Sort items by group, and by layout offset within each group. */
12505 static int
compare_core_items(const void * a,const void * b)12506 compare_core_items (const void *a, const void *b)
12507 {
12508 const Ebl_Core_Item *const *p1 = a;
12509 const Ebl_Core_Item *const *p2 = b;
12510 const Ebl_Core_Item *item1 = *p1;
12511 const Ebl_Core_Item *item2 = *p2;
12512
12513 return ((item1->group == item2->group ? 0
12514 : strcmp (item1->group, item2->group))
12515 ?: (int) item1->offset - (int) item2->offset);
12516 }
12517
12518 /* Sort item groups by layout offset of the first item in the group. */
12519 static int
compare_core_item_groups(const void * a,const void * b)12520 compare_core_item_groups (const void *a, const void *b)
12521 {
12522 const Ebl_Core_Item *const *const *p1 = a;
12523 const Ebl_Core_Item *const *const *p2 = b;
12524 const Ebl_Core_Item *const *group1 = *p1;
12525 const Ebl_Core_Item *const *group2 = *p2;
12526 const Ebl_Core_Item *item1 = *group1;
12527 const Ebl_Core_Item *item2 = *group2;
12528
12529 return (int) item1->offset - (int) item2->offset;
12530 }
12531
12532 static unsigned int
handle_core_items(Elf * core,const void * desc,size_t descsz,const Ebl_Core_Item * items,size_t nitems)12533 handle_core_items (Elf *core, const void *desc, size_t descsz,
12534 const Ebl_Core_Item *items, size_t nitems)
12535 {
12536 if (nitems == 0)
12537 return 0;
12538 unsigned int colno = 0;
12539
12540 /* FORMAT '\n' makes sense to be present only as a single item as it
12541 processes all the data of a note. FORMATs 'b' and 'B' have a special case
12542 if present as a single item but they can be also processed with other
12543 items below. */
12544 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
12545 || items[0].format == 'B'))
12546 {
12547 assert (items[0].offset == 0);
12548 size_t size = descsz;
12549 colno = handle_core_item (core, items, desc, colno, &size);
12550 /* If SIZE is not zero here there is some remaining data. But we do not
12551 know how to process it anyway. */
12552 return colno;
12553 }
12554 for (size_t i = 0; i < nitems; ++i)
12555 assert (items[i].format != '\n');
12556
12557 /* Sort to collect the groups together. */
12558 const Ebl_Core_Item *sorted_items[nitems];
12559 for (size_t i = 0; i < nitems; ++i)
12560 sorted_items[i] = &items[i];
12561 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
12562
12563 /* Collect the unique groups and sort them. */
12564 const Ebl_Core_Item **groups[nitems];
12565 groups[0] = &sorted_items[0];
12566 size_t ngroups = 1;
12567 for (size_t i = 1; i < nitems; ++i)
12568 if (sorted_items[i]->group != sorted_items[i - 1]->group
12569 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
12570 groups[ngroups++] = &sorted_items[i];
12571 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
12572
12573 /* Write out all the groups. */
12574 const void *last = desc;
12575 do
12576 {
12577 for (size_t i = 0; i < ngroups; ++i)
12578 {
12579 for (const Ebl_Core_Item **item = groups[i];
12580 (item < &sorted_items[nitems]
12581 && ((*item)->group == groups[i][0]->group
12582 || !strcmp ((*item)->group, groups[i][0]->group)));
12583 ++item)
12584 colno = handle_core_item (core, *item, desc, colno, NULL);
12585
12586 /* Force a line break at the end of the group. */
12587 colno = WRAP_COLUMN;
12588 }
12589
12590 if (descsz == 0)
12591 break;
12592
12593 /* This set of items consumed a certain amount of the note's data.
12594 If there is more data there, we have another unit of the same size.
12595 Loop to print that out too. */
12596 const Ebl_Core_Item *item = &items[nitems - 1];
12597 size_t eltsz = item->offset + gelf_fsize (core, item->type,
12598 item->count ?: 1, EV_CURRENT);
12599
12600 int reps = -1;
12601 do
12602 {
12603 ++reps;
12604 desc += eltsz;
12605 descsz -= eltsz;
12606 }
12607 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
12608
12609 if (reps == 1)
12610 {
12611 /* For just one repeat, print it unabridged twice. */
12612 desc -= eltsz;
12613 descsz += eltsz;
12614 }
12615 else if (reps > 1)
12616 printf (_("\n%*s... <repeats %u more times> ..."),
12617 ITEM_INDENT, "", reps);
12618
12619 last = desc;
12620 }
12621 while (descsz > 0);
12622
12623 return colno;
12624 }
12625
12626 static unsigned int
handle_core_register(Ebl * ebl,Elf * core,int maxregname,const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)12627 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
12628 const Ebl_Register_Location *regloc, const void *desc,
12629 unsigned int colno)
12630 {
12631 if (regloc->bits % 8 != 0)
12632 {
12633 error (0, 0, "Warning: Cannot handle register with %" PRIu8 "bits\n",
12634 regloc->bits);
12635 return colno;
12636 }
12637
12638 desc += regloc->offset;
12639
12640 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
12641 {
12642 char name[REGNAMESZ];
12643 int bits;
12644 int type;
12645 register_info (ebl, reg, regloc, name, &bits, &type);
12646
12647 #define TYPES \
12648 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
12649 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
12650 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
12651 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
12652
12653 #define BITS(bits, xtype, sfmt, ufmt) \
12654 uint##bits##_t b##bits; int##bits##_t b##bits##s
12655 union { TYPES; uint64_t b128[2]; } value;
12656 #undef BITS
12657
12658 switch (type)
12659 {
12660 case DW_ATE_unsigned:
12661 case DW_ATE_signed:
12662 case DW_ATE_address:
12663 switch (bits)
12664 {
12665 #define BITS(bits, xtype, sfmt, ufmt) \
12666 case bits: \
12667 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
12668 if (type == DW_ATE_signed) \
12669 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
12670 maxregname, name, \
12671 sfmt, value.b##bits##s); \
12672 else \
12673 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
12674 maxregname, name, \
12675 ufmt, value.b##bits); \
12676 break
12677
12678 TYPES;
12679
12680 case 128:
12681 assert (type == DW_ATE_unsigned);
12682 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
12683 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
12684 colno = print_core_item (colno, ' ', WRAP_COLUMN,
12685 maxregname, name,
12686 "0x%.16" PRIx64 "%.16" PRIx64,
12687 value.b128[!be], value.b128[be]);
12688 break;
12689
12690 default:
12691 abort ();
12692 #undef BITS
12693 }
12694 break;
12695
12696 default:
12697 /* Print each byte in hex, the whole thing in native byte order. */
12698 assert (bits % 8 == 0);
12699 const uint8_t *bytes = desc;
12700 desc += bits / 8;
12701 char hex[bits / 4 + 1];
12702 hex[bits / 4] = '\0';
12703 int incr = 1;
12704 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
12705 {
12706 bytes += bits / 8 - 1;
12707 incr = -1;
12708 }
12709 size_t idx = 0;
12710 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
12711 {
12712 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
12713 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
12714 }
12715 colno = print_core_item (colno, ' ', WRAP_COLUMN,
12716 maxregname, name, "0x%s", hex);
12717 break;
12718 }
12719 desc += regloc->pad;
12720
12721 #undef TYPES
12722 }
12723
12724 return colno;
12725 }
12726
12727
12728 struct register_info
12729 {
12730 const Ebl_Register_Location *regloc;
12731 const char *set;
12732 char name[REGNAMESZ];
12733 int regno;
12734 int bits;
12735 int type;
12736 };
12737
12738 static int
register_bitpos(const struct register_info * r)12739 register_bitpos (const struct register_info *r)
12740 {
12741 return (r->regloc->offset * 8
12742 + ((r->regno - r->regloc->regno)
12743 * (r->regloc->bits + r->regloc->pad * 8)));
12744 }
12745
12746 static int
compare_sets_by_info(const struct register_info * r1,const struct register_info * r2)12747 compare_sets_by_info (const struct register_info *r1,
12748 const struct register_info *r2)
12749 {
12750 return ((int) r2->bits - (int) r1->bits
12751 ?: register_bitpos (r1) - register_bitpos (r2));
12752 }
12753
12754 /* Sort registers by set, and by size and layout offset within each set. */
12755 static int
compare_registers(const void * a,const void * b)12756 compare_registers (const void *a, const void *b)
12757 {
12758 const struct register_info *r1 = a;
12759 const struct register_info *r2 = b;
12760
12761 /* Unused elements sort last. */
12762 if (r1->regloc == NULL)
12763 return r2->regloc == NULL ? 0 : 1;
12764 if (r2->regloc == NULL)
12765 return -1;
12766
12767 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
12768 ?: compare_sets_by_info (r1, r2));
12769 }
12770
12771 /* Sort register sets by layout offset of the first register in the set. */
12772 static int
compare_register_sets(const void * a,const void * b)12773 compare_register_sets (const void *a, const void *b)
12774 {
12775 const struct register_info *const *p1 = a;
12776 const struct register_info *const *p2 = b;
12777 return compare_sets_by_info (*p1, *p2);
12778 }
12779
12780 static inline bool
same_set(const struct register_info * a,const struct register_info * b,const struct register_info * regs,size_t maxnreg)12781 same_set (const struct register_info *a,
12782 const struct register_info *b,
12783 const struct register_info *regs,
12784 size_t maxnreg)
12785 {
12786 return (a < ®s[maxnreg] && a->regloc != NULL
12787 && b < ®s[maxnreg] && b->regloc != NULL
12788 && a->bits == b->bits
12789 && (a->set == b->set || !strcmp (a->set, b->set)));
12790 }
12791
12792 static unsigned int
handle_core_registers(Ebl * ebl,Elf * core,const void * desc,const Ebl_Register_Location * reglocs,size_t nregloc)12793 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
12794 const Ebl_Register_Location *reglocs, size_t nregloc)
12795 {
12796 if (nregloc == 0)
12797 return 0;
12798
12799 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
12800 if (maxnreg <= 0)
12801 {
12802 for (size_t i = 0; i < nregloc; ++i)
12803 if (maxnreg < reglocs[i].regno + reglocs[i].count)
12804 maxnreg = reglocs[i].regno + reglocs[i].count;
12805 assert (maxnreg > 0);
12806 }
12807
12808 struct register_info regs[maxnreg];
12809 memset (regs, 0, sizeof regs);
12810
12811 /* Sort to collect the sets together. */
12812 int maxreg = 0;
12813 for (size_t i = 0; i < nregloc; ++i)
12814 for (int reg = reglocs[i].regno;
12815 reg < reglocs[i].regno + reglocs[i].count;
12816 ++reg)
12817 {
12818 assert (reg < maxnreg);
12819 if (reg > maxreg)
12820 maxreg = reg;
12821 struct register_info *info = ®s[reg];
12822 info->regloc = ®locs[i];
12823 info->regno = reg;
12824 info->set = register_info (ebl, reg, ®locs[i],
12825 info->name, &info->bits, &info->type);
12826 }
12827 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
12828
12829 /* Collect the unique sets and sort them. */
12830 struct register_info *sets[maxreg + 1];
12831 sets[0] = ®s[0];
12832 size_t nsets = 1;
12833 for (int i = 1; i <= maxreg; ++i)
12834 if (regs[i].regloc != NULL
12835 && !same_set (®s[i], ®s[i - 1], regs, maxnreg))
12836 sets[nsets++] = ®s[i];
12837 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
12838
12839 /* Write out all the sets. */
12840 unsigned int colno = 0;
12841 for (size_t i = 0; i < nsets; ++i)
12842 {
12843 /* Find the longest name of a register in this set. */
12844 size_t maxname = 0;
12845 const struct register_info *end;
12846 for (end = sets[i]; same_set (sets[i], end, regs, maxnreg); ++end)
12847 {
12848 size_t len = strlen (end->name);
12849 if (len > maxname)
12850 maxname = len;
12851 }
12852
12853 for (const struct register_info *reg = sets[i];
12854 reg < end;
12855 reg += reg->regloc->count ?: 1)
12856 colno = handle_core_register (ebl, core, maxname,
12857 reg->regloc, desc, colno);
12858
12859 /* Force a line break at the end of the group. */
12860 colno = WRAP_COLUMN;
12861 }
12862
12863 return colno;
12864 }
12865
12866 static void
handle_auxv_note(Ebl * ebl,Elf * core,GElf_Word descsz,GElf_Off desc_pos)12867 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12868 {
12869 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
12870 if (data == NULL)
12871 elf_error:
12872 error_exit (0, _("cannot convert core note data: %s"), elf_errmsg (-1));
12873
12874 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
12875 for (size_t i = 0; i < nauxv; ++i)
12876 {
12877 GElf_auxv_t av_mem;
12878 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
12879 if (av == NULL)
12880 goto elf_error;
12881
12882 const char *name;
12883 const char *fmt;
12884 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
12885 {
12886 /* Unknown type. */
12887 if (av->a_un.a_val == 0)
12888 printf (" %" PRIu64 "\n", av->a_type);
12889 else
12890 printf (" %" PRIu64 ": %#" PRIx64 "\n",
12891 av->a_type, av->a_un.a_val);
12892 }
12893 else
12894 switch (fmt[0])
12895 {
12896 case '\0': /* Normally zero. */
12897 if (av->a_un.a_val == 0)
12898 {
12899 printf (" %s\n", name);
12900 break;
12901 }
12902 FALLTHROUGH;
12903 case 'x': /* hex */
12904 case 'p': /* address */
12905 case 's': /* address of string */
12906 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
12907 break;
12908 case 'u':
12909 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
12910 break;
12911 case 'd':
12912 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
12913 break;
12914
12915 case 'b':
12916 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
12917 GElf_Xword bit = 1;
12918 const char *pfx = "<";
12919 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
12920 {
12921 if (av->a_un.a_val & bit)
12922 {
12923 printf ("%s%s", pfx, p);
12924 pfx = " ";
12925 }
12926 bit <<= 1;
12927 }
12928 printf (">\n");
12929 break;
12930
12931 default:
12932 abort ();
12933 }
12934 }
12935 }
12936
12937 static bool
buf_has_data(unsigned char const * ptr,unsigned char const * end,size_t sz)12938 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
12939 {
12940 return ptr < end && (size_t) (end - ptr) >= sz;
12941 }
12942
12943 static bool
buf_read_int(Elf * core,unsigned char const ** ptrp,unsigned char const * end,int * retp)12944 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12945 int *retp)
12946 {
12947 if (! buf_has_data (*ptrp, end, 4))
12948 return false;
12949
12950 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
12951 return true;
12952 }
12953
12954 static bool
buf_read_ulong(Elf * core,unsigned char const ** ptrp,unsigned char const * end,uint64_t * retp)12955 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12956 uint64_t *retp)
12957 {
12958 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12959 if (! buf_has_data (*ptrp, end, sz))
12960 return false;
12961
12962 union
12963 {
12964 uint64_t u64;
12965 uint32_t u32;
12966 } u;
12967
12968 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
12969
12970 if (sz == 4)
12971 *retp = u.u32;
12972 else
12973 *retp = u.u64;
12974 return true;
12975 }
12976
12977 static void
handle_siginfo_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12978 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12979 {
12980 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12981 if (data == NULL)
12982 error_exit (0, _("cannot convert core note data: %s"), elf_errmsg (-1));
12983
12984 unsigned char const *ptr = data->d_buf;
12985 unsigned char const *const end = data->d_buf + data->d_size;
12986
12987 /* Siginfo head is three ints: signal number, error number, origin
12988 code. */
12989 int si_signo, si_errno, si_code;
12990 if (! buf_read_int (core, &ptr, end, &si_signo)
12991 || ! buf_read_int (core, &ptr, end, &si_errno)
12992 || ! buf_read_int (core, &ptr, end, &si_code))
12993 {
12994 fail:
12995 printf (" Not enough data in NT_SIGINFO note.\n");
12996 return;
12997 }
12998
12999 /* Next is a pointer-aligned union of structures. On 64-bit
13000 machines, that implies a word of padding. */
13001 if (gelf_getclass (core) == ELFCLASS64)
13002 ptr += 4;
13003
13004 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
13005 si_signo, si_errno, si_code);
13006
13007 if (si_code > 0)
13008 switch (si_signo)
13009 {
13010 case CORE_SIGILL:
13011 case CORE_SIGFPE:
13012 case CORE_SIGSEGV:
13013 case CORE_SIGBUS:
13014 {
13015 uint64_t addr;
13016 if (! buf_read_ulong (core, &ptr, end, &addr))
13017 goto fail;
13018 printf (" fault address: %#" PRIx64 "\n", addr);
13019 break;
13020 }
13021 default:
13022 ;
13023 }
13024 else if (si_code == CORE_SI_USER)
13025 {
13026 int pid, uid;
13027 if (! buf_read_int (core, &ptr, end, &pid)
13028 || ! buf_read_int (core, &ptr, end, &uid))
13029 goto fail;
13030 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
13031 }
13032 }
13033
13034 static void
handle_file_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)13035 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
13036 {
13037 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
13038 if (data == NULL)
13039 error_exit (0, _("cannot convert core note data: %s"), elf_errmsg (-1));
13040
13041 unsigned char const *ptr = data->d_buf;
13042 unsigned char const *const end = data->d_buf + data->d_size;
13043
13044 uint64_t count, page_size;
13045 if (! buf_read_ulong (core, &ptr, end, &count)
13046 || ! buf_read_ulong (core, &ptr, end, &page_size))
13047 {
13048 fail:
13049 printf (" Not enough data in NT_FILE note.\n");
13050 return;
13051 }
13052
13053 size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
13054 uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
13055 if (count > maxcount)
13056 goto fail;
13057
13058 /* Where file names are stored. */
13059 unsigned char const *const fstart = ptr + 3 * count * addrsize;
13060 char const *fptr = (char *) fstart;
13061
13062 printf (" %" PRId64 " files:\n", count);
13063 for (uint64_t i = 0; i < count; ++i)
13064 {
13065 uint64_t mstart, mend, moffset;
13066 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
13067 || ! buf_read_ulong (core, &ptr, fstart, &mend)
13068 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
13069 goto fail;
13070
13071 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
13072 if (fnext == NULL)
13073 goto fail;
13074
13075 int ct = printf (" %08" PRIx64 "-%08" PRIx64
13076 " %08" PRIx64 " %" PRId64,
13077 mstart, mend, moffset * page_size, mend - mstart);
13078 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
13079
13080 fptr = fnext + 1;
13081 }
13082 }
13083
13084 static void
handle_core_note(Ebl * ebl,const GElf_Nhdr * nhdr,const char * name,const void * desc)13085 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
13086 const char *name, const void *desc)
13087 {
13088 GElf_Word regs_offset;
13089 size_t nregloc;
13090 const Ebl_Register_Location *reglocs;
13091 size_t nitems;
13092 const Ebl_Core_Item *items;
13093
13094 if (! ebl_core_note (ebl, nhdr, name, desc,
13095 ®s_offset, &nregloc, ®locs, &nitems, &items))
13096 return;
13097
13098 /* Pass 0 for DESCSZ when there are registers in the note,
13099 so that the ITEMS array does not describe the whole thing.
13100 For non-register notes, the actual descsz might be a multiple
13101 of the unit size, not just exactly the unit size. */
13102 unsigned int colno = handle_core_items (ebl->elf, desc,
13103 nregloc == 0 ? nhdr->n_descsz : 0,
13104 items, nitems);
13105 if (colno != 0)
13106 putchar_unlocked ('\n');
13107
13108 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
13109 reglocs, nregloc);
13110 if (colno != 0)
13111 putchar_unlocked ('\n');
13112 }
13113
13114 static void
handle_notes_data(Ebl * ebl,const GElf_Ehdr * ehdr,GElf_Off start,Elf_Data * data)13115 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
13116 GElf_Off start, Elf_Data *data)
13117 {
13118 fputs_unlocked (_(" Owner Data size Type\n"), stdout);
13119
13120 if (data == NULL)
13121 goto bad_note;
13122
13123 size_t offset = 0;
13124 GElf_Nhdr nhdr;
13125 size_t name_offset;
13126 size_t desc_offset;
13127 while (offset < data->d_size
13128 && (offset = gelf_getnote (data, offset,
13129 &nhdr, &name_offset, &desc_offset)) > 0)
13130 {
13131 const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
13132 const char *desc = data->d_buf + desc_offset;
13133
13134 /* GNU Build Attributes are weird, they store most of their data
13135 into the owner name field. Extract just the owner name
13136 prefix here, then use the rest later as data. */
13137 bool is_gnu_build_attr
13138 = startswith (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX);
13139 const char *print_name = (is_gnu_build_attr
13140 ? ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX : name);
13141 size_t print_namesz = (is_gnu_build_attr
13142 ? strlen (print_name) : nhdr.n_namesz);
13143
13144 char buf[100];
13145 char buf2[100];
13146 printf (_(" %-13.*s %9" PRId32 " %s\n"),
13147 (int) print_namesz, print_name, nhdr.n_descsz,
13148 ehdr->e_type == ET_CORE
13149 ? ebl_core_note_type_name (ebl, nhdr.n_type,
13150 buf, sizeof (buf))
13151 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
13152 nhdr.n_descsz,
13153 buf2, sizeof (buf2)));
13154
13155 /* Filter out invalid entries. */
13156 if (memchr (name, '\0', nhdr.n_namesz) != NULL
13157 /* XXX For now help broken Linux kernels. */
13158 || 1)
13159 {
13160 if (ehdr->e_type == ET_CORE)
13161 {
13162 if (nhdr.n_type == NT_AUXV
13163 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
13164 || (nhdr.n_namesz == 5 && name[4] == '\0'))
13165 && !memcmp (name, "CORE", 4))
13166 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
13167 start + desc_offset);
13168 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
13169 switch (nhdr.n_type)
13170 {
13171 case NT_SIGINFO:
13172 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
13173 start + desc_offset);
13174 break;
13175
13176 case NT_FILE:
13177 handle_file_note (ebl->elf, nhdr.n_descsz,
13178 start + desc_offset);
13179 break;
13180
13181 default:
13182 handle_core_note (ebl, &nhdr, name, desc);
13183 }
13184 else
13185 handle_core_note (ebl, &nhdr, name, desc);
13186 }
13187 else
13188 ebl_object_note (ebl, nhdr.n_namesz, name, nhdr.n_type,
13189 nhdr.n_descsz, desc);
13190 }
13191 }
13192
13193 if (offset == data->d_size)
13194 return;
13195
13196 bad_note:
13197 error (0, 0,
13198 _("cannot get content of note: %s"),
13199 data != NULL ? "garbage data" : elf_errmsg (-1));
13200 }
13201
13202 static void
handle_notes(Ebl * ebl,GElf_Ehdr * ehdr)13203 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
13204 {
13205 /* If we have section headers, just look for SHT_NOTE sections.
13206 In a debuginfo file, the program headers are not reliable. */
13207 if (shnum != 0)
13208 {
13209 /* Get the section header string table index. */
13210 size_t shstrndx;
13211 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
13212 error_exit (0, _("cannot get section header string table index"));
13213
13214 Elf_Scn *scn = NULL;
13215 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
13216 {
13217 GElf_Shdr shdr_mem;
13218 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
13219
13220 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
13221 /* Not what we are looking for. */
13222 continue;
13223
13224 if (notes_section != NULL)
13225 {
13226 char *sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
13227 if (sname == NULL || strcmp (sname, notes_section) != 0)
13228 continue;
13229 }
13230
13231 printf (_("\
13232 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
13233 elf_ndxscn (scn),
13234 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
13235 shdr->sh_size, shdr->sh_offset);
13236
13237 handle_notes_data (ebl, ehdr, shdr->sh_offset,
13238 elf_getdata (scn, NULL));
13239 }
13240 return;
13241 }
13242
13243 /* We have to look through the program header to find the note
13244 sections. There can be more than one. */
13245 for (size_t cnt = 0; cnt < phnum; ++cnt)
13246 {
13247 GElf_Phdr mem;
13248 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
13249
13250 if (phdr == NULL || phdr->p_type != PT_NOTE)
13251 /* Not what we are looking for. */
13252 continue;
13253
13254 printf (_("\
13255 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
13256 phdr->p_filesz, phdr->p_offset);
13257
13258 handle_notes_data (ebl, ehdr, phdr->p_offset,
13259 elf_getdata_rawchunk (ebl->elf,
13260 phdr->p_offset, phdr->p_filesz,
13261 (phdr->p_align == 8
13262 ? ELF_T_NHDR8 : ELF_T_NHDR)));
13263 }
13264 }
13265
13266
13267 static void
hex_dump(const uint8_t * data,size_t len)13268 hex_dump (const uint8_t *data, size_t len)
13269 {
13270 size_t pos = 0;
13271 while (pos < len)
13272 {
13273 printf (" 0x%08zx ", pos);
13274
13275 const size_t chunk = MIN (len - pos, 16);
13276
13277 for (size_t i = 0; i < chunk; ++i)
13278 if (i % 4 == 3)
13279 printf ("%02x ", data[pos + i]);
13280 else
13281 printf ("%02x", data[pos + i]);
13282
13283 if (chunk < 16)
13284 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
13285
13286 for (size_t i = 0; i < chunk; ++i)
13287 {
13288 unsigned char b = data[pos + i];
13289 printf ("%c", isprint (b) ? b : '.');
13290 }
13291
13292 putchar ('\n');
13293 pos += chunk;
13294 }
13295 }
13296
13297 static void
dump_data_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)13298 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
13299 {
13300 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
13301 printf (_("\nSection [%zu] '%s' has no data to dump.\n"),
13302 elf_ndxscn (scn), name);
13303 else
13304 {
13305 if (print_decompress)
13306 {
13307 /* We try to decompress the section, but keep the old shdr around
13308 so we can show both the original shdr size and the uncompressed
13309 data size. */
13310 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
13311 {
13312 if (elf_compress (scn, 0, 0) < 0)
13313 printf ("WARNING: %s [%zd]\n",
13314 _("Couldn't uncompress section"),
13315 elf_ndxscn (scn));
13316 }
13317 else if (startswith (name, ".zdebug"))
13318 {
13319 if (elf_compress_gnu (scn, 0, 0) < 0)
13320 printf ("WARNING: %s [%zd]\n",
13321 _("Couldn't uncompress section"),
13322 elf_ndxscn (scn));
13323 }
13324 }
13325
13326 Elf_Data *data = elf_rawdata (scn, NULL);
13327 if (data == NULL)
13328 error (0, 0, _("cannot get data for section [%zu] '%s': %s"),
13329 elf_ndxscn (scn), name, elf_errmsg (-1));
13330 else
13331 {
13332 if (data->d_size == shdr->sh_size)
13333 printf (_("\nHex dump of section [%zu] '%s', %" PRIu64
13334 " bytes at offset %#0" PRIx64 ":\n"),
13335 elf_ndxscn (scn), name,
13336 shdr->sh_size, shdr->sh_offset);
13337 else
13338 printf (_("\nHex dump of section [%zu] '%s', %" PRIu64
13339 " bytes (%zd uncompressed) at offset %#0"
13340 PRIx64 ":\n"),
13341 elf_ndxscn (scn), name,
13342 shdr->sh_size, data->d_size, shdr->sh_offset);
13343 hex_dump (data->d_buf, data->d_size);
13344 }
13345 }
13346 }
13347
13348 static void
print_string_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)13349 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
13350 {
13351 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
13352 printf (_("\nSection [%zu] '%s' has no strings to dump.\n"),
13353 elf_ndxscn (scn), name);
13354 else
13355 {
13356 if (print_decompress)
13357 {
13358 /* We try to decompress the section, but keep the old shdr around
13359 so we can show both the original shdr size and the uncompressed
13360 data size. */
13361 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
13362 {
13363 if (elf_compress (scn, 0, 0) < 0)
13364 printf ("WARNING: %s [%zd]\n",
13365 _("Couldn't uncompress section"),
13366 elf_ndxscn (scn));
13367 }
13368 else if (startswith (name, ".zdebug"))
13369 {
13370 if (elf_compress_gnu (scn, 0, 0) < 0)
13371 printf ("WARNING: %s [%zd]\n",
13372 _("Couldn't uncompress section"),
13373 elf_ndxscn (scn));
13374 }
13375 }
13376
13377 Elf_Data *data = elf_rawdata (scn, NULL);
13378 if (data == NULL)
13379 error (0, 0, _("cannot get data for section [%zu] '%s': %s"),
13380 elf_ndxscn (scn), name, elf_errmsg (-1));
13381 else
13382 {
13383 if (data->d_size == shdr->sh_size)
13384 printf (_("\nString section [%zu] '%s' contains %" PRIu64
13385 " bytes at offset %#0" PRIx64 ":\n"),
13386 elf_ndxscn (scn), name,
13387 shdr->sh_size, shdr->sh_offset);
13388 else
13389 printf (_("\nString section [%zu] '%s' contains %" PRIu64
13390 " bytes (%zd uncompressed) at offset %#0"
13391 PRIx64 ":\n"),
13392 elf_ndxscn (scn), name,
13393 shdr->sh_size, data->d_size, shdr->sh_offset);
13394
13395 const char *start = data->d_buf;
13396 const char *const limit = start + data->d_size;
13397 do
13398 {
13399 const char *end = memchr (start, '\0', limit - start);
13400 const size_t pos = start - (const char *) data->d_buf;
13401 if (unlikely (end == NULL))
13402 {
13403 printf (" [%6zx]- %.*s\n",
13404 pos, (int) (limit - start), start);
13405 break;
13406 }
13407 printf (" [%6zx] %s\n", pos, start);
13408 start = end + 1;
13409 } while (start < limit);
13410 }
13411 }
13412 }
13413
13414 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))13415 for_each_section_argument (Elf *elf, const struct section_argument *list,
13416 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
13417 const char *name))
13418 {
13419 /* Get the section header string table index. */
13420 size_t shstrndx;
13421 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
13422 error_exit (0, _("cannot get section header string table index"));
13423
13424 for (const struct section_argument *a = list; a != NULL; a = a->next)
13425 {
13426 Elf_Scn *scn;
13427 GElf_Shdr shdr_mem;
13428 const char *name = NULL;
13429
13430 char *endp = NULL;
13431 unsigned long int shndx = strtoul (a->arg, &endp, 0);
13432 if (endp != a->arg && *endp == '\0')
13433 {
13434 scn = elf_getscn (elf, shndx);
13435 if (scn == NULL)
13436 {
13437 error (0, 0, _("\nsection [%lu] does not exist"), shndx);
13438 continue;
13439 }
13440
13441 if (gelf_getshdr (scn, &shdr_mem) == NULL)
13442 error_exit (0, _("cannot get section header: %s"),
13443 elf_errmsg (-1));
13444 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
13445 (*dump) (scn, &shdr_mem, name);
13446 }
13447 else
13448 {
13449 /* Need to look up the section by name. */
13450 scn = NULL;
13451 bool found = false;
13452 while ((scn = elf_nextscn (elf, scn)) != NULL)
13453 {
13454 if (gelf_getshdr (scn, &shdr_mem) == NULL)
13455 continue;
13456 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
13457 if (name == NULL)
13458 continue;
13459 if (!strcmp (name, a->arg))
13460 {
13461 found = true;
13462 (*dump) (scn, &shdr_mem, name);
13463 }
13464 }
13465
13466 if (unlikely (!found) && !a->implicit)
13467 error (0, 0, _("\nsection '%s' does not exist"), a->arg);
13468 }
13469 }
13470 }
13471
13472 static void
dump_data(Ebl * ebl)13473 dump_data (Ebl *ebl)
13474 {
13475 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
13476 }
13477
13478 static void
dump_strings(Ebl * ebl)13479 dump_strings (Ebl *ebl)
13480 {
13481 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
13482 }
13483
13484 static void
print_strings(Ebl * ebl)13485 print_strings (Ebl *ebl)
13486 {
13487 /* Get the section header string table index. */
13488 size_t shstrndx;
13489 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
13490 error_exit (0, _("cannot get section header string table index"));
13491
13492 Elf_Scn *scn;
13493 GElf_Shdr shdr_mem;
13494 const char *name;
13495 scn = NULL;
13496 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
13497 {
13498 if (gelf_getshdr (scn, &shdr_mem) == NULL)
13499 continue;
13500
13501 if (shdr_mem.sh_type != SHT_PROGBITS
13502 || !(shdr_mem.sh_flags & SHF_STRINGS))
13503 continue;
13504
13505 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
13506 if (name == NULL)
13507 continue;
13508
13509 print_string_section (scn, &shdr_mem, name);
13510 }
13511 }
13512
13513 static void
dump_archive_index(Elf * elf,const char * fname)13514 dump_archive_index (Elf *elf, const char *fname)
13515 {
13516 size_t narsym;
13517 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
13518 if (arsym == NULL)
13519 {
13520 int result = elf_errno ();
13521 if (unlikely (result != ELF_E_NO_INDEX))
13522 error_exit (0, _("cannot get symbol index of archive '%s': %s"),
13523 fname, elf_errmsg (result));
13524 else
13525 printf (_("\nArchive '%s' has no symbol index\n"), fname);
13526 return;
13527 }
13528
13529 printf (_("\nIndex of archive '%s' has %zu entries:\n"),
13530 fname, narsym);
13531
13532 size_t as_off = 0;
13533 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
13534 {
13535 if (s->as_off != as_off)
13536 {
13537 as_off = s->as_off;
13538
13539 Elf *subelf = NULL;
13540 if (unlikely (elf_rand (elf, as_off) == 0)
13541 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
13542 == NULL))
13543 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
13544 while (1)
13545 #endif
13546 error_exit (0,
13547 _("cannot extract member at offset %zu in '%s': %s"),
13548 as_off, fname, elf_errmsg (-1));
13549
13550 const Elf_Arhdr *h = elf_getarhdr (subelf);
13551
13552 printf (_("Archive member '%s' contains:\n"), h->ar_name);
13553
13554 elf_end (subelf);
13555 }
13556
13557 printf ("\t%s\n", s->as_name);
13558 }
13559 }
13560
13561 #include "debugpred.h"
13562