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