1 /* Print information from ELF file in human-readable form.
2 Copyright (C) 1999-2018 Red Hat, Inc.
3 This file is part of elfutils.
4
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 elfutils is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <argp.h>
23 #include <assert.h>
24 #include <ctype.h>
25 #include <dwarf.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <gelf.h>
29 #include <inttypes.h>
30 #include <langinfo.h>
31 #include <libdw.h>
32 #include <libdwfl.h>
33 #include <libintl.h>
34 #include <locale.h>
35 #include <stdarg.h>
36 #include <stdbool.h>
37 #include <stdio.h>
38 #include <stdio_ext.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <strings.h>
42 #include <time.h>
43 #include <unistd.h>
44 #include <sys/stat.h>
45 #include <signal.h>
46
47 #include <libeu.h>
48 #include <system.h>
49 #include <printversion.h>
50 #include "../libelf/libelfP.h"
51 #include "../libelf/common.h"
52 #include "../libebl/libeblP.h"
53 #include "../libdwelf/libdwelf.h"
54 #include "../libdw/libdwP.h"
55 #include "../libdwfl/libdwflP.h"
56 #include "../libdw/memory-access.h"
57
58 #include "../libdw/known-dwarf.h"
59
60 #ifdef __linux__
61 #define CORE_SIGILL SIGILL
62 #define CORE_SIGBUS SIGBUS
63 #define CORE_SIGFPE SIGFPE
64 #define CORE_SIGSEGV SIGSEGV
65 #define CORE_SI_USER SI_USER
66 #else
67 /* We want the linux version of those as that is what shows up in the core files. */
68 #define CORE_SIGILL 4 /* Illegal instruction (ANSI). */
69 #define CORE_SIGBUS 7 /* BUS error (4.2 BSD). */
70 #define CORE_SIGFPE 8 /* Floating-point exception (ANSI). */
71 #define CORE_SIGSEGV 11 /* Segmentation violation (ANSI). */
72 #define CORE_SI_USER 0 /* Sent by kill, sigsend. */
73 #endif
74
75 /* Name and version of program. */
76 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
77
78 /* Bug report address. */
79 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
80
81 /* argp key value for --elf-section, non-ascii. */
82 #define ELF_INPUT_SECTION 256
83
84 /* argp key value for --dwarf-skeleton, non-ascii. */
85 #define DWARF_SKELETON 257
86
87 /* Terrible hack for hooking unrelated skeleton/split compile units,
88 see __libdw_link_skel_split in print_debug. */
89 static bool do_not_close_dwfl = false;
90
91 /* Definitions of arguments for argp functions. */
92 static const struct argp_option options[] =
93 {
94 { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 },
95 { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL,
96 N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF "
97 "input data"), 0 },
98 { "dwarf-skeleton", DWARF_SKELETON, "FILE", 0,
99 N_("Used with -w to find the skeleton Compile Units in FILE associated "
100 "with the Split Compile units in a .dwo input file"), 0 },
101 { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
102 { "all", 'a', NULL, 0,
103 N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
104 { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
105 { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
106 { "histogram", 'I', NULL, 0,
107 N_("Display histogram of bucket list lengths"), 0 },
108 { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
109 { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
110 { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
111 { "section-groups", 'g', NULL, 0, N_("Display the section groups"), 0 },
112 { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
113 { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
114 { "symbols", 's', "SECTION", OPTION_ARG_OPTIONAL,
115 N_("Display the symbol table sections"), 0 },
116 { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
117 { "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 },
118 { "arch-specific", 'A', NULL, 0,
119 N_("Display architecture specific information, if any"), 0 },
120 { "exception", 'e', NULL, 0,
121 N_("Display sections for exception handling"), 0 },
122
123 { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
124 { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
125 N_("Display DWARF section content. SECTION can be one of abbrev, addr, "
126 "aranges, decodedaranges, frame, gdb_index, info, info+, loc, line, "
127 "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 },
128 { "hex-dump", 'x', "SECTION", 0,
129 N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
130 { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
131 N_("Print string contents of sections"), 0 },
132 { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
133 { "archive-index", 'c', NULL, 0,
134 N_("Display the symbol index of an archive"), 0 },
135
136 { NULL, 0, NULL, 0, N_("Output control:"), 0 },
137 { "numeric-addresses", 'N', NULL, 0,
138 N_("Do not find symbol names for addresses in DWARF data"), 0 },
139 { "unresolved-address-offsets", 'U', NULL, 0,
140 N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
141 { "wide", 'W', NULL, 0,
142 N_("Ignored for compatibility (lines always wide)"), 0 },
143 { "decompress", 'z', NULL, 0,
144 N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 },
145 { NULL, 0, NULL, 0, NULL, 0 }
146 };
147
148 /* Short description of program. */
149 static const char doc[] = N_("\
150 Print information from ELF file in human-readable form.");
151
152 /* Strings for arguments in help texts. */
153 static const char args_doc[] = N_("FILE...");
154
155 /* Prototype for option handler. */
156 static error_t parse_opt (int key, char *arg, struct argp_state *state);
157
158 /* Data structure to communicate with argp functions. */
159 static struct argp argp =
160 {
161 options, parse_opt, args_doc, doc, NULL, NULL, NULL
162 };
163
164 /* If non-null, the section from which we should read to (compressed) ELF. */
165 static const char *elf_input_section = NULL;
166
167 /* If non-null, the file that contains the skeleton CUs. */
168 static const char *dwarf_skeleton = NULL;
169
170 /* Flags set by the option controlling the output. */
171
172 /* True if dynamic segment should be printed. */
173 static bool print_dynamic_table;
174
175 /* True if the file header should be printed. */
176 static bool print_file_header;
177
178 /* True if the program headers should be printed. */
179 static bool print_program_header;
180
181 /* True if relocations should be printed. */
182 static bool print_relocations;
183
184 /* True if the section headers should be printed. */
185 static bool print_section_header;
186
187 /* True if the symbol table should be printed. */
188 static bool print_symbol_table;
189
190 /* A specific section name, or NULL to print all symbol tables. */
191 static char *symbol_table_section;
192
193 /* True if the version information should be printed. */
194 static bool print_version_info;
195
196 /* True if section groups should be printed. */
197 static bool print_section_groups;
198
199 /* True if bucket list length histogram should be printed. */
200 static bool print_histogram;
201
202 /* True if the architecture specific data should be printed. */
203 static bool print_arch;
204
205 /* True if note section content should be printed. */
206 static bool print_notes;
207
208 /* True if SHF_STRINGS section content should be printed. */
209 static bool print_string_sections;
210
211 /* True if archive index should be printed. */
212 static bool print_archive_index;
213
214 /* True if any of the control options except print_archive_index is set. */
215 static bool any_control_option;
216
217 /* True if we should print addresses from DWARF in symbolic form. */
218 static bool print_address_names = true;
219
220 /* True if we should print raw values instead of relativized addresses. */
221 static bool print_unresolved_addresses = false;
222
223 /* True if we should print the .debug_aranges section using libdw. */
224 static bool decodedaranges = false;
225
226 /* True if we should print the .debug_aranges section using libdw. */
227 static bool decodedline = false;
228
229 /* True if we want to show more information about compressed sections. */
230 static bool print_decompress = false;
231
232 /* True if we want to show split compile units for debug_info skeletons. */
233 static bool show_split_units = false;
234
235 /* Select printing of debugging sections. */
236 static enum section_e
237 {
238 section_abbrev = 1, /* .debug_abbrev */
239 section_aranges = 2, /* .debug_aranges */
240 section_frame = 4, /* .debug_frame or .eh_frame & al. */
241 section_info = 8, /* .debug_info, (implies .debug_types) */
242 section_line = 16, /* .debug_line */
243 section_loc = 32, /* .debug_loc */
244 section_pubnames = 64, /* .debug_pubnames */
245 section_str = 128, /* .debug_str */
246 section_macinfo = 256, /* .debug_macinfo */
247 section_ranges = 512, /* .debug_ranges */
248 section_exception = 1024, /* .eh_frame & al. */
249 section_gdb_index = 2048, /* .gdb_index */
250 section_macro = 4096, /* .debug_macro */
251 section_addr = 8192, /* .debug_addr */
252 section_types = 16384, /* .debug_types (implied by .debug_info) */
253 section_all = (section_abbrev | section_aranges | section_frame
254 | section_info | section_line | section_loc
255 | section_pubnames | section_str | section_macinfo
256 | section_ranges | section_exception | section_gdb_index
257 | section_macro | section_addr | section_types)
258 } print_debug_sections, implicit_debug_sections;
259
260 /* Select hex dumping of sections. */
261 static struct section_argument *dump_data_sections;
262 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
263
264 /* Select string dumping of sections. */
265 static struct section_argument *string_sections;
266 static struct section_argument **string_sections_tail = &string_sections;
267
268 struct section_argument
269 {
270 struct section_argument *next;
271 const char *arg;
272 bool implicit;
273 };
274
275 /* Numbers of sections and program headers in the file. */
276 static size_t shnum;
277 static size_t phnum;
278
279
280 /* Declarations of local functions. */
281 static void process_file (int fd, const char *fname, bool only_one);
282 static void process_elf_file (Dwfl_Module *dwflmod, int fd);
283 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
284 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
285 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
286 static void print_scngrp (Ebl *ebl);
287 static void print_dynamic (Ebl *ebl);
288 static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
289 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
290 GElf_Shdr *shdr);
291 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
292 GElf_Shdr *shdr);
293 static void print_symtab (Ebl *ebl, int type);
294 static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
295 static void print_verinfo (Ebl *ebl);
296 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
297 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
298 static void handle_versym (Ebl *ebl, Elf_Scn *scn,
299 GElf_Shdr *shdr);
300 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
301 static void handle_hash (Ebl *ebl);
302 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
303 static void print_liblist (Ebl *ebl);
304 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
305 static void dump_data (Ebl *ebl);
306 static void dump_strings (Ebl *ebl);
307 static void print_strings (Ebl *ebl);
308 static void dump_archive_index (Elf *, const char *);
309
310
311 /* Looked up once with gettext in main. */
312 static char *yes_str;
313 static char *no_str;
314
315 int
main(int argc,char * argv[])316 main (int argc, char *argv[])
317 {
318 /* We use no threads here which can interfere with handling a stream. */
319 (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
320
321 /* Set locale. */
322 setlocale (LC_ALL, "");
323
324 /* Initialize the message catalog. */
325 textdomain (PACKAGE_TARNAME);
326
327 /* Look up once. */
328 yes_str = gettext ("yes");
329 no_str = gettext ("no");
330
331 /* Parse and process arguments. */
332 int remaining;
333 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
334
335 /* Before we start tell the ELF library which version we are using. */
336 elf_version (EV_CURRENT);
337
338 /* Now process all the files given at the command line. */
339 bool only_one = remaining + 1 == argc;
340 do
341 {
342 /* Open the file. */
343 int fd = open (argv[remaining], O_RDONLY);
344 if (fd == -1)
345 {
346 error (0, errno, gettext ("cannot open input file"));
347 continue;
348 }
349
350 process_file (fd, argv[remaining], only_one);
351
352 close (fd);
353 }
354 while (++remaining < argc);
355
356 return error_message_count != 0;
357 }
358
359
360 /* Handle program arguments. */
361 static error_t
parse_opt(int key,char * arg,struct argp_state * state)362 parse_opt (int key, char *arg,
363 struct argp_state *state __attribute__ ((unused)))
364 {
365 void add_dump_section (const char *name, bool implicit)
366 {
367 struct section_argument *a = xmalloc (sizeof *a);
368 a->arg = name;
369 a->next = NULL;
370 a->implicit = implicit;
371 struct section_argument ***tailp
372 = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
373 **tailp = a;
374 *tailp = &a->next;
375 }
376
377 switch (key)
378 {
379 case 'a':
380 print_file_header = true;
381 print_program_header = true;
382 print_relocations = true;
383 print_section_header = true;
384 print_symbol_table = true;
385 print_version_info = true;
386 print_dynamic_table = true;
387 print_section_groups = true;
388 print_histogram = true;
389 print_arch = true;
390 print_notes = true;
391 implicit_debug_sections |= section_exception;
392 add_dump_section (".strtab", true);
393 add_dump_section (".dynstr", true);
394 add_dump_section (".comment", true);
395 any_control_option = true;
396 break;
397 case 'A':
398 print_arch = true;
399 any_control_option = true;
400 break;
401 case 'd':
402 print_dynamic_table = true;
403 any_control_option = true;
404 break;
405 case 'e':
406 print_debug_sections |= section_exception;
407 any_control_option = true;
408 break;
409 case 'g':
410 print_section_groups = true;
411 any_control_option = true;
412 break;
413 case 'h':
414 print_file_header = true;
415 any_control_option = true;
416 break;
417 case 'I':
418 print_histogram = true;
419 any_control_option = true;
420 break;
421 case 'l':
422 print_program_header = true;
423 any_control_option = true;
424 break;
425 case 'n':
426 print_notes = true;
427 any_control_option = true;
428 break;
429 case 'r':
430 print_relocations = true;
431 any_control_option = true;
432 break;
433 case 'S':
434 print_section_header = true;
435 any_control_option = true;
436 break;
437 case 's':
438 print_symbol_table = true;
439 any_control_option = true;
440 symbol_table_section = arg;
441 break;
442 case 'V':
443 print_version_info = true;
444 any_control_option = true;
445 break;
446 case 'c':
447 print_archive_index = true;
448 break;
449 case 'w':
450 if (arg == NULL)
451 {
452 print_debug_sections = section_all;
453 implicit_debug_sections = section_info;
454 show_split_units = true;
455 }
456 else if (strcmp (arg, "abbrev") == 0)
457 print_debug_sections |= section_abbrev;
458 else if (strcmp (arg, "addr") == 0)
459 {
460 print_debug_sections |= section_addr;
461 implicit_debug_sections |= section_info;
462 }
463 else if (strcmp (arg, "aranges") == 0)
464 print_debug_sections |= section_aranges;
465 else if (strcmp (arg, "decodedaranges") == 0)
466 {
467 print_debug_sections |= section_aranges;
468 decodedaranges = true;
469 }
470 else if (strcmp (arg, "ranges") == 0)
471 {
472 print_debug_sections |= section_ranges;
473 implicit_debug_sections |= section_info;
474 }
475 else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
476 print_debug_sections |= section_frame;
477 else if (strcmp (arg, "info") == 0)
478 {
479 print_debug_sections |= section_info;
480 print_debug_sections |= section_types;
481 }
482 else if (strcmp (arg, "info+") == 0)
483 {
484 print_debug_sections |= section_info;
485 print_debug_sections |= section_types;
486 show_split_units = true;
487 }
488 else if (strcmp (arg, "loc") == 0)
489 {
490 print_debug_sections |= section_loc;
491 implicit_debug_sections |= section_info;
492 }
493 else if (strcmp (arg, "line") == 0)
494 print_debug_sections |= section_line;
495 else if (strcmp (arg, "decodedline") == 0)
496 {
497 print_debug_sections |= section_line;
498 decodedline = true;
499 }
500 else if (strcmp (arg, "pubnames") == 0)
501 print_debug_sections |= section_pubnames;
502 else if (strcmp (arg, "str") == 0)
503 {
504 print_debug_sections |= section_str;
505 /* For mapping string offset tables to CUs. */
506 implicit_debug_sections |= section_info;
507 }
508 else if (strcmp (arg, "macinfo") == 0)
509 print_debug_sections |= section_macinfo;
510 else if (strcmp (arg, "macro") == 0)
511 print_debug_sections |= section_macro;
512 else if (strcmp (arg, "exception") == 0)
513 print_debug_sections |= section_exception;
514 else if (strcmp (arg, "gdb_index") == 0)
515 print_debug_sections |= section_gdb_index;
516 else
517 {
518 fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"),
519 arg);
520 argp_help (&argp, stderr, ARGP_HELP_SEE,
521 program_invocation_short_name);
522 exit (1);
523 }
524 any_control_option = true;
525 break;
526 case 'p':
527 any_control_option = true;
528 if (arg == NULL)
529 {
530 print_string_sections = true;
531 break;
532 }
533 FALLTHROUGH;
534 case 'x':
535 add_dump_section (arg, false);
536 any_control_option = true;
537 break;
538 case 'N':
539 print_address_names = false;
540 break;
541 case 'U':
542 print_unresolved_addresses = true;
543 break;
544 case ARGP_KEY_NO_ARGS:
545 fputs (gettext ("Missing file name.\n"), stderr);
546 goto do_argp_help;
547 case ARGP_KEY_FINI:
548 if (! any_control_option && ! print_archive_index)
549 {
550 fputs (gettext ("No operation specified.\n"), stderr);
551 do_argp_help:
552 argp_help (&argp, stderr, ARGP_HELP_SEE,
553 program_invocation_short_name);
554 exit (EXIT_FAILURE);
555 }
556 break;
557 case 'W': /* Ignored. */
558 break;
559 case 'z':
560 print_decompress = true;
561 break;
562 case ELF_INPUT_SECTION:
563 if (arg == NULL)
564 elf_input_section = ".gnu_debugdata";
565 else
566 elf_input_section = arg;
567 break;
568 case DWARF_SKELETON:
569 dwarf_skeleton = arg;
570 break;
571 default:
572 return ARGP_ERR_UNKNOWN;
573 }
574 return 0;
575 }
576
577
578 /* Create a file descriptor to read the data from the
579 elf_input_section given a file descriptor to an ELF file. */
580 static int
open_input_section(int fd)581 open_input_section (int fd)
582 {
583 size_t shnums;
584 size_t cnt;
585 size_t shstrndx;
586 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
587 if (elf == NULL)
588 {
589 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
590 elf_errmsg (-1));
591 return -1;
592 }
593
594 if (elf_getshdrnum (elf, &shnums) < 0)
595 {
596 error (0, 0, gettext ("cannot determine number of sections: %s"),
597 elf_errmsg (-1));
598 open_error:
599 elf_end (elf);
600 return -1;
601 }
602
603 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
604 {
605 error (0, 0, gettext ("cannot get section header string table index"));
606 goto open_error;
607 }
608
609 for (cnt = 0; cnt < shnums; ++cnt)
610 {
611 Elf_Scn *scn = elf_getscn (elf, cnt);
612 if (scn == NULL)
613 {
614 error (0, 0, gettext ("cannot get section: %s"),
615 elf_errmsg (-1));
616 goto open_error;
617 }
618
619 GElf_Shdr shdr_mem;
620 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
621 if (unlikely (shdr == NULL))
622 {
623 error (0, 0, gettext ("cannot get section header: %s"),
624 elf_errmsg (-1));
625 goto open_error;
626 }
627
628 const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
629 if (sname == NULL)
630 {
631 error (0, 0, gettext ("cannot get section name"));
632 goto open_error;
633 }
634
635 if (strcmp (sname, elf_input_section) == 0)
636 {
637 Elf_Data *data = elf_rawdata (scn, NULL);
638 if (data == NULL)
639 {
640 error (0, 0, gettext ("cannot get %s content: %s"),
641 sname, elf_errmsg (-1));
642 goto open_error;
643 }
644
645 /* Create (and immediately unlink) a temporary file to store
646 section data in to create a file descriptor for it. */
647 const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
648 static const char suffix[] = "/readelfXXXXXX";
649 int tmplen = strlen (tmpdir) + sizeof (suffix);
650 char *tempname = alloca (tmplen);
651 sprintf (tempname, "%s%s", tmpdir, suffix);
652
653 int sfd = mkstemp (tempname);
654 if (sfd == -1)
655 {
656 error (0, 0, gettext ("cannot create temp file '%s'"),
657 tempname);
658 goto open_error;
659 }
660 unlink (tempname);
661
662 ssize_t size = data->d_size;
663 if (write_retry (sfd, data->d_buf, size) != size)
664 {
665 error (0, 0, gettext ("cannot write section data"));
666 goto open_error;
667 }
668
669 if (elf_end (elf) != 0)
670 {
671 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
672 elf_errmsg (-1));
673 return -1;
674 }
675
676 if (lseek (sfd, 0, SEEK_SET) == -1)
677 {
678 error (0, 0, gettext ("error while rewinding file descriptor"));
679 return -1;
680 }
681
682 return sfd;
683 }
684 }
685
686 /* Named section not found. */
687 if (elf_end (elf) != 0)
688 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
689 elf_errmsg (-1));
690 return -1;
691 }
692
693 /* Check if the file is an archive, and if so dump its index. */
694 static void
check_archive_index(int fd,const char * fname,bool only_one)695 check_archive_index (int fd, const char *fname, bool only_one)
696 {
697 /* Create an `Elf' descriptor. */
698 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
699 if (elf == NULL)
700 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
701 elf_errmsg (-1));
702 else
703 {
704 if (elf_kind (elf) == ELF_K_AR)
705 {
706 if (!only_one)
707 printf ("\n%s:\n\n", fname);
708 dump_archive_index (elf, fname);
709 }
710 else
711 error (0, 0,
712 gettext ("'%s' is not an archive, cannot print archive index"),
713 fname);
714
715 /* Now we can close the descriptor. */
716 if (elf_end (elf) != 0)
717 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
718 elf_errmsg (-1));
719 }
720 }
721
722 /* Trivial callback used for checking if we opened an archive. */
723 static int
count_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)724 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
725 void **userdata __attribute__ ((unused)),
726 const char *name __attribute__ ((unused)),
727 Dwarf_Addr base __attribute__ ((unused)),
728 void *arg)
729 {
730 if (*(bool *) arg)
731 return DWARF_CB_ABORT;
732 *(bool *) arg = true;
733 return DWARF_CB_OK;
734 }
735
736 struct process_dwflmod_args
737 {
738 int fd;
739 bool only_one;
740 };
741
742 static int
process_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)743 process_dwflmod (Dwfl_Module *dwflmod,
744 void **userdata __attribute__ ((unused)),
745 const char *name __attribute__ ((unused)),
746 Dwarf_Addr base __attribute__ ((unused)),
747 void *arg)
748 {
749 const struct process_dwflmod_args *a = arg;
750
751 /* Print the file name. */
752 if (!a->only_one)
753 {
754 const char *fname;
755 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
756
757 printf ("\n%s:\n\n", fname);
758 }
759
760 process_elf_file (dwflmod, a->fd);
761
762 return DWARF_CB_OK;
763 }
764
765 /* Stub libdwfl callback, only the ELF handle already open is ever used.
766 Only used for finding the alternate debug file if the Dwarf comes from
767 the main file. We are not interested in separate debuginfo. */
768 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)769 find_no_debuginfo (Dwfl_Module *mod,
770 void **userdata,
771 const char *modname,
772 Dwarf_Addr base,
773 const char *file_name,
774 const char *debuglink_file,
775 GElf_Word debuglink_crc,
776 char **debuginfo_file_name)
777 {
778 Dwarf_Addr dwbias;
779 dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
780
781 /* We are only interested if the Dwarf has been setup on the main
782 elf file but is only missing the alternate debug link. If dwbias
783 hasn't even been setup, this is searching for separate debuginfo
784 for the main elf. We don't care in that case. */
785 if (dwbias == (Dwarf_Addr) -1)
786 return -1;
787
788 return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
789 file_name, debuglink_file,
790 debuglink_crc, debuginfo_file_name);
791 }
792
793 static Dwfl *
create_dwfl(int fd,const char * fname)794 create_dwfl (int fd, const char *fname)
795 {
796 /* Duplicate an fd for dwfl_report_offline to swallow. */
797 int dwfl_fd = dup (fd);
798 if (unlikely (dwfl_fd < 0))
799 error (EXIT_FAILURE, errno, "dup");
800
801 /* Use libdwfl in a trivial way to open the libdw handle for us.
802 This takes care of applying relocations to DWARF data in ET_REL files. */
803 static const Dwfl_Callbacks callbacks =
804 {
805 .section_address = dwfl_offline_section_address,
806 .find_debuginfo = find_no_debuginfo
807 };
808 Dwfl *dwfl = dwfl_begin (&callbacks);
809 if (likely (dwfl != NULL))
810 /* Let 0 be the logical address of the file (or first in archive). */
811 dwfl->offline_next_address = 0;
812 if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
813 {
814 struct stat st;
815 if (fstat (dwfl_fd, &st) != 0)
816 error (0, errno, gettext ("cannot stat input file"));
817 else if (unlikely (st.st_size == 0))
818 error (0, 0, gettext ("input file is empty"));
819 else
820 error (0, 0, gettext ("failed reading '%s': %s"),
821 fname, dwfl_errmsg (-1));
822 close (dwfl_fd); /* Consumed on success, not on failure. */
823 dwfl = NULL;
824 }
825 else
826 dwfl_report_end (dwfl, NULL, NULL);
827
828 return dwfl;
829 }
830
831 /* Process one input file. */
832 static void
process_file(int fd,const char * fname,bool only_one)833 process_file (int fd, const char *fname, bool only_one)
834 {
835 if (print_archive_index)
836 check_archive_index (fd, fname, only_one);
837
838 if (!any_control_option)
839 return;
840
841 if (elf_input_section != NULL)
842 {
843 /* Replace fname and fd with section content. */
844 char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
845 sprintf (fnname, "%s:%s", fname, elf_input_section);
846 fd = open_input_section (fd);
847 if (fd == -1)
848 {
849 error (0, 0, gettext ("No such section '%s' in '%s'"),
850 elf_input_section, fname);
851 return;
852 }
853 fname = fnname;
854 }
855
856 Dwfl *dwfl = create_dwfl (fd, fname);
857 if (dwfl != NULL)
858 {
859 if (only_one)
860 {
861 /* Clear ONLY_ONE if we have multiple modules, from an archive. */
862 bool seen = false;
863 only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
864 }
865
866 /* Process the one or more modules gleaned from this file. */
867 struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
868 dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
869 }
870 /* Terrible hack for hooking unrelated skeleton/split compile units,
871 see __libdw_link_skel_split in print_debug. */
872 if (! do_not_close_dwfl)
873 dwfl_end (dwfl);
874
875 /* Need to close the replaced fd if we created it. Caller takes
876 care of original. */
877 if (elf_input_section != NULL)
878 close (fd);
879 }
880
881 /* Check whether there are any compressed sections in the ELF file. */
882 static bool
elf_contains_chdrs(Elf * elf)883 elf_contains_chdrs (Elf *elf)
884 {
885 Elf_Scn *scn = NULL;
886 while ((scn = elf_nextscn (elf, scn)) != NULL)
887 {
888 GElf_Shdr shdr_mem;
889 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
890 if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
891 return true;
892 }
893 return false;
894 }
895
896 /* Process one ELF file. */
897 static void
process_elf_file(Dwfl_Module * dwflmod,int fd)898 process_elf_file (Dwfl_Module *dwflmod, int fd)
899 {
900 GElf_Addr dwflbias;
901 Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
902
903 GElf_Ehdr ehdr_mem;
904 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
905
906 if (ehdr == NULL)
907 {
908 error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
909 return;
910 }
911
912 Ebl *ebl = ebl_openbackend (elf);
913 if (unlikely (ebl == NULL))
914 {
915 ebl_error:
916 error (0, errno, gettext ("cannot create EBL handle"));
917 return;
918 }
919
920 /* Determine the number of sections. */
921 if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
922 error (EXIT_FAILURE, 0,
923 gettext ("cannot determine number of sections: %s"),
924 elf_errmsg (-1));
925
926 /* Determine the number of phdrs. */
927 if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
928 error (EXIT_FAILURE, 0,
929 gettext ("cannot determine number of program headers: %s"),
930 elf_errmsg (-1));
931
932 /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
933 may have applied relocation to some sections. If there are any
934 compressed sections, any pass (or libdw/libdwfl) might have
935 uncompressed them. So we need to get a fresh Elf handle on the
936 file to display those. */
937 bool print_unchanged = ((print_section_header
938 || print_relocations
939 || dump_data_sections != NULL
940 || print_notes)
941 && (ehdr->e_type == ET_REL
942 || elf_contains_chdrs (ebl->elf)));
943
944 Elf *pure_elf = NULL;
945 Ebl *pure_ebl = ebl;
946 if (print_unchanged)
947 {
948 /* Read the file afresh. */
949 off_t aroff = elf_getaroff (elf);
950 pure_elf = dwelf_elf_begin (fd);
951 if (aroff > 0)
952 {
953 /* Archive member. */
954 (void) elf_rand (pure_elf, aroff);
955 Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
956 elf_end (pure_elf);
957 pure_elf = armem;
958 }
959 if (pure_elf == NULL)
960 {
961 error (0, 0, gettext ("cannot read ELF: %s"), elf_errmsg (-1));
962 return;
963 }
964 pure_ebl = ebl_openbackend (pure_elf);
965 if (pure_ebl == NULL)
966 goto ebl_error;
967 }
968
969 if (print_file_header)
970 print_ehdr (ebl, ehdr);
971 if (print_section_header)
972 print_shdr (pure_ebl, ehdr);
973 if (print_program_header)
974 print_phdr (ebl, ehdr);
975 if (print_section_groups)
976 print_scngrp (ebl);
977 if (print_dynamic_table)
978 print_dynamic (ebl);
979 if (print_relocations)
980 print_relocs (pure_ebl, ehdr);
981 if (print_histogram)
982 handle_hash (ebl);
983 if (print_symbol_table)
984 print_symtab (ebl, SHT_DYNSYM);
985 if (print_version_info)
986 print_verinfo (ebl);
987 if (print_symbol_table)
988 print_symtab (ebl, SHT_SYMTAB);
989 if (print_arch)
990 print_liblist (ebl);
991 if (print_arch)
992 print_attributes (ebl, ehdr);
993 if (dump_data_sections != NULL)
994 dump_data (pure_ebl);
995 if (string_sections != NULL)
996 dump_strings (ebl);
997 if ((print_debug_sections | implicit_debug_sections) != 0)
998 print_debug (dwflmod, ebl, ehdr);
999 if (print_notes)
1000 handle_notes (pure_ebl, ehdr);
1001 if (print_string_sections)
1002 print_strings (ebl);
1003
1004 ebl_closebackend (ebl);
1005
1006 if (pure_ebl != ebl)
1007 {
1008 ebl_closebackend (pure_ebl);
1009 elf_end (pure_elf);
1010 }
1011 }
1012
1013
1014 /* Print file type. */
1015 static void
print_file_type(unsigned short int e_type)1016 print_file_type (unsigned short int e_type)
1017 {
1018 if (likely (e_type <= ET_CORE))
1019 {
1020 static const char *const knowntypes[] =
1021 {
1022 N_("NONE (None)"),
1023 N_("REL (Relocatable file)"),
1024 N_("EXEC (Executable file)"),
1025 N_("DYN (Shared object file)"),
1026 N_("CORE (Core file)")
1027 };
1028 puts (gettext (knowntypes[e_type]));
1029 }
1030 else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
1031 printf (gettext ("OS Specific: (%x)\n"), e_type);
1032 else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
1033 printf (gettext ("Processor Specific: (%x)\n"), e_type);
1034 else
1035 puts ("???");
1036 }
1037
1038
1039 /* Print ELF header. */
1040 static void
print_ehdr(Ebl * ebl,GElf_Ehdr * ehdr)1041 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
1042 {
1043 fputs_unlocked (gettext ("ELF Header:\n Magic: "), stdout);
1044 for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
1045 printf (" %02hhx", ehdr->e_ident[cnt]);
1046
1047 printf (gettext ("\n Class: %s\n"),
1048 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
1049 : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
1050 : "\?\?\?");
1051
1052 printf (gettext (" Data: %s\n"),
1053 ehdr->e_ident[EI_DATA] == ELFDATA2LSB
1054 ? "2's complement, little endian"
1055 : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
1056 ? "2's complement, big endian" : "\?\?\?");
1057
1058 printf (gettext (" Ident Version: %hhd %s\n"),
1059 ehdr->e_ident[EI_VERSION],
1060 ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
1061 : "(\?\?\?)");
1062
1063 char buf[512];
1064 printf (gettext (" OS/ABI: %s\n"),
1065 ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
1066
1067 printf (gettext (" ABI Version: %hhd\n"),
1068 ehdr->e_ident[EI_ABIVERSION]);
1069
1070 fputs_unlocked (gettext (" Type: "), stdout);
1071 print_file_type (ehdr->e_type);
1072
1073 printf (gettext (" Machine: %s\n"), ebl->name);
1074
1075 printf (gettext (" Version: %d %s\n"),
1076 ehdr->e_version,
1077 ehdr->e_version == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
1078
1079 printf (gettext (" Entry point address: %#" PRIx64 "\n"),
1080 ehdr->e_entry);
1081
1082 printf (gettext (" Start of program headers: %" PRId64 " %s\n"),
1083 ehdr->e_phoff, gettext ("(bytes into file)"));
1084
1085 printf (gettext (" Start of section headers: %" PRId64 " %s\n"),
1086 ehdr->e_shoff, gettext ("(bytes into file)"));
1087
1088 printf (gettext (" Flags: %s\n"),
1089 ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
1090
1091 printf (gettext (" Size of this header: %" PRId16 " %s\n"),
1092 ehdr->e_ehsize, gettext ("(bytes)"));
1093
1094 printf (gettext (" Size of program header entries: %" PRId16 " %s\n"),
1095 ehdr->e_phentsize, gettext ("(bytes)"));
1096
1097 printf (gettext (" Number of program headers entries: %" PRId16),
1098 ehdr->e_phnum);
1099 if (ehdr->e_phnum == PN_XNUM)
1100 {
1101 GElf_Shdr shdr_mem;
1102 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1103 if (shdr != NULL)
1104 printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
1105 (uint32_t) shdr->sh_info);
1106 else
1107 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1108 }
1109 fputc_unlocked ('\n', stdout);
1110
1111 printf (gettext (" Size of section header entries: %" PRId16 " %s\n"),
1112 ehdr->e_shentsize, gettext ("(bytes)"));
1113
1114 printf (gettext (" Number of section headers entries: %" PRId16),
1115 ehdr->e_shnum);
1116 if (ehdr->e_shnum == 0)
1117 {
1118 GElf_Shdr shdr_mem;
1119 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1120 if (shdr != NULL)
1121 printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
1122 (uint32_t) shdr->sh_size);
1123 else
1124 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1125 }
1126 fputc_unlocked ('\n', stdout);
1127
1128 if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1129 {
1130 GElf_Shdr shdr_mem;
1131 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1132 if (shdr != NULL)
1133 /* We managed to get the zeroth section. */
1134 snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
1135 (uint32_t) shdr->sh_link);
1136 else
1137 {
1138 strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
1139 buf[sizeof (buf) - 1] = '\0';
1140 }
1141
1142 printf (gettext (" Section header string table index: XINDEX%s\n\n"),
1143 buf);
1144 }
1145 else
1146 printf (gettext (" Section header string table index: %" PRId16 "\n\n"),
1147 ehdr->e_shstrndx);
1148 }
1149
1150
1151 static const char *
get_visibility_type(int value)1152 get_visibility_type (int value)
1153 {
1154 switch (value)
1155 {
1156 case STV_DEFAULT:
1157 return "DEFAULT";
1158 case STV_INTERNAL:
1159 return "INTERNAL";
1160 case STV_HIDDEN:
1161 return "HIDDEN";
1162 case STV_PROTECTED:
1163 return "PROTECTED";
1164 default:
1165 return "???";
1166 }
1167 }
1168
1169 static const char *
elf_ch_type_name(unsigned int code)1170 elf_ch_type_name (unsigned int code)
1171 {
1172 if (code == 0)
1173 return "NONE";
1174
1175 if (code == ELFCOMPRESS_ZLIB)
1176 return "ZLIB";
1177
1178 return "UNKNOWN";
1179 }
1180
1181 /* Print the section headers. */
1182 static void
print_shdr(Ebl * ebl,GElf_Ehdr * ehdr)1183 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1184 {
1185 size_t cnt;
1186 size_t shstrndx;
1187
1188 if (! print_file_header)
1189 {
1190 size_t sections;
1191 if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0))
1192 error (EXIT_FAILURE, 0,
1193 gettext ("cannot get number of sections: %s"),
1194 elf_errmsg (-1));
1195
1196 printf (gettext ("\
1197 There are %zd section headers, starting at offset %#" PRIx64 ":\n\
1198 \n"),
1199 sections, ehdr->e_shoff);
1200 }
1201
1202 /* Get the section header string table index. */
1203 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1204 error (EXIT_FAILURE, 0,
1205 gettext ("cannot get section header string table index: %s"),
1206 elf_errmsg (-1));
1207
1208 puts (gettext ("Section Headers:"));
1209
1210 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1211 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1212 else
1213 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1214
1215 if (print_decompress)
1216 {
1217 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1218 puts (gettext (" [Compression Size Al]"));
1219 else
1220 puts (gettext (" [Compression Size Al]"));
1221 }
1222
1223 for (cnt = 0; cnt < shnum; ++cnt)
1224 {
1225 Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1226
1227 if (unlikely (scn == NULL))
1228 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1229 elf_errmsg (-1));
1230
1231 /* Get the section header. */
1232 GElf_Shdr shdr_mem;
1233 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1234 if (unlikely (shdr == NULL))
1235 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
1236 elf_errmsg (-1));
1237
1238 char flagbuf[20];
1239 char *cp = flagbuf;
1240 if (shdr->sh_flags & SHF_WRITE)
1241 *cp++ = 'W';
1242 if (shdr->sh_flags & SHF_ALLOC)
1243 *cp++ = 'A';
1244 if (shdr->sh_flags & SHF_EXECINSTR)
1245 *cp++ = 'X';
1246 if (shdr->sh_flags & SHF_MERGE)
1247 *cp++ = 'M';
1248 if (shdr->sh_flags & SHF_STRINGS)
1249 *cp++ = 'S';
1250 if (shdr->sh_flags & SHF_INFO_LINK)
1251 *cp++ = 'I';
1252 if (shdr->sh_flags & SHF_LINK_ORDER)
1253 *cp++ = 'L';
1254 if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1255 *cp++ = 'N';
1256 if (shdr->sh_flags & SHF_GROUP)
1257 *cp++ = 'G';
1258 if (shdr->sh_flags & SHF_TLS)
1259 *cp++ = 'T';
1260 if (shdr->sh_flags & SHF_COMPRESSED)
1261 *cp++ = 'C';
1262 if (shdr->sh_flags & SHF_ORDERED)
1263 *cp++ = 'O';
1264 if (shdr->sh_flags & SHF_EXCLUDE)
1265 *cp++ = 'E';
1266 *cp = '\0';
1267
1268 const char *sname;
1269 char buf[128];
1270 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>";
1271 printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1272 " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1273 " %2" PRId64 "\n",
1274 cnt, sname,
1275 ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1276 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1277 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1278 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1279 shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1280 shdr->sh_addralign);
1281
1282 if (print_decompress)
1283 {
1284 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1285 {
1286 GElf_Chdr chdr;
1287 if (gelf_getchdr (scn, &chdr) != NULL)
1288 printf (" [ELF %s (%" PRId32 ") %0*" PRIx64
1289 " %2" PRId64 "]\n",
1290 elf_ch_type_name (chdr.ch_type),
1291 chdr.ch_type,
1292 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8,
1293 chdr.ch_size, chdr.ch_addralign);
1294 else
1295 error (0, 0,
1296 gettext ("bad compression header for section %zd: %s"),
1297 elf_ndxscn (scn), elf_errmsg (-1));
1298 }
1299 else if (strncmp(".zdebug", sname, strlen (".zdebug")) == 0)
1300 {
1301 ssize_t size;
1302 if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0)
1303 printf (" [GNU ZLIB %0*zx ]\n",
1304 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size);
1305 else
1306 error (0, 0,
1307 gettext ("bad gnu compressed size for section %zd: %s"),
1308 elf_ndxscn (scn), elf_errmsg (-1));
1309 }
1310 }
1311 }
1312
1313 fputc_unlocked ('\n', stdout);
1314 }
1315
1316
1317 /* Print the program header. */
1318 static void
print_phdr(Ebl * ebl,GElf_Ehdr * ehdr)1319 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1320 {
1321 if (phnum == 0)
1322 /* No program header, this is OK in relocatable objects. */
1323 return;
1324
1325 puts (gettext ("Program Headers:"));
1326 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1327 puts (gettext ("\
1328 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1329 else
1330 puts (gettext ("\
1331 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1332
1333 /* Process all program headers. */
1334 bool has_relro = false;
1335 GElf_Addr relro_from = 0;
1336 GElf_Addr relro_to = 0;
1337 for (size_t cnt = 0; cnt < phnum; ++cnt)
1338 {
1339 char buf[128];
1340 GElf_Phdr mem;
1341 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1342
1343 /* If for some reason the header cannot be returned show this. */
1344 if (unlikely (phdr == NULL))
1345 {
1346 puts (" ???");
1347 continue;
1348 }
1349
1350 printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1351 " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1352 ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1353 phdr->p_offset,
1354 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1355 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1356 phdr->p_filesz,
1357 phdr->p_memsz,
1358 phdr->p_flags & PF_R ? 'R' : ' ',
1359 phdr->p_flags & PF_W ? 'W' : ' ',
1360 phdr->p_flags & PF_X ? 'E' : ' ',
1361 phdr->p_align);
1362
1363 if (phdr->p_type == PT_INTERP)
1364 {
1365 /* If we are sure the file offset is valid then we can show
1366 the user the name of the interpreter. We check whether
1367 there is a section at the file offset. Normally there
1368 would be a section called ".interp". But in separate
1369 .debug files it is a NOBITS section (and so doesn't match
1370 with gelf_offscn). Which probably means the offset is
1371 not valid another reason could be because the ELF file
1372 just doesn't contain any section headers, in that case
1373 just play it safe and don't display anything. */
1374
1375 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1376 GElf_Shdr shdr_mem;
1377 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1378
1379 size_t maxsize;
1380 char *filedata = elf_rawfile (ebl->elf, &maxsize);
1381
1382 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
1383 && filedata != NULL && phdr->p_offset < maxsize
1384 && phdr->p_filesz <= maxsize - phdr->p_offset
1385 && memchr (filedata + phdr->p_offset, '\0',
1386 phdr->p_filesz) != NULL)
1387 printf (gettext ("\t[Requesting program interpreter: %s]\n"),
1388 filedata + phdr->p_offset);
1389 }
1390 else if (phdr->p_type == PT_GNU_RELRO)
1391 {
1392 has_relro = true;
1393 relro_from = phdr->p_vaddr;
1394 relro_to = relro_from + phdr->p_memsz;
1395 }
1396 }
1397
1398 size_t sections;
1399 if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0))
1400 error (EXIT_FAILURE, 0,
1401 gettext ("cannot get number of sections: %s"),
1402 elf_errmsg (-1));
1403
1404 if (sections == 0)
1405 /* No sections in the file. Punt. */
1406 return;
1407
1408 /* Get the section header string table index. */
1409 size_t shstrndx;
1410 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1411 error (EXIT_FAILURE, 0,
1412 gettext ("cannot get section header string table index"));
1413
1414 puts (gettext ("\n Section to Segment mapping:\n Segment Sections..."));
1415
1416 for (size_t cnt = 0; cnt < phnum; ++cnt)
1417 {
1418 /* Print the segment number. */
1419 printf (" %2.2zu ", cnt);
1420
1421 GElf_Phdr phdr_mem;
1422 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1423 /* This must not happen. */
1424 if (unlikely (phdr == NULL))
1425 error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
1426 elf_errmsg (-1));
1427
1428 /* Iterate over the sections. */
1429 bool in_relro = false;
1430 bool in_ro = false;
1431 for (size_t inner = 1; inner < shnum; ++inner)
1432 {
1433 Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1434 /* This should not happen. */
1435 if (unlikely (scn == NULL))
1436 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1437 elf_errmsg (-1));
1438
1439 /* Get the section header. */
1440 GElf_Shdr shdr_mem;
1441 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1442 if (unlikely (shdr == NULL))
1443 error (EXIT_FAILURE, 0,
1444 gettext ("cannot get section header: %s"),
1445 elf_errmsg (-1));
1446
1447 if (shdr->sh_size > 0
1448 /* Compare allocated sections by VMA, unallocated
1449 sections by file offset. */
1450 && (shdr->sh_flags & SHF_ALLOC
1451 ? (shdr->sh_addr >= phdr->p_vaddr
1452 && (shdr->sh_addr + shdr->sh_size
1453 <= phdr->p_vaddr + phdr->p_memsz))
1454 : (shdr->sh_offset >= phdr->p_offset
1455 && (shdr->sh_offset + shdr->sh_size
1456 <= phdr->p_offset + phdr->p_filesz))))
1457 {
1458 if (has_relro && !in_relro
1459 && shdr->sh_addr >= relro_from
1460 && shdr->sh_addr + shdr->sh_size <= relro_to)
1461 {
1462 fputs_unlocked (" [RELRO:", stdout);
1463 in_relro = true;
1464 }
1465 else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1466 {
1467 fputs_unlocked ("]", stdout);
1468 in_relro = false;
1469 }
1470 else if (has_relro && in_relro
1471 && shdr->sh_addr + shdr->sh_size > relro_to)
1472 fputs_unlocked ("] <RELRO:", stdout);
1473 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1474 {
1475 if (!in_ro)
1476 {
1477 fputs_unlocked (" [RO:", stdout);
1478 in_ro = true;
1479 }
1480 }
1481 else
1482 {
1483 /* Determine the segment this section is part of. */
1484 size_t cnt2;
1485 GElf_Phdr phdr2_mem;
1486 GElf_Phdr *phdr2 = NULL;
1487 for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1488 {
1489 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1490
1491 if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1492 && shdr->sh_addr >= phdr2->p_vaddr
1493 && (shdr->sh_addr + shdr->sh_size
1494 <= phdr2->p_vaddr + phdr2->p_memsz))
1495 break;
1496 }
1497
1498 if (cnt2 < phnum)
1499 {
1500 if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1501 {
1502 fputs_unlocked (" [RO:", stdout);
1503 in_ro = true;
1504 }
1505 else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1506 {
1507 fputs_unlocked ("]", stdout);
1508 in_ro = false;
1509 }
1510 }
1511 }
1512
1513 printf (" %s",
1514 elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1515
1516 /* Signal that this sectin is only partially covered. */
1517 if (has_relro && in_relro
1518 && shdr->sh_addr + shdr->sh_size > relro_to)
1519 {
1520 fputs_unlocked (">", stdout);
1521 in_relro = false;
1522 }
1523 }
1524 }
1525 if (in_relro || in_ro)
1526 fputs_unlocked ("]", stdout);
1527
1528 /* Finish the line. */
1529 fputc_unlocked ('\n', stdout);
1530 }
1531 }
1532
1533
1534 static const char *
section_name(Ebl * ebl,GElf_Shdr * shdr)1535 section_name (Ebl *ebl, GElf_Shdr *shdr)
1536 {
1537 size_t shstrndx;
1538 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
1539 return "???";
1540 return elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "???";
1541 }
1542
1543
1544 static void
handle_scngrp(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1545 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1546 {
1547 /* Get the data of the section. */
1548 Elf_Data *data = elf_getdata (scn, NULL);
1549
1550 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1551 GElf_Shdr symshdr_mem;
1552 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1553 Elf_Data *symdata = elf_getdata (symscn, NULL);
1554
1555 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1556 || symdata == NULL)
1557 return;
1558
1559 /* Get the section header string table index. */
1560 size_t shstrndx;
1561 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1562 error (EXIT_FAILURE, 0,
1563 gettext ("cannot get section header string table index"));
1564
1565 Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1566
1567 GElf_Sym sym_mem;
1568 GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1569
1570 printf ((grpref[0] & GRP_COMDAT)
1571 ? ngettext ("\
1572 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1573 "\
1574 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1575 data->d_size / sizeof (Elf32_Word) - 1)
1576 : ngettext ("\
1577 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1578 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1579 data->d_size / sizeof (Elf32_Word) - 1),
1580 elf_ndxscn (scn),
1581 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1582 (sym == NULL ? NULL
1583 : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1584 ?: gettext ("<INVALID SYMBOL>"),
1585 data->d_size / sizeof (Elf32_Word) - 1);
1586
1587 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1588 {
1589 GElf_Shdr grpshdr_mem;
1590 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1591 &grpshdr_mem);
1592
1593 const char *str;
1594 printf (" [%2u] %s\n",
1595 grpref[cnt],
1596 grpshdr != NULL
1597 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1598 ? str : gettext ("<INVALID SECTION>"));
1599 }
1600 }
1601
1602
1603 static void
print_scngrp(Ebl * ebl)1604 print_scngrp (Ebl *ebl)
1605 {
1606 /* Find all relocation sections and handle them. */
1607 Elf_Scn *scn = NULL;
1608
1609 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1610 {
1611 /* Handle the section if it is a symbol table. */
1612 GElf_Shdr shdr_mem;
1613 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1614
1615 if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1616 {
1617 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1618 {
1619 if (elf_compress (scn, 0, 0) < 0)
1620 printf ("WARNING: %s [%zd]\n",
1621 gettext ("Couldn't uncompress section"),
1622 elf_ndxscn (scn));
1623 shdr = gelf_getshdr (scn, &shdr_mem);
1624 if (unlikely (shdr == NULL))
1625 error (EXIT_FAILURE, 0,
1626 gettext ("cannot get section [%zd] header: %s"),
1627 elf_ndxscn (scn),
1628 elf_errmsg (-1));
1629 }
1630 handle_scngrp (ebl, scn, shdr);
1631 }
1632 }
1633 }
1634
1635
1636 static const struct flags
1637 {
1638 int mask;
1639 const char *str;
1640 } dt_flags[] =
1641 {
1642 { DF_ORIGIN, "ORIGIN" },
1643 { DF_SYMBOLIC, "SYMBOLIC" },
1644 { DF_TEXTREL, "TEXTREL" },
1645 { DF_BIND_NOW, "BIND_NOW" },
1646 { DF_STATIC_TLS, "STATIC_TLS" }
1647 };
1648 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1649
1650 static const struct flags dt_flags_1[] =
1651 {
1652 { DF_1_NOW, "NOW" },
1653 { DF_1_GLOBAL, "GLOBAL" },
1654 { DF_1_GROUP, "GROUP" },
1655 { DF_1_NODELETE, "NODELETE" },
1656 { DF_1_LOADFLTR, "LOADFLTR" },
1657 { DF_1_INITFIRST, "INITFIRST" },
1658 { DF_1_NOOPEN, "NOOPEN" },
1659 { DF_1_ORIGIN, "ORIGIN" },
1660 { DF_1_DIRECT, "DIRECT" },
1661 { DF_1_TRANS, "TRANS" },
1662 { DF_1_INTERPOSE, "INTERPOSE" },
1663 { DF_1_NODEFLIB, "NODEFLIB" },
1664 { DF_1_NODUMP, "NODUMP" },
1665 { DF_1_CONFALT, "CONFALT" },
1666 { DF_1_ENDFILTEE, "ENDFILTEE" },
1667 { DF_1_DISPRELDNE, "DISPRELDNE" },
1668 { DF_1_DISPRELPND, "DISPRELPND" },
1669 };
1670 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1671
1672 static const struct flags dt_feature_1[] =
1673 {
1674 { DTF_1_PARINIT, "PARINIT" },
1675 { DTF_1_CONFEXP, "CONFEXP" }
1676 };
1677 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1678 / sizeof (dt_feature_1[0]));
1679
1680 static const struct flags dt_posflag_1[] =
1681 {
1682 { DF_P1_LAZYLOAD, "LAZYLOAD" },
1683 { DF_P1_GROUPPERM, "GROUPPERM" }
1684 };
1685 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1686 / sizeof (dt_posflag_1[0]));
1687
1688
1689 static void
print_flags(int class,GElf_Xword d_val,const struct flags * flags,int nflags)1690 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1691 int nflags)
1692 {
1693 bool first = true;
1694 int cnt;
1695
1696 for (cnt = 0; cnt < nflags; ++cnt)
1697 if (d_val & flags[cnt].mask)
1698 {
1699 if (!first)
1700 putchar_unlocked (' ');
1701 fputs_unlocked (flags[cnt].str, stdout);
1702 d_val &= ~flags[cnt].mask;
1703 first = false;
1704 }
1705
1706 if (d_val != 0)
1707 {
1708 if (!first)
1709 putchar_unlocked (' ');
1710 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1711 }
1712
1713 putchar_unlocked ('\n');
1714 }
1715
1716
1717 static void
print_dt_flags(int class,GElf_Xword d_val)1718 print_dt_flags (int class, GElf_Xword d_val)
1719 {
1720 print_flags (class, d_val, dt_flags, ndt_flags);
1721 }
1722
1723
1724 static void
print_dt_flags_1(int class,GElf_Xword d_val)1725 print_dt_flags_1 (int class, GElf_Xword d_val)
1726 {
1727 print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1728 }
1729
1730
1731 static void
print_dt_feature_1(int class,GElf_Xword d_val)1732 print_dt_feature_1 (int class, GElf_Xword d_val)
1733 {
1734 print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1735 }
1736
1737
1738 static void
print_dt_posflag_1(int class,GElf_Xword d_val)1739 print_dt_posflag_1 (int class, GElf_Xword d_val)
1740 {
1741 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1742 }
1743
1744
1745 static void
handle_dynamic(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1746 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1747 {
1748 int class = gelf_getclass (ebl->elf);
1749 GElf_Shdr glink_mem;
1750 GElf_Shdr *glink;
1751 Elf_Data *data;
1752 size_t cnt;
1753 size_t shstrndx;
1754 size_t sh_entsize;
1755
1756 /* Get the data of the section. */
1757 data = elf_getdata (scn, NULL);
1758 if (data == NULL)
1759 return;
1760
1761 /* Get the section header string table index. */
1762 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1763 error (EXIT_FAILURE, 0,
1764 gettext ("cannot get section header string table index"));
1765
1766 sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1767
1768 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1769 if (glink == NULL)
1770 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
1771 elf_ndxscn (scn));
1772
1773 printf (ngettext ("\
1774 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1775 "\
1776 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1777 shdr->sh_size / sh_entsize),
1778 (unsigned long int) (shdr->sh_size / sh_entsize),
1779 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1780 shdr->sh_offset,
1781 (int) shdr->sh_link,
1782 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1783 fputs_unlocked (gettext (" Type Value\n"), stdout);
1784
1785 for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1786 {
1787 GElf_Dyn dynmem;
1788 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1789 if (dyn == NULL)
1790 break;
1791
1792 char buf[64];
1793 printf (" %-17s ",
1794 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1795
1796 switch (dyn->d_tag)
1797 {
1798 case DT_NULL:
1799 case DT_DEBUG:
1800 case DT_BIND_NOW:
1801 case DT_TEXTREL:
1802 /* No further output. */
1803 fputc_unlocked ('\n', stdout);
1804 break;
1805
1806 case DT_NEEDED:
1807 printf (gettext ("Shared library: [%s]\n"),
1808 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1809 break;
1810
1811 case DT_SONAME:
1812 printf (gettext ("Library soname: [%s]\n"),
1813 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1814 break;
1815
1816 case DT_RPATH:
1817 printf (gettext ("Library rpath: [%s]\n"),
1818 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1819 break;
1820
1821 case DT_RUNPATH:
1822 printf (gettext ("Library runpath: [%s]\n"),
1823 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1824 break;
1825
1826 case DT_PLTRELSZ:
1827 case DT_RELASZ:
1828 case DT_STRSZ:
1829 case DT_RELSZ:
1830 case DT_RELAENT:
1831 case DT_SYMENT:
1832 case DT_RELENT:
1833 case DT_PLTPADSZ:
1834 case DT_MOVEENT:
1835 case DT_MOVESZ:
1836 case DT_INIT_ARRAYSZ:
1837 case DT_FINI_ARRAYSZ:
1838 case DT_SYMINSZ:
1839 case DT_SYMINENT:
1840 case DT_GNU_CONFLICTSZ:
1841 case DT_GNU_LIBLISTSZ:
1842 printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1843 break;
1844
1845 case DT_VERDEFNUM:
1846 case DT_VERNEEDNUM:
1847 case DT_RELACOUNT:
1848 case DT_RELCOUNT:
1849 printf ("%" PRId64 "\n", dyn->d_un.d_val);
1850 break;
1851
1852 case DT_PLTREL:;
1853 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1854 NULL, 0);
1855 puts (tagname ?: "???");
1856 break;
1857
1858 case DT_FLAGS:
1859 print_dt_flags (class, dyn->d_un.d_val);
1860 break;
1861
1862 case DT_FLAGS_1:
1863 print_dt_flags_1 (class, dyn->d_un.d_val);
1864 break;
1865
1866 case DT_FEATURE_1:
1867 print_dt_feature_1 (class, dyn->d_un.d_val);
1868 break;
1869
1870 case DT_POSFLAG_1:
1871 print_dt_posflag_1 (class, dyn->d_un.d_val);
1872 break;
1873
1874 default:
1875 printf ("%#0*" PRIx64 "\n",
1876 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1877 break;
1878 }
1879 }
1880 }
1881
1882
1883 /* Print the dynamic segment. */
1884 static void
print_dynamic(Ebl * ebl)1885 print_dynamic (Ebl *ebl)
1886 {
1887 for (size_t i = 0; i < phnum; ++i)
1888 {
1889 GElf_Phdr phdr_mem;
1890 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1891
1892 if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1893 {
1894 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1895 GElf_Shdr shdr_mem;
1896 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1897 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1898 handle_dynamic (ebl, scn, shdr);
1899 break;
1900 }
1901 }
1902 }
1903
1904
1905 /* Print relocations. */
1906 static void
print_relocs(Ebl * ebl,GElf_Ehdr * ehdr)1907 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1908 {
1909 /* Find all relocation sections and handle them. */
1910 Elf_Scn *scn = NULL;
1911
1912 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1913 {
1914 /* Handle the section if it is a symbol table. */
1915 GElf_Shdr shdr_mem;
1916 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1917
1918 if (likely (shdr != NULL))
1919 {
1920 if (shdr->sh_type == SHT_REL)
1921 handle_relocs_rel (ebl, ehdr, scn, shdr);
1922 else if (shdr->sh_type == SHT_RELA)
1923 handle_relocs_rela (ebl, ehdr, scn, shdr);
1924 }
1925 }
1926 }
1927
1928
1929 /* Handle a relocation section. */
1930 static void
handle_relocs_rel(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)1931 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1932 {
1933 int class = gelf_getclass (ebl->elf);
1934 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1935 int nentries = shdr->sh_size / sh_entsize;
1936
1937 /* Get the data of the section. */
1938 Elf_Data *data = elf_getdata (scn, NULL);
1939 if (data == NULL)
1940 return;
1941
1942 /* Get the symbol table information. */
1943 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1944 GElf_Shdr symshdr_mem;
1945 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1946 Elf_Data *symdata = elf_getdata (symscn, NULL);
1947
1948 /* Get the section header of the section the relocations are for. */
1949 GElf_Shdr destshdr_mem;
1950 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1951 &destshdr_mem);
1952
1953 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1954 {
1955 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1956 shdr->sh_offset);
1957 return;
1958 }
1959
1960 /* Search for the optional extended section index table. */
1961 Elf_Data *xndxdata = NULL;
1962 int xndxscnidx = elf_scnshndx (scn);
1963 if (unlikely (xndxscnidx > 0))
1964 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1965
1966 /* Get the section header string table index. */
1967 size_t shstrndx;
1968 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1969 error (EXIT_FAILURE, 0,
1970 gettext ("cannot get section header string table index"));
1971
1972 if (shdr->sh_info != 0)
1973 printf (ngettext ("\
1974 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1975 "\
1976 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1977 nentries),
1978 elf_ndxscn (scn),
1979 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1980 (unsigned int) shdr->sh_info,
1981 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1982 shdr->sh_offset,
1983 nentries);
1984 else
1985 /* The .rel.dyn section does not refer to a specific section but
1986 instead of section index zero. Do not try to print a section
1987 name. */
1988 printf (ngettext ("\
1989 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1990 "\
1991 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1992 nentries),
1993 (unsigned int) elf_ndxscn (scn),
1994 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1995 shdr->sh_offset,
1996 nentries);
1997 fputs_unlocked (class == ELFCLASS32
1998 ? gettext ("\
1999 Offset Type Value Name\n")
2000 : gettext ("\
2001 Offset Type Value Name\n"),
2002 stdout);
2003
2004 int is_statically_linked = 0;
2005 for (int cnt = 0; cnt < nentries; ++cnt)
2006 {
2007 GElf_Rel relmem;
2008 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
2009 if (likely (rel != NULL))
2010 {
2011 char buf[128];
2012 GElf_Sym symmem;
2013 Elf32_Word xndx;
2014 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2015 GELF_R_SYM (rel->r_info),
2016 &symmem, &xndx);
2017 if (unlikely (sym == NULL))
2018 {
2019 /* As a special case we have to handle relocations in static
2020 executables. This only happens for IRELATIVE relocations
2021 (so far). There is no symbol table. */
2022 if (is_statically_linked == 0)
2023 {
2024 /* Find the program header and look for a PT_INTERP entry. */
2025 is_statically_linked = -1;
2026 if (ehdr->e_type == ET_EXEC)
2027 {
2028 is_statically_linked = 1;
2029
2030 for (size_t inner = 0; inner < phnum; ++inner)
2031 {
2032 GElf_Phdr phdr_mem;
2033 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2034 &phdr_mem);
2035 if (phdr != NULL && phdr->p_type == PT_INTERP)
2036 {
2037 is_statically_linked = -1;
2038 break;
2039 }
2040 }
2041 }
2042 }
2043
2044 if (is_statically_linked > 0 && shdr->sh_link == 0)
2045 printf ("\
2046 %#0*" PRIx64 " %-20s %*s %s\n",
2047 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2048 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2049 /* Avoid the leading R_ which isn't carrying any
2050 information. */
2051 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2052 buf, sizeof (buf)) + 2
2053 : gettext ("<INVALID RELOC>"),
2054 class == ELFCLASS32 ? 10 : 18, "",
2055 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2056 else
2057 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
2058 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2059 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2060 /* Avoid the leading R_ which isn't carrying any
2061 information. */
2062 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2063 buf, sizeof (buf)) + 2
2064 : gettext ("<INVALID RELOC>"),
2065 gettext ("INVALID SYMBOL"),
2066 (long int) GELF_R_SYM (rel->r_info));
2067 }
2068 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2069 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
2070 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2071 likely (ebl_reloc_type_check (ebl,
2072 GELF_R_TYPE (rel->r_info)))
2073 /* Avoid the leading R_ which isn't carrying any
2074 information. */
2075 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2076 buf, sizeof (buf)) + 2
2077 : gettext ("<INVALID RELOC>"),
2078 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2079 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2080 else
2081 {
2082 /* This is a relocation against a STT_SECTION symbol. */
2083 GElf_Shdr secshdr_mem;
2084 GElf_Shdr *secshdr;
2085 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2086 sym->st_shndx == SHN_XINDEX
2087 ? xndx : sym->st_shndx),
2088 &secshdr_mem);
2089
2090 if (unlikely (secshdr == NULL))
2091 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
2092 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2093 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2094 /* Avoid the leading R_ which isn't carrying any
2095 information. */
2096 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2097 buf, sizeof (buf)) + 2
2098 : gettext ("<INVALID RELOC>"),
2099 gettext ("INVALID SECTION"),
2100 (long int) (sym->st_shndx == SHN_XINDEX
2101 ? xndx : sym->st_shndx));
2102 else
2103 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
2104 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2105 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2106 /* Avoid the leading R_ which isn't carrying any
2107 information. */
2108 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2109 buf, sizeof (buf)) + 2
2110 : gettext ("<INVALID RELOC>"),
2111 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2112 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2113 }
2114 }
2115 }
2116 }
2117
2118
2119 /* Handle a relocation section. */
2120 static void
handle_relocs_rela(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)2121 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2122 {
2123 int class = gelf_getclass (ebl->elf);
2124 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
2125 int nentries = shdr->sh_size / sh_entsize;
2126
2127 /* Get the data of the section. */
2128 Elf_Data *data = elf_getdata (scn, NULL);
2129 if (data == NULL)
2130 return;
2131
2132 /* Get the symbol table information. */
2133 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2134 GElf_Shdr symshdr_mem;
2135 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2136 Elf_Data *symdata = elf_getdata (symscn, NULL);
2137
2138 /* Get the section header of the section the relocations are for. */
2139 GElf_Shdr destshdr_mem;
2140 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2141 &destshdr_mem);
2142
2143 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2144 {
2145 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2146 shdr->sh_offset);
2147 return;
2148 }
2149
2150 /* Search for the optional extended section index table. */
2151 Elf_Data *xndxdata = NULL;
2152 int xndxscnidx = elf_scnshndx (scn);
2153 if (unlikely (xndxscnidx > 0))
2154 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2155
2156 /* Get the section header string table index. */
2157 size_t shstrndx;
2158 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2159 error (EXIT_FAILURE, 0,
2160 gettext ("cannot get section header string table index"));
2161
2162 if (shdr->sh_info != 0)
2163 printf (ngettext ("\
2164 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2165 "\
2166 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2167 nentries),
2168 elf_ndxscn (scn),
2169 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2170 (unsigned int) shdr->sh_info,
2171 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2172 shdr->sh_offset,
2173 nentries);
2174 else
2175 /* The .rela.dyn section does not refer to a specific section but
2176 instead of section index zero. Do not try to print a section
2177 name. */
2178 printf (ngettext ("\
2179 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2180 "\
2181 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2182 nentries),
2183 (unsigned int) elf_ndxscn (scn),
2184 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2185 shdr->sh_offset,
2186 nentries);
2187 fputs_unlocked (class == ELFCLASS32
2188 ? gettext ("\
2189 Offset Type Value Addend Name\n")
2190 : gettext ("\
2191 Offset Type Value Addend Name\n"),
2192 stdout);
2193
2194 int is_statically_linked = 0;
2195 for (int cnt = 0; cnt < nentries; ++cnt)
2196 {
2197 GElf_Rela relmem;
2198 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2199 if (likely (rel != NULL))
2200 {
2201 char buf[64];
2202 GElf_Sym symmem;
2203 Elf32_Word xndx;
2204 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2205 GELF_R_SYM (rel->r_info),
2206 &symmem, &xndx);
2207
2208 if (unlikely (sym == NULL))
2209 {
2210 /* As a special case we have to handle relocations in static
2211 executables. This only happens for IRELATIVE relocations
2212 (so far). There is no symbol table. */
2213 if (is_statically_linked == 0)
2214 {
2215 /* Find the program header and look for a PT_INTERP entry. */
2216 is_statically_linked = -1;
2217 if (ehdr->e_type == ET_EXEC)
2218 {
2219 is_statically_linked = 1;
2220
2221 for (size_t inner = 0; inner < phnum; ++inner)
2222 {
2223 GElf_Phdr phdr_mem;
2224 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2225 &phdr_mem);
2226 if (phdr != NULL && phdr->p_type == PT_INTERP)
2227 {
2228 is_statically_linked = -1;
2229 break;
2230 }
2231 }
2232 }
2233 }
2234
2235 if (is_statically_linked > 0 && shdr->sh_link == 0)
2236 printf ("\
2237 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
2238 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2239 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2240 /* Avoid the leading R_ which isn't carrying any
2241 information. */
2242 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2243 buf, sizeof (buf)) + 2
2244 : gettext ("<INVALID RELOC>"),
2245 class == ELFCLASS32 ? 10 : 18, "",
2246 rel->r_addend,
2247 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2248 else
2249 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2250 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2251 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2252 /* Avoid the leading R_ which isn't carrying any
2253 information. */
2254 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2255 buf, sizeof (buf)) + 2
2256 : gettext ("<INVALID RELOC>"),
2257 gettext ("INVALID SYMBOL"),
2258 (long int) GELF_R_SYM (rel->r_info));
2259 }
2260 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2261 printf ("\
2262 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2263 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2264 likely (ebl_reloc_type_check (ebl,
2265 GELF_R_TYPE (rel->r_info)))
2266 /* Avoid the leading R_ which isn't carrying any
2267 information. */
2268 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2269 buf, sizeof (buf)) + 2
2270 : gettext ("<INVALID RELOC>"),
2271 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2272 rel->r_addend,
2273 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2274 else
2275 {
2276 /* This is a relocation against a STT_SECTION symbol. */
2277 GElf_Shdr secshdr_mem;
2278 GElf_Shdr *secshdr;
2279 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2280 sym->st_shndx == SHN_XINDEX
2281 ? xndx : sym->st_shndx),
2282 &secshdr_mem);
2283
2284 if (unlikely (secshdr == NULL))
2285 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2286 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2287 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2288 /* Avoid the leading R_ which isn't carrying any
2289 information. */
2290 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2291 buf, sizeof (buf)) + 2
2292 : gettext ("<INVALID RELOC>"),
2293 gettext ("INVALID SECTION"),
2294 (long int) (sym->st_shndx == SHN_XINDEX
2295 ? xndx : sym->st_shndx));
2296 else
2297 printf ("\
2298 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2299 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2300 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2301 /* Avoid the leading R_ which isn't carrying any
2302 information. */
2303 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2304 buf, sizeof (buf)) + 2
2305 : gettext ("<INVALID RELOC>"),
2306 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2307 rel->r_addend,
2308 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2309 }
2310 }
2311 }
2312 }
2313
2314
2315 /* Print the program header. */
2316 static void
print_symtab(Ebl * ebl,int type)2317 print_symtab (Ebl *ebl, int type)
2318 {
2319 /* Find the symbol table(s). For this we have to search through the
2320 section table. */
2321 Elf_Scn *scn = NULL;
2322
2323 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2324 {
2325 /* Handle the section if it is a symbol table. */
2326 GElf_Shdr shdr_mem;
2327 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2328
2329 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2330 {
2331 if (symbol_table_section != NULL)
2332 {
2333 /* Get the section header string table index. */
2334 size_t shstrndx;
2335 const char *sname;
2336 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2337 error (EXIT_FAILURE, 0,
2338 gettext ("cannot get section header string table index"));
2339 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
2340 if (sname == NULL || strcmp (sname, symbol_table_section) != 0)
2341 continue;
2342 }
2343
2344 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
2345 {
2346 if (elf_compress (scn, 0, 0) < 0)
2347 printf ("WARNING: %s [%zd]\n",
2348 gettext ("Couldn't uncompress section"),
2349 elf_ndxscn (scn));
2350 shdr = gelf_getshdr (scn, &shdr_mem);
2351 if (unlikely (shdr == NULL))
2352 error (EXIT_FAILURE, 0,
2353 gettext ("cannot get section [%zd] header: %s"),
2354 elf_ndxscn (scn), elf_errmsg (-1));
2355 }
2356 handle_symtab (ebl, scn, shdr);
2357 }
2358 }
2359 }
2360
2361
2362 static void
handle_symtab(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2363 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2364 {
2365 Elf_Data *versym_data = NULL;
2366 Elf_Data *verneed_data = NULL;
2367 Elf_Data *verdef_data = NULL;
2368 Elf_Data *xndx_data = NULL;
2369 int class = gelf_getclass (ebl->elf);
2370 Elf32_Word verneed_stridx = 0;
2371 Elf32_Word verdef_stridx = 0;
2372
2373 /* Get the data of the section. */
2374 Elf_Data *data = elf_getdata (scn, NULL);
2375 if (data == NULL)
2376 return;
2377
2378 /* Find out whether we have other sections we might need. */
2379 Elf_Scn *runscn = NULL;
2380 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2381 {
2382 GElf_Shdr runshdr_mem;
2383 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2384
2385 if (likely (runshdr != NULL))
2386 {
2387 if (runshdr->sh_type == SHT_GNU_versym
2388 && runshdr->sh_link == elf_ndxscn (scn))
2389 /* Bingo, found the version information. Now get the data. */
2390 versym_data = elf_getdata (runscn, NULL);
2391 else if (runshdr->sh_type == SHT_GNU_verneed)
2392 {
2393 /* This is the information about the needed versions. */
2394 verneed_data = elf_getdata (runscn, NULL);
2395 verneed_stridx = runshdr->sh_link;
2396 }
2397 else if (runshdr->sh_type == SHT_GNU_verdef)
2398 {
2399 /* This is the information about the defined versions. */
2400 verdef_data = elf_getdata (runscn, NULL);
2401 verdef_stridx = runshdr->sh_link;
2402 }
2403 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2404 && runshdr->sh_link == elf_ndxscn (scn))
2405 /* Extended section index. */
2406 xndx_data = elf_getdata (runscn, NULL);
2407 }
2408 }
2409
2410 /* Get the section header string table index. */
2411 size_t shstrndx;
2412 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2413 error (EXIT_FAILURE, 0,
2414 gettext ("cannot get section header string table index"));
2415
2416 GElf_Shdr glink_mem;
2417 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2418 &glink_mem);
2419 if (glink == NULL)
2420 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2421 elf_ndxscn (scn));
2422
2423 /* Now we can compute the number of entries in the section. */
2424 unsigned int nsyms = data->d_size / (class == ELFCLASS32
2425 ? sizeof (Elf32_Sym)
2426 : sizeof (Elf64_Sym));
2427
2428 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2429 "\nSymbol table [%2u] '%s' contains %u entries:\n",
2430 nsyms),
2431 (unsigned int) elf_ndxscn (scn),
2432 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2433 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
2434 " %lu local symbols String table: [%2u] '%s'\n",
2435 shdr->sh_info),
2436 (unsigned long int) shdr->sh_info,
2437 (unsigned int) shdr->sh_link,
2438 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2439
2440 fputs_unlocked (class == ELFCLASS32
2441 ? gettext ("\
2442 Num: Value Size Type Bind Vis Ndx Name\n")
2443 : gettext ("\
2444 Num: Value Size Type Bind Vis Ndx Name\n"),
2445 stdout);
2446
2447 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2448 {
2449 char typebuf[64];
2450 char bindbuf[64];
2451 char scnbuf[64];
2452 Elf32_Word xndx;
2453 GElf_Sym sym_mem;
2454 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2455
2456 if (unlikely (sym == NULL))
2457 continue;
2458
2459 /* Determine the real section index. */
2460 if (likely (sym->st_shndx != SHN_XINDEX))
2461 xndx = sym->st_shndx;
2462
2463 printf (gettext ("\
2464 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2465 cnt,
2466 class == ELFCLASS32 ? 8 : 16,
2467 sym->st_value,
2468 sym->st_size,
2469 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2470 typebuf, sizeof (typebuf)),
2471 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2472 bindbuf, sizeof (bindbuf)),
2473 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2474 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2475 sizeof (scnbuf), NULL, shnum),
2476 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2477
2478 if (versym_data != NULL)
2479 {
2480 /* Get the version information. */
2481 GElf_Versym versym_mem;
2482 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2483
2484 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2485 {
2486 bool is_nobits = false;
2487 bool check_def = xndx != SHN_UNDEF;
2488
2489 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2490 {
2491 GElf_Shdr symshdr_mem;
2492 GElf_Shdr *symshdr =
2493 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2494
2495 is_nobits = (symshdr != NULL
2496 && symshdr->sh_type == SHT_NOBITS);
2497 }
2498
2499 if (is_nobits || ! check_def)
2500 {
2501 /* We must test both. */
2502 GElf_Vernaux vernaux_mem;
2503 GElf_Vernaux *vernaux = NULL;
2504 size_t vn_offset = 0;
2505
2506 GElf_Verneed verneed_mem;
2507 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2508 &verneed_mem);
2509 while (verneed != NULL)
2510 {
2511 size_t vna_offset = vn_offset;
2512
2513 vernaux = gelf_getvernaux (verneed_data,
2514 vna_offset += verneed->vn_aux,
2515 &vernaux_mem);
2516 while (vernaux != NULL
2517 && vernaux->vna_other != *versym
2518 && vernaux->vna_next != 0)
2519 {
2520 /* Update the offset. */
2521 vna_offset += vernaux->vna_next;
2522
2523 vernaux = (vernaux->vna_next == 0
2524 ? NULL
2525 : gelf_getvernaux (verneed_data,
2526 vna_offset,
2527 &vernaux_mem));
2528 }
2529
2530 /* Check whether we found the version. */
2531 if (vernaux != NULL && vernaux->vna_other == *versym)
2532 /* Found it. */
2533 break;
2534
2535 vn_offset += verneed->vn_next;
2536 verneed = (verneed->vn_next == 0
2537 ? NULL
2538 : gelf_getverneed (verneed_data, vn_offset,
2539 &verneed_mem));
2540 }
2541
2542 if (vernaux != NULL && vernaux->vna_other == *versym)
2543 {
2544 printf ("@%s (%u)",
2545 elf_strptr (ebl->elf, verneed_stridx,
2546 vernaux->vna_name),
2547 (unsigned int) vernaux->vna_other);
2548 check_def = 0;
2549 }
2550 else if (unlikely (! is_nobits))
2551 error (0, 0, gettext ("bad dynamic symbol"));
2552 else
2553 check_def = 1;
2554 }
2555
2556 if (check_def && *versym != 0x8001)
2557 {
2558 /* We must test both. */
2559 size_t vd_offset = 0;
2560
2561 GElf_Verdef verdef_mem;
2562 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2563 &verdef_mem);
2564 while (verdef != NULL)
2565 {
2566 if (verdef->vd_ndx == (*versym & 0x7fff))
2567 /* Found the definition. */
2568 break;
2569
2570 vd_offset += verdef->vd_next;
2571 verdef = (verdef->vd_next == 0
2572 ? NULL
2573 : gelf_getverdef (verdef_data, vd_offset,
2574 &verdef_mem));
2575 }
2576
2577 if (verdef != NULL)
2578 {
2579 GElf_Verdaux verdaux_mem;
2580 GElf_Verdaux *verdaux
2581 = gelf_getverdaux (verdef_data,
2582 vd_offset + verdef->vd_aux,
2583 &verdaux_mem);
2584
2585 if (verdaux != NULL)
2586 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2587 elf_strptr (ebl->elf, verdef_stridx,
2588 verdaux->vda_name));
2589 }
2590 }
2591 }
2592 }
2593
2594 putchar_unlocked ('\n');
2595 }
2596 }
2597
2598
2599 /* Print version information. */
2600 static void
print_verinfo(Ebl * ebl)2601 print_verinfo (Ebl *ebl)
2602 {
2603 /* Find the version information sections. For this we have to
2604 search through the section table. */
2605 Elf_Scn *scn = NULL;
2606
2607 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2608 {
2609 /* Handle the section if it is part of the versioning handling. */
2610 GElf_Shdr shdr_mem;
2611 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2612
2613 if (likely (shdr != NULL))
2614 {
2615 if (shdr->sh_type == SHT_GNU_verneed)
2616 handle_verneed (ebl, scn, shdr);
2617 else if (shdr->sh_type == SHT_GNU_verdef)
2618 handle_verdef (ebl, scn, shdr);
2619 else if (shdr->sh_type == SHT_GNU_versym)
2620 handle_versym (ebl, scn, shdr);
2621 }
2622 }
2623 }
2624
2625
2626 static const char *
get_ver_flags(unsigned int flags)2627 get_ver_flags (unsigned int flags)
2628 {
2629 static char buf[32];
2630 char *endp;
2631
2632 if (flags == 0)
2633 return gettext ("none");
2634
2635 if (flags & VER_FLG_BASE)
2636 endp = stpcpy (buf, "BASE ");
2637 else
2638 endp = buf;
2639
2640 if (flags & VER_FLG_WEAK)
2641 {
2642 if (endp != buf)
2643 endp = stpcpy (endp, "| ");
2644
2645 endp = stpcpy (endp, "WEAK ");
2646 }
2647
2648 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2649 {
2650 strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2651 buf[sizeof (buf) - 1] = '\0';
2652 }
2653
2654 return buf;
2655 }
2656
2657
2658 static void
handle_verneed(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2659 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2660 {
2661 int class = gelf_getclass (ebl->elf);
2662
2663 /* Get the data of the section. */
2664 Elf_Data *data = elf_getdata (scn, NULL);
2665 if (data == NULL)
2666 return;
2667
2668 /* Get the section header string table index. */
2669 size_t shstrndx;
2670 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2671 error (EXIT_FAILURE, 0,
2672 gettext ("cannot get section header string table index"));
2673
2674 GElf_Shdr glink_mem;
2675 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2676 &glink_mem);
2677 if (glink == NULL)
2678 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2679 elf_ndxscn (scn));
2680
2681 printf (ngettext ("\
2682 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2683 "\
2684 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2685 shdr->sh_info),
2686 (unsigned int) elf_ndxscn (scn),
2687 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2688 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2689 shdr->sh_offset,
2690 (unsigned int) shdr->sh_link,
2691 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2692
2693 unsigned int offset = 0;
2694 for (int cnt = shdr->sh_info; --cnt >= 0; )
2695 {
2696 /* Get the data at the next offset. */
2697 GElf_Verneed needmem;
2698 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2699 if (unlikely (need == NULL))
2700 break;
2701
2702 printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"),
2703 offset, (unsigned short int) need->vn_version,
2704 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2705 (unsigned short int) need->vn_cnt);
2706
2707 unsigned int auxoffset = offset + need->vn_aux;
2708 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2709 {
2710 GElf_Vernaux auxmem;
2711 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2712 if (unlikely (aux == NULL))
2713 break;
2714
2715 printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"),
2716 auxoffset,
2717 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2718 get_ver_flags (aux->vna_flags),
2719 (unsigned short int) aux->vna_other);
2720
2721 if (aux->vna_next == 0)
2722 break;
2723
2724 auxoffset += aux->vna_next;
2725 }
2726
2727 /* Find the next offset. */
2728 if (need->vn_next == 0)
2729 break;
2730
2731 offset += need->vn_next;
2732 }
2733 }
2734
2735
2736 static void
handle_verdef(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2737 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2738 {
2739 /* Get the data of the section. */
2740 Elf_Data *data = elf_getdata (scn, NULL);
2741 if (data == NULL)
2742 return;
2743
2744 /* Get the section header string table index. */
2745 size_t shstrndx;
2746 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2747 error (EXIT_FAILURE, 0,
2748 gettext ("cannot get section header string table index"));
2749
2750 GElf_Shdr glink_mem;
2751 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2752 &glink_mem);
2753 if (glink == NULL)
2754 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2755 elf_ndxscn (scn));
2756
2757 int class = gelf_getclass (ebl->elf);
2758 printf (ngettext ("\
2759 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2760 "\
2761 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2762 shdr->sh_info),
2763 (unsigned int) elf_ndxscn (scn),
2764 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2765 shdr->sh_info,
2766 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2767 shdr->sh_offset,
2768 (unsigned int) shdr->sh_link,
2769 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2770
2771 unsigned int offset = 0;
2772 for (int cnt = shdr->sh_info; --cnt >= 0; )
2773 {
2774 /* Get the data at the next offset. */
2775 GElf_Verdef defmem;
2776 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2777 if (unlikely (def == NULL))
2778 break;
2779
2780 unsigned int auxoffset = offset + def->vd_aux;
2781 GElf_Verdaux auxmem;
2782 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2783 if (unlikely (aux == NULL))
2784 break;
2785
2786 printf (gettext ("\
2787 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
2788 offset, def->vd_version,
2789 get_ver_flags (def->vd_flags),
2790 def->vd_ndx,
2791 def->vd_cnt,
2792 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2793
2794 auxoffset += aux->vda_next;
2795 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2796 {
2797 aux = gelf_getverdaux (data, auxoffset, &auxmem);
2798 if (unlikely (aux == NULL))
2799 break;
2800
2801 printf (gettext (" %#06x: Parent %d: %s\n"),
2802 auxoffset, cnt2,
2803 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2804
2805 if (aux->vda_next == 0)
2806 break;
2807
2808 auxoffset += aux->vda_next;
2809 }
2810
2811 /* Find the next offset. */
2812 if (def->vd_next == 0)
2813 break;
2814 offset += def->vd_next;
2815 }
2816 }
2817
2818
2819 static void
handle_versym(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2820 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2821 {
2822 int class = gelf_getclass (ebl->elf);
2823 const char **vername;
2824 const char **filename;
2825
2826 /* Get the data of the section. */
2827 Elf_Data *data = elf_getdata (scn, NULL);
2828 if (data == NULL)
2829 return;
2830
2831 /* Get the section header string table index. */
2832 size_t shstrndx;
2833 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2834 error (EXIT_FAILURE, 0,
2835 gettext ("cannot get section header string table index"));
2836
2837 /* We have to find the version definition section and extract the
2838 version names. */
2839 Elf_Scn *defscn = NULL;
2840 Elf_Scn *needscn = NULL;
2841
2842 Elf_Scn *verscn = NULL;
2843 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2844 {
2845 GElf_Shdr vershdr_mem;
2846 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2847
2848 if (likely (vershdr != NULL))
2849 {
2850 if (vershdr->sh_type == SHT_GNU_verdef)
2851 defscn = verscn;
2852 else if (vershdr->sh_type == SHT_GNU_verneed)
2853 needscn = verscn;
2854 }
2855 }
2856
2857 size_t nvername;
2858 if (defscn != NULL || needscn != NULL)
2859 {
2860 /* We have a version information (better should have). Now get
2861 the version names. First find the maximum version number. */
2862 nvername = 0;
2863 if (defscn != NULL)
2864 {
2865 /* Run through the version definitions and find the highest
2866 index. */
2867 unsigned int offset = 0;
2868 Elf_Data *defdata;
2869 GElf_Shdr defshdrmem;
2870 GElf_Shdr *defshdr;
2871
2872 defdata = elf_getdata (defscn, NULL);
2873 if (unlikely (defdata == NULL))
2874 return;
2875
2876 defshdr = gelf_getshdr (defscn, &defshdrmem);
2877 if (unlikely (defshdr == NULL))
2878 return;
2879
2880 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2881 {
2882 GElf_Verdef defmem;
2883 GElf_Verdef *def;
2884
2885 /* Get the data at the next offset. */
2886 def = gelf_getverdef (defdata, offset, &defmem);
2887 if (unlikely (def == NULL))
2888 break;
2889
2890 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2891
2892 if (def->vd_next == 0)
2893 break;
2894 offset += def->vd_next;
2895 }
2896 }
2897 if (needscn != NULL)
2898 {
2899 unsigned int offset = 0;
2900 Elf_Data *needdata;
2901 GElf_Shdr needshdrmem;
2902 GElf_Shdr *needshdr;
2903
2904 needdata = elf_getdata (needscn, NULL);
2905 if (unlikely (needdata == NULL))
2906 return;
2907
2908 needshdr = gelf_getshdr (needscn, &needshdrmem);
2909 if (unlikely (needshdr == NULL))
2910 return;
2911
2912 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2913 {
2914 GElf_Verneed needmem;
2915 GElf_Verneed *need;
2916 unsigned int auxoffset;
2917 int cnt2;
2918
2919 /* Get the data at the next offset. */
2920 need = gelf_getverneed (needdata, offset, &needmem);
2921 if (unlikely (need == NULL))
2922 break;
2923
2924 /* Run through the auxiliary entries. */
2925 auxoffset = offset + need->vn_aux;
2926 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2927 {
2928 GElf_Vernaux auxmem;
2929 GElf_Vernaux *aux;
2930
2931 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2932 if (unlikely (aux == NULL))
2933 break;
2934
2935 nvername = MAX (nvername,
2936 (size_t) (aux->vna_other & 0x7fff));
2937
2938 if (aux->vna_next == 0)
2939 break;
2940 auxoffset += aux->vna_next;
2941 }
2942
2943 if (need->vn_next == 0)
2944 break;
2945 offset += need->vn_next;
2946 }
2947 }
2948
2949 /* This is the number of versions we know about. */
2950 ++nvername;
2951
2952 /* Allocate the array. */
2953 vername = (const char **) alloca (nvername * sizeof (const char *));
2954 memset(vername, 0, nvername * sizeof (const char *));
2955 filename = (const char **) alloca (nvername * sizeof (const char *));
2956 memset(filename, 0, nvername * sizeof (const char *));
2957
2958 /* Run through the data structures again and collect the strings. */
2959 if (defscn != NULL)
2960 {
2961 /* Run through the version definitions and find the highest
2962 index. */
2963 unsigned int offset = 0;
2964 Elf_Data *defdata;
2965 GElf_Shdr defshdrmem;
2966 GElf_Shdr *defshdr;
2967
2968 defdata = elf_getdata (defscn, NULL);
2969 if (unlikely (defdata == NULL))
2970 return;
2971
2972 defshdr = gelf_getshdr (defscn, &defshdrmem);
2973 if (unlikely (defshdr == NULL))
2974 return;
2975
2976 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2977 {
2978
2979 /* Get the data at the next offset. */
2980 GElf_Verdef defmem;
2981 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
2982 if (unlikely (def == NULL))
2983 break;
2984
2985 GElf_Verdaux auxmem;
2986 GElf_Verdaux *aux = gelf_getverdaux (defdata,
2987 offset + def->vd_aux,
2988 &auxmem);
2989 if (unlikely (aux == NULL))
2990 break;
2991
2992 vername[def->vd_ndx & 0x7fff]
2993 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
2994 filename[def->vd_ndx & 0x7fff] = NULL;
2995
2996 if (def->vd_next == 0)
2997 break;
2998 offset += def->vd_next;
2999 }
3000 }
3001 if (needscn != NULL)
3002 {
3003 unsigned int offset = 0;
3004
3005 Elf_Data *needdata = elf_getdata (needscn, NULL);
3006 GElf_Shdr needshdrmem;
3007 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
3008 if (unlikely (needdata == NULL || needshdr == NULL))
3009 return;
3010
3011 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
3012 {
3013 /* Get the data at the next offset. */
3014 GElf_Verneed needmem;
3015 GElf_Verneed *need = gelf_getverneed (needdata, offset,
3016 &needmem);
3017 if (unlikely (need == NULL))
3018 break;
3019
3020 /* Run through the auxiliary entries. */
3021 unsigned int auxoffset = offset + need->vn_aux;
3022 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
3023 {
3024 GElf_Vernaux auxmem;
3025 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
3026 &auxmem);
3027 if (unlikely (aux == NULL))
3028 break;
3029
3030 vername[aux->vna_other & 0x7fff]
3031 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
3032 filename[aux->vna_other & 0x7fff]
3033 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
3034
3035 if (aux->vna_next == 0)
3036 break;
3037 auxoffset += aux->vna_next;
3038 }
3039
3040 if (need->vn_next == 0)
3041 break;
3042 offset += need->vn_next;
3043 }
3044 }
3045 }
3046 else
3047 {
3048 vername = NULL;
3049 nvername = 1;
3050 filename = NULL;
3051 }
3052
3053 GElf_Shdr glink_mem;
3054 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
3055 &glink_mem);
3056 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
3057 if (glink == NULL)
3058 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
3059 elf_ndxscn (scn));
3060
3061 /* Print the header. */
3062 printf (ngettext ("\
3063 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
3064 "\
3065 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
3066 shdr->sh_size / sh_entsize),
3067 (unsigned int) elf_ndxscn (scn),
3068 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3069 (int) (shdr->sh_size / sh_entsize),
3070 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
3071 shdr->sh_offset,
3072 (unsigned int) shdr->sh_link,
3073 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3074
3075 /* Now we can finally look at the actual contents of this section. */
3076 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
3077 {
3078 if (cnt % 2 == 0)
3079 printf ("\n %4d:", cnt);
3080
3081 GElf_Versym symmem;
3082 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
3083 if (sym == NULL)
3084 break;
3085
3086 switch (*sym)
3087 {
3088 ssize_t n;
3089 case 0:
3090 fputs_unlocked (gettext (" 0 *local* "),
3091 stdout);
3092 break;
3093
3094 case 1:
3095 fputs_unlocked (gettext (" 1 *global* "),
3096 stdout);
3097 break;
3098
3099 default:
3100 n = printf ("%4d%c%s",
3101 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
3102 (vername != NULL
3103 && (unsigned int) (*sym & 0x7fff) < nvername)
3104 ? vername[*sym & 0x7fff] : "???");
3105 if ((unsigned int) (*sym & 0x7fff) < nvername
3106 && filename != NULL && filename[*sym & 0x7fff] != NULL)
3107 n += printf ("(%s)", filename[*sym & 0x7fff]);
3108 printf ("%*s", MAX (0, 33 - (int) n), " ");
3109 break;
3110 }
3111 }
3112 putchar_unlocked ('\n');
3113 }
3114
3115
3116 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)3117 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
3118 uint_fast32_t maxlength, Elf32_Word nbucket,
3119 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
3120 {
3121 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
3122
3123 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3124 ++counts[lengths[cnt]];
3125
3126 GElf_Shdr glink_mem;
3127 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
3128 shdr->sh_link),
3129 &glink_mem);
3130 if (glink == NULL)
3131 {
3132 error (0, 0, gettext ("invalid sh_link value in section %zu"),
3133 elf_ndxscn (scn));
3134 return;
3135 }
3136
3137 printf (ngettext ("\
3138 \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",
3139 "\
3140 \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",
3141 nbucket),
3142 (unsigned int) elf_ndxscn (scn),
3143 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3144 (int) nbucket,
3145 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
3146 shdr->sh_addr,
3147 shdr->sh_offset,
3148 (unsigned int) shdr->sh_link,
3149 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3150
3151 if (extrastr != NULL)
3152 fputs (extrastr, stdout);
3153
3154 if (likely (nbucket > 0))
3155 {
3156 uint64_t success = 0;
3157
3158 /* xgettext:no-c-format */
3159 fputs_unlocked (gettext ("\
3160 Length Number % of total Coverage\n"), stdout);
3161 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
3162 counts[0], (counts[0] * 100.0) / nbucket);
3163
3164 uint64_t nzero_counts = 0;
3165 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3166 {
3167 nzero_counts += counts[cnt] * cnt;
3168 printf (gettext ("\
3169 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
3170 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
3171 (nzero_counts * 100.0) / nsyms);
3172 }
3173
3174 Elf32_Word acc = 0;
3175 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3176 {
3177 acc += cnt;
3178 success += counts[cnt] * acc;
3179 }
3180
3181 printf (gettext ("\
3182 Average number of tests: successful lookup: %f\n\
3183 unsuccessful lookup: %f\n"),
3184 (double) success / (double) nzero_counts,
3185 (double) nzero_counts / (double) nbucket);
3186 }
3187
3188 free (counts);
3189 }
3190
3191
3192 /* This function handles the traditional System V-style hash table format. */
3193 static void
handle_sysv_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3194 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3195 {
3196 Elf_Data *data = elf_getdata (scn, NULL);
3197 if (unlikely (data == NULL))
3198 {
3199 error (0, 0, gettext ("cannot get data for section %d: %s"),
3200 (int) elf_ndxscn (scn), elf_errmsg (-1));
3201 return;
3202 }
3203
3204 if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
3205 {
3206 invalid_data:
3207 error (0, 0, gettext ("invalid data in sysv.hash section %d"),
3208 (int) elf_ndxscn (scn));
3209 return;
3210 }
3211
3212 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3213 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
3214
3215 uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
3216 if (used_buf > data->d_size)
3217 goto invalid_data;
3218
3219 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
3220 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
3221
3222 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3223
3224 uint_fast32_t maxlength = 0;
3225 uint_fast32_t nsyms = 0;
3226 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3227 {
3228 Elf32_Word inner = bucket[cnt];
3229 Elf32_Word chain_len = 0;
3230 while (inner > 0 && inner < nchain)
3231 {
3232 ++nsyms;
3233 ++chain_len;
3234 if (chain_len > nchain)
3235 {
3236 error (0, 0, gettext ("invalid chain in sysv.hash section %d"),
3237 (int) elf_ndxscn (scn));
3238 free (lengths);
3239 return;
3240 }
3241 if (maxlength < ++lengths[cnt])
3242 ++maxlength;
3243
3244 inner = chain[inner];
3245 }
3246 }
3247
3248 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3249 lengths, NULL);
3250
3251 free (lengths);
3252 }
3253
3254
3255 /* This function handles the incorrect, System V-style hash table
3256 format some 64-bit architectures use. */
3257 static void
handle_sysv_hash64(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3258 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3259 {
3260 Elf_Data *data = elf_getdata (scn, NULL);
3261 if (unlikely (data == NULL))
3262 {
3263 error (0, 0, gettext ("cannot get data for section %d: %s"),
3264 (int) elf_ndxscn (scn), elf_errmsg (-1));
3265 return;
3266 }
3267
3268 if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3269 {
3270 invalid_data:
3271 error (0, 0, gettext ("invalid data in sysv.hash64 section %d"),
3272 (int) elf_ndxscn (scn));
3273 return;
3274 }
3275
3276 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3277 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3278
3279 uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
3280 if (maxwords < 2
3281 || maxwords - 2 < nbucket
3282 || maxwords - 2 - nbucket < nchain)
3283 goto invalid_data;
3284
3285 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3286 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3287
3288 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3289
3290 uint_fast32_t maxlength = 0;
3291 uint_fast32_t nsyms = 0;
3292 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3293 {
3294 Elf64_Xword inner = bucket[cnt];
3295 Elf64_Xword chain_len = 0;
3296 while (inner > 0 && inner < nchain)
3297 {
3298 ++nsyms;
3299 ++chain_len;
3300 if (chain_len > nchain)
3301 {
3302 error (0, 0, gettext ("invalid chain in sysv.hash64 section %d"),
3303 (int) elf_ndxscn (scn));
3304 free (lengths);
3305 return;
3306 }
3307 if (maxlength < ++lengths[cnt])
3308 ++maxlength;
3309
3310 inner = chain[inner];
3311 }
3312 }
3313
3314 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3315 lengths, NULL);
3316
3317 free (lengths);
3318 }
3319
3320
3321 /* This function handles the GNU-style hash table format. */
3322 static void
handle_gnu_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3323 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3324 {
3325 uint32_t *lengths = NULL;
3326 Elf_Data *data = elf_getdata (scn, NULL);
3327 if (unlikely (data == NULL))
3328 {
3329 error (0, 0, gettext ("cannot get data for section %d: %s"),
3330 (int) elf_ndxscn (scn), elf_errmsg (-1));
3331 return;
3332 }
3333
3334 if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3335 {
3336 invalid_data:
3337 free (lengths);
3338 error (0, 0, gettext ("invalid data in gnu.hash section %d"),
3339 (int) elf_ndxscn (scn));
3340 return;
3341 }
3342
3343 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3344 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3345
3346 /* Next comes the size of the bitmap. It's measured in words for
3347 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3348 64 bit archs. There is always a bloom filter present, so zero is
3349 an invalid value. */
3350 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3351 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3352 bitmask_words *= 2;
3353
3354 if (bitmask_words == 0)
3355 goto invalid_data;
3356
3357 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3358
3359 /* Is there still room for the sym chain?
3360 Use uint64_t calculation to prevent 32bit overlow. */
3361 uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3362 uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3363 if (used_buf > data->d_size)
3364 goto invalid_data;
3365
3366 lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3367
3368 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3369 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3370 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3371 + nbucket];
3372
3373 /* Compute distribution of chain lengths. */
3374 uint_fast32_t maxlength = 0;
3375 uint_fast32_t nsyms = 0;
3376 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3377 if (bucket[cnt] != 0)
3378 {
3379 Elf32_Word inner = bucket[cnt] - symbias;
3380 do
3381 {
3382 ++nsyms;
3383 if (maxlength < ++lengths[cnt])
3384 ++maxlength;
3385 if (inner >= max_nsyms)
3386 goto invalid_data;
3387 }
3388 while ((chain[inner++] & 1) == 0);
3389 }
3390
3391 /* Count bits in bitmask. */
3392 uint_fast32_t nbits = 0;
3393 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3394 {
3395 uint_fast32_t word = bitmask[cnt];
3396
3397 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3398 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3399 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3400 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3401 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3402 }
3403
3404 char *str;
3405 if (unlikely (asprintf (&str, gettext ("\
3406 Symbol Bias: %u\n\
3407 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3408 (unsigned int) symbias,
3409 bitmask_words * sizeof (Elf32_Word),
3410 ((nbits * 100 + 50)
3411 / (uint_fast32_t) (bitmask_words
3412 * sizeof (Elf32_Word) * 8)),
3413 (unsigned int) shift) == -1))
3414 error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3415
3416 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3417 lengths, str);
3418
3419 free (str);
3420 free (lengths);
3421 }
3422
3423
3424 /* Find the symbol table(s). For this we have to search through the
3425 section table. */
3426 static void
handle_hash(Ebl * ebl)3427 handle_hash (Ebl *ebl)
3428 {
3429 /* Get the section header string table index. */
3430 size_t shstrndx;
3431 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3432 error (EXIT_FAILURE, 0,
3433 gettext ("cannot get section header string table index"));
3434
3435 Elf_Scn *scn = NULL;
3436 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3437 {
3438 /* Handle the section if it is a symbol table. */
3439 GElf_Shdr shdr_mem;
3440 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3441
3442 if (likely (shdr != NULL))
3443 {
3444 if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH)
3445 && (shdr->sh_flags & SHF_COMPRESSED) != 0)
3446 {
3447 if (elf_compress (scn, 0, 0) < 0)
3448 printf ("WARNING: %s [%zd]\n",
3449 gettext ("Couldn't uncompress section"),
3450 elf_ndxscn (scn));
3451 shdr = gelf_getshdr (scn, &shdr_mem);
3452 if (unlikely (shdr == NULL))
3453 error (EXIT_FAILURE, 0,
3454 gettext ("cannot get section [%zd] header: %s"),
3455 elf_ndxscn (scn), elf_errmsg (-1));
3456 }
3457
3458 if (shdr->sh_type == SHT_HASH)
3459 {
3460 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3461 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3462 else
3463 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3464 }
3465 else if (shdr->sh_type == SHT_GNU_HASH)
3466 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3467 }
3468 }
3469 }
3470
3471
3472 static void
print_liblist(Ebl * ebl)3473 print_liblist (Ebl *ebl)
3474 {
3475 /* Find the library list sections. For this we have to search
3476 through the section table. */
3477 Elf_Scn *scn = NULL;
3478
3479 /* Get the section header string table index. */
3480 size_t shstrndx;
3481 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3482 error (EXIT_FAILURE, 0,
3483 gettext ("cannot get section header string table index"));
3484
3485 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3486 {
3487 GElf_Shdr shdr_mem;
3488 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3489
3490 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3491 {
3492 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3493 int nentries = shdr->sh_size / sh_entsize;
3494 printf (ngettext ("\
3495 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3496 "\
3497 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3498 nentries),
3499 elf_ndxscn (scn),
3500 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3501 shdr->sh_offset,
3502 nentries);
3503
3504 Elf_Data *data = elf_getdata (scn, NULL);
3505 if (data == NULL)
3506 return;
3507
3508 puts (gettext ("\
3509 Library Time Stamp Checksum Version Flags"));
3510
3511 for (int cnt = 0; cnt < nentries; ++cnt)
3512 {
3513 GElf_Lib lib_mem;
3514 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3515 if (unlikely (lib == NULL))
3516 continue;
3517
3518 time_t t = (time_t) lib->l_time_stamp;
3519 struct tm *tm = gmtime (&t);
3520 if (unlikely (tm == NULL))
3521 continue;
3522
3523 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3524 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3525 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3526 tm->tm_hour, tm->tm_min, tm->tm_sec,
3527 (unsigned int) lib->l_checksum,
3528 (unsigned int) lib->l_version,
3529 (unsigned int) lib->l_flags);
3530 }
3531 }
3532 }
3533 }
3534
3535 static void
print_attributes(Ebl * ebl,const GElf_Ehdr * ehdr)3536 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3537 {
3538 /* Find the object attributes sections. For this we have to search
3539 through the section table. */
3540 Elf_Scn *scn = NULL;
3541
3542 /* Get the section header string table index. */
3543 size_t shstrndx;
3544 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3545 error (EXIT_FAILURE, 0,
3546 gettext ("cannot get section header string table index"));
3547
3548 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3549 {
3550 GElf_Shdr shdr_mem;
3551 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3552
3553 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3554 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3555 || ehdr->e_machine != EM_ARM)))
3556 continue;
3557
3558 printf (gettext ("\
3559 \nObject attributes section [%2zu] '%s' of %" PRIu64
3560 " bytes at offset %#0" PRIx64 ":\n"),
3561 elf_ndxscn (scn),
3562 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3563 shdr->sh_size, shdr->sh_offset);
3564
3565 Elf_Data *data = elf_rawdata (scn, NULL);
3566 if (unlikely (data == NULL || data->d_size == 0))
3567 return;
3568
3569 const unsigned char *p = data->d_buf;
3570
3571 /* There is only one 'version', A. */
3572 if (unlikely (*p++ != 'A'))
3573 return;
3574
3575 fputs_unlocked (gettext (" Owner Size\n"), stdout);
3576
3577 inline size_t left (void)
3578 {
3579 return (const unsigned char *) data->d_buf + data->d_size - p;
3580 }
3581
3582 /* Loop over the sections. */
3583 while (left () >= 4)
3584 {
3585 /* Section length. */
3586 uint32_t len;
3587 memcpy (&len, p, sizeof len);
3588
3589 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3590 CONVERT (len);
3591
3592 if (unlikely (len > left ()))
3593 break;
3594
3595 /* Section vendor name. */
3596 const unsigned char *name = p + sizeof len;
3597 p += len;
3598
3599 unsigned const char *q = memchr (name, '\0', len);
3600 if (unlikely (q == NULL))
3601 break;
3602 ++q;
3603
3604 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
3605
3606 bool gnu_vendor = (q - name == sizeof "gnu"
3607 && !memcmp (name, "gnu", sizeof "gnu"));
3608
3609 /* Loop over subsections. */
3610 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3611 || gnu_vendor)
3612 while (q < p)
3613 {
3614 const unsigned char *const sub = q;
3615
3616 unsigned int subsection_tag;
3617 get_uleb128 (subsection_tag, q, p);
3618 if (unlikely (q >= p))
3619 break;
3620
3621 uint32_t subsection_len;
3622 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3623 break;
3624
3625 memcpy (&subsection_len, q, sizeof subsection_len);
3626
3627 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3628 CONVERT (subsection_len);
3629
3630 /* Don't overflow, ptrdiff_t might be 32bits, but signed. */
3631 if (unlikely (subsection_len == 0
3632 || subsection_len >= (uint32_t) PTRDIFF_MAX
3633 || p - sub < (ptrdiff_t) subsection_len))
3634 break;
3635
3636 const unsigned char *r = q + sizeof subsection_len;
3637 q = sub + subsection_len;
3638
3639 switch (subsection_tag)
3640 {
3641 default:
3642 /* Unknown subsection, print and skip. */
3643 printf (gettext (" %-4u %12" PRIu32 "\n"),
3644 subsection_tag, subsection_len);
3645 break;
3646
3647 case 1: /* Tag_File */
3648 printf (gettext (" File: %11" PRIu32 "\n"),
3649 subsection_len);
3650
3651 while (r < q)
3652 {
3653 unsigned int tag;
3654 get_uleb128 (tag, r, q);
3655 if (unlikely (r >= q))
3656 break;
3657
3658 /* GNU style tags have either a uleb128 value,
3659 when lowest bit is not set, or a string
3660 when the lowest bit is set.
3661 "compatibility" (32) is special. It has
3662 both a string and a uleb128 value. For
3663 non-gnu we assume 6 till 31 only take ints.
3664 XXX see arm backend, do we need a separate
3665 hook? */
3666 uint64_t value = 0;
3667 const char *string = NULL;
3668 if (tag == 32 || (tag & 1) == 0
3669 || (! gnu_vendor && (tag > 5 && tag < 32)))
3670 {
3671 get_uleb128 (value, r, q);
3672 if (r > q)
3673 break;
3674 }
3675 if (tag == 32
3676 || ((tag & 1) != 0
3677 && (gnu_vendor
3678 || (! gnu_vendor && tag > 32)))
3679 || (! gnu_vendor && tag > 3 && tag < 6))
3680 {
3681 string = (const char *) r;
3682 r = memchr (r, '\0', q - r);
3683 if (r == NULL)
3684 break;
3685 ++r;
3686 }
3687
3688 const char *tag_name = NULL;
3689 const char *value_name = NULL;
3690 ebl_check_object_attribute (ebl, (const char *) name,
3691 tag, value,
3692 &tag_name, &value_name);
3693
3694 if (tag_name != NULL)
3695 {
3696 if (tag == 32)
3697 printf (gettext (" %s: %" PRId64 ", %s\n"),
3698 tag_name, value, string);
3699 else if (string == NULL && value_name == NULL)
3700 printf (gettext (" %s: %" PRId64 "\n"),
3701 tag_name, value);
3702 else
3703 printf (gettext (" %s: %s\n"),
3704 tag_name, string ?: value_name);
3705 }
3706 else
3707 {
3708 /* For "gnu" vendor 32 "compatibility" has
3709 already been handled above. */
3710 assert (tag != 32
3711 || strcmp ((const char *) name, "gnu"));
3712 if (string == NULL)
3713 printf (gettext (" %u: %" PRId64 "\n"),
3714 tag, value);
3715 else
3716 printf (gettext (" %u: %s\n"),
3717 tag, string);
3718 }
3719 }
3720 }
3721 }
3722 }
3723 }
3724 }
3725
3726
3727 void
print_dwarf_addr(Dwfl_Module * dwflmod,int address_size,Dwarf_Addr address,Dwarf_Addr raw)3728 print_dwarf_addr (Dwfl_Module *dwflmod,
3729 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3730 {
3731 /* See if there is a name we can give for this address. */
3732 GElf_Sym sym;
3733 GElf_Off off = 0;
3734 const char *name = (print_address_names && ! print_unresolved_addresses)
3735 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3736 : NULL;
3737
3738 const char *scn;
3739 if (print_unresolved_addresses)
3740 {
3741 address = raw;
3742 scn = NULL;
3743 }
3744 else
3745 {
3746 /* Relativize the address. */
3747 int n = dwfl_module_relocations (dwflmod);
3748 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3749
3750 /* In an ET_REL file there is a section name to refer to. */
3751 scn = (i < 0 ? NULL
3752 : dwfl_module_relocation_info (dwflmod, i, NULL));
3753 }
3754
3755 if ((name != NULL
3756 ? (off != 0
3757 ? (scn != NULL
3758 ? (address_size == 0
3759 ? printf ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">",
3760 scn, address, name, off)
3761 : printf ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">",
3762 scn, 2 + address_size * 2, address,
3763 name, off))
3764 : (address_size == 0
3765 ? printf ("%#" PRIx64 " <%s+%#" PRIx64 ">",
3766 address, name, off)
3767 : printf ("%#0*" PRIx64 " <%s+%#" PRIx64 ">",
3768 2 + address_size * 2, address,
3769 name, off)))
3770 : (scn != NULL
3771 ? (address_size == 0
3772 ? printf ("%s+%#" PRIx64 " <%s>", scn, address, name)
3773 : printf ("%s+%#0*" PRIx64 " <%s>",
3774 scn, 2 + address_size * 2, address, name))
3775 : (address_size == 0
3776 ? printf ("%#" PRIx64 " <%s>", address, name)
3777 : printf ("%#0*" PRIx64 " <%s>",
3778 2 + address_size * 2, address, name))))
3779 : (scn != NULL
3780 ? (address_size == 0
3781 ? printf ("%s+%#" PRIx64, scn, address)
3782 : printf ("%s+%#0*" PRIx64, scn, 2 + address_size * 2, address))
3783 : (address_size == 0
3784 ? printf ("%#" PRIx64, address)
3785 : printf ("%#0*" PRIx64, 2 + address_size * 2, address)))) < 0)
3786 error (EXIT_FAILURE, 0, _("sprintf failure"));
3787 }
3788
3789
3790 static const char *
dwarf_tag_string(unsigned int tag)3791 dwarf_tag_string (unsigned int tag)
3792 {
3793 switch (tag)
3794 {
3795 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3796 DWARF_ALL_KNOWN_DW_TAG
3797 #undef DWARF_ONE_KNOWN_DW_TAG
3798 default:
3799 return NULL;
3800 }
3801 }
3802
3803
3804 static const char *
dwarf_attr_string(unsigned int attrnum)3805 dwarf_attr_string (unsigned int attrnum)
3806 {
3807 switch (attrnum)
3808 {
3809 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3810 DWARF_ALL_KNOWN_DW_AT
3811 #undef DWARF_ONE_KNOWN_DW_AT
3812 default:
3813 return NULL;
3814 }
3815 }
3816
3817
3818 static const char *
dwarf_form_string(unsigned int form)3819 dwarf_form_string (unsigned int form)
3820 {
3821 switch (form)
3822 {
3823 #define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3824 DWARF_ALL_KNOWN_DW_FORM
3825 #undef DWARF_ONE_KNOWN_DW_FORM
3826 default:
3827 return NULL;
3828 }
3829 }
3830
3831
3832 static const char *
dwarf_lang_string(unsigned int lang)3833 dwarf_lang_string (unsigned int lang)
3834 {
3835 switch (lang)
3836 {
3837 #define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
3838 DWARF_ALL_KNOWN_DW_LANG
3839 #undef DWARF_ONE_KNOWN_DW_LANG
3840 default:
3841 return NULL;
3842 }
3843 }
3844
3845
3846 static const char *
dwarf_inline_string(unsigned int code)3847 dwarf_inline_string (unsigned int code)
3848 {
3849 static const char *const known[] =
3850 {
3851 #define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3852 DWARF_ALL_KNOWN_DW_INL
3853 #undef DWARF_ONE_KNOWN_DW_INL
3854 };
3855
3856 if (likely (code < sizeof (known) / sizeof (known[0])))
3857 return known[code];
3858
3859 return NULL;
3860 }
3861
3862
3863 static const char *
dwarf_encoding_string(unsigned int code)3864 dwarf_encoding_string (unsigned int code)
3865 {
3866 static const char *const known[] =
3867 {
3868 #define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3869 DWARF_ALL_KNOWN_DW_ATE
3870 #undef DWARF_ONE_KNOWN_DW_ATE
3871 };
3872
3873 if (likely (code < sizeof (known) / sizeof (known[0])))
3874 return known[code];
3875
3876 return NULL;
3877 }
3878
3879
3880 static const char *
dwarf_access_string(unsigned int code)3881 dwarf_access_string (unsigned int code)
3882 {
3883 static const char *const known[] =
3884 {
3885 #define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3886 DWARF_ALL_KNOWN_DW_ACCESS
3887 #undef DWARF_ONE_KNOWN_DW_ACCESS
3888 };
3889
3890 if (likely (code < sizeof (known) / sizeof (known[0])))
3891 return known[code];
3892
3893 return NULL;
3894 }
3895
3896
3897 static const char *
dwarf_defaulted_string(unsigned int code)3898 dwarf_defaulted_string (unsigned int code)
3899 {
3900 static const char *const known[] =
3901 {
3902 #define DWARF_ONE_KNOWN_DW_DEFAULTED(NAME, CODE) [CODE] = #NAME,
3903 DWARF_ALL_KNOWN_DW_DEFAULTED
3904 #undef DWARF_ONE_KNOWN_DW_DEFAULTED
3905 };
3906
3907 if (likely (code < sizeof (known) / sizeof (known[0])))
3908 return known[code];
3909
3910 return NULL;
3911 }
3912
3913
3914 static const char *
dwarf_visibility_string(unsigned int code)3915 dwarf_visibility_string (unsigned int code)
3916 {
3917 static const char *const known[] =
3918 {
3919 #define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3920 DWARF_ALL_KNOWN_DW_VIS
3921 #undef DWARF_ONE_KNOWN_DW_VIS
3922 };
3923
3924 if (likely (code < sizeof (known) / sizeof (known[0])))
3925 return known[code];
3926
3927 return NULL;
3928 }
3929
3930
3931 static const char *
dwarf_virtuality_string(unsigned int code)3932 dwarf_virtuality_string (unsigned int code)
3933 {
3934 static const char *const known[] =
3935 {
3936 #define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3937 DWARF_ALL_KNOWN_DW_VIRTUALITY
3938 #undef DWARF_ONE_KNOWN_DW_VIRTUALITY
3939 };
3940
3941 if (likely (code < sizeof (known) / sizeof (known[0])))
3942 return known[code];
3943
3944 return NULL;
3945 }
3946
3947
3948 static const char *
dwarf_identifier_case_string(unsigned int code)3949 dwarf_identifier_case_string (unsigned int code)
3950 {
3951 static const char *const known[] =
3952 {
3953 #define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3954 DWARF_ALL_KNOWN_DW_ID
3955 #undef DWARF_ONE_KNOWN_DW_ID
3956 };
3957
3958 if (likely (code < sizeof (known) / sizeof (known[0])))
3959 return known[code];
3960
3961 return NULL;
3962 }
3963
3964
3965 static const char *
dwarf_calling_convention_string(unsigned int code)3966 dwarf_calling_convention_string (unsigned int code)
3967 {
3968 static const char *const known[] =
3969 {
3970 #define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
3971 DWARF_ALL_KNOWN_DW_CC
3972 #undef DWARF_ONE_KNOWN_DW_CC
3973 };
3974
3975 if (likely (code < sizeof (known) / sizeof (known[0])))
3976 return known[code];
3977
3978 return NULL;
3979 }
3980
3981
3982 static const char *
dwarf_ordering_string(unsigned int code)3983 dwarf_ordering_string (unsigned int code)
3984 {
3985 static const char *const known[] =
3986 {
3987 #define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
3988 DWARF_ALL_KNOWN_DW_ORD
3989 #undef DWARF_ONE_KNOWN_DW_ORD
3990 };
3991
3992 if (likely (code < sizeof (known) / sizeof (known[0])))
3993 return known[code];
3994
3995 return NULL;
3996 }
3997
3998
3999 static const char *
dwarf_discr_list_string(unsigned int code)4000 dwarf_discr_list_string (unsigned int code)
4001 {
4002 static const char *const known[] =
4003 {
4004 #define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
4005 DWARF_ALL_KNOWN_DW_DSC
4006 #undef DWARF_ONE_KNOWN_DW_DSC
4007 };
4008
4009 if (likely (code < sizeof (known) / sizeof (known[0])))
4010 return known[code];
4011
4012 return NULL;
4013 }
4014
4015
4016 static const char *
dwarf_locexpr_opcode_string(unsigned int code)4017 dwarf_locexpr_opcode_string (unsigned int code)
4018 {
4019 static const char *const known[] =
4020 {
4021 /* Normally we can't affort building huge table of 64K entries,
4022 most of them zero, just because there are a couple defined
4023 values at the far end. In case of opcodes, it's OK. */
4024 #define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
4025 DWARF_ALL_KNOWN_DW_OP
4026 #undef DWARF_ONE_KNOWN_DW_OP
4027 };
4028
4029 if (likely (code < sizeof (known) / sizeof (known[0])))
4030 return known[code];
4031
4032 return NULL;
4033 }
4034
4035
4036 static const char *
dwarf_unit_string(unsigned int type)4037 dwarf_unit_string (unsigned int type)
4038 {
4039 switch (type)
4040 {
4041 #define DWARF_ONE_KNOWN_DW_UT(NAME, CODE) case CODE: return #NAME;
4042 DWARF_ALL_KNOWN_DW_UT
4043 #undef DWARF_ONE_KNOWN_DW_UT
4044 default:
4045 return NULL;
4046 }
4047 }
4048
4049
4050 static const char *
dwarf_range_list_encoding_string(unsigned int kind)4051 dwarf_range_list_encoding_string (unsigned int kind)
4052 {
4053 switch (kind)
4054 {
4055 #define DWARF_ONE_KNOWN_DW_RLE(NAME, CODE) case CODE: return #NAME;
4056 DWARF_ALL_KNOWN_DW_RLE
4057 #undef DWARF_ONE_KNOWN_DW_RLE
4058 default:
4059 return NULL;
4060 }
4061 }
4062
4063
4064 static const char *
dwarf_loc_list_encoding_string(unsigned int kind)4065 dwarf_loc_list_encoding_string (unsigned int kind)
4066 {
4067 switch (kind)
4068 {
4069 #define DWARF_ONE_KNOWN_DW_LLE(NAME, CODE) case CODE: return #NAME;
4070 DWARF_ALL_KNOWN_DW_LLE
4071 #undef DWARF_ONE_KNOWN_DW_LLE
4072 default:
4073 return NULL;
4074 }
4075 }
4076
4077
4078 static const char *
dwarf_line_content_description_string(unsigned int kind)4079 dwarf_line_content_description_string (unsigned int kind)
4080 {
4081 switch (kind)
4082 {
4083 #define DWARF_ONE_KNOWN_DW_LNCT(NAME, CODE) case CODE: return #NAME;
4084 DWARF_ALL_KNOWN_DW_LNCT
4085 #undef DWARF_ONE_KNOWN_DW_LNCT
4086 default:
4087 return NULL;
4088 }
4089 }
4090
4091
4092 /* Used by all dwarf_foo_name functions. */
4093 static const char *
string_or_unknown(const char * known,unsigned int code,unsigned int lo_user,unsigned int hi_user,bool print_unknown_num)4094 string_or_unknown (const char *known, unsigned int code,
4095 unsigned int lo_user, unsigned int hi_user,
4096 bool print_unknown_num)
4097 {
4098 static char unknown_buf[20];
4099
4100 if (likely (known != NULL))
4101 return known;
4102
4103 if (lo_user != 0 && code >= lo_user && code <= hi_user)
4104 {
4105 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
4106 code - lo_user);
4107 return unknown_buf;
4108 }
4109
4110 if (print_unknown_num)
4111 {
4112 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
4113 return unknown_buf;
4114 }
4115
4116 return "???";
4117 }
4118
4119
4120 static const char *
dwarf_tag_name(unsigned int tag)4121 dwarf_tag_name (unsigned int tag)
4122 {
4123 const char *ret = dwarf_tag_string (tag);
4124 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
4125 }
4126
4127 static const char *
dwarf_attr_name(unsigned int attr)4128 dwarf_attr_name (unsigned int attr)
4129 {
4130 const char *ret = dwarf_attr_string (attr);
4131 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
4132 }
4133
4134
4135 static const char *
dwarf_form_name(unsigned int form)4136 dwarf_form_name (unsigned int form)
4137 {
4138 const char *ret = dwarf_form_string (form);
4139 return string_or_unknown (ret, form, 0, 0, true);
4140 }
4141
4142
4143 static const char *
dwarf_lang_name(unsigned int lang)4144 dwarf_lang_name (unsigned int lang)
4145 {
4146 const char *ret = dwarf_lang_string (lang);
4147 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
4148 }
4149
4150
4151 static const char *
dwarf_inline_name(unsigned int code)4152 dwarf_inline_name (unsigned int code)
4153 {
4154 const char *ret = dwarf_inline_string (code);
4155 return string_or_unknown (ret, code, 0, 0, false);
4156 }
4157
4158
4159 static const char *
dwarf_encoding_name(unsigned int code)4160 dwarf_encoding_name (unsigned int code)
4161 {
4162 const char *ret = dwarf_encoding_string (code);
4163 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
4164 }
4165
4166
4167 static const char *
dwarf_access_name(unsigned int code)4168 dwarf_access_name (unsigned int code)
4169 {
4170 const char *ret = dwarf_access_string (code);
4171 return string_or_unknown (ret, code, 0, 0, false);
4172 }
4173
4174
4175 static const char *
dwarf_defaulted_name(unsigned int code)4176 dwarf_defaulted_name (unsigned int code)
4177 {
4178 const char *ret = dwarf_defaulted_string (code);
4179 return string_or_unknown (ret, code, 0, 0, false);
4180 }
4181
4182
4183 static const char *
dwarf_visibility_name(unsigned int code)4184 dwarf_visibility_name (unsigned int code)
4185 {
4186 const char *ret = dwarf_visibility_string (code);
4187 return string_or_unknown (ret, code, 0, 0, false);
4188 }
4189
4190
4191 static const char *
dwarf_virtuality_name(unsigned int code)4192 dwarf_virtuality_name (unsigned int code)
4193 {
4194 const char *ret = dwarf_virtuality_string (code);
4195 return string_or_unknown (ret, code, 0, 0, false);
4196 }
4197
4198
4199 static const char *
dwarf_identifier_case_name(unsigned int code)4200 dwarf_identifier_case_name (unsigned int code)
4201 {
4202 const char *ret = dwarf_identifier_case_string (code);
4203 return string_or_unknown (ret, code, 0, 0, false);
4204 }
4205
4206
4207 static const char *
dwarf_calling_convention_name(unsigned int code)4208 dwarf_calling_convention_name (unsigned int code)
4209 {
4210 const char *ret = dwarf_calling_convention_string (code);
4211 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
4212 }
4213
4214
4215 static const char *
dwarf_ordering_name(unsigned int code)4216 dwarf_ordering_name (unsigned int code)
4217 {
4218 const char *ret = dwarf_ordering_string (code);
4219 return string_or_unknown (ret, code, 0, 0, false);
4220 }
4221
4222
4223 static const char *
dwarf_discr_list_name(unsigned int code)4224 dwarf_discr_list_name (unsigned int code)
4225 {
4226 const char *ret = dwarf_discr_list_string (code);
4227 return string_or_unknown (ret, code, 0, 0, false);
4228 }
4229
4230
4231 static const char *
dwarf_unit_name(unsigned int type)4232 dwarf_unit_name (unsigned int type)
4233 {
4234 const char *ret = dwarf_unit_string (type);
4235 return string_or_unknown (ret, type, DW_UT_lo_user, DW_UT_hi_user, true);
4236 }
4237
4238
4239 static const char *
dwarf_range_list_encoding_name(unsigned int kind)4240 dwarf_range_list_encoding_name (unsigned int kind)
4241 {
4242 const char *ret = dwarf_range_list_encoding_string (kind);
4243 return string_or_unknown (ret, kind, 0, 0, false);
4244 }
4245
4246
4247 static const char *
dwarf_loc_list_encoding_name(unsigned int kind)4248 dwarf_loc_list_encoding_name (unsigned int kind)
4249 {
4250 const char *ret = dwarf_loc_list_encoding_string (kind);
4251 return string_or_unknown (ret, kind, 0, 0, false);
4252 }
4253
4254
4255 static const char *
dwarf_line_content_description_name(unsigned int kind)4256 dwarf_line_content_description_name (unsigned int kind)
4257 {
4258 const char *ret = dwarf_line_content_description_string (kind);
4259 return string_or_unknown (ret, kind, DW_LNCT_lo_user, DW_LNCT_hi_user,
4260 false);
4261 }
4262
4263
4264 static void
print_block(size_t n,const void * block)4265 print_block (size_t n, const void *block)
4266 {
4267 if (n == 0)
4268 puts (_("empty block"));
4269 else
4270 {
4271 printf (_("%zu byte block:"), n);
4272 const unsigned char *data = block;
4273 do
4274 printf (" %02x", *data++);
4275 while (--n > 0);
4276 putchar ('\n');
4277 }
4278 }
4279
4280 static void
print_bytes(size_t n,const unsigned char * bytes)4281 print_bytes (size_t n, const unsigned char *bytes)
4282 {
4283 while (n-- > 0)
4284 {
4285 printf ("%02x", *bytes++);
4286 if (n > 0)
4287 printf (" ");
4288 }
4289 }
4290
4291 static int
get_indexed_addr(Dwarf_CU * cu,Dwarf_Word idx,Dwarf_Addr * addr)4292 get_indexed_addr (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
4293 {
4294 if (cu == NULL)
4295 return -1;
4296
4297 Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
4298 if (debug_addr == NULL)
4299 return -1;
4300
4301 Dwarf_Off base = __libdw_cu_addr_base (cu);
4302 Dwarf_Word off = idx * cu->address_size;
4303 if (base > debug_addr->d_size
4304 || off > debug_addr->d_size - base
4305 || cu->address_size > debug_addr->d_size - base - off)
4306 return -1;
4307
4308 const unsigned char *addrp = debug_addr->d_buf + base + off;
4309 if (cu->address_size == 4)
4310 *addr = read_4ubyte_unaligned (cu->dbg, addrp);
4311 else
4312 *addr = read_8ubyte_unaligned (cu->dbg, addrp);
4313
4314 return 0;
4315 }
4316
4317 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)4318 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
4319 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
4320 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
4321 {
4322 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
4323
4324 if (len == 0)
4325 {
4326 printf ("%*s(empty)\n", indent, "");
4327 return;
4328 }
4329
4330 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
4331 #define CONSUME(n) NEED (n); else len -= (n)
4332
4333 Dwarf_Word offset = 0;
4334 while (len-- > 0)
4335 {
4336 uint_fast8_t op = *data++;
4337
4338 const char *op_name = dwarf_locexpr_opcode_string (op);
4339 if (unlikely (op_name == NULL))
4340 {
4341 static char buf[20];
4342 if (op >= DW_OP_lo_user)
4343 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
4344 else
4345 snprintf (buf, sizeof buf, "??? (%#x)", op);
4346 op_name = buf;
4347 }
4348
4349 switch (op)
4350 {
4351 case DW_OP_addr:;
4352 /* Address operand. */
4353 Dwarf_Word addr;
4354 NEED (addrsize);
4355 if (addrsize == 4)
4356 addr = read_4ubyte_unaligned (dbg, data);
4357 else if (addrsize == 8)
4358 addr = read_8ubyte_unaligned (dbg, data);
4359 else
4360 goto invalid;
4361 data += addrsize;
4362 CONSUME (addrsize);
4363
4364 printf ("%*s[%2" PRIuMAX "] %s ",
4365 indent, "", (uintmax_t) offset, op_name);
4366 print_dwarf_addr (dwflmod, 0, addr, addr);
4367 printf ("\n");
4368
4369 offset += 1 + addrsize;
4370 break;
4371
4372 case DW_OP_call_ref:
4373 case DW_OP_GNU_variable_value:
4374 /* Offset operand. */
4375 if (ref_size != 4 && ref_size != 8)
4376 goto invalid; /* Cannot be used in CFA. */
4377 NEED (ref_size);
4378 if (ref_size == 4)
4379 addr = read_4ubyte_unaligned (dbg, data);
4380 else
4381 addr = read_8ubyte_unaligned (dbg, data);
4382 data += ref_size;
4383 CONSUME (ref_size);
4384 /* addr is a DIE offset, so format it as one. */
4385 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4386 indent, "", (uintmax_t) offset,
4387 op_name, (uintmax_t) addr);
4388 offset += 1 + ref_size;
4389 break;
4390
4391 case DW_OP_deref_size:
4392 case DW_OP_xderef_size:
4393 case DW_OP_pick:
4394 case DW_OP_const1u:
4395 // XXX value might be modified by relocation
4396 NEED (1);
4397 printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 "\n",
4398 indent, "", (uintmax_t) offset,
4399 op_name, *((uint8_t *) data));
4400 ++data;
4401 --len;
4402 offset += 2;
4403 break;
4404
4405 case DW_OP_const2u:
4406 NEED (2);
4407 // XXX value might be modified by relocation
4408 printf ("%*s[%2" PRIuMAX "] %s %" PRIu16 "\n",
4409 indent, "", (uintmax_t) offset,
4410 op_name, read_2ubyte_unaligned (dbg, data));
4411 CONSUME (2);
4412 data += 2;
4413 offset += 3;
4414 break;
4415
4416 case DW_OP_const4u:
4417 NEED (4);
4418 // XXX value might be modified by relocation
4419 printf ("%*s[%2" PRIuMAX "] %s %" PRIu32 "\n",
4420 indent, "", (uintmax_t) offset,
4421 op_name, read_4ubyte_unaligned (dbg, data));
4422 CONSUME (4);
4423 data += 4;
4424 offset += 5;
4425 break;
4426
4427 case DW_OP_const8u:
4428 NEED (8);
4429 // XXX value might be modified by relocation
4430 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4431 indent, "", (uintmax_t) offset,
4432 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4433 CONSUME (8);
4434 data += 8;
4435 offset += 9;
4436 break;
4437
4438 case DW_OP_const1s:
4439 NEED (1);
4440 // XXX value might be modified by relocation
4441 printf ("%*s[%2" PRIuMAX "] %s %" PRId8 "\n",
4442 indent, "", (uintmax_t) offset,
4443 op_name, *((int8_t *) data));
4444 ++data;
4445 --len;
4446 offset += 2;
4447 break;
4448
4449 case DW_OP_const2s:
4450 NEED (2);
4451 // XXX value might be modified by relocation
4452 printf ("%*s[%2" PRIuMAX "] %s %" PRId16 "\n",
4453 indent, "", (uintmax_t) offset,
4454 op_name, read_2sbyte_unaligned (dbg, data));
4455 CONSUME (2);
4456 data += 2;
4457 offset += 3;
4458 break;
4459
4460 case DW_OP_const4s:
4461 NEED (4);
4462 // XXX value might be modified by relocation
4463 printf ("%*s[%2" PRIuMAX "] %s %" PRId32 "\n",
4464 indent, "", (uintmax_t) offset,
4465 op_name, read_4sbyte_unaligned (dbg, data));
4466 CONSUME (4);
4467 data += 4;
4468 offset += 5;
4469 break;
4470
4471 case DW_OP_const8s:
4472 NEED (8);
4473 // XXX value might be modified by relocation
4474 printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4475 indent, "", (uintmax_t) offset,
4476 op_name, read_8sbyte_unaligned (dbg, data));
4477 CONSUME (8);
4478 data += 8;
4479 offset += 9;
4480 break;
4481
4482 case DW_OP_piece:
4483 case DW_OP_regx:
4484 case DW_OP_plus_uconst:
4485 case DW_OP_constu:;
4486 const unsigned char *start = data;
4487 uint64_t uleb;
4488 NEED (1);
4489 get_uleb128 (uleb, data, data + len);
4490 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
4491 indent, "", (uintmax_t) offset, op_name, uleb);
4492 CONSUME (data - start);
4493 offset += 1 + (data - start);
4494 break;
4495
4496 case DW_OP_addrx:
4497 case DW_OP_GNU_addr_index:
4498 case DW_OP_constx:
4499 case DW_OP_GNU_const_index:;
4500 start = data;
4501 NEED (1);
4502 get_uleb128 (uleb, data, data + len);
4503 printf ("%*s[%2" PRIuMAX "] %s [%" PRIu64 "] ",
4504 indent, "", (uintmax_t) offset, op_name, uleb);
4505 CONSUME (data - start);
4506 offset += 1 + (data - start);
4507 if (get_indexed_addr (cu, uleb, &addr) != 0)
4508 printf ("???\n");
4509 else
4510 {
4511 print_dwarf_addr (dwflmod, 0, addr, addr);
4512 printf ("\n");
4513 }
4514 break;
4515
4516 case DW_OP_bit_piece:
4517 start = data;
4518 uint64_t uleb2;
4519 NEED (1);
4520 get_uleb128 (uleb, data, data + len);
4521 NEED (1);
4522 get_uleb128 (uleb2, data, data + len);
4523 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4524 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4525 CONSUME (data - start);
4526 offset += 1 + (data - start);
4527 break;
4528
4529 case DW_OP_fbreg:
4530 case DW_OP_breg0 ... DW_OP_breg31:
4531 case DW_OP_consts:
4532 start = data;
4533 int64_t sleb;
4534 NEED (1);
4535 get_sleb128 (sleb, data, data + len);
4536 printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
4537 indent, "", (uintmax_t) offset, op_name, sleb);
4538 CONSUME (data - start);
4539 offset += 1 + (data - start);
4540 break;
4541
4542 case DW_OP_bregx:
4543 start = data;
4544 NEED (1);
4545 get_uleb128 (uleb, data, data + len);
4546 NEED (1);
4547 get_sleb128 (sleb, data, data + len);
4548 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4549 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4550 CONSUME (data - start);
4551 offset += 1 + (data - start);
4552 break;
4553
4554 case DW_OP_call2:
4555 NEED (2);
4556 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx16 "]\n",
4557 indent, "", (uintmax_t) offset, op_name,
4558 read_2ubyte_unaligned (dbg, data));
4559 CONSUME (2);
4560 data += 2;
4561 offset += 3;
4562 break;
4563
4564 case DW_OP_call4:
4565 NEED (4);
4566 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx32 "]\n",
4567 indent, "", (uintmax_t) offset, op_name,
4568 read_4ubyte_unaligned (dbg, data));
4569 CONSUME (4);
4570 data += 4;
4571 offset += 5;
4572 break;
4573
4574 case DW_OP_skip:
4575 case DW_OP_bra:
4576 NEED (2);
4577 printf ("%*s[%2" PRIuMAX "] %s %" PRIuMAX "\n",
4578 indent, "", (uintmax_t) offset, op_name,
4579 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4580 CONSUME (2);
4581 data += 2;
4582 offset += 3;
4583 break;
4584
4585 case DW_OP_implicit_value:
4586 start = data;
4587 NEED (1);
4588 get_uleb128 (uleb, data, data + len);
4589 printf ("%*s[%2" PRIuMAX "] %s: ",
4590 indent, "", (uintmax_t) offset, op_name);
4591 NEED (uleb);
4592 print_block (uleb, data);
4593 data += uleb;
4594 CONSUME (data - start);
4595 offset += 1 + (data - start);
4596 break;
4597
4598 case DW_OP_implicit_pointer:
4599 case DW_OP_GNU_implicit_pointer:
4600 /* DIE offset operand. */
4601 start = data;
4602 NEED (ref_size);
4603 if (ref_size != 4 && ref_size != 8)
4604 goto invalid; /* Cannot be used in CFA. */
4605 if (ref_size == 4)
4606 addr = read_4ubyte_unaligned (dbg, data);
4607 else
4608 addr = read_8ubyte_unaligned (dbg, data);
4609 data += ref_size;
4610 /* Byte offset operand. */
4611 NEED (1);
4612 get_sleb128 (sleb, data, data + len);
4613
4614 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4615 indent, "", (intmax_t) offset,
4616 op_name, (uintmax_t) addr, sleb);
4617 CONSUME (data - start);
4618 offset += 1 + (data - start);
4619 break;
4620
4621 case DW_OP_entry_value:
4622 case DW_OP_GNU_entry_value:
4623 /* Size plus expression block. */
4624 start = data;
4625 NEED (1);
4626 get_uleb128 (uleb, data, data + len);
4627 printf ("%*s[%2" PRIuMAX "] %s:\n",
4628 indent, "", (uintmax_t) offset, op_name);
4629 NEED (uleb);
4630 print_ops (dwflmod, dbg, indent + 5, indent + 5, vers,
4631 addrsize, offset_size, cu, uleb, data);
4632 data += uleb;
4633 CONSUME (data - start);
4634 offset += 1 + (data - start);
4635 break;
4636
4637 case DW_OP_const_type:
4638 case DW_OP_GNU_const_type:
4639 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4640 unsigned size plus block. */
4641 start = data;
4642 NEED (1);
4643 get_uleb128 (uleb, data, data + len);
4644 if (! print_unresolved_addresses && cu != NULL)
4645 uleb += cu->start;
4646 NEED (1);
4647 uint8_t usize = *(uint8_t *) data++;
4648 NEED (usize);
4649 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] ",
4650 indent, "", (uintmax_t) offset, op_name, uleb);
4651 print_block (usize, data);
4652 data += usize;
4653 CONSUME (data - start);
4654 offset += 1 + (data - start);
4655 break;
4656
4657 case DW_OP_regval_type:
4658 case DW_OP_GNU_regval_type:
4659 /* uleb128 register number, uleb128 CU relative
4660 DW_TAG_base_type DIE offset. */
4661 start = data;
4662 NEED (1);
4663 get_uleb128 (uleb, data, data + len);
4664 NEED (1);
4665 get_uleb128 (uleb2, data, data + len);
4666 if (! print_unresolved_addresses && cu != NULL)
4667 uleb2 += cu->start;
4668 printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4669 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4670 CONSUME (data - start);
4671 offset += 1 + (data - start);
4672 break;
4673
4674 case DW_OP_deref_type:
4675 case DW_OP_GNU_deref_type:
4676 /* 1-byte unsigned size of value, uleb128 CU relative
4677 DW_TAG_base_type DIE offset. */
4678 start = data;
4679 NEED (1);
4680 usize = *(uint8_t *) data++;
4681 NEED (1);
4682 get_uleb128 (uleb, data, data + len);
4683 if (! print_unresolved_addresses && cu != NULL)
4684 uleb += cu->start;
4685 printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4686 indent, "", (uintmax_t) offset,
4687 op_name, usize, uleb);
4688 CONSUME (data - start);
4689 offset += 1 + (data - start);
4690 break;
4691
4692 case DW_OP_xderef_type:
4693 /* 1-byte unsigned size of value, uleb128 base_type DIE offset. */
4694 start = data;
4695 NEED (1);
4696 usize = *(uint8_t *) data++;
4697 NEED (1);
4698 get_uleb128 (uleb, data, data + len);
4699 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4700 indent, "", (uintmax_t) offset,
4701 op_name, usize, uleb);
4702 CONSUME (data - start);
4703 offset += 1 + (data - start);
4704 break;
4705
4706 case DW_OP_convert:
4707 case DW_OP_GNU_convert:
4708 case DW_OP_reinterpret:
4709 case DW_OP_GNU_reinterpret:
4710 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4711 for conversion to untyped. */
4712 start = data;
4713 NEED (1);
4714 get_uleb128 (uleb, data, data + len);
4715 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4716 uleb += cu->start;
4717 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4718 indent, "", (uintmax_t) offset, op_name, uleb);
4719 CONSUME (data - start);
4720 offset += 1 + (data - start);
4721 break;
4722
4723 case DW_OP_GNU_parameter_ref:
4724 /* 4 byte CU relative reference to the abstract optimized away
4725 DW_TAG_formal_parameter. */
4726 NEED (4);
4727 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4728 if (! print_unresolved_addresses && cu != NULL)
4729 param_off += cu->start;
4730 printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4731 indent, "", (uintmax_t) offset, op_name, param_off);
4732 CONSUME (4);
4733 data += 4;
4734 offset += 5;
4735 break;
4736
4737 default:
4738 /* No Operand. */
4739 printf ("%*s[%2" PRIuMAX "] %s\n",
4740 indent, "", (uintmax_t) offset, op_name);
4741 ++offset;
4742 break;
4743 }
4744
4745 indent = indentrest;
4746 continue;
4747
4748 invalid:
4749 printf (gettext ("%*s[%2" PRIuMAX "] %s <TRUNCATED>\n"),
4750 indent, "", (uintmax_t) offset, op_name);
4751 break;
4752 }
4753 }
4754
4755
4756 struct listptr
4757 {
4758 Dwarf_Off offset:(64 - 3);
4759 bool addr64:1;
4760 bool dwarf64:1;
4761 bool warned:1;
4762 struct Dwarf_CU *cu;
4763 unsigned int attr;
4764 };
4765
4766 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4767 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4768
4769 static Dwarf_Addr
cudie_base(Dwarf_Die * cudie)4770 cudie_base (Dwarf_Die *cudie)
4771 {
4772 Dwarf_Addr base;
4773 /* Find the base address of the compilation unit. It will normally
4774 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4775 address could be overridden by DW_AT_entry_pc. It's been
4776 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4777 compilation units with discontinuous ranges. */
4778 if (unlikely (dwarf_lowpc (cudie, &base) != 0))
4779 {
4780 Dwarf_Attribute attr_mem;
4781 if (dwarf_formaddr (dwarf_attr (cudie, DW_AT_entry_pc, &attr_mem),
4782 &base) != 0)
4783 base = 0;
4784 }
4785 return base;
4786 }
4787
4788 static Dwarf_Addr
listptr_base(struct listptr * p)4789 listptr_base (struct listptr *p)
4790 {
4791 Dwarf_Die cu = CUDIE (p->cu);
4792 return cudie_base (&cu);
4793 }
4794
4795 static int
compare_listptr(const void * a,const void * b,void * arg)4796 compare_listptr (const void *a, const void *b, void *arg)
4797 {
4798 const char *name = arg;
4799 struct listptr *p1 = (void *) a;
4800 struct listptr *p2 = (void *) b;
4801
4802 if (p1->offset < p2->offset)
4803 return -1;
4804 if (p1->offset > p2->offset)
4805 return 1;
4806
4807 if (!p1->warned && !p2->warned)
4808 {
4809 if (p1->addr64 != p2->addr64)
4810 {
4811 p1->warned = p2->warned = true;
4812 error (0, 0,
4813 gettext ("%s %#" PRIx64 " used with different address sizes"),
4814 name, (uint64_t) p1->offset);
4815 }
4816 if (p1->dwarf64 != p2->dwarf64)
4817 {
4818 p1->warned = p2->warned = true;
4819 error (0, 0,
4820 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4821 name, (uint64_t) p1->offset);
4822 }
4823 if (listptr_base (p1) != listptr_base (p2))
4824 {
4825 p1->warned = p2->warned = true;
4826 error (0, 0,
4827 gettext ("%s %#" PRIx64 " used with different base addresses"),
4828 name, (uint64_t) p1->offset);
4829 }
4830 if (p1->attr != p2 ->attr)
4831 {
4832 p1->warned = p2->warned = true;
4833 error (0, 0,
4834 gettext ("%s %#" PRIx64
4835 " used with different attribute %s and %s"),
4836 name, (uint64_t) p1->offset, dwarf_attr_name (p2->attr),
4837 dwarf_attr_name (p2->attr));
4838 }
4839 }
4840
4841 return 0;
4842 }
4843
4844 struct listptr_table
4845 {
4846 size_t n;
4847 size_t alloc;
4848 struct listptr *table;
4849 };
4850
4851 static struct listptr_table known_locsptr;
4852 static struct listptr_table known_loclistsptr;
4853 static struct listptr_table known_rangelistptr;
4854 static struct listptr_table known_rnglistptr;
4855 static struct listptr_table known_addrbases;
4856 static struct listptr_table known_stroffbases;
4857
4858 static void
reset_listptr(struct listptr_table * table)4859 reset_listptr (struct listptr_table *table)
4860 {
4861 free (table->table);
4862 table->table = NULL;
4863 table->n = table->alloc = 0;
4864 }
4865
4866 /* Returns false if offset doesn't fit. See struct listptr. */
4867 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)4868 notice_listptr (enum section_e section, struct listptr_table *table,
4869 uint_fast8_t address_size, uint_fast8_t offset_size,
4870 struct Dwarf_CU *cu, Dwarf_Off offset, unsigned int attr)
4871 {
4872 if (print_debug_sections & section)
4873 {
4874 if (table->n == table->alloc)
4875 {
4876 if (table->alloc == 0)
4877 table->alloc = 128;
4878 else
4879 table->alloc *= 2;
4880 table->table = xrealloc (table->table,
4881 table->alloc * sizeof table->table[0]);
4882 }
4883
4884 struct listptr *p = &table->table[table->n++];
4885
4886 *p = (struct listptr)
4887 {
4888 .addr64 = address_size == 8,
4889 .dwarf64 = offset_size == 8,
4890 .offset = offset,
4891 .cu = cu,
4892 .attr = attr
4893 };
4894
4895 if (p->offset != offset)
4896 {
4897 table->n--;
4898 return false;
4899 }
4900 }
4901 return true;
4902 }
4903
4904 static void
sort_listptr(struct listptr_table * table,const char * name)4905 sort_listptr (struct listptr_table *table, const char *name)
4906 {
4907 if (table->n > 0)
4908 qsort_r (table->table, table->n, sizeof table->table[0],
4909 &compare_listptr, (void *) name);
4910 }
4911
4912 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)4913 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4914 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4915 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4916 unsigned char **readp, unsigned char *endp,
4917 unsigned int *attr)
4918 {
4919 if (table->n == 0)
4920 return false;
4921
4922 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4923 ++*idxp;
4924
4925 struct listptr *p = &table->table[*idxp];
4926
4927 if (*idxp == table->n
4928 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4929 {
4930 *readp = endp;
4931 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4932 offset);
4933 return true;
4934 }
4935
4936 if (p->offset != (Dwarf_Off) offset)
4937 {
4938 *readp += p->offset - offset;
4939 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4940 offset, (Dwarf_Off) p->offset - offset);
4941 return true;
4942 }
4943
4944 if (address_sizep != NULL)
4945 *address_sizep = listptr_address_size (p);
4946 if (offset_sizep != NULL)
4947 *offset_sizep = listptr_offset_size (p);
4948 if (base != NULL)
4949 *base = listptr_base (p);
4950 if (cu != NULL)
4951 *cu = p->cu;
4952 if (attr != NULL)
4953 *attr = p->attr;
4954
4955 return false;
4956 }
4957
4958 static Dwarf_Off
next_listptr_offset(struct listptr_table * table,size_t idx)4959 next_listptr_offset (struct listptr_table *table, size_t idx)
4960 {
4961 /* Note that multiple attributes could in theory point to the same loclist
4962 offset, so make sure we pick one that is bigger than the current one.
4963 The table is sorted on offset. */
4964 Dwarf_Off offset = table->table[idx].offset;
4965 while (++idx < table->n)
4966 {
4967 Dwarf_Off next = table->table[idx].offset;
4968 if (next > offset)
4969 return next;
4970 }
4971 return 0;
4972 }
4973
4974 /* Returns the listptr associated with the given index, or NULL. */
4975 static struct listptr *
get_listptr(struct listptr_table * table,size_t idx)4976 get_listptr (struct listptr_table *table, size_t idx)
4977 {
4978 if (idx >= table->n)
4979 return NULL;
4980 return &table->table[idx];
4981 }
4982
4983 /* Returns the next index, base address and CU associated with the
4984 list unit offsets. If there is none false is returned, otherwise
4985 true. Assumes the table has been sorted. */
4986 static bool
listptr_cu(struct listptr_table * table,size_t * idxp,Dwarf_Off start,Dwarf_Off end,Dwarf_Addr * base,struct Dwarf_CU ** cu)4987 listptr_cu (struct listptr_table *table, size_t *idxp,
4988 Dwarf_Off start, Dwarf_Off end,
4989 Dwarf_Addr *base, struct Dwarf_CU **cu)
4990 {
4991 while (*idxp < table->n
4992 && table->table[*idxp].offset < start)
4993 ++*idxp;
4994
4995 if (*idxp < table->n
4996 && table->table[*idxp].offset >= start
4997 && table->table[*idxp].offset < end)
4998 {
4999 struct listptr *p = &table->table[*idxp];
5000 *base = listptr_base (p);
5001 *cu = p->cu;
5002 ++*idxp;
5003 return true;
5004 }
5005
5006 return false;
5007 }
5008
5009 static void
print_debug_abbrev_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5010 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5011 Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
5012 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5013 {
5014 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
5015 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
5016
5017 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
5018 " [ Code]\n"),
5019 elf_ndxscn (scn), section_name (ebl, shdr),
5020 (uint64_t) shdr->sh_offset);
5021
5022 Dwarf_Off offset = 0;
5023 while (offset < sh_size)
5024 {
5025 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
5026 offset);
5027
5028 while (1)
5029 {
5030 size_t length;
5031 Dwarf_Abbrev abbrev;
5032
5033 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
5034 if (res != 0)
5035 {
5036 if (unlikely (res < 0))
5037 {
5038 printf (gettext ("\
5039 *** error while reading abbreviation: %s\n"),
5040 dwarf_errmsg (-1));
5041 return;
5042 }
5043
5044 /* This is the NUL byte at the end of the section. */
5045 ++offset;
5046 break;
5047 }
5048
5049 /* We know these calls can never fail. */
5050 unsigned int code = dwarf_getabbrevcode (&abbrev);
5051 unsigned int tag = dwarf_getabbrevtag (&abbrev);
5052 int has_children = dwarf_abbrevhaschildren (&abbrev);
5053
5054 printf (gettext (" [%5u] offset: %" PRId64
5055 ", children: %s, tag: %s\n"),
5056 code, (int64_t) offset,
5057 has_children ? yes_str : no_str,
5058 dwarf_tag_name (tag));
5059
5060 size_t cnt = 0;
5061 unsigned int name;
5062 unsigned int form;
5063 Dwarf_Sword data;
5064 Dwarf_Off enoffset;
5065 while (dwarf_getabbrevattr_data (&abbrev, cnt, &name, &form,
5066 &data, &enoffset) == 0)
5067 {
5068 printf (" attr: %s, form: %s",
5069 dwarf_attr_name (name), dwarf_form_name (form));
5070 if (form == DW_FORM_implicit_const)
5071 printf (" (%" PRId64 ")", data);
5072 printf (", offset: %#" PRIx64 "\n", (uint64_t) enoffset);
5073 ++cnt;
5074 }
5075
5076 offset += length;
5077 }
5078 }
5079 }
5080
5081
5082 static void
print_debug_addr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5083 print_debug_addr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5084 Ebl *ebl, GElf_Ehdr *ehdr,
5085 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5086 {
5087 printf (gettext ("\
5088 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5089 elf_ndxscn (scn), section_name (ebl, shdr),
5090 (uint64_t) shdr->sh_offset);
5091
5092 if (shdr->sh_size == 0)
5093 return;
5094
5095 /* We like to get the section from libdw to make sure they are relocated. */
5096 Elf_Data *data = (dbg->sectiondata[IDX_debug_addr]
5097 ?: elf_rawdata (scn, NULL));
5098 if (unlikely (data == NULL))
5099 {
5100 error (0, 0, gettext ("cannot get .debug_addr section data: %s"),
5101 elf_errmsg (-1));
5102 return;
5103 }
5104
5105 size_t idx = 0;
5106 sort_listptr (&known_addrbases, "addr_base");
5107
5108 const unsigned char *start = (const unsigned char *) data->d_buf;
5109 const unsigned char *readp = start;
5110 const unsigned char *readendp = ((const unsigned char *) data->d_buf
5111 + data->d_size);
5112
5113 while (readp < readendp)
5114 {
5115 /* We cannot really know whether or not there is an header. The
5116 DebugFission extension to DWARF4 doesn't add one. The DWARF5
5117 .debug_addr variant does. Whether or not we have an header,
5118 DW_AT_[GNU_]addr_base points at "index 0". So if the current
5119 offset equals the CU addr_base then we can just start
5120 printing addresses. If there is no CU with an exact match
5121 then we'll try to parse the header first. */
5122 Dwarf_Off off = (Dwarf_Off) (readp
5123 - (const unsigned char *) data->d_buf);
5124
5125 printf ("Table at offset %" PRIx64 " ", off);
5126
5127 struct listptr *listptr = get_listptr (&known_addrbases, idx++);
5128 const unsigned char *next_unitp;
5129
5130 uint64_t unit_length;
5131 uint16_t version;
5132 uint8_t address_size;
5133 uint8_t segment_size;
5134 if (listptr == NULL)
5135 {
5136 error (0, 0, "Warning: No CU references .debug_addr after %" PRIx64,
5137 off);
5138
5139 /* We will have to assume it is just addresses to the end... */
5140 address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5141 next_unitp = readendp;
5142 printf ("Unknown CU:\n");
5143 }
5144 else
5145 {
5146 Dwarf_Die cudie;
5147 if (dwarf_cu_die (listptr->cu, &cudie,
5148 NULL, NULL, NULL, NULL,
5149 NULL, NULL) == NULL)
5150 printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
5151 else
5152 printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
5153
5154 if (listptr->offset == off)
5155 {
5156 address_size = listptr_address_size (listptr);
5157 segment_size = 0;
5158 version = 4;
5159
5160 /* The addresses start here, but where do they end? */
5161 listptr = get_listptr (&known_addrbases, idx);
5162 if (listptr == NULL)
5163 next_unitp = readendp;
5164 else if (listptr->cu->version < 5)
5165 {
5166 next_unitp = start + listptr->offset;
5167 if (listptr->offset < off || listptr->offset > data->d_size)
5168 {
5169 error (0, 0,
5170 "Warning: Bad address base for next unit at %"
5171 PRIx64, off);
5172 next_unitp = readendp;
5173 }
5174 }
5175 else
5176 {
5177 /* Tricky, we don't have a header for this unit, but
5178 there is one for the next. We will have to
5179 "guess" how big it is and subtract it from the
5180 offset (because that points after the header). */
5181 unsigned int offset_size = listptr_offset_size (listptr);
5182 Dwarf_Off next_off = (listptr->offset
5183 - (offset_size == 4 ? 4 : 12) /* len */
5184 - 2 /* version */
5185 - 1 /* address size */
5186 - 1); /* segment selector size */
5187 next_unitp = start + next_off;
5188 if (next_off < off || next_off > data->d_size)
5189 {
5190 error (0, 0,
5191 "Warning: Couldn't calculate .debug_addr "
5192 " unit lenght at %" PRIx64, off);
5193 next_unitp = readendp;
5194 }
5195 }
5196 unit_length = (uint64_t) (next_unitp - readp);
5197
5198 /* Pretend we have a header. */
5199 printf ("\n");
5200 printf (gettext (" Length: %8" PRIu64 "\n"),
5201 unit_length);
5202 printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
5203 printf (gettext (" Address size: %8" PRIu64 "\n"),
5204 (uint64_t) address_size);
5205 printf (gettext (" Segment size: %8" PRIu64 "\n"),
5206 (uint64_t) segment_size);
5207 printf ("\n");
5208 }
5209 else
5210 {
5211 /* OK, we have to parse an header first. */
5212 unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5213 if (unlikely (unit_length == 0xffffffff))
5214 {
5215 if (unlikely (readp > readendp - 8))
5216 {
5217 invalid_data:
5218 error (0, 0, "Invalid data");
5219 return;
5220 }
5221 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5222 }
5223 printf ("\n");
5224 printf (gettext (" Length: %8" PRIu64 "\n"),
5225 unit_length);
5226
5227 /* We need at least 2-bytes (version) + 1-byte
5228 (addr_size) + 1-byte (segment_size) = 4 bytes to
5229 complete the header. And this unit cannot go beyond
5230 the section data. */
5231 if (readp > readendp - 4
5232 || unit_length < 4
5233 || unit_length > (uint64_t) (readendp - readp))
5234 goto invalid_data;
5235
5236 next_unitp = readp + unit_length;
5237
5238 version = read_2ubyte_unaligned_inc (dbg, readp);
5239 printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
5240
5241 if (version != 5)
5242 {
5243 error (0, 0, gettext ("Unknown version"));
5244 goto next_unit;
5245 }
5246
5247 address_size = *readp++;
5248 printf (gettext (" Address size: %8" PRIu64 "\n"),
5249 (uint64_t) address_size);
5250
5251 if (address_size != 4 && address_size != 8)
5252 {
5253 error (0, 0, gettext ("unsupported address size"));
5254 goto next_unit;
5255 }
5256
5257 segment_size = *readp++;
5258 printf (gettext (" Segment size: %8" PRIu64 "\n"),
5259 (uint64_t) segment_size);
5260 printf ("\n");
5261
5262 if (segment_size != 0)
5263 {
5264 error (0, 0, gettext ("unsupported segment size"));
5265 goto next_unit;
5266 }
5267
5268 if (listptr->offset != (Dwarf_Off) (readp - start))
5269 {
5270 error (0, 0, "Address index doesn't start after header");
5271 goto next_unit;
5272 }
5273 }
5274 }
5275
5276 int digits = 1;
5277 size_t addresses = (next_unitp - readp) / address_size;
5278 while (addresses >= 10)
5279 {
5280 ++digits;
5281 addresses /= 10;
5282 }
5283
5284 unsigned int uidx = 0;
5285 size_t index_offset = readp - (const unsigned char *) data->d_buf;
5286 printf (" Addresses start at offset 0x%zx:\n", index_offset);
5287 while (readp <= next_unitp - address_size)
5288 {
5289 Dwarf_Addr addr = read_addr_unaligned_inc (address_size, dbg,
5290 readp);
5291 printf (" [%*u] ", digits, uidx++);
5292 print_dwarf_addr (dwflmod, address_size, addr, addr);
5293 printf ("\n");
5294 }
5295 printf ("\n");
5296
5297 if (readp != next_unitp)
5298 error (0, 0, "extra %zd bytes at end of unit",
5299 (size_t) (next_unitp - readp));
5300
5301 next_unit:
5302 readp = next_unitp;
5303 }
5304 }
5305
5306 /* Print content of DWARF .debug_aranges section. We fortunately do
5307 not have to know a bit about the structure of the section, libdwarf
5308 takes care of it. */
5309 static void
print_decoded_aranges_section(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5310 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5311 GElf_Shdr *shdr, Dwarf *dbg)
5312 {
5313 Dwarf_Aranges *aranges;
5314 size_t cnt;
5315 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
5316 {
5317 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
5318 dwarf_errmsg (-1));
5319 return;
5320 }
5321
5322 GElf_Shdr glink_mem;
5323 GElf_Shdr *glink;
5324 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
5325 if (glink == NULL)
5326 {
5327 error (0, 0, gettext ("invalid sh_link value in section %zu"),
5328 elf_ndxscn (scn));
5329 return;
5330 }
5331
5332 printf (ngettext ("\
5333 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
5334 "\
5335 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
5336 cnt),
5337 elf_ndxscn (scn), section_name (ebl, shdr),
5338 (uint64_t) shdr->sh_offset, cnt);
5339
5340 /* Compute floor(log16(cnt)). */
5341 size_t tmp = cnt;
5342 int digits = 1;
5343 while (tmp >= 16)
5344 {
5345 ++digits;
5346 tmp >>= 4;
5347 }
5348
5349 for (size_t n = 0; n < cnt; ++n)
5350 {
5351 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
5352 if (unlikely (runp == NULL))
5353 {
5354 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
5355 return;
5356 }
5357
5358 Dwarf_Addr start;
5359 Dwarf_Word length;
5360 Dwarf_Off offset;
5361
5362 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
5363 printf (gettext (" [%*zu] ???\n"), digits, n);
5364 else
5365 printf (gettext (" [%*zu] start: %0#*" PRIx64
5366 ", length: %5" PRIu64 ", CU DIE offset: %6"
5367 PRId64 "\n"),
5368 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
5369 (uint64_t) start, (uint64_t) length, (int64_t) offset);
5370 }
5371 }
5372
5373
5374 /* Print content of DWARF .debug_aranges section. */
5375 static void
print_debug_aranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5376 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
5377 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
5378 GElf_Shdr *shdr, Dwarf *dbg)
5379 {
5380 if (decodedaranges)
5381 {
5382 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
5383 return;
5384 }
5385
5386 Elf_Data *data = (dbg->sectiondata[IDX_debug_aranges]
5387 ?: elf_rawdata (scn, NULL));
5388
5389 if (unlikely (data == NULL))
5390 {
5391 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
5392 elf_errmsg (-1));
5393 return;
5394 }
5395
5396 printf (gettext ("\
5397 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5398 elf_ndxscn (scn), section_name (ebl, shdr),
5399 (uint64_t) shdr->sh_offset);
5400
5401 const unsigned char *readp = data->d_buf;
5402 const unsigned char *readendp = readp + data->d_size;
5403
5404 while (readp < readendp)
5405 {
5406 const unsigned char *hdrstart = readp;
5407 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
5408
5409 printf (gettext ("\nTable at offset %zu:\n"), start_offset);
5410 if (readp + 4 > readendp)
5411 {
5412 invalid_data:
5413 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5414 elf_ndxscn (scn), section_name (ebl, shdr));
5415 return;
5416 }
5417
5418 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
5419 unsigned int length_bytes = 4;
5420 if (length == DWARF3_LENGTH_64_BIT)
5421 {
5422 if (readp + 8 > readendp)
5423 goto invalid_data;
5424 length = read_8ubyte_unaligned_inc (dbg, readp);
5425 length_bytes = 8;
5426 }
5427
5428 const unsigned char *nexthdr = readp + length;
5429 printf (gettext ("\n Length: %6" PRIu64 "\n"),
5430 (uint64_t) length);
5431
5432 if (unlikely (length > (size_t) (readendp - readp)))
5433 goto invalid_data;
5434
5435 if (length == 0)
5436 continue;
5437
5438 if (readp + 2 > readendp)
5439 goto invalid_data;
5440 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5441 printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
5442 version);
5443 if (version != 2)
5444 {
5445 error (0, 0, gettext ("unsupported aranges version"));
5446 goto next_table;
5447 }
5448
5449 Dwarf_Word offset;
5450 if (readp + length_bytes > readendp)
5451 goto invalid_data;
5452 if (length_bytes == 8)
5453 offset = read_8ubyte_unaligned_inc (dbg, readp);
5454 else
5455 offset = read_4ubyte_unaligned_inc (dbg, readp);
5456 printf (gettext (" CU offset: %6" PRIx64 "\n"),
5457 (uint64_t) offset);
5458
5459 if (readp + 1 > readendp)
5460 goto invalid_data;
5461 unsigned int address_size = *readp++;
5462 printf (gettext (" Address size: %6" PRIu64 "\n"),
5463 (uint64_t) address_size);
5464 if (address_size != 4 && address_size != 8)
5465 {
5466 error (0, 0, gettext ("unsupported address size"));
5467 goto next_table;
5468 }
5469
5470 if (readp + 1 > readendp)
5471 goto invalid_data;
5472 unsigned int segment_size = *readp++;
5473 printf (gettext (" Segment size: %6" PRIu64 "\n\n"),
5474 (uint64_t) segment_size);
5475 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5476 {
5477 error (0, 0, gettext ("unsupported segment size"));
5478 goto next_table;
5479 }
5480
5481 /* Round the address to the next multiple of 2*address_size. */
5482 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
5483 % (2 * address_size));
5484
5485 while (readp < nexthdr)
5486 {
5487 Dwarf_Word range_address;
5488 Dwarf_Word range_length;
5489 Dwarf_Word segment = 0;
5490 if (readp + 2 * address_size + segment_size > readendp)
5491 goto invalid_data;
5492 if (address_size == 4)
5493 {
5494 range_address = read_4ubyte_unaligned_inc (dbg, readp);
5495 range_length = read_4ubyte_unaligned_inc (dbg, readp);
5496 }
5497 else
5498 {
5499 range_address = read_8ubyte_unaligned_inc (dbg, readp);
5500 range_length = read_8ubyte_unaligned_inc (dbg, readp);
5501 }
5502
5503 if (segment_size == 4)
5504 segment = read_4ubyte_unaligned_inc (dbg, readp);
5505 else if (segment_size == 8)
5506 segment = read_8ubyte_unaligned_inc (dbg, readp);
5507
5508 if (range_address == 0 && range_length == 0 && segment == 0)
5509 break;
5510
5511 printf (" ");
5512 print_dwarf_addr (dwflmod, address_size, range_address,
5513 range_address);
5514 printf ("..");
5515 print_dwarf_addr (dwflmod, address_size,
5516 range_address + range_length - 1,
5517 range_length);
5518 if (segment_size != 0)
5519 printf (" (%" PRIx64 ")\n", (uint64_t) segment);
5520 else
5521 printf ("\n");
5522 }
5523
5524 next_table:
5525 if (readp != nexthdr)
5526 {
5527 size_t padding = nexthdr - readp;
5528 printf (gettext (" %zu padding bytes\n"), padding);
5529 readp = nexthdr;
5530 }
5531 }
5532 }
5533
5534
5535 static bool is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu);
5536
5537 /* Returns true and sets cu and cu_base if the given Dwarf is a split
5538 DWARF (.dwo) file. */
5539 static bool
split_dwarf_cu_base(Dwarf * dbg,Dwarf_CU ** cu,Dwarf_Addr * cu_base)5540 split_dwarf_cu_base (Dwarf *dbg, Dwarf_CU **cu, Dwarf_Addr *cu_base)
5541 {
5542 uint64_t id;
5543 if (is_split_dwarf (dbg, &id, cu))
5544 {
5545 Dwarf_Die cudie;
5546 if (dwarf_cu_info (*cu, NULL, NULL, &cudie, NULL, NULL, NULL, NULL) == 0)
5547 {
5548 *cu_base = cudie_base (&cudie);
5549 return true;
5550 }
5551 }
5552 return false;
5553 }
5554
5555 /* Print content of DWARF .debug_rnglists section. */
5556 static void
print_debug_rnglists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5557 print_debug_rnglists_section (Dwfl_Module *dwflmod,
5558 Ebl *ebl,
5559 GElf_Ehdr *ehdr __attribute__ ((unused)),
5560 Elf_Scn *scn, GElf_Shdr *shdr,
5561 Dwarf *dbg __attribute__((unused)))
5562 {
5563 printf (gettext ("\
5564 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5565 elf_ndxscn (scn), section_name (ebl, shdr),
5566 (uint64_t) shdr->sh_offset);
5567
5568 Elf_Data *data =(dbg->sectiondata[IDX_debug_rnglists]
5569 ?: elf_rawdata (scn, NULL));
5570 if (unlikely (data == NULL))
5571 {
5572 error (0, 0, gettext ("cannot get .debug_rnglists content: %s"),
5573 elf_errmsg (-1));
5574 return;
5575 }
5576
5577 /* For the listptr to get the base address/CU. */
5578 sort_listptr (&known_rnglistptr, "rnglistptr");
5579 size_t listptr_idx = 0;
5580
5581 const unsigned char *readp = data->d_buf;
5582 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5583 + data->d_size);
5584 while (readp < dataend)
5585 {
5586 if (unlikely (readp > dataend - 4))
5587 {
5588 invalid_data:
5589 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5590 elf_ndxscn (scn), section_name (ebl, shdr));
5591 return;
5592 }
5593
5594 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5595 printf (gettext ("Table at Offset 0x%" PRIx64 ":\n\n"),
5596 (uint64_t) offset);
5597
5598 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5599 unsigned int offset_size = 4;
5600 if (unlikely (unit_length == 0xffffffff))
5601 {
5602 if (unlikely (readp > dataend - 8))
5603 goto invalid_data;
5604
5605 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5606 offset_size = 8;
5607 }
5608 printf (gettext (" Length: %8" PRIu64 "\n"), unit_length);
5609
5610 /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
5611 bytes to complete the header. And this unit cannot go beyond
5612 the section data. */
5613 if (readp > dataend - 8
5614 || unit_length < 8
5615 || unit_length > (uint64_t) (dataend - readp))
5616 goto invalid_data;
5617
5618 const unsigned char *nexthdr = readp + unit_length;
5619
5620 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
5621 printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
5622
5623 if (version != 5)
5624 {
5625 error (0, 0, gettext ("Unknown version"));
5626 goto next_table;
5627 }
5628
5629 uint8_t address_size = *readp++;
5630 printf (gettext (" Address size: %8" PRIu64 "\n"),
5631 (uint64_t) address_size);
5632
5633 if (address_size != 4 && address_size != 8)
5634 {
5635 error (0, 0, gettext ("unsupported address size"));
5636 goto next_table;
5637 }
5638
5639 uint8_t segment_size = *readp++;
5640 printf (gettext (" Segment size: %8" PRIu64 "\n"),
5641 (uint64_t) segment_size);
5642
5643 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
5644 {
5645 error (0, 0, gettext ("unsupported segment size"));
5646 goto next_table;
5647 }
5648
5649 uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
5650 printf (gettext (" Offset entries: %8" PRIu64 "\n"),
5651 (uint64_t) offset_entry_count);
5652
5653 /* We need the CU that uses this unit to get the initial base address. */
5654 Dwarf_Addr cu_base = 0;
5655 struct Dwarf_CU *cu = NULL;
5656 if (listptr_cu (&known_rnglistptr, &listptr_idx,
5657 (Dwarf_Off) offset,
5658 (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
5659 &cu_base, &cu)
5660 || split_dwarf_cu_base (dbg, &cu, &cu_base))
5661 {
5662 Dwarf_Die cudie;
5663 if (dwarf_cu_die (cu, &cudie,
5664 NULL, NULL, NULL, NULL,
5665 NULL, NULL) == NULL)
5666 printf (gettext (" Unknown CU base: "));
5667 else
5668 printf (gettext (" CU [%6" PRIx64 "] base: "),
5669 dwarf_dieoffset (&cudie));
5670 print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
5671 printf ("\n");
5672 }
5673 else
5674 printf (gettext (" Not associated with a CU.\n"));
5675
5676 printf ("\n");
5677
5678 const unsigned char *offset_array_start = readp;
5679 if (offset_entry_count > 0)
5680 {
5681 uint64_t max_entries = (unit_length - 8) / offset_size;
5682 if (offset_entry_count > max_entries)
5683 {
5684 error (0, 0,
5685 gettext ("too many offset entries for unit length"));
5686 offset_entry_count = max_entries;
5687 }
5688
5689 printf (gettext (" Offsets starting at 0x%" PRIx64 ":\n"),
5690 (uint64_t) (offset_array_start
5691 - (unsigned char *) data->d_buf));
5692 for (uint32_t idx = 0; idx < offset_entry_count; idx++)
5693 {
5694 printf (" [%6" PRIu32 "] ", idx);
5695 if (offset_size == 4)
5696 {
5697 uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
5698 printf ("0x%" PRIx32 "\n", off);
5699 }
5700 else
5701 {
5702 uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
5703 printf ("0x%" PRIx64 "\n", off);
5704 }
5705 }
5706 printf ("\n");
5707 }
5708
5709 Dwarf_Addr base = cu_base;
5710 bool start_of_list = true;
5711 while (readp < nexthdr)
5712 {
5713 uint8_t kind = *readp++;
5714 uint64_t op1, op2;
5715
5716 /* Skip padding. */
5717 if (start_of_list && kind == DW_RLE_end_of_list)
5718 continue;
5719
5720 if (start_of_list)
5721 {
5722 base = cu_base;
5723 printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
5724 (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
5725 (uint64_t) (readp - offset_array_start - 1));
5726 start_of_list = false;
5727 }
5728
5729 printf (" %s", dwarf_range_list_encoding_name (kind));
5730 switch (kind)
5731 {
5732 case DW_RLE_end_of_list:
5733 start_of_list = true;
5734 printf ("\n\n");
5735 break;
5736
5737 case DW_RLE_base_addressx:
5738 if ((uint64_t) (nexthdr - readp) < 1)
5739 {
5740 invalid_range:
5741 error (0, 0, gettext ("invalid range list data"));
5742 goto next_table;
5743 }
5744 get_uleb128 (op1, readp, nexthdr);
5745 printf (" %" PRIx64 "\n", op1);
5746 if (! print_unresolved_addresses)
5747 {
5748 Dwarf_Addr addr;
5749 if (get_indexed_addr (cu, op1, &addr) != 0)
5750 printf (" ???\n");
5751 else
5752 {
5753 printf (" ");
5754 print_dwarf_addr (dwflmod, address_size, addr, addr);
5755 printf ("\n");
5756 }
5757 }
5758 break;
5759
5760 case DW_RLE_startx_endx:
5761 if ((uint64_t) (nexthdr - readp) < 1)
5762 goto invalid_range;
5763 get_uleb128 (op1, readp, nexthdr);
5764 if ((uint64_t) (nexthdr - readp) < 1)
5765 goto invalid_range;
5766 get_uleb128 (op2, readp, nexthdr);
5767 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5768 if (! print_unresolved_addresses)
5769 {
5770 Dwarf_Addr addr1;
5771 Dwarf_Addr addr2;
5772 if (get_indexed_addr (cu, op1, &addr1) != 0
5773 || get_indexed_addr (cu, op2, &addr2) != 0)
5774 {
5775 printf (" ???..\n");
5776 printf (" ???\n");
5777 }
5778 else
5779 {
5780 printf (" ");
5781 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
5782 printf ("..\n ");
5783 print_dwarf_addr (dwflmod, address_size,
5784 addr2 - 1, addr2);
5785 printf ("\n");
5786 }
5787 }
5788 break;
5789
5790 case DW_RLE_startx_length:
5791 if ((uint64_t) (nexthdr - readp) < 1)
5792 goto invalid_range;
5793 get_uleb128 (op1, readp, nexthdr);
5794 if ((uint64_t) (nexthdr - readp) < 1)
5795 goto invalid_range;
5796 get_uleb128 (op2, readp, nexthdr);
5797 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5798 if (! print_unresolved_addresses)
5799 {
5800 Dwarf_Addr addr1;
5801 Dwarf_Addr addr2;
5802 if (get_indexed_addr (cu, op1, &addr1) != 0)
5803 {
5804 printf (" ???..\n");
5805 printf (" ???\n");
5806 }
5807 else
5808 {
5809 addr2 = addr1 + op2;
5810 printf (" ");
5811 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
5812 printf ("..\n ");
5813 print_dwarf_addr (dwflmod, address_size,
5814 addr2 - 1, addr2);
5815 printf ("\n");
5816 }
5817 }
5818 break;
5819
5820 case DW_RLE_offset_pair:
5821 if ((uint64_t) (nexthdr - readp) < 1)
5822 goto invalid_range;
5823 get_uleb128 (op1, readp, nexthdr);
5824 if ((uint64_t) (nexthdr - readp) < 1)
5825 goto invalid_range;
5826 get_uleb128 (op2, readp, nexthdr);
5827 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
5828 if (! print_unresolved_addresses)
5829 {
5830 op1 += base;
5831 op2 += base;
5832 printf (" ");
5833 print_dwarf_addr (dwflmod, address_size, op1, op1);
5834 printf ("..\n ");
5835 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5836 printf ("\n");
5837 }
5838 break;
5839
5840 case DW_RLE_base_address:
5841 if (address_size == 4)
5842 {
5843 if ((uint64_t) (nexthdr - readp) < 4)
5844 goto invalid_range;
5845 op1 = read_4ubyte_unaligned_inc (dbg, readp);
5846 }
5847 else
5848 {
5849 if ((uint64_t) (nexthdr - readp) < 8)
5850 goto invalid_range;
5851 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5852 }
5853 base = op1;
5854 printf (" 0x%" PRIx64 "\n", base);
5855 if (! print_unresolved_addresses)
5856 {
5857 printf (" ");
5858 print_dwarf_addr (dwflmod, address_size, base, base);
5859 printf ("\n");
5860 }
5861 break;
5862
5863 case DW_RLE_start_end:
5864 if (address_size == 4)
5865 {
5866 if ((uint64_t) (nexthdr - readp) < 8)
5867 goto invalid_range;
5868 op1 = read_4ubyte_unaligned_inc (dbg, readp);
5869 op2 = read_4ubyte_unaligned_inc (dbg, readp);
5870 }
5871 else
5872 {
5873 if ((uint64_t) (nexthdr - readp) < 16)
5874 goto invalid_range;
5875 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5876 op2 = read_8ubyte_unaligned_inc (dbg, readp);
5877 }
5878 printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
5879 if (! print_unresolved_addresses)
5880 {
5881 printf (" ");
5882 print_dwarf_addr (dwflmod, address_size, op1, op1);
5883 printf ("..\n ");
5884 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5885 printf ("\n");
5886 }
5887 break;
5888
5889 case DW_RLE_start_length:
5890 if (address_size == 4)
5891 {
5892 if ((uint64_t) (nexthdr - readp) < 4)
5893 goto invalid_range;
5894 op1 = read_4ubyte_unaligned_inc (dbg, readp);
5895 }
5896 else
5897 {
5898 if ((uint64_t) (nexthdr - readp) < 8)
5899 goto invalid_range;
5900 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5901 }
5902 if ((uint64_t) (nexthdr - readp) < 1)
5903 goto invalid_range;
5904 get_uleb128 (op2, readp, nexthdr);
5905 printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
5906 if (! print_unresolved_addresses)
5907 {
5908 op2 = op1 + op2;
5909 printf (" ");
5910 print_dwarf_addr (dwflmod, address_size, op1, op1);
5911 printf ("..\n ");
5912 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
5913 printf ("\n");
5914 }
5915 break;
5916
5917 default:
5918 goto invalid_range;
5919 }
5920 }
5921
5922 next_table:
5923 if (readp != nexthdr)
5924 {
5925 size_t padding = nexthdr - readp;
5926 printf (gettext (" %zu padding bytes\n\n"), padding);
5927 readp = nexthdr;
5928 }
5929 }
5930 }
5931
5932 /* Print content of DWARF .debug_ranges section. */
5933 static void
print_debug_ranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5934 print_debug_ranges_section (Dwfl_Module *dwflmod,
5935 Ebl *ebl, GElf_Ehdr *ehdr,
5936 Elf_Scn *scn, GElf_Shdr *shdr,
5937 Dwarf *dbg)
5938 {
5939 Elf_Data *data = (dbg->sectiondata[IDX_debug_ranges]
5940 ?: elf_rawdata (scn, NULL));
5941 if (unlikely (data == NULL))
5942 {
5943 error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
5944 elf_errmsg (-1));
5945 return;
5946 }
5947
5948 printf (gettext ("\
5949 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5950 elf_ndxscn (scn), section_name (ebl, shdr),
5951 (uint64_t) shdr->sh_offset);
5952
5953 sort_listptr (&known_rangelistptr, "rangelistptr");
5954 size_t listptr_idx = 0;
5955
5956 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5957
5958 bool first = true;
5959 Dwarf_Addr base = 0;
5960 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
5961 unsigned char *readp = data->d_buf;
5962 Dwarf_CU *last_cu = NULL;
5963 while (readp < endp)
5964 {
5965 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5966 Dwarf_CU *cu = last_cu;
5967
5968 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
5969 &address_size, NULL, &base, &cu,
5970 offset, &readp, endp, NULL))
5971 continue;
5972
5973 if (last_cu != cu)
5974 {
5975 Dwarf_Die cudie;
5976 if (dwarf_cu_die (cu, &cudie,
5977 NULL, NULL, NULL, NULL,
5978 NULL, NULL) == NULL)
5979 printf (gettext ("\n Unknown CU base: "));
5980 else
5981 printf (gettext ("\n CU [%6" PRIx64 "] base: "),
5982 dwarf_dieoffset (&cudie));
5983 print_dwarf_addr (dwflmod, address_size, base, base);
5984 printf ("\n");
5985 }
5986 last_cu = cu;
5987
5988 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
5989 {
5990 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
5991 break;
5992 }
5993
5994 Dwarf_Addr begin;
5995 Dwarf_Addr end;
5996 if (address_size == 8)
5997 {
5998 begin = read_8ubyte_unaligned_inc (dbg, readp);
5999 end = read_8ubyte_unaligned_inc (dbg, readp);
6000 }
6001 else
6002 {
6003 begin = read_4ubyte_unaligned_inc (dbg, readp);
6004 end = read_4ubyte_unaligned_inc (dbg, readp);
6005 if (begin == (Dwarf_Addr) (uint32_t) -1)
6006 begin = (Dwarf_Addr) -1l;
6007 }
6008
6009 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
6010 {
6011 printf (gettext (" [%6tx] base address\n "), offset);
6012 print_dwarf_addr (dwflmod, address_size, end, end);
6013 printf ("\n");
6014 base = end;
6015 }
6016 else if (begin == 0 && end == 0) /* End of list entry. */
6017 {
6018 if (first)
6019 printf (gettext (" [%6tx] empty list\n"), offset);
6020 first = true;
6021 }
6022 else
6023 {
6024 /* We have an address range entry. */
6025 if (first) /* First address range entry in a list. */
6026 printf (" [%6tx] ", offset);
6027 else
6028 printf (" ");
6029
6030 printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
6031 if (! print_unresolved_addresses)
6032 {
6033 printf (" ");
6034 print_dwarf_addr (dwflmod, address_size, base + begin,
6035 base + begin);
6036 printf ("..\n ");
6037 print_dwarf_addr (dwflmod, address_size,
6038 base + end - 1, base + end);
6039 printf ("\n");
6040 }
6041
6042 first = false;
6043 }
6044 }
6045 }
6046
6047 #define REGNAMESZ 16
6048 static const char *
register_info(Ebl * ebl,unsigned int regno,const Ebl_Register_Location * loc,char name[REGNAMESZ],int * bits,int * type)6049 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
6050 char name[REGNAMESZ], int *bits, int *type)
6051 {
6052 const char *set;
6053 const char *pfx;
6054 int ignore;
6055 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
6056 bits ?: &ignore, type ?: &ignore);
6057 if (n <= 0)
6058 {
6059 if (loc != NULL)
6060 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
6061 else
6062 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
6063 if (bits != NULL)
6064 *bits = loc != NULL ? loc->bits : 0;
6065 if (type != NULL)
6066 *type = DW_ATE_unsigned;
6067 set = "??? unrecognized";
6068 }
6069 else
6070 {
6071 if (bits != NULL && *bits <= 0)
6072 *bits = loc != NULL ? loc->bits : 0;
6073 if (type != NULL && *type == DW_ATE_void)
6074 *type = DW_ATE_unsigned;
6075
6076 }
6077 return set;
6078 }
6079
6080 static const unsigned char *
read_encoded(unsigned int encoding,const unsigned char * readp,const unsigned char * const endp,uint64_t * res,Dwarf * dbg)6081 read_encoded (unsigned int encoding, const unsigned char *readp,
6082 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
6083 {
6084 if ((encoding & 0xf) == DW_EH_PE_absptr)
6085 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
6086 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
6087
6088 switch (encoding & 0xf)
6089 {
6090 case DW_EH_PE_uleb128:
6091 get_uleb128 (*res, readp, endp);
6092 break;
6093 case DW_EH_PE_sleb128:
6094 get_sleb128 (*res, readp, endp);
6095 break;
6096 case DW_EH_PE_udata2:
6097 if (readp + 2 > endp)
6098 goto invalid;
6099 *res = read_2ubyte_unaligned_inc (dbg, readp);
6100 break;
6101 case DW_EH_PE_udata4:
6102 if (readp + 4 > endp)
6103 goto invalid;
6104 *res = read_4ubyte_unaligned_inc (dbg, readp);
6105 break;
6106 case DW_EH_PE_udata8:
6107 if (readp + 8 > endp)
6108 goto invalid;
6109 *res = read_8ubyte_unaligned_inc (dbg, readp);
6110 break;
6111 case DW_EH_PE_sdata2:
6112 if (readp + 2 > endp)
6113 goto invalid;
6114 *res = read_2sbyte_unaligned_inc (dbg, readp);
6115 break;
6116 case DW_EH_PE_sdata4:
6117 if (readp + 4 > endp)
6118 goto invalid;
6119 *res = read_4sbyte_unaligned_inc (dbg, readp);
6120 break;
6121 case DW_EH_PE_sdata8:
6122 if (readp + 8 > endp)
6123 goto invalid;
6124 *res = read_8sbyte_unaligned_inc (dbg, readp);
6125 break;
6126 default:
6127 invalid:
6128 error (1, 0,
6129 gettext ("invalid encoding"));
6130 }
6131
6132 return readp;
6133 }
6134
6135
6136 static void
print_cfa_program(const unsigned char * readp,const unsigned char * const endp,Dwarf_Word vma_base,unsigned int code_align,int data_align,unsigned int version,unsigned int ptr_size,unsigned int encoding,Dwfl_Module * dwflmod,Ebl * ebl,Dwarf * dbg)6137 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
6138 Dwarf_Word vma_base, unsigned int code_align,
6139 int data_align,
6140 unsigned int version, unsigned int ptr_size,
6141 unsigned int encoding,
6142 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
6143 {
6144 char regnamebuf[REGNAMESZ];
6145 const char *regname (unsigned int regno)
6146 {
6147 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
6148 return regnamebuf;
6149 }
6150
6151 puts ("\n Program:");
6152 Dwarf_Word pc = vma_base;
6153 while (readp < endp)
6154 {
6155 unsigned int opcode = *readp++;
6156
6157 if (opcode < DW_CFA_advance_loc)
6158 /* Extended opcode. */
6159 switch (opcode)
6160 {
6161 uint64_t op1;
6162 int64_t sop1;
6163 uint64_t op2;
6164 int64_t sop2;
6165
6166 case DW_CFA_nop:
6167 puts (" nop");
6168 break;
6169 case DW_CFA_set_loc:
6170 if ((uint64_t) (endp - readp) < 1)
6171 goto invalid;
6172 readp = read_encoded (encoding, readp, endp, &op1, dbg);
6173 printf (" set_loc %#" PRIx64 " to %#" PRIx64 "\n",
6174 op1, pc = vma_base + op1);
6175 break;
6176 case DW_CFA_advance_loc1:
6177 if ((uint64_t) (endp - readp) < 1)
6178 goto invalid;
6179 printf (" advance_loc1 %u to %#" PRIx64 "\n",
6180 *readp, pc += *readp * code_align);
6181 ++readp;
6182 break;
6183 case DW_CFA_advance_loc2:
6184 if ((uint64_t) (endp - readp) < 2)
6185 goto invalid;
6186 op1 = read_2ubyte_unaligned_inc (dbg, readp);
6187 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
6188 op1, pc += op1 * code_align);
6189 break;
6190 case DW_CFA_advance_loc4:
6191 if ((uint64_t) (endp - readp) < 4)
6192 goto invalid;
6193 op1 = read_4ubyte_unaligned_inc (dbg, readp);
6194 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
6195 op1, pc += op1 * code_align);
6196 break;
6197 case DW_CFA_offset_extended:
6198 if ((uint64_t) (endp - readp) < 1)
6199 goto invalid;
6200 get_uleb128 (op1, readp, endp);
6201 if ((uint64_t) (endp - readp) < 1)
6202 goto invalid;
6203 get_uleb128 (op2, readp, endp);
6204 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
6205 "\n",
6206 op1, regname (op1), op2 * data_align);
6207 break;
6208 case DW_CFA_restore_extended:
6209 if ((uint64_t) (endp - readp) < 1)
6210 goto invalid;
6211 get_uleb128 (op1, readp, endp);
6212 printf (" restore_extended r%" PRIu64 " (%s)\n",
6213 op1, regname (op1));
6214 break;
6215 case DW_CFA_undefined:
6216 if ((uint64_t) (endp - readp) < 1)
6217 goto invalid;
6218 get_uleb128 (op1, readp, endp);
6219 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
6220 break;
6221 case DW_CFA_same_value:
6222 if ((uint64_t) (endp - readp) < 1)
6223 goto invalid;
6224 get_uleb128 (op1, readp, endp);
6225 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
6226 break;
6227 case DW_CFA_register:
6228 if ((uint64_t) (endp - readp) < 1)
6229 goto invalid;
6230 get_uleb128 (op1, readp, endp);
6231 if ((uint64_t) (endp - readp) < 1)
6232 goto invalid;
6233 get_uleb128 (op2, readp, endp);
6234 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
6235 op1, regname (op1), op2, regname (op2));
6236 break;
6237 case DW_CFA_remember_state:
6238 puts (" remember_state");
6239 break;
6240 case DW_CFA_restore_state:
6241 puts (" restore_state");
6242 break;
6243 case DW_CFA_def_cfa:
6244 if ((uint64_t) (endp - readp) < 1)
6245 goto invalid;
6246 get_uleb128 (op1, readp, endp);
6247 if ((uint64_t) (endp - readp) < 1)
6248 goto invalid;
6249 get_uleb128 (op2, readp, endp);
6250 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
6251 op1, regname (op1), op2);
6252 break;
6253 case DW_CFA_def_cfa_register:
6254 if ((uint64_t) (endp - readp) < 1)
6255 goto invalid;
6256 get_uleb128 (op1, readp, endp);
6257 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
6258 op1, regname (op1));
6259 break;
6260 case DW_CFA_def_cfa_offset:
6261 if ((uint64_t) (endp - readp) < 1)
6262 goto invalid;
6263 get_uleb128 (op1, readp, endp);
6264 printf (" def_cfa_offset %" PRIu64 "\n", op1);
6265 break;
6266 case DW_CFA_def_cfa_expression:
6267 if ((uint64_t) (endp - readp) < 1)
6268 goto invalid;
6269 get_uleb128 (op1, readp, endp); /* Length of DW_FORM_block. */
6270 printf (" def_cfa_expression %" PRIu64 "\n", op1);
6271 if ((uint64_t) (endp - readp) < op1)
6272 {
6273 invalid:
6274 fputs (gettext (" <INVALID DATA>\n"), stdout);
6275 return;
6276 }
6277 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6278 op1, readp);
6279 readp += op1;
6280 break;
6281 case DW_CFA_expression:
6282 if ((uint64_t) (endp - readp) < 1)
6283 goto invalid;
6284 get_uleb128 (op1, readp, endp);
6285 if ((uint64_t) (endp - readp) < 1)
6286 goto invalid;
6287 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
6288 printf (" expression r%" PRIu64 " (%s) \n",
6289 op1, regname (op1));
6290 if ((uint64_t) (endp - readp) < op2)
6291 goto invalid;
6292 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
6293 op2, readp);
6294 readp += op2;
6295 break;
6296 case DW_CFA_offset_extended_sf:
6297 if ((uint64_t) (endp - readp) < 1)
6298 goto invalid;
6299 get_uleb128 (op1, readp, endp);
6300 if ((uint64_t) (endp - readp) < 1)
6301 goto invalid;
6302 get_sleb128 (sop2, readp, endp);
6303 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
6304 PRId64 "\n",
6305 op1, regname (op1), sop2 * data_align);
6306 break;
6307 case DW_CFA_def_cfa_sf:
6308 if ((uint64_t) (endp - readp) < 1)
6309 goto invalid;
6310 get_uleb128 (op1, readp, endp);
6311 if ((uint64_t) (endp - readp) < 1)
6312 goto invalid;
6313 get_sleb128 (sop2, readp, endp);
6314 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
6315 op1, regname (op1), sop2 * data_align);
6316 break;
6317 case DW_CFA_def_cfa_offset_sf:
6318 if ((uint64_t) (endp - readp) < 1)
6319 goto invalid;
6320 get_sleb128 (sop1, readp, endp);
6321 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
6322 break;
6323 case DW_CFA_val_offset:
6324 if ((uint64_t) (endp - readp) < 1)
6325 goto invalid;
6326 get_uleb128 (op1, readp, endp);
6327 if ((uint64_t) (endp - readp) < 1)
6328 goto invalid;
6329 get_uleb128 (op2, readp, endp);
6330 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
6331 op1, op2 * data_align);
6332 break;
6333 case DW_CFA_val_offset_sf:
6334 if ((uint64_t) (endp - readp) < 1)
6335 goto invalid;
6336 get_uleb128 (op1, readp, endp);
6337 if ((uint64_t) (endp - readp) < 1)
6338 goto invalid;
6339 get_sleb128 (sop2, readp, endp);
6340 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
6341 op1, sop2 * data_align);
6342 break;
6343 case DW_CFA_val_expression:
6344 if ((uint64_t) (endp - readp) < 1)
6345 goto invalid;
6346 get_uleb128 (op1, readp, endp);
6347 if ((uint64_t) (endp - readp) < 1)
6348 goto invalid;
6349 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
6350 printf (" val_expression r%" PRIu64 " (%s)\n",
6351 op1, regname (op1));
6352 if ((uint64_t) (endp - readp) < op2)
6353 goto invalid;
6354 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
6355 NULL, op2, readp);
6356 readp += op2;
6357 break;
6358 case DW_CFA_MIPS_advance_loc8:
6359 if ((uint64_t) (endp - readp) < 8)
6360 goto invalid;
6361 op1 = read_8ubyte_unaligned_inc (dbg, readp);
6362 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
6363 op1, pc += op1 * code_align);
6364 break;
6365 case DW_CFA_GNU_window_save:
6366 puts (" GNU_window_save");
6367 break;
6368 case DW_CFA_GNU_args_size:
6369 if ((uint64_t) (endp - readp) < 1)
6370 goto invalid;
6371 get_uleb128 (op1, readp, endp);
6372 printf (" args_size %" PRIu64 "\n", op1);
6373 break;
6374 default:
6375 printf (" ??? (%u)\n", opcode);
6376 break;
6377 }
6378 else if (opcode < DW_CFA_offset)
6379 printf (" advance_loc %u to %#" PRIx64 "\n",
6380 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
6381 else if (opcode < DW_CFA_restore)
6382 {
6383 uint64_t offset;
6384 if ((uint64_t) (endp - readp) < 1)
6385 goto invalid;
6386 get_uleb128 (offset, readp, endp);
6387 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
6388 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
6389 }
6390 else
6391 printf (" restore r%u (%s)\n",
6392 opcode & 0x3f, regname (opcode & 0x3f));
6393 }
6394 }
6395
6396
6397 static unsigned int
encoded_ptr_size(int encoding,unsigned int ptr_size)6398 encoded_ptr_size (int encoding, unsigned int ptr_size)
6399 {
6400 switch (encoding & 7)
6401 {
6402 case DW_EH_PE_udata4:
6403 return 4;
6404 case DW_EH_PE_udata8:
6405 return 8;
6406 case 0:
6407 return ptr_size;
6408 }
6409
6410 fprintf (stderr, "Unsupported pointer encoding: %#x, "
6411 "assuming pointer size of %d.\n", encoding, ptr_size);
6412 return ptr_size;
6413 }
6414
6415
6416 static unsigned int
print_encoding(unsigned int val)6417 print_encoding (unsigned int val)
6418 {
6419 switch (val & 0xf)
6420 {
6421 case DW_EH_PE_absptr:
6422 fputs ("absptr", stdout);
6423 break;
6424 case DW_EH_PE_uleb128:
6425 fputs ("uleb128", stdout);
6426 break;
6427 case DW_EH_PE_udata2:
6428 fputs ("udata2", stdout);
6429 break;
6430 case DW_EH_PE_udata4:
6431 fputs ("udata4", stdout);
6432 break;
6433 case DW_EH_PE_udata8:
6434 fputs ("udata8", stdout);
6435 break;
6436 case DW_EH_PE_sleb128:
6437 fputs ("sleb128", stdout);
6438 break;
6439 case DW_EH_PE_sdata2:
6440 fputs ("sdata2", stdout);
6441 break;
6442 case DW_EH_PE_sdata4:
6443 fputs ("sdata4", stdout);
6444 break;
6445 case DW_EH_PE_sdata8:
6446 fputs ("sdata8", stdout);
6447 break;
6448 default:
6449 /* We did not use any of the bits after all. */
6450 return val;
6451 }
6452
6453 return val & ~0xf;
6454 }
6455
6456
6457 static unsigned int
print_relinfo(unsigned int val)6458 print_relinfo (unsigned int val)
6459 {
6460 switch (val & 0x70)
6461 {
6462 case DW_EH_PE_pcrel:
6463 fputs ("pcrel", stdout);
6464 break;
6465 case DW_EH_PE_textrel:
6466 fputs ("textrel", stdout);
6467 break;
6468 case DW_EH_PE_datarel:
6469 fputs ("datarel", stdout);
6470 break;
6471 case DW_EH_PE_funcrel:
6472 fputs ("funcrel", stdout);
6473 break;
6474 case DW_EH_PE_aligned:
6475 fputs ("aligned", stdout);
6476 break;
6477 default:
6478 return val;
6479 }
6480
6481 return val & ~0x70;
6482 }
6483
6484
6485 static void
print_encoding_base(const char * pfx,unsigned int fde_encoding)6486 print_encoding_base (const char *pfx, unsigned int fde_encoding)
6487 {
6488 printf ("(%s", pfx);
6489
6490 if (fde_encoding == DW_EH_PE_omit)
6491 puts ("omit)");
6492 else
6493 {
6494 unsigned int w = fde_encoding;
6495
6496 w = print_encoding (w);
6497
6498 if (w & 0x70)
6499 {
6500 if (w != fde_encoding)
6501 fputc_unlocked (' ', stdout);
6502
6503 w = print_relinfo (w);
6504 }
6505
6506 if (w != 0)
6507 printf ("%s%x", w != fde_encoding ? " " : "", w);
6508
6509 puts (")");
6510 }
6511 }
6512
6513
6514 static void
print_debug_frame_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6515 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6516 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6517 {
6518 size_t shstrndx;
6519 /* We know this call will succeed since it did in the caller. */
6520 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
6521 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
6522
6523 /* Needed if we find PC-relative addresses. */
6524 GElf_Addr bias;
6525 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
6526 {
6527 error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
6528 return;
6529 }
6530
6531 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
6532 Elf_Data *data = (is_eh_frame
6533 ? elf_rawdata (scn, NULL)
6534 : (dbg->sectiondata[IDX_debug_frame]
6535 ?: elf_rawdata (scn, NULL)));
6536
6537 if (unlikely (data == NULL))
6538 {
6539 error (0, 0, gettext ("cannot get %s content: %s"),
6540 scnname, elf_errmsg (-1));
6541 return;
6542 }
6543
6544 if (is_eh_frame)
6545 printf (gettext ("\
6546 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6547 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6548 else
6549 printf (gettext ("\
6550 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6551 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
6552
6553 struct cieinfo
6554 {
6555 ptrdiff_t cie_offset;
6556 const char *augmentation;
6557 unsigned int code_alignment_factor;
6558 unsigned int data_alignment_factor;
6559 uint8_t address_size;
6560 uint8_t fde_encoding;
6561 uint8_t lsda_encoding;
6562 struct cieinfo *next;
6563 } *cies = NULL;
6564
6565 const unsigned char *readp = data->d_buf;
6566 const unsigned char *const dataend = ((unsigned char *) data->d_buf
6567 + data->d_size);
6568 while (readp < dataend)
6569 {
6570 if (unlikely (readp + 4 > dataend))
6571 {
6572 invalid_data:
6573 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6574 elf_ndxscn (scn), scnname);
6575 return;
6576 }
6577
6578 /* At the beginning there must be a CIE. There can be multiple,
6579 hence we test tis in a loop. */
6580 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
6581
6582 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
6583 unsigned int length = 4;
6584 if (unlikely (unit_length == 0xffffffff))
6585 {
6586 if (unlikely (readp + 8 > dataend))
6587 goto invalid_data;
6588
6589 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
6590 length = 8;
6591 }
6592
6593 if (unlikely (unit_length == 0))
6594 {
6595 printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
6596 continue;
6597 }
6598
6599 Dwarf_Word maxsize = dataend - readp;
6600 if (unlikely (unit_length > maxsize))
6601 goto invalid_data;
6602
6603 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6604
6605 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
6606 const unsigned char *const cieend = readp + unit_length;
6607 if (unlikely (cieend > dataend))
6608 goto invalid_data;
6609
6610 Dwarf_Off cie_id;
6611 if (length == 4)
6612 {
6613 if (unlikely (cieend - readp < 4))
6614 goto invalid_data;
6615 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
6616 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
6617 cie_id = DW_CIE_ID_64;
6618 }
6619 else
6620 {
6621 if (unlikely (cieend - readp < 8))
6622 goto invalid_data;
6623 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
6624 }
6625
6626 uint_fast8_t version = 2;
6627 unsigned int code_alignment_factor;
6628 int data_alignment_factor;
6629 unsigned int fde_encoding = 0;
6630 unsigned int lsda_encoding = 0;
6631 Dwarf_Word initial_location = 0;
6632 Dwarf_Word vma_base = 0;
6633
6634 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
6635 {
6636 if (unlikely (cieend - readp < 2))
6637 goto invalid_data;
6638 version = *readp++;
6639 const char *const augmentation = (const char *) readp;
6640 readp = memchr (readp, '\0', cieend - readp);
6641 if (unlikely (readp == NULL))
6642 goto invalid_data;
6643 ++readp;
6644
6645 uint_fast8_t segment_size = 0;
6646 if (version >= 4)
6647 {
6648 if (cieend - readp < 5)
6649 goto invalid_data;
6650 ptr_size = *readp++;
6651 segment_size = *readp++;
6652 }
6653
6654 if (cieend - readp < 1)
6655 goto invalid_data;
6656 get_uleb128 (code_alignment_factor, readp, cieend);
6657 if (cieend - readp < 1)
6658 goto invalid_data;
6659 get_sleb128 (data_alignment_factor, readp, cieend);
6660
6661 /* In some variant for unwind data there is another field. */
6662 if (strcmp (augmentation, "eh") == 0)
6663 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6664
6665 unsigned int return_address_register;
6666 if (cieend - readp < 1)
6667 goto invalid_data;
6668 if (unlikely (version == 1))
6669 return_address_register = *readp++;
6670 else
6671 get_uleb128 (return_address_register, readp, cieend);
6672
6673 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
6674 " CIE_id: %" PRIu64 "\n"
6675 " version: %u\n"
6676 " augmentation: \"%s\"\n",
6677 offset, (uint64_t) unit_length, (uint64_t) cie_id,
6678 version, augmentation);
6679 if (version >= 4)
6680 printf (" address_size: %u\n"
6681 " segment_size: %u\n",
6682 ptr_size, segment_size);
6683 printf (" code_alignment_factor: %u\n"
6684 " data_alignment_factor: %d\n"
6685 " return_address_register: %u\n",
6686 code_alignment_factor,
6687 data_alignment_factor, return_address_register);
6688
6689 if (augmentation[0] == 'z')
6690 {
6691 unsigned int augmentationlen;
6692 get_uleb128 (augmentationlen, readp, cieend);
6693
6694 if (augmentationlen > (size_t) (cieend - readp))
6695 {
6696 error (0, 0, gettext ("invalid augmentation length"));
6697 readp = cieend;
6698 continue;
6699 }
6700
6701 const char *hdr = "Augmentation data:";
6702 const char *cp = augmentation + 1;
6703 while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
6704 {
6705 printf (" %-26s%#x ", hdr, *readp);
6706 hdr = "";
6707
6708 if (*cp == 'R')
6709 {
6710 fde_encoding = *readp++;
6711 print_encoding_base (gettext ("FDE address encoding: "),
6712 fde_encoding);
6713 }
6714 else if (*cp == 'L')
6715 {
6716 lsda_encoding = *readp++;
6717 print_encoding_base (gettext ("LSDA pointer encoding: "),
6718 lsda_encoding);
6719 }
6720 else if (*cp == 'P')
6721 {
6722 /* Personality. This field usually has a relocation
6723 attached pointing to __gcc_personality_v0. */
6724 const unsigned char *startp = readp;
6725 unsigned int encoding = *readp++;
6726 uint64_t val = 0;
6727 readp = read_encoded (encoding, readp,
6728 readp - 1 + augmentationlen,
6729 &val, dbg);
6730
6731 while (++startp < readp)
6732 printf ("%#x ", *startp);
6733
6734 putchar ('(');
6735 print_encoding (encoding);
6736 putchar (' ');
6737 switch (encoding & 0xf)
6738 {
6739 case DW_EH_PE_sleb128:
6740 case DW_EH_PE_sdata2:
6741 case DW_EH_PE_sdata4:
6742 printf ("%" PRId64 ")\n", val);
6743 break;
6744 default:
6745 printf ("%#" PRIx64 ")\n", val);
6746 break;
6747 }
6748 }
6749 else
6750 printf ("(%x)\n", *readp++);
6751
6752 ++cp;
6753 }
6754 }
6755
6756 if (likely (ptr_size == 4 || ptr_size == 8))
6757 {
6758 struct cieinfo *newp = alloca (sizeof (*newp));
6759 newp->cie_offset = offset;
6760 newp->augmentation = augmentation;
6761 newp->fde_encoding = fde_encoding;
6762 newp->lsda_encoding = lsda_encoding;
6763 newp->address_size = ptr_size;
6764 newp->code_alignment_factor = code_alignment_factor;
6765 newp->data_alignment_factor = data_alignment_factor;
6766 newp->next = cies;
6767 cies = newp;
6768 }
6769 }
6770 else
6771 {
6772 struct cieinfo *cie = cies;
6773 while (cie != NULL)
6774 if (is_eh_frame
6775 ? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
6776 : cie_id == (Dwarf_Off) cie->cie_offset)
6777 break;
6778 else
6779 cie = cie->next;
6780 if (unlikely (cie == NULL))
6781 {
6782 puts ("invalid CIE reference in FDE");
6783 return;
6784 }
6785
6786 /* Initialize from CIE data. */
6787 fde_encoding = cie->fde_encoding;
6788 lsda_encoding = cie->lsda_encoding;
6789 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
6790 code_alignment_factor = cie->code_alignment_factor;
6791 data_alignment_factor = cie->data_alignment_factor;
6792
6793 const unsigned char *base = readp;
6794 // XXX There are sometimes relocations for this value
6795 initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
6796 Dwarf_Word address_range
6797 = read_addr_unaligned_inc (ptr_size, dbg, readp);
6798
6799 /* pcrel for an FDE address is relative to the runtime
6800 address of the start_address field itself. Sign extend
6801 if necessary to make sure the calculation is done on the
6802 full 64 bit address even when initial_location only holds
6803 the lower 32 bits. */
6804 Dwarf_Addr pc_start = initial_location;
6805 if (ptr_size == 4)
6806 pc_start = (uint64_t) (int32_t) pc_start;
6807 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6808 pc_start += ((uint64_t) shdr->sh_addr
6809 + (base - (const unsigned char *) data->d_buf)
6810 - bias);
6811
6812 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
6813 " CIE_pointer: %" PRIu64 "\n"
6814 " initial_location: ",
6815 offset, (uint64_t) unit_length,
6816 cie->cie_offset, (uint64_t) cie_id);
6817 print_dwarf_addr (dwflmod, cie->address_size,
6818 pc_start, initial_location);
6819 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6820 {
6821 vma_base = (((uint64_t) shdr->sh_offset
6822 + (base - (const unsigned char *) data->d_buf)
6823 + (uint64_t) initial_location)
6824 & (ptr_size == 4
6825 ? UINT64_C (0xffffffff)
6826 : UINT64_C (0xffffffffffffffff)));
6827 printf (gettext (" (offset: %#" PRIx64 ")"),
6828 (uint64_t) vma_base);
6829 }
6830
6831 printf ("\n address_range: %#" PRIx64,
6832 (uint64_t) address_range);
6833 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
6834 printf (gettext (" (end offset: %#" PRIx64 ")"),
6835 ((uint64_t) vma_base + (uint64_t) address_range)
6836 & (ptr_size == 4
6837 ? UINT64_C (0xffffffff)
6838 : UINT64_C (0xffffffffffffffff)));
6839 putchar ('\n');
6840
6841 if (cie->augmentation[0] == 'z')
6842 {
6843 unsigned int augmentationlen;
6844 if (cieend - readp < 1)
6845 goto invalid_data;
6846 get_uleb128 (augmentationlen, readp, cieend);
6847
6848 if (augmentationlen > (size_t) (cieend - readp))
6849 {
6850 error (0, 0, gettext ("invalid augmentation length"));
6851 readp = cieend;
6852 continue;
6853 }
6854
6855 if (augmentationlen > 0)
6856 {
6857 const char *hdr = "Augmentation data:";
6858 const char *cp = cie->augmentation + 1;
6859 unsigned int u = 0;
6860 while (*cp != '\0'
6861 && cp < cie->augmentation + augmentationlen + 1)
6862 {
6863 if (*cp == 'L')
6864 {
6865 uint64_t lsda_pointer;
6866 const unsigned char *p
6867 = read_encoded (lsda_encoding, &readp[u],
6868 &readp[augmentationlen],
6869 &lsda_pointer, dbg);
6870 u = p - readp;
6871 printf (gettext ("\
6872 %-26sLSDA pointer: %#" PRIx64 "\n"),
6873 hdr, lsda_pointer);
6874 hdr = "";
6875 }
6876 ++cp;
6877 }
6878
6879 while (u < augmentationlen)
6880 {
6881 printf (" %-26s%#x\n", hdr, readp[u++]);
6882 hdr = "";
6883 }
6884 }
6885
6886 readp += augmentationlen;
6887 }
6888 }
6889
6890 /* Handle the initialization instructions. */
6891 if (ptr_size != 4 && ptr_size !=8)
6892 printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
6893 else
6894 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
6895 data_alignment_factor, version, ptr_size,
6896 fde_encoding, dwflmod, ebl, dbg);
6897 readp = cieend;
6898 }
6899 }
6900
6901
6902 /* Returns the signedness (or false if it cannot be determined) and
6903 the byte size (or zero if it cannot be gotten) of the given DIE
6904 DW_AT_type attribute. Uses dwarf_peel_type and dwarf_aggregate_size. */
6905 static void
die_type_sign_bytes(Dwarf_Die * die,bool * is_signed,int * bytes)6906 die_type_sign_bytes (Dwarf_Die *die, bool *is_signed, int *bytes)
6907 {
6908 Dwarf_Attribute attr;
6909 Dwarf_Die type;
6910
6911 *bytes = 0;
6912 *is_signed = false;
6913
6914 if (dwarf_peel_type (dwarf_formref_die (dwarf_attr_integrate (die,
6915 DW_AT_type,
6916 &attr), &type),
6917 &type) == 0)
6918 {
6919 Dwarf_Word val;
6920 *is_signed = (dwarf_formudata (dwarf_attr (&type, DW_AT_encoding,
6921 &attr), &val) == 0
6922 && (val == DW_ATE_signed || val == DW_ATE_signed_char));
6923
6924 if (dwarf_aggregate_size (&type, &val) == 0)
6925 *bytes = val;
6926 }
6927 }
6928
6929 struct attrcb_args
6930 {
6931 Dwfl_Module *dwflmod;
6932 Dwarf *dbg;
6933 Dwarf_Die *die;
6934 int level;
6935 bool silent;
6936 bool is_split;
6937 unsigned int version;
6938 unsigned int addrsize;
6939 unsigned int offset_size;
6940 struct Dwarf_CU *cu;
6941 };
6942
6943
6944 static int
attr_callback(Dwarf_Attribute * attrp,void * arg)6945 attr_callback (Dwarf_Attribute *attrp, void *arg)
6946 {
6947 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
6948 const int level = cbargs->level;
6949 Dwarf_Die *die = cbargs->die;
6950 bool is_split = cbargs->is_split;
6951
6952 unsigned int attr = dwarf_whatattr (attrp);
6953 if (unlikely (attr == 0))
6954 {
6955 if (!cbargs->silent)
6956 error (0, 0, gettext ("DIE [%" PRIx64 "] "
6957 "cannot get attribute code: %s"),
6958 dwarf_dieoffset (die), dwarf_errmsg (-1));
6959 return DWARF_CB_ABORT;
6960 }
6961
6962 unsigned int form = dwarf_whatform (attrp);
6963 if (unlikely (form == 0))
6964 {
6965 if (!cbargs->silent)
6966 error (0, 0, gettext ("DIE [%" PRIx64 "] "
6967 "cannot get attribute form: %s"),
6968 dwarf_dieoffset (die), dwarf_errmsg (-1));
6969 return DWARF_CB_ABORT;
6970 }
6971
6972 switch (form)
6973 {
6974 case DW_FORM_addr:
6975 case DW_FORM_addrx:
6976 case DW_FORM_addrx1:
6977 case DW_FORM_addrx2:
6978 case DW_FORM_addrx3:
6979 case DW_FORM_addrx4:
6980 case DW_FORM_GNU_addr_index:
6981 if (!cbargs->silent)
6982 {
6983 Dwarf_Addr addr;
6984 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
6985 {
6986 attrval_out:
6987 if (!cbargs->silent)
6988 error (0, 0, gettext ("DIE [%" PRIx64 "] "
6989 "cannot get attribute '%s' (%s) value: "
6990 "%s"),
6991 dwarf_dieoffset (die),
6992 dwarf_attr_name (attr),
6993 dwarf_form_name (form),
6994 dwarf_errmsg (-1));
6995 /* Don't ABORT, it might be other attributes can be resolved. */
6996 return DWARF_CB_OK;
6997 }
6998 if (form != DW_FORM_addr )
6999 {
7000 Dwarf_Word word;
7001 if (dwarf_formudata (attrp, &word) != 0)
7002 goto attrval_out;
7003 printf (" %*s%-20s (%s) [%" PRIx64 "] ",
7004 (int) (level * 2), "", dwarf_attr_name (attr),
7005 dwarf_form_name (form), word);
7006 }
7007 else
7008 printf (" %*s%-20s (%s) ",
7009 (int) (level * 2), "", dwarf_attr_name (attr),
7010 dwarf_form_name (form));
7011 print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr, addr);
7012 printf ("\n");
7013 }
7014 break;
7015
7016 case DW_FORM_indirect:
7017 case DW_FORM_strp:
7018 case DW_FORM_line_strp:
7019 case DW_FORM_strx:
7020 case DW_FORM_strx1:
7021 case DW_FORM_strx2:
7022 case DW_FORM_strx3:
7023 case DW_FORM_strx4:
7024 case DW_FORM_string:
7025 case DW_FORM_GNU_strp_alt:
7026 case DW_FORM_GNU_str_index:
7027 if (cbargs->silent)
7028 break;
7029 const char *str = dwarf_formstring (attrp);
7030 if (unlikely (str == NULL))
7031 goto attrval_out;
7032 printf (" %*s%-20s (%s) \"%s\"\n",
7033 (int) (level * 2), "", dwarf_attr_name (attr),
7034 dwarf_form_name (form), str);
7035 break;
7036
7037 case DW_FORM_ref_addr:
7038 case DW_FORM_ref_udata:
7039 case DW_FORM_ref8:
7040 case DW_FORM_ref4:
7041 case DW_FORM_ref2:
7042 case DW_FORM_ref1:
7043 case DW_FORM_GNU_ref_alt:
7044 case DW_FORM_ref_sup4:
7045 case DW_FORM_ref_sup8:
7046 if (cbargs->silent)
7047 break;
7048 Dwarf_Die ref;
7049 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
7050 goto attrval_out;
7051
7052 printf (" %*s%-20s (%s) ",
7053 (int) (level * 2), "", dwarf_attr_name (attr),
7054 dwarf_form_name (form));
7055 if (is_split)
7056 printf ("{%6" PRIxMAX "}\n", (uintmax_t) dwarf_dieoffset (&ref));
7057 else
7058 printf ("[%6" PRIxMAX "]\n", (uintmax_t) dwarf_dieoffset (&ref));
7059 break;
7060
7061 case DW_FORM_ref_sig8:
7062 if (cbargs->silent)
7063 break;
7064 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
7065 (int) (level * 2), "", dwarf_attr_name (attr),
7066 dwarf_form_name (form),
7067 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
7068 break;
7069
7070 case DW_FORM_sec_offset:
7071 case DW_FORM_rnglistx:
7072 case DW_FORM_loclistx:
7073 case DW_FORM_implicit_const:
7074 case DW_FORM_udata:
7075 case DW_FORM_sdata:
7076 case DW_FORM_data8: /* Note no data16 here, we see that as block. */
7077 case DW_FORM_data4:
7078 case DW_FORM_data2:
7079 case DW_FORM_data1:;
7080 Dwarf_Word num;
7081 if (unlikely (dwarf_formudata (attrp, &num) != 0))
7082 goto attrval_out;
7083
7084 const char *valuestr = NULL;
7085 bool as_hex_id = false;
7086 switch (attr)
7087 {
7088 /* This case can take either a constant or a loclistptr. */
7089 case DW_AT_data_member_location:
7090 if (form != DW_FORM_sec_offset
7091 && (cbargs->version >= 4
7092 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
7093 {
7094 if (!cbargs->silent)
7095 printf (" %*s%-20s (%s) %" PRIxMAX "\n",
7096 (int) (level * 2), "", dwarf_attr_name (attr),
7097 dwarf_form_name (form), (uintmax_t) num);
7098 return DWARF_CB_OK;
7099 }
7100 FALLTHROUGH;
7101
7102 /* These cases always take a loclist[ptr] and no constant. */
7103 case DW_AT_location:
7104 case DW_AT_data_location:
7105 case DW_AT_vtable_elem_location:
7106 case DW_AT_string_length:
7107 case DW_AT_use_location:
7108 case DW_AT_frame_base:
7109 case DW_AT_return_addr:
7110 case DW_AT_static_link:
7111 case DW_AT_segment:
7112 case DW_AT_GNU_call_site_value:
7113 case DW_AT_GNU_call_site_data_value:
7114 case DW_AT_GNU_call_site_target:
7115 case DW_AT_GNU_call_site_target_clobbered:
7116 case DW_AT_GNU_locviews:
7117 {
7118 bool nlpt;
7119 if (cbargs->cu->version < 5)
7120 {
7121 if (! cbargs->is_split)
7122 {
7123 nlpt = notice_listptr (section_loc, &known_locsptr,
7124 cbargs->addrsize,
7125 cbargs->offset_size,
7126 cbargs->cu, num, attr);
7127 }
7128 else
7129 nlpt = true;
7130 }
7131 else
7132 {
7133 /* Only register for a real section offset. Otherwise
7134 it is a DW_FORM_loclistx which is just an index
7135 number and we should already have registered the
7136 section offset for the index when we saw the
7137 DW_AT_loclists_base CU attribute. */
7138 if (form == DW_FORM_sec_offset)
7139 nlpt = notice_listptr (section_loc, &known_loclistsptr,
7140 cbargs->addrsize, cbargs->offset_size,
7141 cbargs->cu, num, attr);
7142 else
7143 nlpt = true;
7144
7145 }
7146
7147 if (!cbargs->silent)
7148 {
7149 if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7150 printf (" %*s%-20s (%s) location list [%6"
7151 PRIxMAX "]%s\n",
7152 (int) (level * 2), "", dwarf_attr_name (attr),
7153 dwarf_form_name (form), (uintmax_t) num,
7154 nlpt ? "" : " <WARNING offset too big>");
7155 else
7156 printf (" %*s%-20s (%s) location index [%6"
7157 PRIxMAX "]\n",
7158 (int) (level * 2), "", dwarf_attr_name (attr),
7159 dwarf_form_name (form), (uintmax_t) num);
7160 }
7161 }
7162 return DWARF_CB_OK;
7163
7164 case DW_AT_loclists_base:
7165 {
7166 bool nlpt = notice_listptr (section_loc, &known_loclistsptr,
7167 cbargs->addrsize, cbargs->offset_size,
7168 cbargs->cu, num, attr);
7169
7170 if (!cbargs->silent)
7171 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
7172 (int) (level * 2), "", dwarf_attr_name (attr),
7173 dwarf_form_name (form), (uintmax_t) num,
7174 nlpt ? "" : " <WARNING offset too big>");
7175 }
7176 return DWARF_CB_OK;
7177
7178 case DW_AT_ranges:
7179 case DW_AT_start_scope:
7180 {
7181 bool nlpt;
7182 if (cbargs->cu->version < 5)
7183 nlpt = notice_listptr (section_ranges, &known_rangelistptr,
7184 cbargs->addrsize, cbargs->offset_size,
7185 cbargs->cu, num, attr);
7186 else
7187 {
7188 /* Only register for a real section offset. Otherwise
7189 it is a DW_FORM_rangelistx which is just an index
7190 number and we should already have registered the
7191 section offset for the index when we saw the
7192 DW_AT_rnglists_base CU attribute. */
7193 if (form == DW_FORM_sec_offset)
7194 nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7195 cbargs->addrsize, cbargs->offset_size,
7196 cbargs->cu, num, attr);
7197 else
7198 nlpt = true;
7199 }
7200
7201 if (!cbargs->silent)
7202 {
7203 if (cbargs->cu->version < 5 || form == DW_FORM_sec_offset)
7204 printf (" %*s%-20s (%s) range list [%6"
7205 PRIxMAX "]%s\n",
7206 (int) (level * 2), "", dwarf_attr_name (attr),
7207 dwarf_form_name (form), (uintmax_t) num,
7208 nlpt ? "" : " <WARNING offset too big>");
7209 else
7210 printf (" %*s%-20s (%s) range index [%6"
7211 PRIxMAX "]\n",
7212 (int) (level * 2), "", dwarf_attr_name (attr),
7213 dwarf_form_name (form), (uintmax_t) num);
7214 }
7215 }
7216 return DWARF_CB_OK;
7217
7218 case DW_AT_rnglists_base:
7219 {
7220 bool nlpt = notice_listptr (section_ranges, &known_rnglistptr,
7221 cbargs->addrsize, cbargs->offset_size,
7222 cbargs->cu, num, attr);
7223 if (!cbargs->silent)
7224 printf (" %*s%-20s (%s) range list [%6"
7225 PRIxMAX "]%s\n",
7226 (int) (level * 2), "", dwarf_attr_name (attr),
7227 dwarf_form_name (form), (uintmax_t) num,
7228 nlpt ? "" : " <WARNING offset too big>");
7229 }
7230 return DWARF_CB_OK;
7231
7232 case DW_AT_addr_base:
7233 case DW_AT_GNU_addr_base:
7234 {
7235 bool addrbase = notice_listptr (section_addr, &known_addrbases,
7236 cbargs->addrsize,
7237 cbargs->offset_size,
7238 cbargs->cu, num, attr);
7239 if (!cbargs->silent)
7240 printf (" %*s%-20s (%s) address base [%6"
7241 PRIxMAX "]%s\n",
7242 (int) (level * 2), "", dwarf_attr_name (attr),
7243 dwarf_form_name (form), (uintmax_t) num,
7244 addrbase ? "" : " <WARNING offset too big>");
7245 }
7246 return DWARF_CB_OK;
7247
7248 case DW_AT_str_offsets_base:
7249 {
7250 bool stroffbase = notice_listptr (section_str, &known_stroffbases,
7251 cbargs->addrsize,
7252 cbargs->offset_size,
7253 cbargs->cu, num, attr);
7254 if (!cbargs->silent)
7255 printf (" %*s%-20s (%s) str offsets base [%6"
7256 PRIxMAX "]%s\n",
7257 (int) (level * 2), "", dwarf_attr_name (attr),
7258 dwarf_form_name (form), (uintmax_t) num,
7259 stroffbase ? "" : " <WARNING offset too big>");
7260 }
7261 return DWARF_CB_OK;
7262
7263 case DW_AT_language:
7264 valuestr = dwarf_lang_name (num);
7265 break;
7266 case DW_AT_encoding:
7267 valuestr = dwarf_encoding_name (num);
7268 break;
7269 case DW_AT_accessibility:
7270 valuestr = dwarf_access_name (num);
7271 break;
7272 case DW_AT_defaulted:
7273 valuestr = dwarf_defaulted_name (num);
7274 break;
7275 case DW_AT_visibility:
7276 valuestr = dwarf_visibility_name (num);
7277 break;
7278 case DW_AT_virtuality:
7279 valuestr = dwarf_virtuality_name (num);
7280 break;
7281 case DW_AT_identifier_case:
7282 valuestr = dwarf_identifier_case_name (num);
7283 break;
7284 case DW_AT_calling_convention:
7285 valuestr = dwarf_calling_convention_name (num);
7286 break;
7287 case DW_AT_inline:
7288 valuestr = dwarf_inline_name (num);
7289 break;
7290 case DW_AT_ordering:
7291 valuestr = dwarf_ordering_name (num);
7292 break;
7293 case DW_AT_discr_list:
7294 valuestr = dwarf_discr_list_name (num);
7295 break;
7296 case DW_AT_decl_file:
7297 case DW_AT_call_file:
7298 {
7299 if (cbargs->silent)
7300 break;
7301
7302 /* Try to get the actual file, the current interface only
7303 gives us full paths, but we only want to show the file
7304 name for now. */
7305 Dwarf_Die cudie;
7306 if (dwarf_cu_die (cbargs->cu, &cudie,
7307 NULL, NULL, NULL, NULL, NULL, NULL) != NULL)
7308 {
7309 Dwarf_Files *files;
7310 size_t nfiles;
7311 if (dwarf_getsrcfiles (&cudie, &files, &nfiles) == 0)
7312 {
7313 valuestr = dwarf_filesrc (files, num, NULL, NULL);
7314 if (valuestr != NULL)
7315 {
7316 char *filename = strrchr (valuestr, '/');
7317 if (filename != NULL)
7318 valuestr = filename + 1;
7319 }
7320 else
7321 error (0, 0, gettext ("invalid file (%" PRId64 "): %s"),
7322 num, dwarf_errmsg (-1));
7323 }
7324 else
7325 error (0, 0, gettext ("no srcfiles for CU [%" PRIx64 "]"),
7326 dwarf_dieoffset (&cudie));
7327 }
7328 else
7329 error (0, 0, gettext ("couldn't get DWARF CU: %s"),
7330 dwarf_errmsg (-1));
7331 if (valuestr == NULL)
7332 valuestr = "???";
7333 }
7334 break;
7335 case DW_AT_GNU_dwo_id:
7336 as_hex_id = true;
7337 break;
7338
7339 default:
7340 /* Nothing. */
7341 break;
7342 }
7343
7344 if (cbargs->silent)
7345 break;
7346
7347 /* When highpc is in constant form it is relative to lowpc.
7348 In that case also show the address. */
7349 Dwarf_Addr highpc;
7350 if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
7351 {
7352 printf (" %*s%-20s (%s) %" PRIuMAX " (",
7353 (int) (level * 2), "", dwarf_attr_name (attr),
7354 dwarf_form_name (form), (uintmax_t) num);
7355 print_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, highpc, highpc);
7356 printf (")\n");
7357 }
7358 else
7359 {
7360 if (as_hex_id)
7361 {
7362 printf (" %*s%-20s (%s) 0x%.16" PRIx64 "\n",
7363 (int) (level * 2), "", dwarf_attr_name (attr),
7364 dwarf_form_name (form), num);
7365 }
7366 else
7367 {
7368 Dwarf_Sword snum = 0;
7369 bool is_signed;
7370 int bytes = 0;
7371 if (attr == DW_AT_const_value)
7372 die_type_sign_bytes (cbargs->die, &is_signed, &bytes);
7373 else
7374 is_signed = (form == DW_FORM_sdata
7375 || form == DW_FORM_implicit_const);
7376
7377 if (is_signed)
7378 if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
7379 goto attrval_out;
7380
7381 if (valuestr == NULL)
7382 {
7383 printf (" %*s%-20s (%s) ",
7384 (int) (level * 2), "", dwarf_attr_name (attr),
7385 dwarf_form_name (form));
7386 }
7387 else
7388 {
7389 printf (" %*s%-20s (%s) %s (",
7390 (int) (level * 2), "", dwarf_attr_name (attr),
7391 dwarf_form_name (form), valuestr);
7392 }
7393
7394 switch (bytes)
7395 {
7396 case 1:
7397 if (is_signed)
7398 printf ("%" PRId8, (int8_t) snum);
7399 else
7400 printf ("%" PRIu8, (uint8_t) num);
7401 break;
7402
7403 case 2:
7404 if (is_signed)
7405 printf ("%" PRId16, (int16_t) snum);
7406 else
7407 printf ("%" PRIu16, (uint16_t) num);
7408 break;
7409
7410 case 4:
7411 if (is_signed)
7412 printf ("%" PRId32, (int32_t) snum);
7413 else
7414 printf ("%" PRIu32, (uint32_t) num);
7415 break;
7416
7417 case 8:
7418 if (is_signed)
7419 printf ("%" PRId64, (int64_t) snum);
7420 else
7421 printf ("%" PRIu64, (uint64_t) num);
7422 break;
7423
7424 default:
7425 if (is_signed)
7426 printf ("%" PRIdMAX, (intmax_t) snum);
7427 else
7428 printf ("%" PRIuMAX, (uintmax_t) num);
7429 break;
7430 }
7431
7432 /* Make clear if we switched from a signed encoding to
7433 an unsigned value. */
7434 if (attr == DW_AT_const_value
7435 && (form == DW_FORM_sdata || form == DW_FORM_implicit_const)
7436 && !is_signed)
7437 printf (" (%" PRIdMAX ")", (intmax_t) num);
7438
7439 if (valuestr == NULL)
7440 printf ("\n");
7441 else
7442 printf (")\n");
7443 }
7444 }
7445 break;
7446
7447 case DW_FORM_flag:
7448 if (cbargs->silent)
7449 break;
7450 bool flag;
7451 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
7452 goto attrval_out;
7453
7454 printf (" %*s%-20s (%s) %s\n",
7455 (int) (level * 2), "", dwarf_attr_name (attr),
7456 dwarf_form_name (form), flag ? yes_str : no_str);
7457 break;
7458
7459 case DW_FORM_flag_present:
7460 if (cbargs->silent)
7461 break;
7462 printf (" %*s%-20s (%s) %s\n",
7463 (int) (level * 2), "", dwarf_attr_name (attr),
7464 dwarf_form_name (form), yes_str);
7465 break;
7466
7467 case DW_FORM_exprloc:
7468 case DW_FORM_block4:
7469 case DW_FORM_block2:
7470 case DW_FORM_block1:
7471 case DW_FORM_block:
7472 case DW_FORM_data16: /* DWARF5 calls this a constant class. */
7473 if (cbargs->silent)
7474 break;
7475 Dwarf_Block block;
7476 if (unlikely (dwarf_formblock (attrp, &block) != 0))
7477 goto attrval_out;
7478
7479 printf (" %*s%-20s (%s) ",
7480 (int) (level * 2), "", dwarf_attr_name (attr),
7481 dwarf_form_name (form));
7482
7483 switch (attr)
7484 {
7485 default:
7486 if (form != DW_FORM_exprloc)
7487 {
7488 print_block (block.length, block.data);
7489 break;
7490 }
7491 FALLTHROUGH;
7492
7493 case DW_AT_location:
7494 case DW_AT_data_location:
7495 case DW_AT_data_member_location:
7496 case DW_AT_vtable_elem_location:
7497 case DW_AT_string_length:
7498 case DW_AT_use_location:
7499 case DW_AT_frame_base:
7500 case DW_AT_return_addr:
7501 case DW_AT_static_link:
7502 case DW_AT_allocated:
7503 case DW_AT_associated:
7504 case DW_AT_bit_size:
7505 case DW_AT_bit_offset:
7506 case DW_AT_bit_stride:
7507 case DW_AT_byte_size:
7508 case DW_AT_byte_stride:
7509 case DW_AT_count:
7510 case DW_AT_lower_bound:
7511 case DW_AT_upper_bound:
7512 case DW_AT_GNU_call_site_value:
7513 case DW_AT_GNU_call_site_data_value:
7514 case DW_AT_GNU_call_site_target:
7515 case DW_AT_GNU_call_site_target_clobbered:
7516 if (form != DW_FORM_data16)
7517 {
7518 putchar ('\n');
7519 print_ops (cbargs->dwflmod, cbargs->dbg,
7520 12 + level * 2, 12 + level * 2,
7521 cbargs->version, cbargs->addrsize, cbargs->offset_size,
7522 attrp->cu, block.length, block.data);
7523 }
7524 else
7525 print_block (block.length, block.data);
7526 break;
7527 }
7528 break;
7529
7530 default:
7531 if (cbargs->silent)
7532 break;
7533 printf (" %*s%-20s (%s) ???\n",
7534 (int) (level * 2), "", dwarf_attr_name (attr),
7535 dwarf_form_name (form));
7536 break;
7537 }
7538
7539 return DWARF_CB_OK;
7540 }
7541
7542 static void
print_debug_units(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg,bool debug_types)7543 print_debug_units (Dwfl_Module *dwflmod,
7544 Ebl *ebl, GElf_Ehdr *ehdr __attribute__ ((unused)),
7545 Elf_Scn *scn, GElf_Shdr *shdr,
7546 Dwarf *dbg, bool debug_types)
7547 {
7548 const bool silent = !(print_debug_sections & section_info) && !debug_types;
7549 const char *secname = section_name (ebl, shdr);
7550
7551 if (!silent)
7552 printf (gettext ("\
7553 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
7554 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
7555
7556 /* If the section is empty we don't have to do anything. */
7557 if (!silent && shdr->sh_size == 0)
7558 return;
7559
7560 int maxdies = 20;
7561 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
7562
7563 /* New compilation unit. */
7564 Dwarf_Half version;
7565
7566 Dwarf_Die result;
7567 Dwarf_Off abbroffset;
7568 uint8_t addrsize;
7569 uint8_t offsize;
7570 uint64_t unit_id;
7571 Dwarf_Off subdie_off;
7572
7573 int unit_res;
7574 Dwarf_CU *cu;
7575 Dwarf_CU cu_mem;
7576 uint8_t unit_type;
7577 Dwarf_Die cudie;
7578
7579 /* We cheat a little because we want to see only the CUs from .debug_info
7580 or .debug_types. We know the Dwarf_CU struct layout. Set it up at
7581 the end of .debug_info if we want .debug_types only. Check the returned
7582 Dwarf_CU is still in the expected section. */
7583 if (debug_types)
7584 {
7585 cu_mem.dbg = dbg;
7586 cu_mem.end = dbg->sectiondata[IDX_debug_info]->d_size;
7587 cu_mem.sec_idx = IDX_debug_info;
7588 cu = &cu_mem;
7589 }
7590 else
7591 cu = NULL;
7592
7593 next_cu:
7594 unit_res = dwarf_get_units (dbg, cu, &cu, &version, &unit_type,
7595 &cudie, NULL);
7596 if (unit_res == 1)
7597 goto do_return;
7598
7599 if (unit_res == -1)
7600 {
7601 if (!silent)
7602 error (0, 0, gettext ("cannot get next unit: %s"), dwarf_errmsg (-1));
7603 goto do_return;
7604 }
7605
7606 if (cu->sec_idx != (size_t) (debug_types ? IDX_debug_types : IDX_debug_info))
7607 goto do_return;
7608
7609 dwarf_cu_die (cu, &result, NULL, &abbroffset, &addrsize, &offsize,
7610 &unit_id, &subdie_off);
7611
7612 if (!silent)
7613 {
7614 Dwarf_Off offset = cu->start;
7615 if (debug_types && version < 5)
7616 {
7617 Dwarf_Die typedie;
7618 Dwarf_Off dieoffset;
7619 dieoffset = dwarf_dieoffset (dwarf_offdie_types (dbg, subdie_off,
7620 &typedie));
7621 printf (gettext (" Type unit at offset %" PRIu64 ":\n"
7622 " Version: %" PRIu16
7623 ", Abbreviation section offset: %" PRIu64
7624 ", Address size: %" PRIu8
7625 ", Offset size: %" PRIu8
7626 "\n Type signature: %#" PRIx64
7627 ", Type offset: %#" PRIx64 " [%" PRIx64 "]\n"),
7628 (uint64_t) offset, version, abbroffset, addrsize, offsize,
7629 unit_id, (uint64_t) subdie_off, dieoffset);
7630 }
7631 else
7632 {
7633 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
7634 " Version: %" PRIu16
7635 ", Abbreviation section offset: %" PRIu64
7636 ", Address size: %" PRIu8
7637 ", Offset size: %" PRIu8 "\n"),
7638 (uint64_t) offset, version, abbroffset, addrsize, offsize);
7639
7640 if (version >= 5 || (unit_type != DW_UT_compile
7641 && unit_type != DW_UT_partial))
7642 {
7643 printf (gettext (" Unit type: %s (%" PRIu8 ")"),
7644 dwarf_unit_name (unit_type), unit_type);
7645 if (unit_type == DW_UT_type
7646 || unit_type == DW_UT_skeleton
7647 || unit_type == DW_UT_split_compile
7648 || unit_type == DW_UT_split_type)
7649 printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7650 if (unit_type == DW_UT_type
7651 || unit_type == DW_UT_split_type)
7652 {
7653 Dwarf_Die typedie;
7654 Dwarf_Off dieoffset;
7655 dwarf_cu_info (cu, NULL, NULL, NULL, &typedie,
7656 NULL, NULL, NULL);
7657 dieoffset = dwarf_dieoffset (&typedie);
7658 printf (", Unit DIE off: %#" PRIx64 " [%" PRIx64 "]",
7659 subdie_off, dieoffset);
7660 }
7661 printf ("\n");
7662 }
7663 }
7664 }
7665
7666 if (version < 2 || version > 5
7667 || unit_type < DW_UT_compile || unit_type > DW_UT_split_type)
7668 {
7669 if (!silent)
7670 error (0, 0, gettext ("unknown version (%d) or unit type (%d)"),
7671 version, unit_type);
7672 goto next_cu;
7673 }
7674
7675 struct attrcb_args args =
7676 {
7677 .dwflmod = dwflmod,
7678 .silent = silent,
7679 .version = version,
7680 .addrsize = addrsize,
7681 .offset_size = offsize
7682 };
7683
7684 bool is_split = false;
7685 int level = 0;
7686 dies[0] = cudie;
7687 args.cu = dies[0].cu;
7688 args.dbg = dbg;
7689 args.is_split = is_split;
7690
7691 /* We might return here again for the split CU subdie. */
7692 do_cu:
7693 do
7694 {
7695 Dwarf_Off offset = dwarf_dieoffset (&dies[level]);
7696 if (unlikely (offset == (Dwarf_Off) -1))
7697 {
7698 if (!silent)
7699 error (0, 0, gettext ("cannot get DIE offset: %s"),
7700 dwarf_errmsg (-1));
7701 goto do_return;
7702 }
7703
7704 int tag = dwarf_tag (&dies[level]);
7705 if (unlikely (tag == DW_TAG_invalid))
7706 {
7707 if (!silent)
7708 error (0, 0, gettext ("cannot get tag of DIE at offset [%" PRIx64
7709 "] in section '%s': %s"),
7710 (uint64_t) offset, secname, dwarf_errmsg (-1));
7711 goto do_return;
7712 }
7713
7714 if (!silent)
7715 {
7716 unsigned int code = dwarf_getabbrevcode (dies[level].abbrev);
7717 if (is_split)
7718 printf (" {%6" PRIx64 "} ", (uint64_t) offset);
7719 else
7720 printf (" [%6" PRIx64 "] ", (uint64_t) offset);
7721 printf ("%*s%-20s abbrev: %u\n", (int) (level * 2), "",
7722 dwarf_tag_name (tag), code);
7723 }
7724
7725 /* Print the attribute values. */
7726 args.level = level;
7727 args.die = &dies[level];
7728 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
7729
7730 /* Make room for the next level's DIE. */
7731 if (level + 1 == maxdies)
7732 dies = (Dwarf_Die *) xrealloc (dies,
7733 (maxdies += 10)
7734 * sizeof (Dwarf_Die));
7735
7736 int res = dwarf_child (&dies[level], &dies[level + 1]);
7737 if (res > 0)
7738 {
7739 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
7740 if (level-- == 0)
7741 break;
7742
7743 if (unlikely (res == -1))
7744 {
7745 if (!silent)
7746 error (0, 0, gettext ("cannot get next DIE: %s\n"),
7747 dwarf_errmsg (-1));
7748 goto do_return;
7749 }
7750 }
7751 else if (unlikely (res < 0))
7752 {
7753 if (!silent)
7754 error (0, 0, gettext ("cannot get next DIE: %s"),
7755 dwarf_errmsg (-1));
7756 goto do_return;
7757 }
7758 else
7759 ++level;
7760 }
7761 while (level >= 0);
7762
7763 /* We might want to show the split compile unit if this was a skeleton.
7764 We need to scan it if we are requesting printing .debug_ranges for
7765 DWARF4 since GNU DebugFission uses "offsets" into the main ranges
7766 section. */
7767 if (unit_type == DW_UT_skeleton
7768 && ((!silent && show_split_units)
7769 || (version < 5 && (print_debug_sections & section_ranges) != 0)))
7770 {
7771 Dwarf_Die subdie;
7772 if (dwarf_cu_info (cu, NULL, NULL, NULL, &subdie, NULL, NULL, NULL) != 0
7773 || dwarf_tag (&subdie) == DW_TAG_invalid)
7774 {
7775 if (!silent)
7776 {
7777 Dwarf_Attribute dwo_at;
7778 const char *dwo_name =
7779 (dwarf_formstring (dwarf_attr (&cudie, DW_AT_dwo_name,
7780 &dwo_at))
7781 ?: (dwarf_formstring (dwarf_attr (&cudie, DW_AT_GNU_dwo_name,
7782 &dwo_at))
7783 ?: "<unknown>"));
7784 fprintf (stderr,
7785 "Could not find split unit '%s', id: %" PRIx64 "\n",
7786 dwo_name, unit_id);
7787 }
7788 }
7789 else
7790 {
7791 Dwarf_CU *split_cu = subdie.cu;
7792 dwarf_cu_die (split_cu, &result, NULL, &abbroffset,
7793 &addrsize, &offsize, &unit_id, &subdie_off);
7794 Dwarf_Off offset = cu->start;
7795
7796 if (!silent)
7797 {
7798 printf (gettext (" Split compilation unit at offset %"
7799 PRIu64 ":\n"
7800 " Version: %" PRIu16
7801 ", Abbreviation section offset: %" PRIu64
7802 ", Address size: %" PRIu8
7803 ", Offset size: %" PRIu8 "\n"),
7804 (uint64_t) offset, version, abbroffset,
7805 addrsize, offsize);
7806 printf (gettext (" Unit type: %s (%" PRIu8 ")"),
7807 dwarf_unit_name (unit_type), unit_type);
7808 printf (", Unit id: 0x%.16" PRIx64 "", unit_id);
7809 printf ("\n");
7810 }
7811
7812 unit_type = DW_UT_split_compile;
7813 is_split = true;
7814 level = 0;
7815 dies[0] = subdie;
7816 args.cu = dies[0].cu;
7817 args.dbg = split_cu->dbg;
7818 args.is_split = is_split;
7819 goto do_cu;
7820 }
7821 }
7822
7823 /* And again... */
7824 goto next_cu;
7825
7826 do_return:
7827 free (dies);
7828 }
7829
7830 static void
print_debug_info_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7831 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7832 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7833 {
7834 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
7835 }
7836
7837 static void
print_debug_types_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7838 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
7839 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7840 {
7841 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
7842 }
7843
7844
7845 static void
print_decoded_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7846 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl,
7847 GElf_Ehdr *ehdr __attribute__ ((unused)),
7848 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7849 {
7850 printf (gettext ("\
7851 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
7852 elf_ndxscn (scn), section_name (ebl, shdr),
7853 (uint64_t) shdr->sh_offset);
7854
7855 size_t address_size
7856 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
7857
7858 Dwarf_Lines *lines;
7859 size_t nlines;
7860 Dwarf_Off off, next_off = 0;
7861 Dwarf_CU *cu = NULL;
7862 while (dwarf_next_lines (dbg, off = next_off, &next_off, &cu, NULL, NULL,
7863 &lines, &nlines) == 0)
7864 {
7865 Dwarf_Die cudie;
7866 if (cu != NULL && dwarf_cu_info (cu, NULL, NULL, &cudie,
7867 NULL, NULL, NULL, NULL) == 0)
7868 printf (" CU [%" PRIx64 "] %s\n",
7869 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
7870 else
7871 {
7872 /* DWARF5 lines can be independent of any CU, but they probably
7873 are used by some CU. Determine the CU this block is for. */
7874 Dwarf_Off cuoffset;
7875 Dwarf_Off ncuoffset = 0;
7876 size_t hsize;
7877 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
7878 NULL, NULL, NULL) == 0)
7879 {
7880 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
7881 continue;
7882 Dwarf_Attribute stmt_list;
7883 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
7884 continue;
7885 Dwarf_Word lineoff;
7886 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
7887 continue;
7888 if (lineoff == off)
7889 {
7890 /* Found the CU. */
7891 cu = cudie.cu;
7892 break;
7893 }
7894 }
7895
7896 if (cu != NULL)
7897 printf (" CU [%" PRIx64 "] %s\n",
7898 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
7899 else
7900 printf (" No CU\n");
7901 }
7902
7903 printf (" line:col SBPE* disc isa op address"
7904 " (Statement Block Prologue Epilogue *End)\n");
7905 const char *last_file = "";
7906 for (size_t n = 0; n < nlines; n++)
7907 {
7908 Dwarf_Line *line = dwarf_onesrcline (lines, n);
7909 if (line == NULL)
7910 {
7911 printf (" dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
7912 continue;
7913 }
7914 Dwarf_Word mtime, length;
7915 const char *file = dwarf_linesrc (line, &mtime, &length);
7916 if (file == NULL)
7917 {
7918 printf (" <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
7919 last_file = "";
7920 }
7921 else if (strcmp (last_file, file) != 0)
7922 {
7923 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
7924 file, mtime, length);
7925 last_file = file;
7926 }
7927
7928 int lineno, colno;
7929 bool statement, endseq, block, prologue_end, epilogue_begin;
7930 unsigned int lineop, isa, disc;
7931 Dwarf_Addr address;
7932 dwarf_lineaddr (line, &address);
7933 dwarf_lineno (line, &lineno);
7934 dwarf_linecol (line, &colno);
7935 dwarf_lineop_index (line, &lineop);
7936 dwarf_linebeginstatement (line, &statement);
7937 dwarf_lineendsequence (line, &endseq);
7938 dwarf_lineblock (line, &block);
7939 dwarf_lineprologueend (line, &prologue_end);
7940 dwarf_lineepiloguebegin (line, &epilogue_begin);
7941 dwarf_lineisa (line, &isa);
7942 dwarf_linediscriminator (line, &disc);
7943
7944 /* End sequence is special, it is one byte past. */
7945 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d ",
7946 lineno, colno,
7947 (statement ? 'S' : ' '),
7948 (block ? 'B' : ' '),
7949 (prologue_end ? 'P' : ' '),
7950 (epilogue_begin ? 'E' : ' '),
7951 (endseq ? '*' : ' '),
7952 disc, isa, lineop);
7953 print_dwarf_addr (dwflmod, address_size,
7954 address - (endseq ? 1 : 0), address);
7955 printf ("\n");
7956
7957 if (endseq)
7958 printf("\n");
7959 }
7960 }
7961 }
7962
7963
7964 /* Print the value of a form.
7965 Returns new value of readp, or readendp on failure. */
7966 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)7967 print_form_data (Dwarf *dbg, int form, const unsigned char *readp,
7968 const unsigned char *readendp, unsigned int offset_len,
7969 Dwarf_Off str_offsets_base)
7970 {
7971 Dwarf_Word val;
7972 unsigned char *endp;
7973 Elf_Data *data;
7974 char *str;
7975 switch (form)
7976 {
7977 case DW_FORM_data1:
7978 if (readendp - readp < 1)
7979 {
7980 invalid_data:
7981 error (0, 0, "invalid data");
7982 return readendp;
7983 }
7984 val = *readp++;
7985 printf (" %" PRIx8, (unsigned int) val);
7986 break;
7987
7988 case DW_FORM_data2:
7989 if (readendp - readp < 2)
7990 goto invalid_data;
7991 val = read_2ubyte_unaligned_inc (dbg, readp);
7992 printf(" %" PRIx16, (unsigned int) val);
7993 break;
7994
7995 case DW_FORM_data4:
7996 if (readendp - readp < 4)
7997 goto invalid_data;
7998 val = read_4ubyte_unaligned_inc (dbg, readp);
7999 printf (" %" PRIx32, (unsigned int) val);
8000 break;
8001
8002 case DW_FORM_data8:
8003 if (readendp - readp < 8)
8004 goto invalid_data;
8005 val = read_8ubyte_unaligned_inc (dbg, readp);
8006 printf (" %" PRIx64, val);
8007 break;
8008
8009 case DW_FORM_sdata:
8010 if (readendp - readp < 1)
8011 goto invalid_data;
8012 get_sleb128 (val, readp, readendp);
8013 printf (" %" PRIx64, val);
8014 break;
8015
8016 case DW_FORM_udata:
8017 if (readendp - readp < 1)
8018 goto invalid_data;
8019 get_uleb128 (val, readp, readendp);
8020 printf (" %" PRIx64, val);
8021 break;
8022
8023 case DW_FORM_block:
8024 if (readendp - readp < 1)
8025 goto invalid_data;
8026 get_uleb128 (val, readp, readendp);
8027 if ((size_t) (readendp - readp) < val)
8028 goto invalid_data;
8029 print_bytes (val, readp);
8030 readp += val;
8031 break;
8032
8033 case DW_FORM_block1:
8034 if (readendp - readp < 1)
8035 goto invalid_data;
8036 val = *readp++;
8037 if ((size_t) (readendp - readp) < val)
8038 goto invalid_data;
8039 print_bytes (val, readp);
8040 readp += val;
8041 break;
8042
8043 case DW_FORM_block2:
8044 if (readendp - readp < 2)
8045 goto invalid_data;
8046 val = read_2ubyte_unaligned_inc (dbg, readp);
8047 if ((size_t) (readendp - readp) < val)
8048 goto invalid_data;
8049 print_bytes (val, readp);
8050 readp += val;
8051 break;
8052
8053 case DW_FORM_block4:
8054 if (readendp - readp < 4)
8055 goto invalid_data;
8056 val = read_4ubyte_unaligned_inc (dbg, readp);
8057 if ((size_t) (readendp - readp) < val)
8058 goto invalid_data;
8059 print_bytes (val, readp);
8060 readp += val;
8061 break;
8062
8063 case DW_FORM_data16:
8064 if (readendp - readp < 16)
8065 goto invalid_data;
8066 print_bytes (16, readp);
8067 readp += 16;
8068 break;
8069
8070 case DW_FORM_flag:
8071 if (readendp - readp < 1)
8072 goto invalid_data;
8073 val = *readp++;
8074 printf ("%s", val != 0 ? yes_str : no_str);
8075 break;
8076
8077 case DW_FORM_string:
8078 endp = memchr (readp, '\0', readendp - readp);
8079 if (endp == NULL)
8080 goto invalid_data;
8081 printf ("%s", readp);
8082 readp = endp + 1;
8083 break;
8084
8085 case DW_FORM_strp:
8086 case DW_FORM_line_strp:
8087 case DW_FORM_strp_sup:
8088 if ((size_t) (readendp - readp) < offset_len)
8089 goto invalid_data;
8090 if (offset_len == 8)
8091 val = read_8ubyte_unaligned_inc (dbg, readp);
8092 else
8093 val = read_4ubyte_unaligned_inc (dbg, readp);
8094 if (form == DW_FORM_strp)
8095 data = dbg->sectiondata[IDX_debug_str];
8096 else if (form == DW_FORM_line_strp)
8097 data = dbg->sectiondata[IDX_debug_line_str];
8098 else /* form == DW_FORM_strp_sup */
8099 {
8100 Dwarf *alt = dwarf_getalt (dbg);
8101 data = alt != NULL ? alt->sectiondata[IDX_debug_str] : NULL;
8102 }
8103 if (data == NULL || val >= data->d_size
8104 || memchr (data->d_buf + val, '\0', data->d_size - val) == NULL)
8105 str = "???";
8106 else
8107 str = (char *) data->d_buf + val;
8108 printf ("%s (%" PRIu64 ")", str, val);
8109 break;
8110
8111 case DW_FORM_sec_offset:
8112 if ((size_t) (readendp - readp) < offset_len)
8113 goto invalid_data;
8114 if (offset_len == 8)
8115 val = read_8ubyte_unaligned_inc (dbg, readp);
8116 else
8117 val = read_4ubyte_unaligned_inc (dbg, readp);
8118 printf ("[%" PRIx64 "]", val);
8119 break;
8120
8121 case DW_FORM_strx:
8122 case DW_FORM_GNU_str_index:
8123 if (readendp - readp < 1)
8124 goto invalid_data;
8125 get_uleb128 (val, readp, readendp);
8126 strx_val:
8127 data = dbg->sectiondata[IDX_debug_str_offsets];
8128 if (data == NULL
8129 || data->d_size - str_offsets_base < val)
8130 str = "???";
8131 else
8132 {
8133 const unsigned char *strreadp = data->d_buf + str_offsets_base + val;
8134 const unsigned char *strreadendp = data->d_buf + data->d_size;
8135 if ((size_t) (strreadendp - strreadp) < offset_len)
8136 str = "???";
8137 else
8138 {
8139 Dwarf_Off idx;
8140 if (offset_len == 8)
8141 idx = read_8ubyte_unaligned (dbg, strreadp);
8142 else
8143 idx = read_4ubyte_unaligned (dbg, strreadp);
8144
8145 data = dbg->sectiondata[IDX_debug_str];
8146 if (data == NULL || idx >= data->d_size
8147 || memchr (data->d_buf + idx, '\0',
8148 data->d_size - idx) == NULL)
8149 str = "???";
8150 else
8151 str = (char *) data->d_buf + idx;
8152 }
8153 }
8154 printf ("%s (%" PRIu64 ")", str, val);
8155 break;
8156
8157 case DW_FORM_strx1:
8158 if (readendp - readp < 1)
8159 goto invalid_data;
8160 val = *readp++;
8161 goto strx_val;
8162
8163 case DW_FORM_strx2:
8164 if (readendp - readp < 2)
8165 goto invalid_data;
8166 val = read_2ubyte_unaligned_inc (dbg, readp);
8167 goto strx_val;
8168
8169 case DW_FORM_strx3:
8170 if (readendp - readp < 3)
8171 goto invalid_data;
8172 val = read_3ubyte_unaligned_inc (dbg, readp);
8173 goto strx_val;
8174
8175 case DW_FORM_strx4:
8176 if (readendp - readp < 4)
8177 goto invalid_data;
8178 val = read_4ubyte_unaligned_inc (dbg, readp);
8179 goto strx_val;
8180
8181 default:
8182 error (0, 0, gettext ("unknown form: %s"), dwarf_form_name (form));
8183 return readendp;
8184 }
8185
8186 return readp;
8187 }
8188
8189 static void
print_debug_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8190 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8191 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8192 {
8193 if (decodedline)
8194 {
8195 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
8196 return;
8197 }
8198
8199 printf (gettext ("\
8200 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
8201 elf_ndxscn (scn), section_name (ebl, shdr),
8202 (uint64_t) shdr->sh_offset);
8203
8204 if (shdr->sh_size == 0)
8205 return;
8206
8207 /* There is no functionality in libdw to read the information in the
8208 way it is represented here. Hardcode the decoder. */
8209 Elf_Data *data = (dbg->sectiondata[IDX_debug_line]
8210 ?: elf_rawdata (scn, NULL));
8211 if (unlikely (data == NULL))
8212 {
8213 error (0, 0, gettext ("cannot get line data section data: %s"),
8214 elf_errmsg (-1));
8215 return;
8216 }
8217
8218 const unsigned char *linep = (const unsigned char *) data->d_buf;
8219 const unsigned char *lineendp;
8220
8221 while (linep
8222 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
8223 {
8224 size_t start_offset = linep - (const unsigned char *) data->d_buf;
8225
8226 printf (gettext ("\nTable at offset %zu:\n"), start_offset);
8227
8228 if (unlikely (linep + 4 > lineendp))
8229 goto invalid_data;
8230 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
8231 unsigned int length = 4;
8232 if (unlikely (unit_length == 0xffffffff))
8233 {
8234 if (unlikely (linep + 8 > lineendp))
8235 {
8236 invalid_data:
8237 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
8238 elf_ndxscn (scn), section_name (ebl, shdr));
8239 return;
8240 }
8241 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
8242 length = 8;
8243 }
8244
8245 /* Check whether we have enough room in the section. */
8246 if (unlikely (unit_length > (size_t) (lineendp - linep)))
8247 goto invalid_data;
8248 lineendp = linep + unit_length;
8249
8250 /* The next element of the header is the version identifier. */
8251 if ((size_t) (lineendp - linep) < 2)
8252 goto invalid_data;
8253 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
8254
8255 size_t address_size
8256 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
8257 unsigned char segment_selector_size = 0;
8258 if (version > 4)
8259 {
8260 if ((size_t) (lineendp - linep) < 2)
8261 goto invalid_data;
8262 address_size = *linep++;
8263 segment_selector_size = *linep++;
8264 }
8265
8266 /* Next comes the header length. */
8267 Dwarf_Word header_length;
8268 if (length == 4)
8269 {
8270 if ((size_t) (lineendp - linep) < 4)
8271 goto invalid_data;
8272 header_length = read_4ubyte_unaligned_inc (dbg, linep);
8273 }
8274 else
8275 {
8276 if ((size_t) (lineendp - linep) < 8)
8277 goto invalid_data;
8278 header_length = read_8ubyte_unaligned_inc (dbg, linep);
8279 }
8280
8281 /* Next the minimum instruction length. */
8282 if ((size_t) (lineendp - linep) < 1)
8283 goto invalid_data;
8284 uint_fast8_t minimum_instr_len = *linep++;
8285
8286 /* Next the maximum operations per instruction, in version 4 format. */
8287 uint_fast8_t max_ops_per_instr;
8288 if (version < 4)
8289 max_ops_per_instr = 1;
8290 else
8291 {
8292 if ((size_t) (lineendp - linep) < 1)
8293 goto invalid_data;
8294 max_ops_per_instr = *linep++;
8295 }
8296
8297 /* We need at least 4 more bytes. */
8298 if ((size_t) (lineendp - linep) < 4)
8299 goto invalid_data;
8300
8301 /* Then the flag determining the default value of the is_stmt
8302 register. */
8303 uint_fast8_t default_is_stmt = *linep++;
8304
8305 /* Now the line base. */
8306 int_fast8_t line_base = *linep++;
8307
8308 /* And the line range. */
8309 uint_fast8_t line_range = *linep++;
8310
8311 /* The opcode base. */
8312 uint_fast8_t opcode_base = *linep++;
8313
8314 /* Print what we got so far. */
8315 printf (gettext ("\n"
8316 " Length: %" PRIu64 "\n"
8317 " DWARF version: %" PRIuFAST16 "\n"
8318 " Prologue length: %" PRIu64 "\n"
8319 " Address size: %zd\n"
8320 " Segment selector size: %zd\n"
8321 " Min instruction length: %" PRIuFAST8 "\n"
8322 " Max operations per instruction: %" PRIuFAST8 "\n"
8323 " Initial value if 'is_stmt': %" PRIuFAST8 "\n"
8324 " Line base: %" PRIdFAST8 "\n"
8325 " Line range: %" PRIuFAST8 "\n"
8326 " Opcode base: %" PRIuFAST8 "\n"
8327 "\n"
8328 "Opcodes:\n"),
8329 (uint64_t) unit_length, version, (uint64_t) header_length,
8330 address_size, (size_t) segment_selector_size,
8331 minimum_instr_len, max_ops_per_instr,
8332 default_is_stmt, line_base,
8333 line_range, opcode_base);
8334
8335 if (version < 2 || version > 5)
8336 {
8337 error (0, 0, gettext ("cannot handle .debug_line version: %u\n"),
8338 (unsigned int) version);
8339 linep = lineendp;
8340 continue;
8341 }
8342
8343 if (address_size != 4 && address_size != 8)
8344 {
8345 error (0, 0, gettext ("cannot handle address size: %u\n"),
8346 (unsigned int) address_size);
8347 linep = lineendp;
8348 continue;
8349 }
8350
8351 if (segment_selector_size != 0)
8352 {
8353 error (0, 0, gettext ("cannot handle segment selector size: %u\n"),
8354 (unsigned int) segment_selector_size);
8355 linep = lineendp;
8356 continue;
8357 }
8358
8359 if (unlikely (linep + opcode_base - 1 >= lineendp))
8360 {
8361 invalid_unit:
8362 error (0, 0,
8363 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
8364 linep - (const unsigned char *) data->d_buf,
8365 elf_ndxscn (scn), section_name (ebl, shdr));
8366 linep = lineendp;
8367 continue;
8368 }
8369 int opcode_base_l10 = 1;
8370 unsigned int tmp = opcode_base;
8371 while (tmp > 10)
8372 {
8373 tmp /= 10;
8374 ++opcode_base_l10;
8375 }
8376 const uint8_t *standard_opcode_lengths = linep - 1;
8377 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
8378 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
8379 " [%*" PRIuFAST8 "] %hhu arguments\n",
8380 (int) linep[cnt - 1]),
8381 opcode_base_l10, cnt, linep[cnt - 1]);
8382 linep += opcode_base - 1;
8383
8384 if (unlikely (linep >= lineendp))
8385 goto invalid_unit;
8386
8387 Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, NULL);
8388
8389 puts (gettext ("\nDirectory table:"));
8390 if (version > 4)
8391 {
8392 struct encpair { uint16_t desc; uint16_t form; };
8393 struct encpair enc[256];
8394
8395 printf (gettext (" ["));
8396 if ((size_t) (lineendp - linep) < 1)
8397 goto invalid_data;
8398 unsigned char directory_entry_format_count = *linep++;
8399 for (int i = 0; i < directory_entry_format_count; i++)
8400 {
8401 uint16_t desc, form;
8402 if ((size_t) (lineendp - linep) < 1)
8403 goto invalid_data;
8404 get_uleb128 (desc, linep, lineendp);
8405 if ((size_t) (lineendp - linep) < 1)
8406 goto invalid_data;
8407 get_uleb128 (form, linep, lineendp);
8408
8409 enc[i].desc = desc;
8410 enc[i].form = form;
8411
8412 printf ("%s(%s)",
8413 dwarf_line_content_description_name (desc),
8414 dwarf_form_name (form));
8415 if (i + 1 < directory_entry_format_count)
8416 printf (", ");
8417 }
8418 printf ("]\n");
8419
8420 uint64_t directories_count;
8421 if ((size_t) (lineendp - linep) < 1)
8422 goto invalid_data;
8423 get_uleb128 (directories_count, linep, lineendp);
8424
8425 if (directory_entry_format_count == 0
8426 && directories_count != 0)
8427 goto invalid_data;
8428
8429 for (uint64_t i = 0; i < directories_count; i++)
8430 {
8431 printf (" %-5" PRIu64 " ", i);
8432 for (int j = 0; j < directory_entry_format_count; j++)
8433 {
8434 linep = print_form_data (dbg, enc[j].form,
8435 linep, lineendp, length,
8436 str_offsets_base);
8437 if (j + 1 < directory_entry_format_count)
8438 printf (", ");
8439 }
8440 printf ("\n");
8441 if (linep >= lineendp)
8442 goto invalid_unit;
8443 }
8444 }
8445 else
8446 {
8447 while (linep < lineendp && *linep != 0)
8448 {
8449 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
8450 if (unlikely (endp == NULL))
8451 goto invalid_unit;
8452
8453 printf (" %s\n", (char *) linep);
8454
8455 linep = endp + 1;
8456 }
8457 if (linep >= lineendp || *linep != 0)
8458 goto invalid_unit;
8459 /* Skip the final NUL byte. */
8460 ++linep;
8461 }
8462
8463 if (unlikely (linep >= lineendp))
8464 goto invalid_unit;
8465
8466 puts (gettext ("\nFile name table:"));
8467 if (version > 4)
8468 {
8469 struct encpair { uint16_t desc; uint16_t form; };
8470 struct encpair enc[256];
8471
8472 printf (gettext (" ["));
8473 if ((size_t) (lineendp - linep) < 1)
8474 goto invalid_data;
8475 unsigned char file_name_format_count = *linep++;
8476 for (int i = 0; i < file_name_format_count; i++)
8477 {
8478 uint64_t desc, form;
8479 if ((size_t) (lineendp - linep) < 1)
8480 goto invalid_data;
8481 get_uleb128 (desc, linep, lineendp);
8482 if ((size_t) (lineendp - linep) < 1)
8483 goto invalid_data;
8484 get_uleb128 (form, linep, lineendp);
8485
8486 if (! libdw_valid_user_form (form))
8487 goto invalid_data;
8488
8489 enc[i].desc = desc;
8490 enc[i].form = form;
8491
8492 printf ("%s(%s)",
8493 dwarf_line_content_description_name (desc),
8494 dwarf_form_name (form));
8495 if (i + 1 < file_name_format_count)
8496 printf (", ");
8497 }
8498 printf ("]\n");
8499
8500 uint64_t file_name_count;
8501 if ((size_t) (lineendp - linep) < 1)
8502 goto invalid_data;
8503 get_uleb128 (file_name_count, linep, lineendp);
8504
8505 if (file_name_format_count == 0
8506 && file_name_count != 0)
8507 goto invalid_data;
8508
8509 for (uint64_t i = 0; i < file_name_count; i++)
8510 {
8511 printf (" %-5" PRIu64 " ", i);
8512 for (int j = 0; j < file_name_format_count; j++)
8513 {
8514 linep = print_form_data (dbg, enc[j].form,
8515 linep, lineendp, length,
8516 str_offsets_base);
8517 if (j + 1 < file_name_format_count)
8518 printf (", ");
8519 }
8520 printf ("\n");
8521 if (linep >= lineendp)
8522 goto invalid_unit;
8523 }
8524 }
8525 else
8526 {
8527 puts (gettext (" Entry Dir Time Size Name"));
8528 for (unsigned int cnt = 1; linep < lineendp && *linep != 0; ++cnt)
8529 {
8530 /* First comes the file name. */
8531 char *fname = (char *) linep;
8532 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
8533 if (unlikely (endp == NULL))
8534 goto invalid_unit;
8535 linep = endp + 1;
8536
8537 /* Then the index. */
8538 unsigned int diridx;
8539 if (lineendp - linep < 1)
8540 goto invalid_unit;
8541 get_uleb128 (diridx, linep, lineendp);
8542
8543 /* Next comes the modification time. */
8544 unsigned int mtime;
8545 if (lineendp - linep < 1)
8546 goto invalid_unit;
8547 get_uleb128 (mtime, linep, lineendp);
8548
8549 /* Finally the length of the file. */
8550 unsigned int fsize;
8551 if (lineendp - linep < 1)
8552 goto invalid_unit;
8553 get_uleb128 (fsize, linep, lineendp);
8554
8555 printf (" %-5u %-5u %-9u %-9u %s\n",
8556 cnt, diridx, mtime, fsize, fname);
8557 }
8558 if (linep >= lineendp || *linep != '\0')
8559 goto invalid_unit;
8560 /* Skip the final NUL byte. */
8561 ++linep;
8562 }
8563
8564 puts (gettext ("\nLine number statements:"));
8565 Dwarf_Word address = 0;
8566 unsigned int op_index = 0;
8567 size_t line = 1;
8568 uint_fast8_t is_stmt = default_is_stmt;
8569
8570 /* Apply the "operation advance" from a special opcode
8571 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
8572 unsigned int op_addr_advance;
8573 bool show_op_index;
8574 inline void advance_pc (unsigned int op_advance)
8575 {
8576 op_addr_advance = minimum_instr_len * ((op_index + op_advance)
8577 / max_ops_per_instr);
8578 address += op_addr_advance;
8579 show_op_index = (op_index > 0 ||
8580 (op_index + op_advance) % max_ops_per_instr > 0);
8581 op_index = (op_index + op_advance) % max_ops_per_instr;
8582 }
8583
8584 if (max_ops_per_instr == 0)
8585 {
8586 error (0, 0,
8587 gettext ("invalid maximum operations per instruction is zero"));
8588 linep = lineendp;
8589 continue;
8590 }
8591
8592 while (linep < lineendp)
8593 {
8594 size_t offset = linep - (const unsigned char *) data->d_buf;
8595 unsigned int u128;
8596 int s128;
8597
8598 /* Read the opcode. */
8599 unsigned int opcode = *linep++;
8600
8601 printf (" [%6" PRIx64 "]", (uint64_t)offset);
8602 /* Is this a special opcode? */
8603 if (likely (opcode >= opcode_base))
8604 {
8605 if (unlikely (line_range == 0))
8606 goto invalid_unit;
8607
8608 /* Yes. Handling this is quite easy since the opcode value
8609 is computed with
8610
8611 opcode = (desired line increment - line_base)
8612 + (line_range * address advance) + opcode_base
8613 */
8614 int line_increment = (line_base
8615 + (opcode - opcode_base) % line_range);
8616
8617 /* Perform the increments. */
8618 line += line_increment;
8619 advance_pc ((opcode - opcode_base) / line_range);
8620
8621 printf (gettext (" special opcode %u: address+%u = "),
8622 opcode, op_addr_advance);
8623 print_dwarf_addr (dwflmod, 0, address, address);
8624 if (show_op_index)
8625 printf (gettext (", op_index = %u, line%+d = %zu\n"),
8626 op_index, line_increment, line);
8627 else
8628 printf (gettext (", line%+d = %zu\n"),
8629 line_increment, line);
8630 }
8631 else if (opcode == 0)
8632 {
8633 /* This an extended opcode. */
8634 if (unlikely (linep + 2 > lineendp))
8635 goto invalid_unit;
8636
8637 /* The length. */
8638 unsigned int len = *linep++;
8639
8640 if (unlikely (linep + len > lineendp))
8641 goto invalid_unit;
8642
8643 /* The sub-opcode. */
8644 opcode = *linep++;
8645
8646 printf (gettext (" extended opcode %u: "), opcode);
8647
8648 switch (opcode)
8649 {
8650 case DW_LNE_end_sequence:
8651 puts (gettext (" end of sequence"));
8652
8653 /* Reset the registers we care about. */
8654 address = 0;
8655 op_index = 0;
8656 line = 1;
8657 is_stmt = default_is_stmt;
8658 break;
8659
8660 case DW_LNE_set_address:
8661 op_index = 0;
8662 if (unlikely ((size_t) (lineendp - linep) < address_size))
8663 goto invalid_unit;
8664 if (address_size == 4)
8665 address = read_4ubyte_unaligned_inc (dbg, linep);
8666 else
8667 address = read_8ubyte_unaligned_inc (dbg, linep);
8668 {
8669 printf (gettext (" set address to "));
8670 print_dwarf_addr (dwflmod, 0, address, address);
8671 printf ("\n");
8672 }
8673 break;
8674
8675 case DW_LNE_define_file:
8676 {
8677 char *fname = (char *) linep;
8678 unsigned char *endp = memchr (linep, '\0',
8679 lineendp - linep);
8680 if (unlikely (endp == NULL))
8681 goto invalid_unit;
8682 linep = endp + 1;
8683
8684 unsigned int diridx;
8685 if (lineendp - linep < 1)
8686 goto invalid_unit;
8687 get_uleb128 (diridx, linep, lineendp);
8688 Dwarf_Word mtime;
8689 if (lineendp - linep < 1)
8690 goto invalid_unit;
8691 get_uleb128 (mtime, linep, lineendp);
8692 Dwarf_Word filelength;
8693 if (lineendp - linep < 1)
8694 goto invalid_unit;
8695 get_uleb128 (filelength, linep, lineendp);
8696
8697 printf (gettext ("\
8698 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
8699 diridx, (uint64_t) mtime, (uint64_t) filelength,
8700 fname);
8701 }
8702 break;
8703
8704 case DW_LNE_set_discriminator:
8705 /* Takes one ULEB128 parameter, the discriminator. */
8706 if (unlikely (standard_opcode_lengths[opcode] != 1
8707 || lineendp - linep < 1))
8708 goto invalid_unit;
8709
8710 get_uleb128 (u128, linep, lineendp);
8711 printf (gettext (" set discriminator to %u\n"), u128);
8712 break;
8713
8714 default:
8715 /* Unknown, ignore it. */
8716 puts (gettext (" unknown opcode"));
8717 linep += len - 1;
8718 break;
8719 }
8720 }
8721 else if (opcode <= DW_LNS_set_isa)
8722 {
8723 /* This is a known standard opcode. */
8724 switch (opcode)
8725 {
8726 case DW_LNS_copy:
8727 /* Takes no argument. */
8728 puts (gettext (" copy"));
8729 break;
8730
8731 case DW_LNS_advance_pc:
8732 /* Takes one uleb128 parameter which is added to the
8733 address. */
8734 if (lineendp - linep < 1)
8735 goto invalid_unit;
8736 get_uleb128 (u128, linep, lineendp);
8737 advance_pc (u128);
8738 {
8739 printf (gettext (" advance address by %u to "),
8740 op_addr_advance);
8741 print_dwarf_addr (dwflmod, 0, address, address);
8742 if (show_op_index)
8743 printf (gettext (", op_index to %u"), op_index);
8744 printf ("\n");
8745 }
8746 break;
8747
8748 case DW_LNS_advance_line:
8749 /* Takes one sleb128 parameter which is added to the
8750 line. */
8751 if (lineendp - linep < 1)
8752 goto invalid_unit;
8753 get_sleb128 (s128, linep, lineendp);
8754 line += s128;
8755 printf (gettext ("\
8756 advance line by constant %d to %" PRId64 "\n"),
8757 s128, (int64_t) line);
8758 break;
8759
8760 case DW_LNS_set_file:
8761 /* Takes one uleb128 parameter which is stored in file. */
8762 if (lineendp - linep < 1)
8763 goto invalid_unit;
8764 get_uleb128 (u128, linep, lineendp);
8765 printf (gettext (" set file to %" PRIu64 "\n"),
8766 (uint64_t) u128);
8767 break;
8768
8769 case DW_LNS_set_column:
8770 /* Takes one uleb128 parameter which is stored in column. */
8771 if (unlikely (standard_opcode_lengths[opcode] != 1
8772 || lineendp - linep < 1))
8773 goto invalid_unit;
8774
8775 get_uleb128 (u128, linep, lineendp);
8776 printf (gettext (" set column to %" PRIu64 "\n"),
8777 (uint64_t) u128);
8778 break;
8779
8780 case DW_LNS_negate_stmt:
8781 /* Takes no argument. */
8782 is_stmt = 1 - is_stmt;
8783 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
8784 "is_stmt", is_stmt);
8785 break;
8786
8787 case DW_LNS_set_basic_block:
8788 /* Takes no argument. */
8789 puts (gettext (" set basic block flag"));
8790 break;
8791
8792 case DW_LNS_const_add_pc:
8793 /* Takes no argument. */
8794
8795 if (unlikely (line_range == 0))
8796 goto invalid_unit;
8797
8798 advance_pc ((255 - opcode_base) / line_range);
8799 {
8800 printf (gettext (" advance address by constant %u to "),
8801 op_addr_advance);
8802 print_dwarf_addr (dwflmod, 0, address, address);
8803 if (show_op_index)
8804 printf (gettext (", op_index to %u"), op_index);
8805 printf ("\n");
8806 }
8807 break;
8808
8809 case DW_LNS_fixed_advance_pc:
8810 /* Takes one 16 bit parameter which is added to the
8811 address. */
8812 if (unlikely (standard_opcode_lengths[opcode] != 1
8813 || lineendp - linep < 2))
8814 goto invalid_unit;
8815
8816 u128 = read_2ubyte_unaligned_inc (dbg, linep);
8817 address += u128;
8818 op_index = 0;
8819 {
8820 printf (gettext ("\
8821 advance address by fixed value %u to \n"),
8822 u128);
8823 print_dwarf_addr (dwflmod, 0, address, address);
8824 printf ("\n");
8825 }
8826 break;
8827
8828 case DW_LNS_set_prologue_end:
8829 /* Takes no argument. */
8830 puts (gettext (" set prologue end flag"));
8831 break;
8832
8833 case DW_LNS_set_epilogue_begin:
8834 /* Takes no argument. */
8835 puts (gettext (" set epilogue begin flag"));
8836 break;
8837
8838 case DW_LNS_set_isa:
8839 /* Takes one uleb128 parameter which is stored in isa. */
8840 if (unlikely (standard_opcode_lengths[opcode] != 1
8841 || lineendp - linep < 1))
8842 goto invalid_unit;
8843
8844 get_uleb128 (u128, linep, lineendp);
8845 printf (gettext (" set isa to %u\n"), u128);
8846 break;
8847 }
8848 }
8849 else
8850 {
8851 /* This is a new opcode the generator but not we know about.
8852 Read the parameters associated with it but then discard
8853 everything. Read all the parameters for this opcode. */
8854 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
8855 " unknown opcode with %" PRIu8 " parameters:",
8856 standard_opcode_lengths[opcode]),
8857 standard_opcode_lengths[opcode]);
8858 for (int n = standard_opcode_lengths[opcode];
8859 n > 0 && linep < lineendp; --n)
8860 {
8861 get_uleb128 (u128, linep, lineendp);
8862 if (n != standard_opcode_lengths[opcode])
8863 putc_unlocked (',', stdout);
8864 printf (" %u", u128);
8865 }
8866
8867 /* Next round, ignore this opcode. */
8868 continue;
8869 }
8870 }
8871 }
8872
8873 /* There must only be one data block. */
8874 assert (elf_getdata (scn, data) == NULL);
8875 }
8876
8877
8878 static void
print_debug_loclists_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8879 print_debug_loclists_section (Dwfl_Module *dwflmod,
8880 Ebl *ebl,
8881 GElf_Ehdr *ehdr __attribute__ ((unused)),
8882 Elf_Scn *scn, GElf_Shdr *shdr,
8883 Dwarf *dbg)
8884 {
8885 printf (gettext ("\
8886 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
8887 elf_ndxscn (scn), section_name (ebl, shdr),
8888 (uint64_t) shdr->sh_offset);
8889
8890 Elf_Data *data = (dbg->sectiondata[IDX_debug_loclists]
8891 ?: elf_rawdata (scn, NULL));
8892 if (unlikely (data == NULL))
8893 {
8894 error (0, 0, gettext ("cannot get .debug_loclists content: %s"),
8895 elf_errmsg (-1));
8896 return;
8897 }
8898
8899 /* For the listptr to get the base address/CU. */
8900 sort_listptr (&known_loclistsptr, "loclistsptr");
8901 size_t listptr_idx = 0;
8902
8903 const unsigned char *readp = data->d_buf;
8904 const unsigned char *const dataend = ((unsigned char *) data->d_buf
8905 + data->d_size);
8906 while (readp < dataend)
8907 {
8908 if (unlikely (readp > dataend - 4))
8909 {
8910 invalid_data:
8911 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
8912 elf_ndxscn (scn), section_name (ebl, shdr));
8913 return;
8914 }
8915
8916 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
8917 printf (gettext ("Table at Offset 0x%" PRIx64 ":\n\n"),
8918 (uint64_t) offset);
8919
8920 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
8921 unsigned int offset_size = 4;
8922 if (unlikely (unit_length == 0xffffffff))
8923 {
8924 if (unlikely (readp > dataend - 8))
8925 goto invalid_data;
8926
8927 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
8928 offset_size = 8;
8929 }
8930 printf (gettext (" Length: %8" PRIu64 "\n"), unit_length);
8931
8932 /* We need at least 2-bytes + 1-byte + 1-byte + 4-bytes = 8
8933 bytes to complete the header. And this unit cannot go beyond
8934 the section data. */
8935 if (readp > dataend - 8
8936 || unit_length < 8
8937 || unit_length > (uint64_t) (dataend - readp))
8938 goto invalid_data;
8939
8940 const unsigned char *nexthdr = readp + unit_length;
8941
8942 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
8943 printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
8944
8945 if (version != 5)
8946 {
8947 error (0, 0, gettext ("Unknown version"));
8948 goto next_table;
8949 }
8950
8951 uint8_t address_size = *readp++;
8952 printf (gettext (" Address size: %8" PRIu64 "\n"),
8953 (uint64_t) address_size);
8954
8955 if (address_size != 4 && address_size != 8)
8956 {
8957 error (0, 0, gettext ("unsupported address size"));
8958 goto next_table;
8959 }
8960
8961 uint8_t segment_size = *readp++;
8962 printf (gettext (" Segment size: %8" PRIu64 "\n"),
8963 (uint64_t) segment_size);
8964
8965 if (segment_size != 0)
8966 {
8967 error (0, 0, gettext ("unsupported segment size"));
8968 goto next_table;
8969 }
8970
8971 uint32_t offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
8972 printf (gettext (" Offset entries: %8" PRIu64 "\n"),
8973 (uint64_t) offset_entry_count);
8974
8975 /* We need the CU that uses this unit to get the initial base address. */
8976 Dwarf_Addr cu_base = 0;
8977 struct Dwarf_CU *cu = NULL;
8978 if (listptr_cu (&known_loclistsptr, &listptr_idx,
8979 (Dwarf_Off) offset,
8980 (Dwarf_Off) (nexthdr - (unsigned char *) data->d_buf),
8981 &cu_base, &cu)
8982 || split_dwarf_cu_base (dbg, &cu, &cu_base))
8983 {
8984 Dwarf_Die cudie;
8985 if (dwarf_cu_die (cu, &cudie,
8986 NULL, NULL, NULL, NULL,
8987 NULL, NULL) == NULL)
8988 printf (gettext (" Unknown CU base: "));
8989 else
8990 printf (gettext (" CU [%6" PRIx64 "] base: "),
8991 dwarf_dieoffset (&cudie));
8992 print_dwarf_addr (dwflmod, address_size, cu_base, cu_base);
8993 printf ("\n");
8994 }
8995 else
8996 printf (gettext (" Not associated with a CU.\n"));
8997
8998 printf ("\n");
8999
9000 const unsigned char *offset_array_start = readp;
9001 if (offset_entry_count > 0)
9002 {
9003 uint64_t max_entries = (unit_length - 8) / offset_size;
9004 if (offset_entry_count > max_entries)
9005 {
9006 error (0, 0,
9007 gettext ("too many offset entries for unit length"));
9008 offset_entry_count = max_entries;
9009 }
9010
9011 printf (gettext (" Offsets starting at 0x%" PRIx64 ":\n"),
9012 (uint64_t) (offset_array_start
9013 - (unsigned char *) data->d_buf));
9014 for (uint32_t idx = 0; idx < offset_entry_count; idx++)
9015 {
9016 printf (" [%6" PRIu32 "] ", idx);
9017 if (offset_size == 4)
9018 {
9019 uint32_t off = read_4ubyte_unaligned_inc (dbg, readp);
9020 printf ("0x%" PRIx32 "\n", off);
9021 }
9022 else
9023 {
9024 uint64_t off = read_8ubyte_unaligned_inc (dbg, readp);
9025 printf ("0x%" PRIx64 "\n", off);
9026 }
9027 }
9028 printf ("\n");
9029 }
9030
9031 Dwarf_Addr base = cu_base;
9032 bool start_of_list = true;
9033 while (readp < nexthdr)
9034 {
9035 uint8_t kind = *readp++;
9036 uint64_t op1, op2, len;
9037
9038 /* Skip padding. */
9039 if (start_of_list && kind == DW_LLE_end_of_list)
9040 continue;
9041
9042 if (start_of_list)
9043 {
9044 base = cu_base;
9045 printf (" Offset: %" PRIx64 ", Index: %" PRIx64 "\n",
9046 (uint64_t) (readp - (unsigned char *) data->d_buf - 1),
9047 (uint64_t) (readp - offset_array_start - 1));
9048 start_of_list = false;
9049 }
9050
9051 printf (" %s", dwarf_loc_list_encoding_name (kind));
9052 switch (kind)
9053 {
9054 case DW_LLE_end_of_list:
9055 start_of_list = true;
9056 printf ("\n\n");
9057 break;
9058
9059 case DW_LLE_base_addressx:
9060 if ((uint64_t) (nexthdr - readp) < 1)
9061 {
9062 invalid_entry:
9063 error (0, 0, gettext ("invalid loclists data"));
9064 goto next_table;
9065 }
9066 get_uleb128 (op1, readp, nexthdr);
9067 printf (" %" PRIx64 "\n", op1);
9068 if (! print_unresolved_addresses)
9069 {
9070 Dwarf_Addr addr;
9071 if (get_indexed_addr (cu, op1, &addr) != 0)
9072 printf (" ???\n");
9073 else
9074 {
9075 printf (" ");
9076 print_dwarf_addr (dwflmod, address_size, addr, addr);
9077 printf ("\n");
9078 }
9079 }
9080 break;
9081
9082 case DW_LLE_startx_endx:
9083 if ((uint64_t) (nexthdr - readp) < 1)
9084 goto invalid_entry;
9085 get_uleb128 (op1, readp, nexthdr);
9086 if ((uint64_t) (nexthdr - readp) < 1)
9087 goto invalid_entry;
9088 get_uleb128 (op2, readp, nexthdr);
9089 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9090 if (! print_unresolved_addresses)
9091 {
9092 Dwarf_Addr addr1;
9093 Dwarf_Addr addr2;
9094 if (get_indexed_addr (cu, op1, &addr1) != 0
9095 || get_indexed_addr (cu, op2, &addr2) != 0)
9096 {
9097 printf (" ???..\n");
9098 printf (" ???\n");
9099 }
9100 else
9101 {
9102 printf (" ");
9103 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9104 printf ("..\n ");
9105 print_dwarf_addr (dwflmod, address_size,
9106 addr2 - 1, addr2);
9107 printf ("\n");
9108 }
9109 }
9110 if ((uint64_t) (nexthdr - readp) < 1)
9111 goto invalid_entry;
9112 get_uleb128 (len, readp, nexthdr);
9113 if ((uint64_t) (nexthdr - readp) < len)
9114 goto invalid_entry;
9115 print_ops (dwflmod, dbg, 8, 8, version,
9116 address_size, offset_size, cu, len, readp);
9117 readp += len;
9118 break;
9119
9120 case DW_LLE_startx_length:
9121 if ((uint64_t) (nexthdr - readp) < 1)
9122 goto invalid_entry;
9123 get_uleb128 (op1, readp, nexthdr);
9124 if ((uint64_t) (nexthdr - readp) < 1)
9125 goto invalid_entry;
9126 get_uleb128 (op2, readp, nexthdr);
9127 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9128 if (! print_unresolved_addresses)
9129 {
9130 Dwarf_Addr addr1;
9131 Dwarf_Addr addr2;
9132 if (get_indexed_addr (cu, op1, &addr1) != 0)
9133 {
9134 printf (" ???..\n");
9135 printf (" ???\n");
9136 }
9137 else
9138 {
9139 addr2 = addr1 + op2;
9140 printf (" ");
9141 print_dwarf_addr (dwflmod, address_size, addr1, addr1);
9142 printf ("..\n ");
9143 print_dwarf_addr (dwflmod, address_size,
9144 addr2 - 1, addr2);
9145 printf ("\n");
9146 }
9147 }
9148 if ((uint64_t) (nexthdr - readp) < 1)
9149 goto invalid_entry;
9150 get_uleb128 (len, readp, nexthdr);
9151 if ((uint64_t) (nexthdr - readp) < len)
9152 goto invalid_entry;
9153 print_ops (dwflmod, dbg, 8, 8, version,
9154 address_size, offset_size, cu, len, readp);
9155 readp += len;
9156 break;
9157
9158 case DW_LLE_offset_pair:
9159 if ((uint64_t) (nexthdr - readp) < 1)
9160 goto invalid_entry;
9161 get_uleb128 (op1, readp, nexthdr);
9162 if ((uint64_t) (nexthdr - readp) < 1)
9163 goto invalid_entry;
9164 get_uleb128 (op2, readp, nexthdr);
9165 printf (" %" PRIx64 ", %" PRIx64 "\n", op1, op2);
9166 if (! print_unresolved_addresses)
9167 {
9168 op1 += base;
9169 op2 += base;
9170 printf (" ");
9171 print_dwarf_addr (dwflmod, address_size, op1, op1);
9172 printf ("..\n ");
9173 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9174 printf ("\n");
9175 }
9176 if ((uint64_t) (nexthdr - readp) < 1)
9177 goto invalid_entry;
9178 get_uleb128 (len, readp, nexthdr);
9179 if ((uint64_t) (nexthdr - readp) < len)
9180 goto invalid_entry;
9181 print_ops (dwflmod, dbg, 8, 8, version,
9182 address_size, offset_size, cu, len, readp);
9183 readp += len;
9184 break;
9185
9186 case DW_LLE_default_location:
9187 if ((uint64_t) (nexthdr - readp) < 1)
9188 goto invalid_entry;
9189 get_uleb128 (len, readp, nexthdr);
9190 if ((uint64_t) (nexthdr - readp) < len)
9191 goto invalid_entry;
9192 print_ops (dwflmod, dbg, 8, 8, version,
9193 address_size, offset_size, cu, len, readp);
9194 readp += len;
9195 break;
9196
9197 case DW_LLE_base_address:
9198 if (address_size == 4)
9199 {
9200 if ((uint64_t) (nexthdr - readp) < 4)
9201 goto invalid_entry;
9202 op1 = read_4ubyte_unaligned_inc (dbg, readp);
9203 }
9204 else
9205 {
9206 if ((uint64_t) (nexthdr - readp) < 8)
9207 goto invalid_entry;
9208 op1 = read_8ubyte_unaligned_inc (dbg, readp);
9209 }
9210 base = op1;
9211 printf (" 0x%" PRIx64 "\n", base);
9212 if (! print_unresolved_addresses)
9213 {
9214 printf (" ");
9215 print_dwarf_addr (dwflmod, address_size, base, base);
9216 printf ("\n");
9217 }
9218 break;
9219
9220 case DW_LLE_start_end:
9221 if (address_size == 4)
9222 {
9223 if ((uint64_t) (nexthdr - readp) < 8)
9224 goto invalid_entry;
9225 op1 = read_4ubyte_unaligned_inc (dbg, readp);
9226 op2 = read_4ubyte_unaligned_inc (dbg, readp);
9227 }
9228 else
9229 {
9230 if ((uint64_t) (nexthdr - readp) < 16)
9231 goto invalid_entry;
9232 op1 = read_8ubyte_unaligned_inc (dbg, readp);
9233 op2 = read_8ubyte_unaligned_inc (dbg, readp);
9234 }
9235 printf (" 0x%" PRIx64 "..0x%" PRIx64 "\n", op1, op2);
9236 if (! print_unresolved_addresses)
9237 {
9238 printf (" ");
9239 print_dwarf_addr (dwflmod, address_size, op1, op1);
9240 printf ("..\n ");
9241 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9242 printf ("\n");
9243 }
9244 if ((uint64_t) (nexthdr - readp) < 1)
9245 goto invalid_entry;
9246 get_uleb128 (len, readp, nexthdr);
9247 if ((uint64_t) (nexthdr - readp) < len)
9248 goto invalid_entry;
9249 print_ops (dwflmod, dbg, 8, 8, version,
9250 address_size, offset_size, cu, len, readp);
9251 readp += len;
9252 break;
9253
9254 case DW_LLE_start_length:
9255 if (address_size == 4)
9256 {
9257 if ((uint64_t) (nexthdr - readp) < 4)
9258 goto invalid_entry;
9259 op1 = read_4ubyte_unaligned_inc (dbg, readp);
9260 }
9261 else
9262 {
9263 if ((uint64_t) (nexthdr - readp) < 8)
9264 goto invalid_entry;
9265 op1 = read_8ubyte_unaligned_inc (dbg, readp);
9266 }
9267 if ((uint64_t) (nexthdr - readp) < 1)
9268 goto invalid_entry;
9269 get_uleb128 (op2, readp, nexthdr);
9270 printf (" 0x%" PRIx64 ", %" PRIx64 "\n", op1, op2);
9271 if (! print_unresolved_addresses)
9272 {
9273 op2 = op1 + op2;
9274 printf (" ");
9275 print_dwarf_addr (dwflmod, address_size, op1, op1);
9276 printf ("..\n ");
9277 print_dwarf_addr (dwflmod, address_size, op2 - 1, op2);
9278 printf ("\n");
9279 }
9280 if ((uint64_t) (nexthdr - readp) < 1)
9281 goto invalid_entry;
9282 get_uleb128 (len, readp, nexthdr);
9283 if ((uint64_t) (nexthdr - readp) < len)
9284 goto invalid_entry;
9285 print_ops (dwflmod, dbg, 8, 8, version,
9286 address_size, offset_size, cu, len, readp);
9287 readp += len;
9288 break;
9289
9290 default:
9291 goto invalid_entry;
9292 }
9293 }
9294
9295 next_table:
9296 if (readp != nexthdr)
9297 {
9298 size_t padding = nexthdr - readp;
9299 printf (gettext (" %zu padding bytes\n\n"), padding);
9300 readp = nexthdr;
9301 }
9302 }
9303 }
9304
9305
9306 static void
print_debug_loc_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9307 print_debug_loc_section (Dwfl_Module *dwflmod,
9308 Ebl *ebl, GElf_Ehdr *ehdr,
9309 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9310 {
9311 Elf_Data *data = (dbg->sectiondata[IDX_debug_loc]
9312 ?: elf_rawdata (scn, NULL));
9313
9314 if (unlikely (data == NULL))
9315 {
9316 error (0, 0, gettext ("cannot get .debug_loc content: %s"),
9317 elf_errmsg (-1));
9318 return;
9319 }
9320
9321 printf (gettext ("\
9322 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9323 elf_ndxscn (scn), section_name (ebl, shdr),
9324 (uint64_t) shdr->sh_offset);
9325
9326 sort_listptr (&known_locsptr, "loclistptr");
9327 size_t listptr_idx = 0;
9328
9329 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
9330 uint_fast8_t offset_size = 4;
9331
9332 bool first = true;
9333 Dwarf_Addr base = 0;
9334 unsigned char *readp = data->d_buf;
9335 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
9336 Dwarf_CU *last_cu = NULL;
9337 while (readp < endp)
9338 {
9339 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
9340 Dwarf_CU *cu = last_cu;
9341 unsigned int attr = 0;
9342
9343 if (first && skip_listptr_hole (&known_locsptr, &listptr_idx,
9344 &address_size, &offset_size, &base,
9345 &cu, offset, &readp, endp, &attr))
9346 continue;
9347
9348 if (last_cu != cu)
9349 {
9350 Dwarf_Die cudie;
9351 if (dwarf_cu_die (cu, &cudie,
9352 NULL, NULL, NULL, NULL,
9353 NULL, NULL) == NULL)
9354 printf (gettext ("\n Unknown CU base: "));
9355 else
9356 printf (gettext ("\n CU [%6" PRIx64 "] base: "),
9357 dwarf_dieoffset (&cudie));
9358 print_dwarf_addr (dwflmod, address_size, base, base);
9359 printf ("\n");
9360 }
9361 last_cu = cu;
9362
9363 if (attr == DW_AT_GNU_locviews)
9364 {
9365 Dwarf_Off next_off = next_listptr_offset (&known_locsptr,
9366 listptr_idx);
9367 const unsigned char *locp = readp;
9368 const unsigned char *locendp;
9369 if (next_off == 0
9370 || next_off > (size_t) (endp
9371 - (const unsigned char *) data->d_buf))
9372 locendp = endp;
9373 else
9374 locendp = (const unsigned char *) data->d_buf + next_off;
9375
9376 while (locp < locendp)
9377 {
9378 uint64_t v1, v2;
9379 get_uleb128 (v1, locp, locendp);
9380 if (locp >= locendp)
9381 {
9382 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
9383 break;
9384 }
9385 get_uleb128 (v2, locp, locendp);
9386 if (first) /* First view pair in a list. */
9387 printf (" [%6tx] ", offset);
9388 else
9389 printf (" ");
9390 printf ("view pair %" PRId64 ", %" PRId64 "\n", v1, v2);
9391 first = false;
9392 }
9393
9394 first = true;
9395 readp = (unsigned char *) locendp;
9396 continue;
9397 }
9398
9399 /* GNU DebugFission encoded addresses as addrx. */
9400 bool is_debugfission = ((cu != NULL
9401 || split_dwarf_cu_base (dbg, &cu, &base))
9402 && (cu->version < 5
9403 && cu->unit_type == DW_UT_split_compile));
9404 if (!is_debugfission
9405 && unlikely (data->d_size - offset < (size_t) address_size * 2))
9406 {
9407 invalid_data:
9408 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
9409 break;
9410 }
9411
9412 Dwarf_Addr begin;
9413 Dwarf_Addr end;
9414 bool use_base = true;
9415 if (is_debugfission)
9416 {
9417 const unsigned char *locp = readp;
9418 const unsigned char *locendp = readp + data->d_size;
9419 if (locp >= locendp)
9420 goto invalid_data;
9421
9422 Dwarf_Word idx;
9423 unsigned char code = *locp++;
9424 switch (code)
9425 {
9426 case DW_LLE_GNU_end_of_list_entry:
9427 begin = 0;
9428 end = 0;
9429 break;
9430
9431 case DW_LLE_GNU_base_address_selection_entry:
9432 if (locp >= locendp)
9433 goto invalid_data;
9434 begin = (Dwarf_Addr) -1;
9435 get_uleb128 (idx, locp, locendp);
9436 if (get_indexed_addr (cu, idx, &end) != 0)
9437 end = idx; /* ... */
9438 break;
9439
9440 case DW_LLE_GNU_start_end_entry:
9441 if (locp >= locendp)
9442 goto invalid_data;
9443 get_uleb128 (idx, locp, locendp);
9444 if (get_indexed_addr (cu, idx, &begin) != 0)
9445 begin = idx; /* ... */
9446 if (locp >= locendp)
9447 goto invalid_data;
9448 get_uleb128 (idx, locp, locendp);
9449 if (get_indexed_addr (cu, idx, &end) != 0)
9450 end = idx; /* ... */
9451 use_base = false;
9452 break;
9453
9454 case DW_LLE_GNU_start_length_entry:
9455 if (locp >= locendp)
9456 goto invalid_data;
9457 get_uleb128 (idx, locp, locendp);
9458 if (get_indexed_addr (cu, idx, &begin) != 0)
9459 begin = idx; /* ... */
9460 if (locendp - locp < 4)
9461 goto invalid_data;
9462 end = read_4ubyte_unaligned_inc (dbg, locp);
9463 end += begin;
9464 use_base = false;
9465 break;
9466
9467 default:
9468 goto invalid_data;
9469 }
9470
9471 readp = (unsigned char *) locp;
9472 }
9473 else if (address_size == 8)
9474 {
9475 begin = read_8ubyte_unaligned_inc (dbg, readp);
9476 end = read_8ubyte_unaligned_inc (dbg, readp);
9477 }
9478 else
9479 {
9480 begin = read_4ubyte_unaligned_inc (dbg, readp);
9481 end = read_4ubyte_unaligned_inc (dbg, readp);
9482 if (begin == (Dwarf_Addr) (uint32_t) -1)
9483 begin = (Dwarf_Addr) -1l;
9484 }
9485
9486 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
9487 {
9488 printf (gettext (" [%6tx] base address\n "), offset);
9489 print_dwarf_addr (dwflmod, address_size, end, end);
9490 printf ("\n");
9491 base = end;
9492 }
9493 else if (begin == 0 && end == 0) /* End of list entry. */
9494 {
9495 if (first)
9496 printf (gettext (" [%6tx] empty list\n"), offset);
9497 first = true;
9498 }
9499 else
9500 {
9501 /* We have a location expression entry. */
9502 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
9503
9504 if (first) /* First entry in a list. */
9505 printf (" [%6tx] ", offset);
9506 else
9507 printf (" ");
9508
9509 printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
9510 if (! print_unresolved_addresses)
9511 {
9512 Dwarf_Addr dab = use_base ? base + begin : begin;
9513 Dwarf_Addr dae = use_base ? base + end : end;
9514 printf (" ");
9515 print_dwarf_addr (dwflmod, address_size, dab, dab);
9516 printf ("..\n ");
9517 print_dwarf_addr (dwflmod, address_size, dae - 1, dae);
9518 printf ("\n");
9519 }
9520
9521 if (endp - readp <= (ptrdiff_t) len)
9522 {
9523 fputs (gettext (" <INVALID DATA>\n"), stdout);
9524 break;
9525 }
9526
9527 print_ops (dwflmod, dbg, 11, 11,
9528 cu != NULL ? cu->version : 3,
9529 address_size, offset_size, cu, len, readp);
9530
9531 first = false;
9532 readp += len;
9533 }
9534 }
9535 }
9536
9537 struct mac_culist
9538 {
9539 Dwarf_Die die;
9540 Dwarf_Off offset;
9541 Dwarf_Files *files;
9542 struct mac_culist *next;
9543 };
9544
9545
9546 static int
mac_compare(const void * p1,const void * p2)9547 mac_compare (const void *p1, const void *p2)
9548 {
9549 struct mac_culist *m1 = (struct mac_culist *) p1;
9550 struct mac_culist *m2 = (struct mac_culist *) p2;
9551
9552 if (m1->offset < m2->offset)
9553 return -1;
9554 if (m1->offset > m2->offset)
9555 return 1;
9556 return 0;
9557 }
9558
9559
9560 static void
print_debug_macinfo_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9561 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9562 Ebl *ebl,
9563 GElf_Ehdr *ehdr __attribute__ ((unused)),
9564 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9565 {
9566 printf (gettext ("\
9567 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9568 elf_ndxscn (scn), section_name (ebl, shdr),
9569 (uint64_t) shdr->sh_offset);
9570 putc_unlocked ('\n', stdout);
9571
9572 /* There is no function in libdw to iterate over the raw content of
9573 the section but it is easy enough to do. */
9574 Elf_Data *data = (dbg->sectiondata[IDX_debug_macinfo]
9575 ?: elf_rawdata (scn, NULL));
9576 if (unlikely (data == NULL))
9577 {
9578 error (0, 0, gettext ("cannot get macro information section data: %s"),
9579 elf_errmsg (-1));
9580 return;
9581 }
9582
9583 /* Get the source file information for all CUs. */
9584 Dwarf_Off offset;
9585 Dwarf_Off ncu = 0;
9586 size_t hsize;
9587 struct mac_culist *culist = NULL;
9588 size_t nculist = 0;
9589 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9590 {
9591 Dwarf_Die cudie;
9592 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9593 continue;
9594
9595 Dwarf_Attribute attr;
9596 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
9597 continue;
9598
9599 Dwarf_Word macoff;
9600 if (dwarf_formudata (&attr, &macoff) != 0)
9601 continue;
9602
9603 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9604 newp->die = cudie;
9605 newp->offset = macoff;
9606 newp->files = NULL;
9607 newp->next = culist;
9608 culist = newp;
9609 ++nculist;
9610 }
9611
9612 /* Convert the list into an array for easier consumption. */
9613 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
9614 * sizeof (*cus));
9615 /* Add sentinel. */
9616 cus[nculist].offset = data->d_size;
9617 cus[nculist].files = (Dwarf_Files *) -1l;
9618 if (nculist > 0)
9619 {
9620 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
9621 {
9622 assert (cnt < nculist);
9623 cus[cnt] = *culist;
9624 culist = culist->next;
9625 }
9626
9627 /* Sort the array according to the offset in the .debug_macinfo
9628 section. Note we keep the sentinel at the end. */
9629 qsort (cus, nculist, sizeof (*cus), mac_compare);
9630 }
9631
9632 const unsigned char *readp = (const unsigned char *) data->d_buf;
9633 const unsigned char *readendp = readp + data->d_size;
9634 int level = 1;
9635
9636 while (readp < readendp)
9637 {
9638 unsigned int opcode = *readp++;
9639 unsigned int u128;
9640 unsigned int u128_2;
9641 const unsigned char *endp;
9642
9643 switch (opcode)
9644 {
9645 case DW_MACINFO_define:
9646 case DW_MACINFO_undef:
9647 case DW_MACINFO_vendor_ext:
9648 /* For the first two opcodes the parameters are
9649 line, string
9650 For the latter
9651 number, string.
9652 We can treat these cases together. */
9653 get_uleb128 (u128, readp, readendp);
9654
9655 endp = memchr (readp, '\0', readendp - readp);
9656 if (unlikely (endp == NULL))
9657 {
9658 printf (gettext ("\
9659 %*s*** non-terminated string at end of section"),
9660 level, "");
9661 return;
9662 }
9663
9664 if (opcode == DW_MACINFO_define)
9665 printf ("%*s#define %s, line %u\n",
9666 level, "", (char *) readp, u128);
9667 else if (opcode == DW_MACINFO_undef)
9668 printf ("%*s#undef %s, line %u\n",
9669 level, "", (char *) readp, u128);
9670 else
9671 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
9672
9673 readp = endp + 1;
9674 break;
9675
9676 case DW_MACINFO_start_file:
9677 /* The two parameters are line and file index, in this order. */
9678 get_uleb128 (u128, readp, readendp);
9679 if (readendp - readp < 1)
9680 {
9681 printf (gettext ("\
9682 %*s*** missing DW_MACINFO_start_file argument at end of section"),
9683 level, "");
9684 return;
9685 }
9686 get_uleb128 (u128_2, readp, readendp);
9687
9688 /* Find the CU DIE for this file. */
9689 size_t macoff = readp - (const unsigned char *) data->d_buf;
9690 const char *fname = "???";
9691 if (macoff >= cus[0].offset)
9692 {
9693 while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
9694 ++cus;
9695
9696 if (cus[0].files == NULL
9697 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
9698 cus[0].files = (Dwarf_Files *) -1l;
9699
9700 if (cus[0].files != (Dwarf_Files *) -1l)
9701 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
9702 ?: "???");
9703 }
9704
9705 printf ("%*sstart_file %u, [%u] %s\n",
9706 level, "", u128, u128_2, fname);
9707 ++level;
9708 break;
9709
9710 case DW_MACINFO_end_file:
9711 --level;
9712 printf ("%*send_file\n", level, "");
9713 /* Nothing more to do. */
9714 break;
9715
9716 default:
9717 // XXX gcc seems to generate files with a trailing zero.
9718 if (unlikely (opcode != 0 || readp != readendp))
9719 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
9720 break;
9721 }
9722 }
9723 }
9724
9725
9726 static void
print_debug_macro_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)9727 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
9728 Ebl *ebl,
9729 GElf_Ehdr *ehdr __attribute__ ((unused)),
9730 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
9731 {
9732 printf (gettext ("\
9733 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
9734 elf_ndxscn (scn), section_name (ebl, shdr),
9735 (uint64_t) shdr->sh_offset);
9736 putc_unlocked ('\n', stdout);
9737
9738 Elf_Data *data = elf_getdata (scn, NULL);
9739 if (unlikely (data == NULL))
9740 {
9741 error (0, 0, gettext ("cannot get macro information section data: %s"),
9742 elf_errmsg (-1));
9743 return;
9744 }
9745
9746 /* Get the source file information for all CUs. Uses same
9747 datastructure as macinfo. But uses offset field to directly
9748 match .debug_line offset. And just stored in a list. */
9749 Dwarf_Off offset;
9750 Dwarf_Off ncu = 0;
9751 size_t hsize;
9752 struct mac_culist *culist = NULL;
9753 size_t nculist = 0;
9754 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
9755 {
9756 Dwarf_Die cudie;
9757 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
9758 continue;
9759
9760 Dwarf_Attribute attr;
9761 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
9762 continue;
9763
9764 Dwarf_Word lineoff;
9765 if (dwarf_formudata (&attr, &lineoff) != 0)
9766 continue;
9767
9768 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
9769 newp->die = cudie;
9770 newp->offset = lineoff;
9771 newp->files = NULL;
9772 newp->next = culist;
9773 culist = newp;
9774 ++nculist;
9775 }
9776
9777 const unsigned char *readp = (const unsigned char *) data->d_buf;
9778 const unsigned char *readendp = readp + data->d_size;
9779
9780 while (readp < readendp)
9781 {
9782 printf (gettext (" Offset: 0x%" PRIx64 "\n"),
9783 (uint64_t) (readp - (const unsigned char *) data->d_buf));
9784
9785 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
9786 // optional vendor extension macro entry table.
9787 if (readp + 2 > readendp)
9788 {
9789 invalid_data:
9790 error (0, 0, gettext ("invalid data"));
9791 return;
9792 }
9793 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
9794 printf (gettext (" Version: %" PRIu16 "\n"), vers);
9795
9796 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
9797 // 5 when it gets standardized.
9798 if (vers != 4 && vers != 5)
9799 {
9800 printf (gettext (" unknown version, cannot parse section\n"));
9801 return;
9802 }
9803
9804 if (readp + 1 > readendp)
9805 goto invalid_data;
9806 const unsigned char flag = *readp++;
9807 printf (gettext (" Flag: 0x%" PRIx8), flag);
9808 if (flag != 0)
9809 {
9810 printf (" (");
9811 if ((flag & 0x01) != 0)
9812 {
9813 printf ("offset_size");
9814 if ((flag & 0xFE) != 0)
9815 printf (", ");
9816 }
9817 if ((flag & 0x02) != 0)
9818 {
9819 printf ("debug_line_offset");
9820 if ((flag & 0xFC) != 0)
9821 printf (", ");
9822 }
9823 if ((flag & 0x04) != 0)
9824 {
9825 printf ("operands_table");
9826 if ((flag & 0xF8) != 0)
9827 printf (", ");
9828 }
9829 if ((flag & 0xF8) != 0)
9830 printf ("unknown");
9831 printf (")");
9832 }
9833 printf ("\n");
9834
9835 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
9836 printf (gettext (" Offset length: %" PRIu8 "\n"), offset_len);
9837 Dwarf_Off line_offset = -1;
9838 if (flag & 0x02)
9839 {
9840 if (offset_len == 8)
9841 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
9842 else
9843 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
9844 printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
9845 line_offset);
9846 }
9847
9848 struct mac_culist *cu = NULL;
9849 if (line_offset != (Dwarf_Off) -1)
9850 {
9851 cu = culist;
9852 while (cu != NULL && line_offset != cu->offset)
9853 cu = cu->next;
9854 }
9855
9856 Dwarf_Off str_offsets_base = str_offsets_base_off (dbg, (cu != NULL
9857 ? cu->die.cu
9858 : NULL));
9859
9860 const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user + 1];
9861 memset (vendor, 0, sizeof vendor);
9862 if (flag & 0x04)
9863 {
9864 // 1 byte length, for each item, 1 byte opcode, uleb128 number
9865 // of arguments, for each argument 1 byte form code.
9866 if (readp + 1 > readendp)
9867 goto invalid_data;
9868 unsigned int tlen = *readp++;
9869 printf (gettext (" extension opcode table, %" PRIu8 " items:\n"),
9870 tlen);
9871 for (unsigned int i = 0; i < tlen; i++)
9872 {
9873 if (readp + 1 > readendp)
9874 goto invalid_data;
9875 unsigned int opcode = *readp++;
9876 printf (gettext (" [%" PRIx8 "]"), opcode);
9877 if (opcode < DW_MACRO_lo_user
9878 || opcode > DW_MACRO_hi_user)
9879 goto invalid_data;
9880 // Record the start of description for this vendor opcode.
9881 // uleb128 nr args, 1 byte per arg form.
9882 vendor[opcode - DW_MACRO_lo_user] = readp;
9883 if (readp + 1 > readendp)
9884 goto invalid_data;
9885 unsigned int args = *readp++;
9886 if (args > 0)
9887 {
9888 printf (gettext (" %" PRIu8 " arguments:"), args);
9889 while (args > 0)
9890 {
9891 if (readp + 1 > readendp)
9892 goto invalid_data;
9893 unsigned int form = *readp++;
9894 printf (" %s", dwarf_form_name (form));
9895 if (! libdw_valid_user_form (form))
9896 goto invalid_data;
9897 args--;
9898 if (args > 0)
9899 putchar_unlocked (',');
9900 }
9901 }
9902 else
9903 printf (gettext (" no arguments."));
9904 putchar_unlocked ('\n');
9905 }
9906 }
9907 putchar_unlocked ('\n');
9908
9909 int level = 1;
9910 if (readp + 1 > readendp)
9911 goto invalid_data;
9912 unsigned int opcode = *readp++;
9913 while (opcode != 0)
9914 {
9915 unsigned int u128;
9916 unsigned int u128_2;
9917 const unsigned char *endp;
9918 uint64_t off;
9919
9920 switch (opcode)
9921 {
9922 case DW_MACRO_start_file:
9923 get_uleb128 (u128, readp, readendp);
9924 if (readp >= readendp)
9925 goto invalid_data;
9926 get_uleb128 (u128_2, readp, readendp);
9927
9928 /* Find the CU DIE that matches this line offset. */
9929 const char *fname = "???";
9930 if (cu != NULL)
9931 {
9932 if (cu->files == NULL
9933 && dwarf_getsrcfiles (&cu->die, &cu->files,
9934 NULL) != 0)
9935 cu->files = (Dwarf_Files *) -1l;
9936
9937 if (cu->files != (Dwarf_Files *) -1l)
9938 fname = (dwarf_filesrc (cu->files, u128_2,
9939 NULL, NULL) ?: "???");
9940 }
9941 printf ("%*sstart_file %u, [%u] %s\n",
9942 level, "", u128, u128_2, fname);
9943 ++level;
9944 break;
9945
9946 case DW_MACRO_end_file:
9947 --level;
9948 printf ("%*send_file\n", level, "");
9949 break;
9950
9951 case DW_MACRO_define:
9952 get_uleb128 (u128, readp, readendp);
9953 endp = memchr (readp, '\0', readendp - readp);
9954 if (endp == NULL)
9955 goto invalid_data;
9956 printf ("%*s#define %s, line %u\n",
9957 level, "", readp, u128);
9958 readp = endp + 1;
9959 break;
9960
9961 case DW_MACRO_undef:
9962 get_uleb128 (u128, readp, readendp);
9963 endp = memchr (readp, '\0', readendp - readp);
9964 if (endp == NULL)
9965 goto invalid_data;
9966 printf ("%*s#undef %s, line %u\n",
9967 level, "", readp, u128);
9968 readp = endp + 1;
9969 break;
9970
9971 case DW_MACRO_define_strp:
9972 get_uleb128 (u128, readp, readendp);
9973 if (readp + offset_len > readendp)
9974 goto invalid_data;
9975 if (offset_len == 8)
9976 off = read_8ubyte_unaligned_inc (dbg, readp);
9977 else
9978 off = read_4ubyte_unaligned_inc (dbg, readp);
9979 printf ("%*s#define %s, line %u (indirect)\n",
9980 level, "", dwarf_getstring (dbg, off, NULL), u128);
9981 break;
9982
9983 case DW_MACRO_undef_strp:
9984 get_uleb128 (u128, readp, readendp);
9985 if (readp + offset_len > readendp)
9986 goto invalid_data;
9987 if (offset_len == 8)
9988 off = read_8ubyte_unaligned_inc (dbg, readp);
9989 else
9990 off = read_4ubyte_unaligned_inc (dbg, readp);
9991 printf ("%*s#undef %s, line %u (indirect)\n",
9992 level, "", dwarf_getstring (dbg, off, NULL), u128);
9993 break;
9994
9995 case DW_MACRO_import:
9996 if (readp + offset_len > readendp)
9997 goto invalid_data;
9998 if (offset_len == 8)
9999 off = read_8ubyte_unaligned_inc (dbg, readp);
10000 else
10001 off = read_4ubyte_unaligned_inc (dbg, readp);
10002 printf ("%*s#include offset 0x%" PRIx64 "\n",
10003 level, "", off);
10004 break;
10005
10006 case DW_MACRO_define_sup:
10007 get_uleb128 (u128, readp, readendp);
10008 if (readp + offset_len > readendp)
10009 goto invalid_data;
10010 printf ("%*s#define ", level, "");
10011 readp = print_form_data (dbg, DW_FORM_strp_sup,
10012 readp, readendp, offset_len,
10013 str_offsets_base);
10014 printf (", line %u (sup)\n", u128);
10015 break;
10016
10017 case DW_MACRO_undef_sup:
10018 get_uleb128 (u128, readp, readendp);
10019 if (readp + offset_len > readendp)
10020 goto invalid_data;
10021 printf ("%*s#undef ", level, "");
10022 readp = print_form_data (dbg, DW_FORM_strp_sup,
10023 readp, readendp, offset_len,
10024 str_offsets_base);
10025 printf (", line %u (sup)\n", u128);
10026 break;
10027
10028 case DW_MACRO_import_sup:
10029 if (readp + offset_len > readendp)
10030 goto invalid_data;
10031 if (offset_len == 8)
10032 off = read_8ubyte_unaligned_inc (dbg, readp);
10033 else
10034 off = read_4ubyte_unaligned_inc (dbg, readp);
10035 // XXX Needs support for reading from supplementary object file.
10036 printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
10037 level, "", off);
10038 break;
10039
10040 case DW_MACRO_define_strx:
10041 get_uleb128 (u128, readp, readendp);
10042 if (readp + offset_len > readendp)
10043 goto invalid_data;
10044 printf ("%*s#define ", level, "");
10045 readp = print_form_data (dbg, DW_FORM_strx,
10046 readp, readendp, offset_len,
10047 str_offsets_base);
10048 printf (", line %u (strx)\n", u128);
10049 break;
10050
10051 case DW_MACRO_undef_strx:
10052 get_uleb128 (u128, readp, readendp);
10053 if (readp + offset_len > readendp)
10054 goto invalid_data;
10055 printf ("%*s#undef ", level, "");
10056 readp = print_form_data (dbg, DW_FORM_strx,
10057 readp, readendp, offset_len,
10058 str_offsets_base);
10059 printf (", line %u (strx)\n", u128);
10060 break;
10061
10062 default:
10063 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
10064 if (opcode < DW_MACRO_lo_user
10065 || opcode > DW_MACRO_lo_user
10066 || vendor[opcode - DW_MACRO_lo_user] == NULL)
10067 goto invalid_data;
10068
10069 const unsigned char *op_desc;
10070 op_desc = vendor[opcode - DW_MACRO_lo_user];
10071
10072 // Just skip the arguments, we cannot really interpret them,
10073 // but print as much as we can.
10074 unsigned int args = *op_desc++;
10075 while (args > 0 && readp < readendp)
10076 {
10077 unsigned int form = *op_desc++;
10078 readp = print_form_data (dbg, form, readp, readendp,
10079 offset_len, str_offsets_base);
10080 args--;
10081 if (args > 0)
10082 printf (", ");
10083 }
10084 putchar_unlocked ('\n');
10085 }
10086
10087 if (readp + 1 > readendp)
10088 goto invalid_data;
10089 opcode = *readp++;
10090 if (opcode == 0)
10091 putchar_unlocked ('\n');
10092 }
10093 }
10094 }
10095
10096
10097 /* Callback for printing global names. */
10098 static int
print_pubnames(Dwarf * dbg,Dwarf_Global * global,void * arg)10099 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
10100 void *arg)
10101 {
10102 int *np = (int *) arg;
10103
10104 printf (gettext (" [%5d] DIE offset: %6" PRId64
10105 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
10106 (*np)++, global->die_offset, global->cu_offset, global->name);
10107
10108 return 0;
10109 }
10110
10111
10112 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
10113 static void
print_debug_pubnames_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10114 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10115 Ebl *ebl,
10116 GElf_Ehdr *ehdr __attribute__ ((unused)),
10117 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10118 {
10119 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10120 elf_ndxscn (scn), section_name (ebl, shdr),
10121 (uint64_t) shdr->sh_offset);
10122
10123 int n = 0;
10124 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
10125 }
10126
10127 /* Print the content of the DWARF string section '.debug_str'. */
10128 static void
print_debug_str_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10129 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10130 Ebl *ebl,
10131 GElf_Ehdr *ehdr __attribute__ ((unused)),
10132 Elf_Scn *scn, GElf_Shdr *shdr,
10133 Dwarf *dbg __attribute__ ((unused)))
10134 {
10135 Elf_Data *data = elf_rawdata (scn, NULL);
10136 const size_t sh_size = data ? data->d_size : 0;
10137
10138 /* Compute floor(log16(shdr->sh_size)). */
10139 GElf_Addr tmp = sh_size;
10140 int digits = 1;
10141 while (tmp >= 16)
10142 {
10143 ++digits;
10144 tmp >>= 4;
10145 }
10146 digits = MAX (4, digits);
10147
10148 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
10149 " %*s String\n"),
10150 elf_ndxscn (scn),
10151 section_name (ebl, shdr), (uint64_t) shdr->sh_offset,
10152 /* TRANS: the debugstr| prefix makes the string unique. */
10153 digits + 2, sgettext ("debugstr|Offset"));
10154
10155 Dwarf_Off offset = 0;
10156 while (offset < sh_size)
10157 {
10158 size_t len;
10159 const char *str = (const char *) data->d_buf + offset;
10160 const char *endp = memchr (str, '\0', sh_size - offset);
10161 if (unlikely (endp == NULL))
10162 {
10163 printf (gettext (" *** error, missing string terminator\n"));
10164 break;
10165 }
10166
10167 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
10168 len = endp - str;
10169 offset += len + 1;
10170 }
10171 }
10172
10173 static void
print_debug_str_offsets_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10174 print_debug_str_offsets_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10175 Ebl *ebl,
10176 GElf_Ehdr *ehdr __attribute__ ((unused)),
10177 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10178 {
10179 printf (gettext ("\
10180 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
10181 elf_ndxscn (scn), section_name (ebl, shdr),
10182 (uint64_t) shdr->sh_offset);
10183
10184 if (shdr->sh_size == 0)
10185 return;
10186
10187 /* We like to get the section from libdw to make sure they are relocated. */
10188 Elf_Data *data = (dbg->sectiondata[IDX_debug_str_offsets]
10189 ?: elf_rawdata (scn, NULL));
10190 if (unlikely (data == NULL))
10191 {
10192 error (0, 0, gettext ("cannot get .debug_str_offsets section data: %s"),
10193 elf_errmsg (-1));
10194 return;
10195 }
10196
10197 size_t idx = 0;
10198 sort_listptr (&known_stroffbases, "str_offsets");
10199
10200 const unsigned char *start = (const unsigned char *) data->d_buf;
10201 const unsigned char *readp = start;
10202 const unsigned char *readendp = ((const unsigned char *) data->d_buf
10203 + data->d_size);
10204
10205 while (readp < readendp)
10206 {
10207 /* Most string offset tables will have a header. For split
10208 dwarf unit GNU DebugFission didn't add one. But they were
10209 also only defined for split units (main or skeleton units
10210 didn't have indirect strings). So if we don't have a
10211 DW_AT_str_offsets_base at all and this is offset zero, then
10212 just start printing offsets immediately, if this is a .dwo
10213 section. */
10214 Dwarf_Off off = (Dwarf_Off) (readp
10215 - (const unsigned char *) data->d_buf);
10216
10217 printf ("Table at offset %" PRIx64 " ", off);
10218
10219 struct listptr *listptr = get_listptr (&known_stroffbases, idx++);
10220 const unsigned char *next_unitp = readendp;
10221 uint8_t offset_size;
10222 bool has_header;
10223 if (listptr == NULL)
10224 {
10225 /* This can happen for .dwo files. There is only an header
10226 in the case this is a version 5 split DWARF file. */
10227 Dwarf_CU *cu;
10228 uint8_t unit_type;
10229 if (dwarf_get_units (dbg, NULL, &cu, NULL, &unit_type,
10230 NULL, NULL) != 0)
10231 {
10232 error (0, 0, "Warning: Cannot find any DWARF unit.");
10233 /* Just guess some values. */
10234 has_header = false;
10235 offset_size = 4;
10236 }
10237 else if (off == 0
10238 && (unit_type == DW_UT_split_type
10239 || unit_type == DW_UT_split_compile))
10240 {
10241 has_header = cu->version > 4;
10242 offset_size = cu->offset_size;
10243 }
10244 else
10245 {
10246 error (0, 0,
10247 "Warning: No CU references .debug_str_offsets after %"
10248 PRIx64, off);
10249 has_header = cu->version > 4;
10250 offset_size = cu->offset_size;
10251 }
10252 printf ("\n");
10253 }
10254 else
10255 {
10256 /* This must be DWARF5, since GNU DebugFission didn't define
10257 DW_AT_str_offsets_base. */
10258 has_header = true;
10259
10260 Dwarf_Die cudie;
10261 if (dwarf_cu_die (listptr->cu, &cudie,
10262 NULL, NULL, NULL, NULL,
10263 NULL, NULL) == NULL)
10264 printf ("Unknown CU (%s):\n", dwarf_errmsg (-1));
10265 else
10266 printf ("for CU [%6" PRIx64 "]:\n", dwarf_dieoffset (&cudie));
10267 }
10268
10269 if (has_header)
10270 {
10271 uint64_t unit_length;
10272 uint16_t version;
10273 uint16_t padding;
10274
10275 unit_length = read_4ubyte_unaligned_inc (dbg, readp);
10276 if (unlikely (unit_length == 0xffffffff))
10277 {
10278 if (unlikely (readp > readendp - 8))
10279 {
10280 invalid_data:
10281 error (0, 0, "Invalid data");
10282 return;
10283 }
10284 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
10285 offset_size = 8;
10286 }
10287 else
10288 offset_size = 4;
10289
10290 printf ("\n");
10291 printf (gettext (" Length: %8" PRIu64 "\n"),
10292 unit_length);
10293 printf (gettext (" Offset size: %8" PRIu8 "\n"),
10294 offset_size);
10295
10296 /* We need at least 2-bytes (version) + 2-bytes (padding) =
10297 4 bytes to complete the header. And this unit cannot go
10298 beyond the section data. */
10299 if (readp > readendp - 4
10300 || unit_length < 4
10301 || unit_length > (uint64_t) (readendp - readp))
10302 goto invalid_data;
10303
10304 next_unitp = readp + unit_length;
10305
10306 version = read_2ubyte_unaligned_inc (dbg, readp);
10307 printf (gettext (" DWARF version: %8" PRIu16 "\n"), version);
10308
10309 if (version != 5)
10310 {
10311 error (0, 0, gettext ("Unknown version"));
10312 goto next_unit;
10313 }
10314
10315 padding = read_2ubyte_unaligned_inc (dbg, readp);
10316 printf (gettext (" Padding: %8" PRIx16 "\n"), padding);
10317
10318 if (listptr != NULL
10319 && listptr->offset != (Dwarf_Off) (readp - start))
10320 {
10321 error (0, 0, "String offsets index doesn't start after header");
10322 goto next_unit;
10323 }
10324
10325 printf ("\n");
10326 }
10327
10328 int digits = 1;
10329 size_t offsets = (next_unitp - readp) / offset_size;
10330 while (offsets >= 10)
10331 {
10332 ++digits;
10333 offsets /= 10;
10334 }
10335
10336 unsigned int uidx = 0;
10337 size_t index_offset = readp - (const unsigned char *) data->d_buf;
10338 printf (" Offsets start at 0x%zx:\n", index_offset);
10339 while (readp <= next_unitp - offset_size)
10340 {
10341 Dwarf_Word offset;
10342 if (offset_size == 4)
10343 offset = read_4ubyte_unaligned_inc (dbg, readp);
10344 else
10345 offset = read_8ubyte_unaligned_inc (dbg, readp);
10346 const char *str = dwarf_getstring (dbg, offset, NULL);
10347 printf (" [%*u] [%*" PRIx64 "] \"%s\"\n",
10348 digits, uidx++, (int) offset_size * 2, offset, str ?: "???");
10349 }
10350 printf ("\n");
10351
10352 if (readp != next_unitp)
10353 error (0, 0, "extra %zd bytes at end of unit",
10354 (size_t) (next_unitp - readp));
10355
10356 next_unit:
10357 readp = next_unitp;
10358 }
10359 }
10360
10361
10362 /* Print the content of the call frame search table section
10363 '.eh_frame_hdr'. */
10364 static void
print_debug_frame_hdr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10365 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
10366 Ebl *ebl __attribute__ ((unused)),
10367 GElf_Ehdr *ehdr __attribute__ ((unused)),
10368 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10369 {
10370 printf (gettext ("\
10371 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
10372 elf_ndxscn (scn));
10373
10374 Elf_Data *data = elf_rawdata (scn, NULL);
10375
10376 if (unlikely (data == NULL))
10377 {
10378 error (0, 0, gettext ("cannot get %s content: %s"),
10379 ".eh_frame_hdr", elf_errmsg (-1));
10380 return;
10381 }
10382
10383 const unsigned char *readp = data->d_buf;
10384 const unsigned char *const dataend = ((unsigned char *) data->d_buf
10385 + data->d_size);
10386
10387 if (unlikely (readp + 4 > dataend))
10388 {
10389 invalid_data:
10390 error (0, 0, gettext ("invalid data"));
10391 return;
10392 }
10393
10394 unsigned int version = *readp++;
10395 unsigned int eh_frame_ptr_enc = *readp++;
10396 unsigned int fde_count_enc = *readp++;
10397 unsigned int table_enc = *readp++;
10398
10399 printf (" version: %u\n"
10400 " eh_frame_ptr_enc: %#x ",
10401 version, eh_frame_ptr_enc);
10402 print_encoding_base ("", eh_frame_ptr_enc);
10403 printf (" fde_count_enc: %#x ", fde_count_enc);
10404 print_encoding_base ("", fde_count_enc);
10405 printf (" table_enc: %#x ", table_enc);
10406 print_encoding_base ("", table_enc);
10407
10408 uint64_t eh_frame_ptr = 0;
10409 if (eh_frame_ptr_enc != DW_EH_PE_omit)
10410 {
10411 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
10412 dbg);
10413 if (unlikely (readp == NULL))
10414 goto invalid_data;
10415
10416 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
10417 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
10418 printf (" (offset: %#" PRIx64 ")",
10419 /* +4 because of the 4 byte header of the section. */
10420 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
10421
10422 putchar_unlocked ('\n');
10423 }
10424
10425 uint64_t fde_count = 0;
10426 if (fde_count_enc != DW_EH_PE_omit)
10427 {
10428 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
10429 if (unlikely (readp == NULL))
10430 goto invalid_data;
10431
10432 printf (" fde_count: %" PRIu64 "\n", fde_count);
10433 }
10434
10435 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
10436 return;
10437
10438 puts (" Table:");
10439
10440 /* Optimize for the most common case. */
10441 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
10442 while (fde_count > 0 && readp + 8 <= dataend)
10443 {
10444 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
10445 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
10446 + (int64_t) initial_location);
10447 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
10448 // XXX Possibly print symbol name or section offset for initial_offset
10449 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
10450 " fde=[%6" PRIx64 "]\n",
10451 initial_location, initial_offset,
10452 address, address - (eh_frame_ptr + 4));
10453 }
10454 else
10455 while (0 && readp < dataend)
10456 {
10457
10458 }
10459 }
10460
10461
10462 /* Print the content of the exception handling table section
10463 '.eh_frame_hdr'. */
10464 static void
print_debug_exception_table(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10465 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
10466 Ebl *ebl __attribute__ ((unused)),
10467 GElf_Ehdr *ehdr __attribute__ ((unused)),
10468 Elf_Scn *scn,
10469 GElf_Shdr *shdr __attribute__ ((unused)),
10470 Dwarf *dbg __attribute__ ((unused)))
10471 {
10472 printf (gettext ("\
10473 \nException handling table section [%2zu] '.gcc_except_table':\n"),
10474 elf_ndxscn (scn));
10475
10476 Elf_Data *data = elf_rawdata (scn, NULL);
10477
10478 if (unlikely (data == NULL))
10479 {
10480 error (0, 0, gettext ("cannot get %s content: %s"),
10481 ".gcc_except_table", elf_errmsg (-1));
10482 return;
10483 }
10484
10485 const unsigned char *readp = data->d_buf;
10486 const unsigned char *const dataend = readp + data->d_size;
10487
10488 if (unlikely (readp + 1 > dataend))
10489 {
10490 invalid_data:
10491 error (0, 0, gettext ("invalid data"));
10492 return;
10493 }
10494 unsigned int lpstart_encoding = *readp++;
10495 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding);
10496 print_encoding_base ("", lpstart_encoding);
10497 if (lpstart_encoding != DW_EH_PE_omit)
10498 {
10499 uint64_t lpstart;
10500 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
10501 printf (" LPStart: %#" PRIx64 "\n", lpstart);
10502 }
10503
10504 if (unlikely (readp + 1 > dataend))
10505 goto invalid_data;
10506 unsigned int ttype_encoding = *readp++;
10507 printf (gettext (" TType encoding: %#x "), ttype_encoding);
10508 print_encoding_base ("", ttype_encoding);
10509 const unsigned char *ttype_base = NULL;
10510 if (ttype_encoding != DW_EH_PE_omit)
10511 {
10512 unsigned int ttype_base_offset;
10513 get_uleb128 (ttype_base_offset, readp, dataend);
10514 printf (" TType base offset: %#x\n", ttype_base_offset);
10515 if ((size_t) (dataend - readp) > ttype_base_offset)
10516 ttype_base = readp + ttype_base_offset;
10517 }
10518
10519 if (unlikely (readp + 1 > dataend))
10520 goto invalid_data;
10521 unsigned int call_site_encoding = *readp++;
10522 printf (gettext (" Call site encoding: %#x "), call_site_encoding);
10523 print_encoding_base ("", call_site_encoding);
10524 unsigned int call_site_table_len;
10525 get_uleb128 (call_site_table_len, readp, dataend);
10526
10527 const unsigned char *const action_table = readp + call_site_table_len;
10528 if (unlikely (action_table > dataend))
10529 goto invalid_data;
10530 unsigned int u = 0;
10531 unsigned int max_action = 0;
10532 while (readp < action_table)
10533 {
10534 if (u == 0)
10535 puts (gettext ("\n Call site table:"));
10536
10537 uint64_t call_site_start;
10538 readp = read_encoded (call_site_encoding, readp, dataend,
10539 &call_site_start, dbg);
10540 uint64_t call_site_length;
10541 readp = read_encoded (call_site_encoding, readp, dataend,
10542 &call_site_length, dbg);
10543 uint64_t landing_pad;
10544 readp = read_encoded (call_site_encoding, readp, dataend,
10545 &landing_pad, dbg);
10546 unsigned int action;
10547 get_uleb128 (action, readp, dataend);
10548 max_action = MAX (action, max_action);
10549 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n"
10550 " Call site length: %" PRIu64 "\n"
10551 " Landing pad: %#" PRIx64 "\n"
10552 " Action: %u\n"),
10553 u++, call_site_start, call_site_length, landing_pad, action);
10554 }
10555 if (readp != action_table)
10556 goto invalid_data;
10557
10558 unsigned int max_ar_filter = 0;
10559 if (max_action > 0)
10560 {
10561 puts ("\n Action table:");
10562
10563 size_t maxdata = (size_t) (dataend - action_table);
10564 if (max_action > maxdata || maxdata - max_action < 1)
10565 {
10566 invalid_action_table:
10567 fputs (gettext (" <INVALID DATA>\n"), stdout);
10568 return;
10569 }
10570
10571 const unsigned char *const action_table_end
10572 = action_table + max_action + 1;
10573
10574 u = 0;
10575 do
10576 {
10577 int ar_filter;
10578 get_sleb128 (ar_filter, readp, action_table_end);
10579 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
10580 max_ar_filter = ar_filter;
10581 int ar_disp;
10582 if (readp >= action_table_end)
10583 goto invalid_action_table;
10584 get_sleb128 (ar_disp, readp, action_table_end);
10585
10586 printf (" [%4u] ar_filter: % d\n"
10587 " ar_disp: % -5d",
10588 u, ar_filter, ar_disp);
10589 if (abs (ar_disp) & 1)
10590 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
10591 else if (ar_disp != 0)
10592 puts (" -> ???");
10593 else
10594 putchar_unlocked ('\n');
10595 ++u;
10596 }
10597 while (readp < action_table_end);
10598 }
10599
10600 if (max_ar_filter > 0 && ttype_base != NULL)
10601 {
10602 unsigned char dsize;
10603 puts ("\n TType table:");
10604
10605 // XXX Not *4, size of encoding;
10606 switch (ttype_encoding & 7)
10607 {
10608 case DW_EH_PE_udata2:
10609 case DW_EH_PE_sdata2:
10610 dsize = 2;
10611 break;
10612 case DW_EH_PE_udata4:
10613 case DW_EH_PE_sdata4:
10614 dsize = 4;
10615 break;
10616 case DW_EH_PE_udata8:
10617 case DW_EH_PE_sdata8:
10618 dsize = 8;
10619 break;
10620 default:
10621 dsize = 0;
10622 error (1, 0, gettext ("invalid TType encoding"));
10623 }
10624
10625 if (max_ar_filter
10626 > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
10627 goto invalid_data;
10628
10629 readp = ttype_base - max_ar_filter * dsize;
10630 do
10631 {
10632 uint64_t ttype;
10633 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
10634 dbg);
10635 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
10636 }
10637 while (readp < ttype_base);
10638 }
10639 }
10640
10641 /* Print the content of the '.gdb_index' section.
10642 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
10643 */
10644 static void
print_gdb_index_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)10645 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl,
10646 GElf_Ehdr *ehdr __attribute__ ((unused)),
10647 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
10648 {
10649 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
10650 " contains %" PRId64 " bytes :\n"),
10651 elf_ndxscn (scn), section_name (ebl, shdr),
10652 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
10653
10654 Elf_Data *data = elf_rawdata (scn, NULL);
10655
10656 if (unlikely (data == NULL))
10657 {
10658 error (0, 0, gettext ("cannot get %s content: %s"),
10659 ".gdb_index", elf_errmsg (-1));
10660 return;
10661 }
10662
10663 // .gdb_index is always in little endian.
10664 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
10665 dbg = &dummy_dbg;
10666
10667 const unsigned char *readp = data->d_buf;
10668 const unsigned char *const dataend = readp + data->d_size;
10669
10670 if (unlikely (readp + 4 > dataend))
10671 {
10672 invalid_data:
10673 error (0, 0, gettext ("invalid data"));
10674 return;
10675 }
10676
10677 int32_t vers = read_4ubyte_unaligned (dbg, readp);
10678 printf (gettext (" Version: %" PRId32 "\n"), vers);
10679
10680 // The only difference between version 4 and version 5 is the
10681 // hash used for generating the table. Version 6 contains symbols
10682 // for inlined functions, older versions didn't. Version 7 adds
10683 // symbol kinds. Version 8 just indicates that it correctly includes
10684 // TUs for symbols.
10685 if (vers < 4 || vers > 8)
10686 {
10687 printf (gettext (" unknown version, cannot parse section\n"));
10688 return;
10689 }
10690
10691 readp += 4;
10692 if (unlikely (readp + 4 > dataend))
10693 goto invalid_data;
10694
10695 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
10696 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off);
10697
10698 readp += 4;
10699 if (unlikely (readp + 4 > dataend))
10700 goto invalid_data;
10701
10702 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
10703 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off);
10704
10705 readp += 4;
10706 if (unlikely (readp + 4 > dataend))
10707 goto invalid_data;
10708
10709 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
10710 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off);
10711
10712 readp += 4;
10713 if (unlikely (readp + 4 > dataend))
10714 goto invalid_data;
10715
10716 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
10717 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off);
10718
10719 readp += 4;
10720 if (unlikely (readp + 4 > dataend))
10721 goto invalid_data;
10722
10723 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
10724 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
10725
10726 if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
10727 < const_off))
10728 goto invalid_data;
10729
10730 readp = data->d_buf + cu_off;
10731
10732 const unsigned char *nextp = data->d_buf + tu_off;
10733 if (tu_off >= data->d_size)
10734 goto invalid_data;
10735
10736 size_t cu_nr = (nextp - readp) / 16;
10737
10738 printf (gettext ("\n CU list at offset %#" PRIx32
10739 " contains %zu entries:\n"),
10740 cu_off, cu_nr);
10741
10742 size_t n = 0;
10743 while (dataend - readp >= 16 && n < cu_nr)
10744 {
10745 uint64_t off = read_8ubyte_unaligned (dbg, readp);
10746 readp += 8;
10747
10748 uint64_t len = read_8ubyte_unaligned (dbg, readp);
10749 readp += 8;
10750
10751 printf (" [%4zu] start: %0#8" PRIx64
10752 ", length: %5" PRIu64 "\n", n, off, len);
10753 n++;
10754 }
10755
10756 readp = data->d_buf + tu_off;
10757 nextp = data->d_buf + addr_off;
10758 if (addr_off >= data->d_size)
10759 goto invalid_data;
10760
10761 size_t tu_nr = (nextp - readp) / 24;
10762
10763 printf (gettext ("\n TU list at offset %#" PRIx32
10764 " contains %zu entries:\n"),
10765 tu_off, tu_nr);
10766
10767 n = 0;
10768 while (dataend - readp >= 24 && n < tu_nr)
10769 {
10770 uint64_t off = read_8ubyte_unaligned (dbg, readp);
10771 readp += 8;
10772
10773 uint64_t type = read_8ubyte_unaligned (dbg, readp);
10774 readp += 8;
10775
10776 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
10777 readp += 8;
10778
10779 printf (" [%4zu] CU offset: %5" PRId64
10780 ", type offset: %5" PRId64
10781 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
10782 n++;
10783 }
10784
10785 readp = data->d_buf + addr_off;
10786 nextp = data->d_buf + sym_off;
10787 if (sym_off >= data->d_size)
10788 goto invalid_data;
10789
10790 size_t addr_nr = (nextp - readp) / 20;
10791
10792 printf (gettext ("\n Address list at offset %#" PRIx32
10793 " contains %zu entries:\n"),
10794 addr_off, addr_nr);
10795
10796 n = 0;
10797 while (dataend - readp >= 20 && n < addr_nr)
10798 {
10799 uint64_t low = read_8ubyte_unaligned (dbg, readp);
10800 readp += 8;
10801
10802 uint64_t high = read_8ubyte_unaligned (dbg, readp);
10803 readp += 8;
10804
10805 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
10806 readp += 4;
10807
10808 printf (" [%4zu] ", n);
10809 print_dwarf_addr (dwflmod, 8, low, low);
10810 printf ("..");
10811 print_dwarf_addr (dwflmod, 8, high - 1, high);
10812 printf (", CU index: %5" PRId32 "\n", idx);
10813 n++;
10814 }
10815
10816 const unsigned char *const_start = data->d_buf + const_off;
10817 if (const_off >= data->d_size)
10818 goto invalid_data;
10819
10820 readp = data->d_buf + sym_off;
10821 nextp = const_start;
10822 size_t sym_nr = (nextp - readp) / 8;
10823
10824 printf (gettext ("\n Symbol table at offset %#" PRIx32
10825 " contains %zu slots:\n"),
10826 addr_off, sym_nr);
10827
10828 n = 0;
10829 while (dataend - readp >= 8 && n < sym_nr)
10830 {
10831 uint32_t name = read_4ubyte_unaligned (dbg, readp);
10832 readp += 4;
10833
10834 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
10835 readp += 4;
10836
10837 if (name != 0 || vector != 0)
10838 {
10839 const unsigned char *sym = const_start + name;
10840 if (unlikely ((size_t) (dataend - const_start) < name
10841 || memchr (sym, '\0', dataend - sym) == NULL))
10842 goto invalid_data;
10843
10844 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
10845
10846 const unsigned char *readcus = const_start + vector;
10847 if (unlikely ((size_t) (dataend - const_start) < vector))
10848 goto invalid_data;
10849 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
10850 while (cus--)
10851 {
10852 uint32_t cu_kind, cu, kind;
10853 bool is_static;
10854 readcus += 4;
10855 if (unlikely (readcus + 4 > dataend))
10856 goto invalid_data;
10857 cu_kind = read_4ubyte_unaligned (dbg, readcus);
10858 cu = cu_kind & ((1 << 24) - 1);
10859 kind = (cu_kind >> 28) & 7;
10860 is_static = cu_kind & (1U << 31);
10861 if (cu > cu_nr - 1)
10862 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
10863 else
10864 printf ("%" PRId32, cu);
10865 if (kind != 0)
10866 {
10867 printf (" (");
10868 switch (kind)
10869 {
10870 case 1:
10871 printf ("type");
10872 break;
10873 case 2:
10874 printf ("var");
10875 break;
10876 case 3:
10877 printf ("func");
10878 break;
10879 case 4:
10880 printf ("other");
10881 break;
10882 default:
10883 printf ("unknown-0x%" PRIx32, kind);
10884 break;
10885 }
10886 printf (":%c)", (is_static ? 'S' : 'G'));
10887 }
10888 if (cus > 0)
10889 printf (", ");
10890 }
10891 printf ("\n");
10892 }
10893 n++;
10894 }
10895 }
10896
10897 /* Returns true and sets split DWARF CU id if there is a split compile
10898 unit in the given Dwarf, and no non-split units are found (before it). */
10899 static bool
is_split_dwarf(Dwarf * dbg,uint64_t * id,Dwarf_CU ** split_cu)10900 is_split_dwarf (Dwarf *dbg, uint64_t *id, Dwarf_CU **split_cu)
10901 {
10902 Dwarf_CU *cu = NULL;
10903 while (dwarf_get_units (dbg, cu, &cu, NULL, NULL, NULL, NULL) == 0)
10904 {
10905 uint8_t unit_type;
10906 if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
10907 id, NULL, NULL) != 0)
10908 return false;
10909
10910 if (unit_type != DW_UT_split_compile && unit_type != DW_UT_split_type)
10911 return false;
10912
10913 /* We really only care about the split compile unit, the types
10914 should be fine and self sufficient. Also they don't have an
10915 id that we can match with a skeleton unit. */
10916 if (unit_type == DW_UT_split_compile)
10917 {
10918 *split_cu = cu;
10919 return true;
10920 }
10921 }
10922
10923 return false;
10924 }
10925
10926 /* Check that there is one and only one Dwfl_Module, return in arg. */
10927 static int
getone_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)10928 getone_dwflmod (Dwfl_Module *dwflmod,
10929 void **userdata __attribute__ ((unused)),
10930 const char *name __attribute__ ((unused)),
10931 Dwarf_Addr base __attribute__ ((unused)),
10932 void *arg)
10933 {
10934 Dwfl_Module **m = (Dwfl_Module **) arg;
10935 if (*m != NULL)
10936 return DWARF_CB_ABORT;
10937 *m = dwflmod;
10938 return DWARF_CB_OK;
10939 }
10940
10941 static void
print_debug(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr)10942 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
10943 {
10944 /* Used for skeleton file, if necessary for split DWARF. */
10945 Dwfl *skel_dwfl = NULL;
10946 Dwfl_Module *skel_mod = NULL;
10947 char *skel_name = NULL;
10948 Dwarf *split_dbg = NULL;
10949 Dwarf_CU *split_cu = NULL;
10950
10951 /* Before we start the real work get a debug context descriptor. */
10952 Dwarf_Addr dwbias;
10953 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
10954 Dwarf dummy_dbg =
10955 {
10956 .elf = ebl->elf,
10957 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
10958 };
10959 if (dbg == NULL)
10960 {
10961 if ((print_debug_sections & ~section_exception) != 0)
10962 error (0, 0, gettext ("cannot get debug context descriptor: %s"),
10963 dwfl_errmsg (-1));
10964 dbg = &dummy_dbg;
10965 }
10966 else
10967 {
10968 /* If we are asked about a split dwarf (.dwo) file, use the user
10969 provided, or find the corresponding skeleton file. If we got
10970 a skeleton file, replace the given dwflmod and dbg, with one
10971 derived from the skeleton file to provide enough context. */
10972 uint64_t split_id;
10973 if (is_split_dwarf (dbg, &split_id, &split_cu))
10974 {
10975 if (dwarf_skeleton != NULL)
10976 skel_name = strdup (dwarf_skeleton);
10977 else
10978 {
10979 /* Replace file.dwo with file.o and see if that matches. */
10980 const char *fname;
10981 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL,
10982 &fname, NULL);
10983 if (fname != NULL)
10984 {
10985 size_t flen = strlen (fname);
10986 if (flen > 4 && strcmp (".dwo", fname + flen - 4) == 0)
10987 {
10988 skel_name = strdup (fname);
10989 if (skel_name != NULL)
10990 {
10991 skel_name[flen - 3] = 'o';
10992 skel_name[flen - 2] = '\0';
10993 }
10994 }
10995 }
10996 }
10997
10998 if (skel_name != NULL)
10999 {
11000 int skel_fd = open (skel_name, O_RDONLY);
11001 if (skel_fd == -1)
11002 fprintf (stderr, "Warning: Couldn't open DWARF skeleton file"
11003 " '%s'\n", skel_name);
11004 else
11005 skel_dwfl = create_dwfl (skel_fd, skel_name);
11006
11007 if (skel_dwfl != NULL)
11008 {
11009 if (dwfl_getmodules (skel_dwfl, &getone_dwflmod,
11010 &skel_mod, 0) != 0)
11011 {
11012 fprintf (stderr, "Warning: Bad DWARF skeleton,"
11013 " multiple modules '%s'\n", skel_name);
11014 dwfl_end (skel_dwfl);
11015 skel_mod = NULL;
11016 }
11017 }
11018 else if (skel_fd != -1)
11019 fprintf (stderr, "Warning: Couldn't create skeleton dwfl for"
11020 " '%s': %s\n", skel_name, dwfl_errmsg (-1));
11021
11022 if (skel_mod != NULL)
11023 {
11024 Dwarf *skel_dbg = dwfl_module_getdwarf (skel_mod, &dwbias);
11025 if (skel_dbg != NULL)
11026 {
11027 /* First check the skeleton CU DIE, only fetch
11028 the split DIE if we know the id matches to
11029 not unnecessary search for any split DIEs we
11030 don't need. */
11031 Dwarf_CU *cu = NULL;
11032 while (dwarf_get_units (skel_dbg, cu, &cu,
11033 NULL, NULL, NULL, NULL) == 0)
11034 {
11035 uint8_t unit_type;
11036 uint64_t skel_id;
11037 if (dwarf_cu_info (cu, NULL, &unit_type, NULL, NULL,
11038 &skel_id, NULL, NULL) == 0
11039 && unit_type == DW_UT_skeleton
11040 && split_id == skel_id)
11041 {
11042 Dwarf_Die subdie;
11043 if (dwarf_cu_info (cu, NULL, NULL, NULL,
11044 &subdie,
11045 NULL, NULL, NULL) == 0
11046 && dwarf_tag (&subdie) != DW_TAG_invalid)
11047 {
11048 split_dbg = dwarf_cu_getdwarf (subdie.cu);
11049 if (split_dbg == NULL)
11050 fprintf (stderr,
11051 "Warning: Couldn't get split_dbg:"
11052 " %s\n", dwarf_errmsg (-1));
11053 break;
11054 }
11055 else
11056 {
11057 /* Everything matches up, but not
11058 according to libdw. Which means
11059 the user knew better. So...
11060 Terrible hack... We can never
11061 destroy the underlying dwfl
11062 because it would free the wrong
11063 Dwarfs... So we leak memory...*/
11064 if (cu->split == NULL
11065 && dwarf_skeleton != NULL)
11066 {
11067 do_not_close_dwfl = true;
11068 __libdw_link_skel_split (cu, split_cu);
11069 split_dbg = dwarf_cu_getdwarf (split_cu);
11070 break;
11071 }
11072 else
11073 fprintf (stderr, "Warning: Couldn't get"
11074 " skeleton subdie: %s\n",
11075 dwarf_errmsg (-1));
11076 }
11077 }
11078 }
11079 if (split_dbg == NULL)
11080 fprintf (stderr, "Warning: '%s' didn't contain a skeleton for split id %" PRIx64 "\n", skel_name, split_id);
11081 }
11082 else
11083 fprintf (stderr, "Warning: Couldn't get skeleton DWARF:"
11084 " %s\n", dwfl_errmsg (-1));
11085 }
11086 }
11087
11088 if (split_dbg != NULL)
11089 {
11090 dbg = split_dbg;
11091 dwflmod = skel_mod;
11092 }
11093 else if (skel_name == NULL)
11094 fprintf (stderr,
11095 "Warning: split DWARF file, but no skeleton found.\n");
11096 }
11097 else if (dwarf_skeleton != NULL)
11098 fprintf (stderr, "Warning: DWARF skeleton given,"
11099 " but not a split DWARF file\n");
11100 }
11101
11102 /* Get the section header string table index. */
11103 size_t shstrndx;
11104 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
11105 error (EXIT_FAILURE, 0,
11106 gettext ("cannot get section header string table index"));
11107
11108 /* If the .debug_info section is listed as implicitly required then
11109 we must make sure to handle it before handling any other debug
11110 section. Various other sections depend on the CU DIEs being
11111 scanned (silently) first. */
11112 bool implicit_info = (implicit_debug_sections & section_info) != 0;
11113 bool explicit_info = (print_debug_sections & section_info) != 0;
11114 if (implicit_info)
11115 {
11116 Elf_Scn *scn = NULL;
11117 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11118 {
11119 GElf_Shdr shdr_mem;
11120 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11121
11122 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11123 {
11124 const char *name = elf_strptr (ebl->elf, shstrndx,
11125 shdr->sh_name);
11126 if (name == NULL)
11127 continue;
11128
11129 if (strcmp (name, ".debug_info") == 0
11130 || strcmp (name, ".debug_info.dwo") == 0
11131 || strcmp (name, ".zdebug_info") == 0
11132 || strcmp (name, ".zdebug_info.dwo") == 0)
11133 {
11134 print_debug_info_section (dwflmod, ebl, ehdr,
11135 scn, shdr, dbg);
11136 break;
11137 }
11138 }
11139 }
11140 print_debug_sections &= ~section_info;
11141 implicit_debug_sections &= ~section_info;
11142 }
11143
11144 /* Look through all the sections for the debugging sections to print. */
11145 Elf_Scn *scn = NULL;
11146 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
11147 {
11148 GElf_Shdr shdr_mem;
11149 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
11150
11151 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
11152 {
11153 static const struct
11154 {
11155 const char *name;
11156 enum section_e bitmask;
11157 void (*fp) (Dwfl_Module *, Ebl *,
11158 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
11159 } debug_sections[] =
11160 {
11161 #define NEW_SECTION(name) \
11162 { ".debug_" #name, section_##name, print_debug_##name##_section }
11163 NEW_SECTION (abbrev),
11164 NEW_SECTION (addr),
11165 NEW_SECTION (aranges),
11166 NEW_SECTION (frame),
11167 NEW_SECTION (info),
11168 NEW_SECTION (types),
11169 NEW_SECTION (line),
11170 NEW_SECTION (loc),
11171 /* loclists is loc for DWARF5. */
11172 { ".debug_loclists", section_loc,
11173 print_debug_loclists_section },
11174 NEW_SECTION (pubnames),
11175 NEW_SECTION (str),
11176 /* A DWARF5 specialised debug string section. */
11177 { ".debug_line_str", section_str,
11178 print_debug_str_section },
11179 /* DWARF5 string offsets table. */
11180 { ".debug_str_offsets", section_str,
11181 print_debug_str_offsets_section },
11182 NEW_SECTION (macinfo),
11183 NEW_SECTION (macro),
11184 NEW_SECTION (ranges),
11185 /* rnglists is ranges for DWARF5. */
11186 { ".debug_rnglists", section_ranges,
11187 print_debug_rnglists_section },
11188 { ".eh_frame", section_frame | section_exception,
11189 print_debug_frame_section },
11190 { ".eh_frame_hdr", section_frame | section_exception,
11191 print_debug_frame_hdr_section },
11192 { ".gcc_except_table", section_frame | section_exception,
11193 print_debug_exception_table },
11194 { ".gdb_index", section_gdb_index, print_gdb_index_section }
11195 };
11196 const int ndebug_sections = (sizeof (debug_sections)
11197 / sizeof (debug_sections[0]));
11198 const char *name = elf_strptr (ebl->elf, shstrndx,
11199 shdr->sh_name);
11200 if (name == NULL)
11201 continue;
11202
11203 int n;
11204 for (n = 0; n < ndebug_sections; ++n)
11205 {
11206 size_t dbglen = strlen (debug_sections[n].name);
11207 size_t scnlen = strlen (name);
11208 if ((strncmp (name, debug_sections[n].name, dbglen) == 0
11209 && (dbglen == scnlen
11210 || (scnlen == dbglen + 4
11211 && strstr (name, ".dwo") == name + dbglen)))
11212 || (name[0] == '.' && name[1] == 'z'
11213 && debug_sections[n].name[1] == 'd'
11214 && strncmp (&name[2], &debug_sections[n].name[1],
11215 dbglen - 1) == 0
11216 && (scnlen == dbglen + 1
11217 || (scnlen == dbglen + 5
11218 && strstr (name, ".dwo") == name + dbglen + 1))))
11219 {
11220 if ((print_debug_sections | implicit_debug_sections)
11221 & debug_sections[n].bitmask)
11222 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
11223 break;
11224 }
11225 }
11226 }
11227 }
11228
11229 dwfl_end (skel_dwfl);
11230 free (skel_name);
11231
11232 /* Turn implicit and/or explicit back on in case we go over another file. */
11233 if (implicit_info)
11234 implicit_debug_sections |= section_info;
11235 if (explicit_info)
11236 print_debug_sections |= section_info;
11237
11238 reset_listptr (&known_locsptr);
11239 reset_listptr (&known_loclistsptr);
11240 reset_listptr (&known_rangelistptr);
11241 reset_listptr (&known_rnglistptr);
11242 reset_listptr (&known_addrbases);
11243 reset_listptr (&known_stroffbases);
11244 }
11245
11246
11247 #define ITEM_INDENT 4
11248 #define WRAP_COLUMN 75
11249
11250 /* Print "NAME: FORMAT", wrapping when output text would make the line
11251 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
11252 but this function is also used for registers which should be printed
11253 aligned. Fortunately registers output uses fixed fields width (such
11254 as %11d) for the alignment.
11255
11256 Line breaks should not depend on the particular values although that
11257 may happen in some cases of the core items. */
11258
11259 static unsigned int
11260 __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,...)11261 print_core_item (unsigned int colno, char sep, unsigned int wrap,
11262 size_t name_width, const char *name, const char *format, ...)
11263 {
11264 size_t len = strlen (name);
11265 if (name_width < len)
11266 name_width = len;
11267
11268 char *out;
11269 va_list ap;
11270 va_start (ap, format);
11271 int out_len = vasprintf (&out, format, ap);
11272 va_end (ap);
11273 if (out_len == -1)
11274 error (EXIT_FAILURE, 0, _("memory exhausted"));
11275
11276 size_t n = name_width + sizeof ": " - 1 + out_len;
11277
11278 if (colno == 0)
11279 {
11280 printf ("%*s", ITEM_INDENT, "");
11281 colno = ITEM_INDENT + n;
11282 }
11283 else if (colno + 2 + n < wrap)
11284 {
11285 printf ("%c ", sep);
11286 colno += 2 + n;
11287 }
11288 else
11289 {
11290 printf ("\n%*s", ITEM_INDENT, "");
11291 colno = ITEM_INDENT + n;
11292 }
11293
11294 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
11295
11296 free (out);
11297
11298 return colno;
11299 }
11300
11301 static const void *
convert(Elf * core,Elf_Type type,uint_fast16_t count,void * value,const void * data,size_t size)11302 convert (Elf *core, Elf_Type type, uint_fast16_t count,
11303 void *value, const void *data, size_t size)
11304 {
11305 Elf_Data valuedata =
11306 {
11307 .d_type = type,
11308 .d_buf = value,
11309 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
11310 .d_version = EV_CURRENT,
11311 };
11312 Elf_Data indata =
11313 {
11314 .d_type = type,
11315 .d_buf = (void *) data,
11316 .d_size = valuedata.d_size,
11317 .d_version = EV_CURRENT,
11318 };
11319
11320 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
11321 ? elf32_xlatetom : elf64_xlatetom)
11322 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
11323 if (d == NULL)
11324 error (EXIT_FAILURE, 0,
11325 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
11326
11327 return data + indata.d_size;
11328 }
11329
11330 typedef uint8_t GElf_Byte;
11331
11332 static unsigned int
handle_core_item(Elf * core,const Ebl_Core_Item * item,const void * desc,unsigned int colno,size_t * repeated_size)11333 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
11334 unsigned int colno, size_t *repeated_size)
11335 {
11336 uint_fast16_t count = item->count ?: 1;
11337 /* Ebl_Core_Item count is always a small number.
11338 Make sure the backend didn't put in some large bogus value. */
11339 assert (count < 128);
11340
11341 #define TYPES \
11342 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
11343 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
11344 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
11345 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
11346 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
11347 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
11348
11349 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
11350 typedef union { TYPES; } value_t;
11351 void *data = alloca (count * sizeof (value_t));
11352 #undef DO_TYPE
11353
11354 #define DO_TYPE(NAME, Name, hex, dec) \
11355 GElf_##Name *value_##Name __attribute__((unused)) = data
11356 TYPES;
11357 #undef DO_TYPE
11358
11359 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
11360 size_t convsize = size;
11361 if (repeated_size != NULL)
11362 {
11363 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
11364 {
11365 data = alloca (*repeated_size);
11366 count *= *repeated_size / size;
11367 convsize = count * size;
11368 *repeated_size -= convsize;
11369 }
11370 else if (item->count != 0 || item->format != '\n')
11371 *repeated_size -= size;
11372 }
11373
11374 convert (core, item->type, count, data, desc + item->offset, convsize);
11375
11376 Elf_Type type = item->type;
11377 if (type == ELF_T_ADDR)
11378 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
11379
11380 switch (item->format)
11381 {
11382 case 'd':
11383 assert (count == 1);
11384 switch (type)
11385 {
11386 #define DO_TYPE(NAME, Name, hex, dec) \
11387 case ELF_T_##NAME: \
11388 colno = print_core_item (colno, ',', WRAP_COLUMN, \
11389 0, item->name, dec, value_##Name[0]); \
11390 break
11391 TYPES;
11392 #undef DO_TYPE
11393 default:
11394 abort ();
11395 }
11396 break;
11397
11398 case 'x':
11399 assert (count == 1);
11400 switch (type)
11401 {
11402 #define DO_TYPE(NAME, Name, hex, dec) \
11403 case ELF_T_##NAME: \
11404 colno = print_core_item (colno, ',', WRAP_COLUMN, \
11405 0, item->name, hex, value_##Name[0]); \
11406 break
11407 TYPES;
11408 #undef DO_TYPE
11409 default:
11410 abort ();
11411 }
11412 break;
11413
11414 case 'b':
11415 case 'B':
11416 assert (size % sizeof (unsigned int) == 0);
11417 unsigned int nbits = count * size * 8;
11418 unsigned int pop = 0;
11419 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
11420 pop += __builtin_popcount (*i);
11421 bool negate = pop > nbits / 2;
11422 const unsigned int bias = item->format == 'b';
11423
11424 {
11425 char printed[(negate ? nbits - pop : pop) * 16 + 1];
11426 char *p = printed;
11427 *p = '\0';
11428
11429 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
11430 {
11431 assert (size == sizeof (unsigned int) * 2);
11432 for (unsigned int *i = data;
11433 (void *) i < data + count * size; i += 2)
11434 {
11435 unsigned int w = i[1];
11436 i[1] = i[0];
11437 i[0] = w;
11438 }
11439 }
11440
11441 unsigned int lastbit = 0;
11442 unsigned int run = 0;
11443 for (const unsigned int *i = data;
11444 (void *) i < data + count * size; ++i)
11445 {
11446 unsigned int bit = ((void *) i - data) * 8;
11447 unsigned int w = negate ? ~*i : *i;
11448 while (w != 0)
11449 {
11450 /* Note that a right shift equal to (or greater than)
11451 the number of bits of w is undefined behaviour. In
11452 particular when the least significant bit is bit 32
11453 (w = 0x8000000) then w >>= n is undefined. So
11454 explicitly handle that case separately. */
11455 unsigned int n = ffs (w);
11456 if (n < sizeof (w) * 8)
11457 w >>= n;
11458 else
11459 w = 0;
11460 bit += n;
11461
11462 if (lastbit != 0 && lastbit + 1 == bit)
11463 ++run;
11464 else
11465 {
11466 if (lastbit == 0)
11467 p += sprintf (p, "%u", bit - bias);
11468 else if (run == 0)
11469 p += sprintf (p, ",%u", bit - bias);
11470 else
11471 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
11472 run = 0;
11473 }
11474
11475 lastbit = bit;
11476 }
11477 }
11478 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
11479 p += sprintf (p, "-%u", lastbit - bias);
11480
11481 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11482 negate ? "~<%s>" : "<%s>", printed);
11483 }
11484 break;
11485
11486 case 'T':
11487 case (char) ('T'|0x80):
11488 assert (count == 2);
11489 Dwarf_Word sec;
11490 Dwarf_Word usec;
11491 switch (type)
11492 {
11493 #define DO_TYPE(NAME, Name, hex, dec) \
11494 case ELF_T_##NAME: \
11495 sec = value_##Name[0]; \
11496 usec = value_##Name[1]; \
11497 break
11498 TYPES;
11499 #undef DO_TYPE
11500 default:
11501 abort ();
11502 }
11503 if (unlikely (item->format == (char) ('T'|0x80)))
11504 {
11505 /* This is a hack for an ill-considered 64-bit ABI where
11506 tv_usec is actually a 32-bit field with 32 bits of padding
11507 rounding out struct timeval. We've already converted it as
11508 a 64-bit field. For little-endian, this just means the
11509 high half is the padding; it's presumably zero, but should
11510 be ignored anyway. For big-endian, it means the 32-bit
11511 field went into the high half of USEC. */
11512 GElf_Ehdr ehdr_mem;
11513 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
11514 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
11515 usec >>= 32;
11516 else
11517 usec &= UINT32_MAX;
11518 }
11519 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11520 "%" PRIu64 ".%.6" PRIu64, sec, usec);
11521 break;
11522
11523 case 'c':
11524 assert (count == 1);
11525 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11526 "%c", value_Byte[0]);
11527 break;
11528
11529 case 's':
11530 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
11531 "%.*s", (int) count, value_Byte);
11532 break;
11533
11534 case '\n':
11535 /* This is a list of strings separated by '\n'. */
11536 assert (item->count == 0);
11537 assert (repeated_size != NULL);
11538 assert (item->name == NULL);
11539 if (unlikely (item->offset >= *repeated_size))
11540 break;
11541
11542 const char *s = desc + item->offset;
11543 size = *repeated_size - item->offset;
11544 *repeated_size = 0;
11545 while (size > 0)
11546 {
11547 const char *eol = memchr (s, '\n', size);
11548 int len = size;
11549 if (eol != NULL)
11550 len = eol - s;
11551 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
11552 if (eol == NULL)
11553 break;
11554 size -= eol + 1 - s;
11555 s = eol + 1;
11556 }
11557
11558 colno = WRAP_COLUMN;
11559 break;
11560
11561 case 'h':
11562 break;
11563
11564 default:
11565 error (0, 0, "XXX not handling format '%c' for %s",
11566 item->format, item->name);
11567 break;
11568 }
11569
11570 #undef TYPES
11571
11572 return colno;
11573 }
11574
11575
11576 /* Sort items by group, and by layout offset within each group. */
11577 static int
compare_core_items(const void * a,const void * b)11578 compare_core_items (const void *a, const void *b)
11579 {
11580 const Ebl_Core_Item *const *p1 = a;
11581 const Ebl_Core_Item *const *p2 = b;
11582 const Ebl_Core_Item *item1 = *p1;
11583 const Ebl_Core_Item *item2 = *p2;
11584
11585 return ((item1->group == item2->group ? 0
11586 : strcmp (item1->group, item2->group))
11587 ?: (int) item1->offset - (int) item2->offset);
11588 }
11589
11590 /* Sort item groups by layout offset of the first item in the group. */
11591 static int
compare_core_item_groups(const void * a,const void * b)11592 compare_core_item_groups (const void *a, const void *b)
11593 {
11594 const Ebl_Core_Item *const *const *p1 = a;
11595 const Ebl_Core_Item *const *const *p2 = b;
11596 const Ebl_Core_Item *const *group1 = *p1;
11597 const Ebl_Core_Item *const *group2 = *p2;
11598 const Ebl_Core_Item *item1 = *group1;
11599 const Ebl_Core_Item *item2 = *group2;
11600
11601 return (int) item1->offset - (int) item2->offset;
11602 }
11603
11604 static unsigned int
handle_core_items(Elf * core,const void * desc,size_t descsz,const Ebl_Core_Item * items,size_t nitems)11605 handle_core_items (Elf *core, const void *desc, size_t descsz,
11606 const Ebl_Core_Item *items, size_t nitems)
11607 {
11608 if (nitems == 0)
11609 return 0;
11610 unsigned int colno = 0;
11611
11612 /* FORMAT '\n' makes sense to be present only as a single item as it
11613 processes all the data of a note. FORMATs 'b' and 'B' have a special case
11614 if present as a single item but they can be also processed with other
11615 items below. */
11616 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
11617 || items[0].format == 'B'))
11618 {
11619 assert (items[0].offset == 0);
11620 size_t size = descsz;
11621 colno = handle_core_item (core, items, desc, colno, &size);
11622 /* If SIZE is not zero here there is some remaining data. But we do not
11623 know how to process it anyway. */
11624 return colno;
11625 }
11626 for (size_t i = 0; i < nitems; ++i)
11627 assert (items[i].format != '\n');
11628
11629 /* Sort to collect the groups together. */
11630 const Ebl_Core_Item *sorted_items[nitems];
11631 for (size_t i = 0; i < nitems; ++i)
11632 sorted_items[i] = &items[i];
11633 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
11634
11635 /* Collect the unique groups and sort them. */
11636 const Ebl_Core_Item **groups[nitems];
11637 groups[0] = &sorted_items[0];
11638 size_t ngroups = 1;
11639 for (size_t i = 1; i < nitems; ++i)
11640 if (sorted_items[i]->group != sorted_items[i - 1]->group
11641 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
11642 groups[ngroups++] = &sorted_items[i];
11643 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
11644
11645 /* Write out all the groups. */
11646 const void *last = desc;
11647 do
11648 {
11649 for (size_t i = 0; i < ngroups; ++i)
11650 {
11651 for (const Ebl_Core_Item **item = groups[i];
11652 (item < &sorted_items[nitems]
11653 && ((*item)->group == groups[i][0]->group
11654 || !strcmp ((*item)->group, groups[i][0]->group)));
11655 ++item)
11656 colno = handle_core_item (core, *item, desc, colno, NULL);
11657
11658 /* Force a line break at the end of the group. */
11659 colno = WRAP_COLUMN;
11660 }
11661
11662 if (descsz == 0)
11663 break;
11664
11665 /* This set of items consumed a certain amount of the note's data.
11666 If there is more data there, we have another unit of the same size.
11667 Loop to print that out too. */
11668 const Ebl_Core_Item *item = &items[nitems - 1];
11669 size_t eltsz = item->offset + gelf_fsize (core, item->type,
11670 item->count ?: 1, EV_CURRENT);
11671
11672 int reps = -1;
11673 do
11674 {
11675 ++reps;
11676 desc += eltsz;
11677 descsz -= eltsz;
11678 }
11679 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
11680
11681 if (reps == 1)
11682 {
11683 /* For just one repeat, print it unabridged twice. */
11684 desc -= eltsz;
11685 descsz += eltsz;
11686 }
11687 else if (reps > 1)
11688 printf (gettext ("\n%*s... <repeats %u more times> ..."),
11689 ITEM_INDENT, "", reps);
11690
11691 last = desc;
11692 }
11693 while (descsz > 0);
11694
11695 return colno;
11696 }
11697
11698 static unsigned int
handle_bit_registers(const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)11699 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
11700 unsigned int colno)
11701 {
11702 desc += regloc->offset;
11703
11704 abort (); /* XXX */
11705 return colno;
11706 }
11707
11708
11709 static unsigned int
handle_core_register(Ebl * ebl,Elf * core,int maxregname,const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)11710 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
11711 const Ebl_Register_Location *regloc, const void *desc,
11712 unsigned int colno)
11713 {
11714 if (regloc->bits % 8 != 0)
11715 return handle_bit_registers (regloc, desc, colno);
11716
11717 desc += regloc->offset;
11718
11719 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
11720 {
11721 char name[REGNAMESZ];
11722 int bits;
11723 int type;
11724 register_info (ebl, reg, regloc, name, &bits, &type);
11725
11726 #define TYPES \
11727 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
11728 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
11729 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
11730 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
11731
11732 #define BITS(bits, xtype, sfmt, ufmt) \
11733 uint##bits##_t b##bits; int##bits##_t b##bits##s
11734 union { TYPES; uint64_t b128[2]; } value;
11735 #undef BITS
11736
11737 switch (type)
11738 {
11739 case DW_ATE_unsigned:
11740 case DW_ATE_signed:
11741 case DW_ATE_address:
11742 switch (bits)
11743 {
11744 #define BITS(bits, xtype, sfmt, ufmt) \
11745 case bits: \
11746 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
11747 if (type == DW_ATE_signed) \
11748 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
11749 maxregname, name, \
11750 sfmt, value.b##bits##s); \
11751 else \
11752 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
11753 maxregname, name, \
11754 ufmt, value.b##bits); \
11755 break
11756
11757 TYPES;
11758
11759 case 128:
11760 assert (type == DW_ATE_unsigned);
11761 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
11762 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
11763 colno = print_core_item (colno, ' ', WRAP_COLUMN,
11764 maxregname, name,
11765 "0x%.16" PRIx64 "%.16" PRIx64,
11766 value.b128[!be], value.b128[be]);
11767 break;
11768
11769 default:
11770 abort ();
11771 #undef BITS
11772 }
11773 break;
11774
11775 default:
11776 /* Print each byte in hex, the whole thing in native byte order. */
11777 assert (bits % 8 == 0);
11778 const uint8_t *bytes = desc;
11779 desc += bits / 8;
11780 char hex[bits / 4 + 1];
11781 hex[bits / 4] = '\0';
11782 int incr = 1;
11783 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
11784 {
11785 bytes += bits / 8 - 1;
11786 incr = -1;
11787 }
11788 size_t idx = 0;
11789 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
11790 {
11791 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
11792 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
11793 }
11794 colno = print_core_item (colno, ' ', WRAP_COLUMN,
11795 maxregname, name, "0x%s", hex);
11796 break;
11797 }
11798 desc += regloc->pad;
11799
11800 #undef TYPES
11801 }
11802
11803 return colno;
11804 }
11805
11806
11807 struct register_info
11808 {
11809 const Ebl_Register_Location *regloc;
11810 const char *set;
11811 char name[REGNAMESZ];
11812 int regno;
11813 int bits;
11814 int type;
11815 };
11816
11817 static int
register_bitpos(const struct register_info * r)11818 register_bitpos (const struct register_info *r)
11819 {
11820 return (r->regloc->offset * 8
11821 + ((r->regno - r->regloc->regno)
11822 * (r->regloc->bits + r->regloc->pad * 8)));
11823 }
11824
11825 static int
compare_sets_by_info(const struct register_info * r1,const struct register_info * r2)11826 compare_sets_by_info (const struct register_info *r1,
11827 const struct register_info *r2)
11828 {
11829 return ((int) r2->bits - (int) r1->bits
11830 ?: register_bitpos (r1) - register_bitpos (r2));
11831 }
11832
11833 /* Sort registers by set, and by size and layout offset within each set. */
11834 static int
compare_registers(const void * a,const void * b)11835 compare_registers (const void *a, const void *b)
11836 {
11837 const struct register_info *r1 = a;
11838 const struct register_info *r2 = b;
11839
11840 /* Unused elements sort last. */
11841 if (r1->regloc == NULL)
11842 return r2->regloc == NULL ? 0 : 1;
11843 if (r2->regloc == NULL)
11844 return -1;
11845
11846 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
11847 ?: compare_sets_by_info (r1, r2));
11848 }
11849
11850 /* Sort register sets by layout offset of the first register in the set. */
11851 static int
compare_register_sets(const void * a,const void * b)11852 compare_register_sets (const void *a, const void *b)
11853 {
11854 const struct register_info *const *p1 = a;
11855 const struct register_info *const *p2 = b;
11856 return compare_sets_by_info (*p1, *p2);
11857 }
11858
11859 static unsigned int
handle_core_registers(Ebl * ebl,Elf * core,const void * desc,const Ebl_Register_Location * reglocs,size_t nregloc)11860 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
11861 const Ebl_Register_Location *reglocs, size_t nregloc)
11862 {
11863 if (nregloc == 0)
11864 return 0;
11865
11866 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
11867 if (maxnreg <= 0)
11868 {
11869 for (size_t i = 0; i < nregloc; ++i)
11870 if (maxnreg < reglocs[i].regno + reglocs[i].count)
11871 maxnreg = reglocs[i].regno + reglocs[i].count;
11872 assert (maxnreg > 0);
11873 }
11874
11875 struct register_info regs[maxnreg];
11876 memset (regs, 0, sizeof regs);
11877
11878 /* Sort to collect the sets together. */
11879 int maxreg = 0;
11880 for (size_t i = 0; i < nregloc; ++i)
11881 for (int reg = reglocs[i].regno;
11882 reg < reglocs[i].regno + reglocs[i].count;
11883 ++reg)
11884 {
11885 assert (reg < maxnreg);
11886 if (reg > maxreg)
11887 maxreg = reg;
11888 struct register_info *info = ®s[reg];
11889 info->regloc = ®locs[i];
11890 info->regno = reg;
11891 info->set = register_info (ebl, reg, ®locs[i],
11892 info->name, &info->bits, &info->type);
11893 }
11894 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
11895
11896 /* Collect the unique sets and sort them. */
11897 inline bool same_set (const struct register_info *a,
11898 const struct register_info *b)
11899 {
11900 return (a < ®s[maxnreg] && a->regloc != NULL
11901 && b < ®s[maxnreg] && b->regloc != NULL
11902 && a->bits == b->bits
11903 && (a->set == b->set || !strcmp (a->set, b->set)));
11904 }
11905 struct register_info *sets[maxreg + 1];
11906 sets[0] = ®s[0];
11907 size_t nsets = 1;
11908 for (int i = 1; i <= maxreg; ++i)
11909 if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1]))
11910 sets[nsets++] = ®s[i];
11911 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
11912
11913 /* Write out all the sets. */
11914 unsigned int colno = 0;
11915 for (size_t i = 0; i < nsets; ++i)
11916 {
11917 /* Find the longest name of a register in this set. */
11918 size_t maxname = 0;
11919 const struct register_info *end;
11920 for (end = sets[i]; same_set (sets[i], end); ++end)
11921 {
11922 size_t len = strlen (end->name);
11923 if (len > maxname)
11924 maxname = len;
11925 }
11926
11927 for (const struct register_info *reg = sets[i];
11928 reg < end;
11929 reg += reg->regloc->count ?: 1)
11930 colno = handle_core_register (ebl, core, maxname,
11931 reg->regloc, desc, colno);
11932
11933 /* Force a line break at the end of the group. */
11934 colno = WRAP_COLUMN;
11935 }
11936
11937 return colno;
11938 }
11939
11940 static void
handle_auxv_note(Ebl * ebl,Elf * core,GElf_Word descsz,GElf_Off desc_pos)11941 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
11942 {
11943 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
11944 if (data == NULL)
11945 elf_error:
11946 error (EXIT_FAILURE, 0,
11947 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
11948
11949 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
11950 for (size_t i = 0; i < nauxv; ++i)
11951 {
11952 GElf_auxv_t av_mem;
11953 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
11954 if (av == NULL)
11955 goto elf_error;
11956
11957 const char *name;
11958 const char *fmt;
11959 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
11960 {
11961 /* Unknown type. */
11962 if (av->a_un.a_val == 0)
11963 printf (" %" PRIu64 "\n", av->a_type);
11964 else
11965 printf (" %" PRIu64 ": %#" PRIx64 "\n",
11966 av->a_type, av->a_un.a_val);
11967 }
11968 else
11969 switch (fmt[0])
11970 {
11971 case '\0': /* Normally zero. */
11972 if (av->a_un.a_val == 0)
11973 {
11974 printf (" %s\n", name);
11975 break;
11976 }
11977 FALLTHROUGH;
11978 case 'x': /* hex */
11979 case 'p': /* address */
11980 case 's': /* address of string */
11981 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
11982 break;
11983 case 'u':
11984 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
11985 break;
11986 case 'd':
11987 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
11988 break;
11989
11990 case 'b':
11991 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
11992 GElf_Xword bit = 1;
11993 const char *pfx = "<";
11994 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
11995 {
11996 if (av->a_un.a_val & bit)
11997 {
11998 printf ("%s%s", pfx, p);
11999 pfx = " ";
12000 }
12001 bit <<= 1;
12002 }
12003 printf (">\n");
12004 break;
12005
12006 default:
12007 abort ();
12008 }
12009 }
12010 }
12011
12012 static bool
buf_has_data(unsigned char const * ptr,unsigned char const * end,size_t sz)12013 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
12014 {
12015 return ptr < end && (size_t) (end - ptr) >= sz;
12016 }
12017
12018 static bool
buf_read_int(Elf * core,unsigned char const ** ptrp,unsigned char const * end,int * retp)12019 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12020 int *retp)
12021 {
12022 if (! buf_has_data (*ptrp, end, 4))
12023 return false;
12024
12025 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
12026 return true;
12027 }
12028
12029 static bool
buf_read_ulong(Elf * core,unsigned char const ** ptrp,unsigned char const * end,uint64_t * retp)12030 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
12031 uint64_t *retp)
12032 {
12033 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12034 if (! buf_has_data (*ptrp, end, sz))
12035 return false;
12036
12037 union
12038 {
12039 uint64_t u64;
12040 uint32_t u32;
12041 } u;
12042
12043 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
12044
12045 if (sz == 4)
12046 *retp = u.u32;
12047 else
12048 *retp = u.u64;
12049 return true;
12050 }
12051
12052 static void
handle_siginfo_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12053 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12054 {
12055 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12056 if (data == NULL)
12057 error (EXIT_FAILURE, 0,
12058 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12059
12060 unsigned char const *ptr = data->d_buf;
12061 unsigned char const *const end = data->d_buf + data->d_size;
12062
12063 /* Siginfo head is three ints: signal number, error number, origin
12064 code. */
12065 int si_signo, si_errno, si_code;
12066 if (! buf_read_int (core, &ptr, end, &si_signo)
12067 || ! buf_read_int (core, &ptr, end, &si_errno)
12068 || ! buf_read_int (core, &ptr, end, &si_code))
12069 {
12070 fail:
12071 printf (" Not enough data in NT_SIGINFO note.\n");
12072 return;
12073 }
12074
12075 /* Next is a pointer-aligned union of structures. On 64-bit
12076 machines, that implies a word of padding. */
12077 if (gelf_getclass (core) == ELFCLASS64)
12078 ptr += 4;
12079
12080 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
12081 si_signo, si_errno, si_code);
12082
12083 if (si_code > 0)
12084 switch (si_signo)
12085 {
12086 case CORE_SIGILL:
12087 case CORE_SIGFPE:
12088 case CORE_SIGSEGV:
12089 case CORE_SIGBUS:
12090 {
12091 uint64_t addr;
12092 if (! buf_read_ulong (core, &ptr, end, &addr))
12093 goto fail;
12094 printf (" fault address: %#" PRIx64 "\n", addr);
12095 break;
12096 }
12097 default:
12098 ;
12099 }
12100 else if (si_code == CORE_SI_USER)
12101 {
12102 int pid, uid;
12103 if (! buf_read_int (core, &ptr, end, &pid)
12104 || ! buf_read_int (core, &ptr, end, &uid))
12105 goto fail;
12106 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
12107 }
12108 }
12109
12110 static void
handle_file_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)12111 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
12112 {
12113 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
12114 if (data == NULL)
12115 error (EXIT_FAILURE, 0,
12116 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
12117
12118 unsigned char const *ptr = data->d_buf;
12119 unsigned char const *const end = data->d_buf + data->d_size;
12120
12121 uint64_t count, page_size;
12122 if (! buf_read_ulong (core, &ptr, end, &count)
12123 || ! buf_read_ulong (core, &ptr, end, &page_size))
12124 {
12125 fail:
12126 printf (" Not enough data in NT_FILE note.\n");
12127 return;
12128 }
12129
12130 size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
12131 uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
12132 if (count > maxcount)
12133 goto fail;
12134
12135 /* Where file names are stored. */
12136 unsigned char const *const fstart = ptr + 3 * count * addrsize;
12137 char const *fptr = (char *) fstart;
12138
12139 printf (" %" PRId64 " files:\n", count);
12140 for (uint64_t i = 0; i < count; ++i)
12141 {
12142 uint64_t mstart, mend, moffset;
12143 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
12144 || ! buf_read_ulong (core, &ptr, fstart, &mend)
12145 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
12146 goto fail;
12147
12148 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
12149 if (fnext == NULL)
12150 goto fail;
12151
12152 int ct = printf (" %08" PRIx64 "-%08" PRIx64
12153 " %08" PRIx64 " %" PRId64,
12154 mstart, mend, moffset * page_size, mend - mstart);
12155 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
12156
12157 fptr = fnext + 1;
12158 }
12159 }
12160
12161 static void
handle_core_note(Ebl * ebl,const GElf_Nhdr * nhdr,const char * name,const void * desc)12162 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
12163 const char *name, const void *desc)
12164 {
12165 GElf_Word regs_offset;
12166 size_t nregloc;
12167 const Ebl_Register_Location *reglocs;
12168 size_t nitems;
12169 const Ebl_Core_Item *items;
12170
12171 if (! ebl_core_note (ebl, nhdr, name, desc,
12172 ®s_offset, &nregloc, ®locs, &nitems, &items))
12173 return;
12174
12175 /* Pass 0 for DESCSZ when there are registers in the note,
12176 so that the ITEMS array does not describe the whole thing.
12177 For non-register notes, the actual descsz might be a multiple
12178 of the unit size, not just exactly the unit size. */
12179 unsigned int colno = handle_core_items (ebl->elf, desc,
12180 nregloc == 0 ? nhdr->n_descsz : 0,
12181 items, nitems);
12182 if (colno != 0)
12183 putchar_unlocked ('\n');
12184
12185 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
12186 reglocs, nregloc);
12187 if (colno != 0)
12188 putchar_unlocked ('\n');
12189 }
12190
12191 static void
handle_notes_data(Ebl * ebl,const GElf_Ehdr * ehdr,GElf_Off start,Elf_Data * data)12192 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
12193 GElf_Off start, Elf_Data *data)
12194 {
12195 fputs_unlocked (gettext (" Owner Data size Type\n"), stdout);
12196
12197 if (data == NULL)
12198 goto bad_note;
12199
12200 size_t offset = 0;
12201 GElf_Nhdr nhdr;
12202 size_t name_offset;
12203 size_t desc_offset;
12204 while (offset < data->d_size
12205 && (offset = gelf_getnote (data, offset,
12206 &nhdr, &name_offset, &desc_offset)) > 0)
12207 {
12208 const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
12209 const char *desc = data->d_buf + desc_offset;
12210
12211 /* GNU Build Attributes are weird, they store most of their data
12212 into the owner name field. Extract just the owner name
12213 prefix here, then use the rest later as data. */
12214 bool is_gnu_build_attr
12215 = strncmp (name, ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX,
12216 strlen (ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX)) == 0;
12217 const char *print_name = (is_gnu_build_attr
12218 ? ELF_NOTE_GNU_BUILD_ATTRIBUTE_PREFIX : name);
12219 size_t print_namesz = (is_gnu_build_attr
12220 ? strlen (print_name) : nhdr.n_namesz);
12221
12222 char buf[100];
12223 char buf2[100];
12224 printf (gettext (" %-13.*s %9" PRId32 " %s\n"),
12225 (int) print_namesz, print_name, nhdr.n_descsz,
12226 ehdr->e_type == ET_CORE
12227 ? ebl_core_note_type_name (ebl, nhdr.n_type,
12228 buf, sizeof (buf))
12229 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
12230 nhdr.n_descsz,
12231 buf2, sizeof (buf2)));
12232
12233 /* Filter out invalid entries. */
12234 if (memchr (name, '\0', nhdr.n_namesz) != NULL
12235 /* XXX For now help broken Linux kernels. */
12236 || 1)
12237 {
12238 if (ehdr->e_type == ET_CORE)
12239 {
12240 if (nhdr.n_type == NT_AUXV
12241 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
12242 || (nhdr.n_namesz == 5 && name[4] == '\0'))
12243 && !memcmp (name, "CORE", 4))
12244 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
12245 start + desc_offset);
12246 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
12247 switch (nhdr.n_type)
12248 {
12249 case NT_SIGINFO:
12250 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
12251 start + desc_offset);
12252 break;
12253
12254 case NT_FILE:
12255 handle_file_note (ebl->elf, nhdr.n_descsz,
12256 start + desc_offset);
12257 break;
12258
12259 default:
12260 handle_core_note (ebl, &nhdr, name, desc);
12261 }
12262 else
12263 handle_core_note (ebl, &nhdr, name, desc);
12264 }
12265 else
12266 ebl_object_note (ebl, nhdr.n_namesz, name, nhdr.n_type,
12267 nhdr.n_descsz, desc);
12268 }
12269 }
12270
12271 if (offset == data->d_size)
12272 return;
12273
12274 bad_note:
12275 error (0, 0,
12276 gettext ("cannot get content of note: %s"),
12277 data != NULL ? "garbage data" : elf_errmsg (-1));
12278 }
12279
12280 static void
handle_notes(Ebl * ebl,GElf_Ehdr * ehdr)12281 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
12282 {
12283 /* If we have section headers, just look for SHT_NOTE sections.
12284 In a debuginfo file, the program headers are not reliable. */
12285 if (shnum != 0)
12286 {
12287 /* Get the section header string table index. */
12288 size_t shstrndx;
12289 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
12290 error (EXIT_FAILURE, 0,
12291 gettext ("cannot get section header string table index"));
12292
12293 Elf_Scn *scn = NULL;
12294 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12295 {
12296 GElf_Shdr shdr_mem;
12297 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
12298
12299 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
12300 /* Not what we are looking for. */
12301 continue;
12302
12303 printf (gettext ("\
12304 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12305 elf_ndxscn (scn),
12306 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
12307 shdr->sh_size, shdr->sh_offset);
12308
12309 handle_notes_data (ebl, ehdr, shdr->sh_offset,
12310 elf_getdata (scn, NULL));
12311 }
12312 return;
12313 }
12314
12315 /* We have to look through the program header to find the note
12316 sections. There can be more than one. */
12317 for (size_t cnt = 0; cnt < phnum; ++cnt)
12318 {
12319 GElf_Phdr mem;
12320 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
12321
12322 if (phdr == NULL || phdr->p_type != PT_NOTE)
12323 /* Not what we are looking for. */
12324 continue;
12325
12326 printf (gettext ("\
12327 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
12328 phdr->p_filesz, phdr->p_offset);
12329
12330 handle_notes_data (ebl, ehdr, phdr->p_offset,
12331 elf_getdata_rawchunk (ebl->elf,
12332 phdr->p_offset, phdr->p_filesz,
12333 (phdr->p_align == 8
12334 ? ELF_T_NHDR8 : ELF_T_NHDR)));
12335 }
12336 }
12337
12338
12339 static void
hex_dump(const uint8_t * data,size_t len)12340 hex_dump (const uint8_t *data, size_t len)
12341 {
12342 size_t pos = 0;
12343 while (pos < len)
12344 {
12345 printf (" 0x%08zx ", pos);
12346
12347 const size_t chunk = MIN (len - pos, 16);
12348
12349 for (size_t i = 0; i < chunk; ++i)
12350 if (i % 4 == 3)
12351 printf ("%02x ", data[pos + i]);
12352 else
12353 printf ("%02x", data[pos + i]);
12354
12355 if (chunk < 16)
12356 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
12357
12358 for (size_t i = 0; i < chunk; ++i)
12359 {
12360 unsigned char b = data[pos + i];
12361 printf ("%c", isprint (b) ? b : '.');
12362 }
12363
12364 putchar ('\n');
12365 pos += chunk;
12366 }
12367 }
12368
12369 static void
dump_data_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12370 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12371 {
12372 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12373 printf (gettext ("\nSection [%zu] '%s' has no data to dump.\n"),
12374 elf_ndxscn (scn), name);
12375 else
12376 {
12377 if (print_decompress)
12378 {
12379 /* We try to decompress the section, but keep the old shdr around
12380 so we can show both the original shdr size and the uncompressed
12381 data size. */
12382 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12383 {
12384 if (elf_compress (scn, 0, 0) < 0)
12385 printf ("WARNING: %s [%zd]\n",
12386 gettext ("Couldn't uncompress section"),
12387 elf_ndxscn (scn));
12388 }
12389 else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12390 {
12391 if (elf_compress_gnu (scn, 0, 0) < 0)
12392 printf ("WARNING: %s [%zd]\n",
12393 gettext ("Couldn't uncompress section"),
12394 elf_ndxscn (scn));
12395 }
12396 }
12397
12398 Elf_Data *data = elf_rawdata (scn, NULL);
12399 if (data == NULL)
12400 error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
12401 elf_ndxscn (scn), name, elf_errmsg (-1));
12402 else
12403 {
12404 if (data->d_size == shdr->sh_size)
12405 printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
12406 " bytes at offset %#0" PRIx64 ":\n"),
12407 elf_ndxscn (scn), name,
12408 shdr->sh_size, shdr->sh_offset);
12409 else
12410 printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
12411 " bytes (%zd uncompressed) at offset %#0"
12412 PRIx64 ":\n"),
12413 elf_ndxscn (scn), name,
12414 shdr->sh_size, data->d_size, shdr->sh_offset);
12415 hex_dump (data->d_buf, data->d_size);
12416 }
12417 }
12418 }
12419
12420 static void
print_string_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)12421 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
12422 {
12423 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
12424 printf (gettext ("\nSection [%zu] '%s' has no strings to dump.\n"),
12425 elf_ndxscn (scn), name);
12426 else
12427 {
12428 if (print_decompress)
12429 {
12430 /* We try to decompress the section, but keep the old shdr around
12431 so we can show both the original shdr size and the uncompressed
12432 data size. */
12433 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
12434 {
12435 if (elf_compress (scn, 0, 0) < 0)
12436 printf ("WARNING: %s [%zd]\n",
12437 gettext ("Couldn't uncompress section"),
12438 elf_ndxscn (scn));
12439 }
12440 else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
12441 {
12442 if (elf_compress_gnu (scn, 0, 0) < 0)
12443 printf ("WARNING: %s [%zd]\n",
12444 gettext ("Couldn't uncompress section"),
12445 elf_ndxscn (scn));
12446 }
12447 }
12448
12449 Elf_Data *data = elf_rawdata (scn, NULL);
12450 if (data == NULL)
12451 error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
12452 elf_ndxscn (scn), name, elf_errmsg (-1));
12453 else
12454 {
12455 if (data->d_size == shdr->sh_size)
12456 printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
12457 " bytes at offset %#0" PRIx64 ":\n"),
12458 elf_ndxscn (scn), name,
12459 shdr->sh_size, shdr->sh_offset);
12460 else
12461 printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
12462 " bytes (%zd uncompressed) at offset %#0"
12463 PRIx64 ":\n"),
12464 elf_ndxscn (scn), name,
12465 shdr->sh_size, data->d_size, shdr->sh_offset);
12466
12467 const char *start = data->d_buf;
12468 const char *const limit = start + data->d_size;
12469 do
12470 {
12471 const char *end = memchr (start, '\0', limit - start);
12472 const size_t pos = start - (const char *) data->d_buf;
12473 if (unlikely (end == NULL))
12474 {
12475 printf (" [%6zx]- %.*s\n",
12476 pos, (int) (limit - start), start);
12477 break;
12478 }
12479 printf (" [%6zx] %s\n", pos, start);
12480 start = end + 1;
12481 } while (start < limit);
12482 }
12483 }
12484 }
12485
12486 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))12487 for_each_section_argument (Elf *elf, const struct section_argument *list,
12488 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
12489 const char *name))
12490 {
12491 /* Get the section header string table index. */
12492 size_t shstrndx;
12493 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
12494 error (EXIT_FAILURE, 0,
12495 gettext ("cannot get section header string table index"));
12496
12497 for (const struct section_argument *a = list; a != NULL; a = a->next)
12498 {
12499 Elf_Scn *scn;
12500 GElf_Shdr shdr_mem;
12501 const char *name = NULL;
12502
12503 char *endp = NULL;
12504 unsigned long int shndx = strtoul (a->arg, &endp, 0);
12505 if (endp != a->arg && *endp == '\0')
12506 {
12507 scn = elf_getscn (elf, shndx);
12508 if (scn == NULL)
12509 {
12510 error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
12511 continue;
12512 }
12513
12514 if (gelf_getshdr (scn, &shdr_mem) == NULL)
12515 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
12516 elf_errmsg (-1));
12517 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12518 }
12519 else
12520 {
12521 /* Need to look up the section by name. */
12522 scn = NULL;
12523 bool found = false;
12524 while ((scn = elf_nextscn (elf, scn)) != NULL)
12525 {
12526 if (gelf_getshdr (scn, &shdr_mem) == NULL)
12527 continue;
12528 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
12529 if (name == NULL)
12530 continue;
12531 if (!strcmp (name, a->arg))
12532 {
12533 found = true;
12534 (*dump) (scn, &shdr_mem, name);
12535 }
12536 }
12537
12538 if (unlikely (!found) && !a->implicit)
12539 error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
12540 }
12541 }
12542 }
12543
12544 static void
dump_data(Ebl * ebl)12545 dump_data (Ebl *ebl)
12546 {
12547 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
12548 }
12549
12550 static void
dump_strings(Ebl * ebl)12551 dump_strings (Ebl *ebl)
12552 {
12553 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
12554 }
12555
12556 static void
print_strings(Ebl * ebl)12557 print_strings (Ebl *ebl)
12558 {
12559 /* Get the section header string table index. */
12560 size_t shstrndx;
12561 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
12562 error (EXIT_FAILURE, 0,
12563 gettext ("cannot get section header string table index"));
12564
12565 Elf_Scn *scn;
12566 GElf_Shdr shdr_mem;
12567 const char *name;
12568 scn = NULL;
12569 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
12570 {
12571 if (gelf_getshdr (scn, &shdr_mem) == NULL)
12572 continue;
12573
12574 if (shdr_mem.sh_type != SHT_PROGBITS
12575 || !(shdr_mem.sh_flags & SHF_STRINGS))
12576 continue;
12577
12578 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
12579 if (name == NULL)
12580 continue;
12581
12582 print_string_section (scn, &shdr_mem, name);
12583 }
12584 }
12585
12586 static void
dump_archive_index(Elf * elf,const char * fname)12587 dump_archive_index (Elf *elf, const char *fname)
12588 {
12589 size_t narsym;
12590 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
12591 if (arsym == NULL)
12592 {
12593 int result = elf_errno ();
12594 if (unlikely (result != ELF_E_NO_INDEX))
12595 error (EXIT_FAILURE, 0,
12596 gettext ("cannot get symbol index of archive '%s': %s"),
12597 fname, elf_errmsg (result));
12598 else
12599 printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
12600 return;
12601 }
12602
12603 printf (gettext ("\nIndex of archive '%s' has %zu entries:\n"),
12604 fname, narsym);
12605
12606 size_t as_off = 0;
12607 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
12608 {
12609 if (s->as_off != as_off)
12610 {
12611 as_off = s->as_off;
12612
12613 Elf *subelf = NULL;
12614 if (unlikely (elf_rand (elf, as_off) == 0)
12615 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
12616 == NULL))
12617 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
12618 while (1)
12619 #endif
12620 error (EXIT_FAILURE, 0,
12621 gettext ("cannot extract member at offset %zu in '%s': %s"),
12622 as_off, fname, elf_errmsg (-1));
12623
12624 const Elf_Arhdr *h = elf_getarhdr (subelf);
12625
12626 printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
12627
12628 elf_end (subelf);
12629 }
12630
12631 printf ("\t%s\n", s->as_name);
12632 }
12633 }
12634
12635 #include "debugpred.h"
12636