1 /* Print information from ELF file in human-readable form.
2 Copyright (C) 1999-2015 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 1999.
5
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 elfutils is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <argp.h>
24 #include <assert.h>
25 #include <ctype.h>
26 #include <dwarf.h>
27 #include <errno.h>
28 #include <error.h>
29 #include <fcntl.h>
30 #include <gelf.h>
31 #include <inttypes.h>
32 #include <langinfo.h>
33 #include <libdw.h>
34 #include <libdwfl.h>
35 #include <libintl.h>
36 #include <locale.h>
37 #include <stdarg.h>
38 #include <stdbool.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <time.h>
42 #include <unistd.h>
43 #include <sys/param.h>
44 #include <sys/stat.h>
45 #include <signal.h>
46
47 #include <system.h>
48 #include "../libelf/libelfP.h"
49 #include "../libelf/common.h"
50 #include "../libebl/libeblP.h"
51 #include "../libdwelf/libdwelf.h"
52 #include "../libdw/libdwP.h"
53 #include "../libdwfl/libdwflP.h"
54 #include "../libdw/memory-access.h"
55
56 #include "../libdw/known-dwarf.h"
57
58
59 /* Name and version of program. */
60 static void print_version (FILE *stream, struct argp_state *state);
61 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
62
63 /* Bug report address. */
64 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
65
66 /* argp key value for --elf-section, non-ascii. */
67 #define ELF_INPUT_SECTION 256
68
69 /* Definitions of arguments for argp functions. */
70 static const struct argp_option options[] =
71 {
72 { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 },
73 { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL,
74 N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF "
75 "input data"), 0 },
76 { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
77 { "all", 'a', NULL, 0,
78 N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
79 { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
80 { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
81 { "histogram", 'I', NULL, 0,
82 N_("Display histogram of bucket list lengths"), 0 },
83 { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
84 { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
85 { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
86 { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
87 { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
88 { "symbols", 's', NULL, 0, N_("Display the symbol table"), 0 },
89 { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
90 { "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 },
91 { "arch-specific", 'A', NULL, 0,
92 N_("Display architecture specific information, if any"), 0 },
93 { "exception", 'e', NULL, 0,
94 N_("Display sections for exception handling"), 0 },
95
96 { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
97 { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
98 N_("Display DWARF section content. SECTION can be one of abbrev, "
99 "aranges, decodedaranges, frame, gdb_index, info, loc, line, "
100 "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 },
101 { "hex-dump", 'x', "SECTION", 0,
102 N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
103 { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
104 N_("Print string contents of sections"), 0 },
105 { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
106 { "archive-index", 'c', NULL, 0,
107 N_("Display the symbol index of an archive"), 0 },
108
109 { NULL, 0, NULL, 0, N_("Output control:"), 0 },
110 { "numeric-addresses", 'N', NULL, 0,
111 N_("Do not find symbol names for addresses in DWARF data"), 0 },
112 { "unresolved-address-offsets", 'U', NULL, 0,
113 N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
114 { "wide", 'W', NULL, 0,
115 N_("Ignored for compatibility (lines always wide)"), 0 },
116 { "decompress", 'z', NULL, 0,
117 N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 },
118 { NULL, 0, NULL, 0, NULL, 0 }
119 };
120
121 /* Short description of program. */
122 static const char doc[] = N_("\
123 Print information from ELF file in human-readable form.");
124
125 /* Strings for arguments in help texts. */
126 static const char args_doc[] = N_("FILE...");
127
128 /* Prototype for option handler. */
129 static error_t parse_opt (int key, char *arg, struct argp_state *state);
130
131 /* Data structure to communicate with argp functions. */
132 static struct argp argp =
133 {
134 options, parse_opt, args_doc, doc, NULL, NULL, NULL
135 };
136
137 /* If non-null, the section from which we should read to (compressed) ELF. */
138 static const char *elf_input_section = NULL;
139
140 /* Flags set by the option controlling the output. */
141
142 /* True if dynamic segment should be printed. */
143 static bool print_dynamic_table;
144
145 /* True if the file header should be printed. */
146 static bool print_file_header;
147
148 /* True if the program headers should be printed. */
149 static bool print_program_header;
150
151 /* True if relocations should be printed. */
152 static bool print_relocations;
153
154 /* True if the section headers should be printed. */
155 static bool print_section_header;
156
157 /* True if the symbol table should be printed. */
158 static bool print_symbol_table;
159
160 /* True if the version information should be printed. */
161 static bool print_version_info;
162
163 /* True if section groups should be printed. */
164 static bool print_section_groups;
165
166 /* True if bucket list length histogram should be printed. */
167 static bool print_histogram;
168
169 /* True if the architecture specific data should be printed. */
170 static bool print_arch;
171
172 /* True if note section content should be printed. */
173 static bool print_notes;
174
175 /* True if SHF_STRINGS section content should be printed. */
176 static bool print_string_sections;
177
178 /* True if archive index should be printed. */
179 static bool print_archive_index;
180
181 /* True if any of the control options except print_archive_index is set. */
182 static bool any_control_option;
183
184 /* True if we should print addresses from DWARF in symbolic form. */
185 static bool print_address_names = true;
186
187 /* True if we should print raw values instead of relativized addresses. */
188 static bool print_unresolved_addresses = false;
189
190 /* True if we should print the .debug_aranges section using libdw. */
191 static bool decodedaranges = false;
192
193 /* True if we should print the .debug_aranges section using libdw. */
194 static bool decodedline = false;
195
196 /* True if we want to show more information about compressed sections. */
197 static bool print_decompress = false;
198
199 /* Select printing of debugging sections. */
200 static enum section_e
201 {
202 section_abbrev = 1, /* .debug_abbrev */
203 section_aranges = 2, /* .debug_aranges */
204 section_frame = 4, /* .debug_frame or .eh_frame & al. */
205 section_info = 8, /* .debug_info, .debug_types */
206 section_types = section_info,
207 section_line = 16, /* .debug_line */
208 section_loc = 32, /* .debug_loc */
209 section_pubnames = 64, /* .debug_pubnames */
210 section_str = 128, /* .debug_str */
211 section_macinfo = 256, /* .debug_macinfo */
212 section_ranges = 512, /* .debug_ranges */
213 section_exception = 1024, /* .eh_frame & al. */
214 section_gdb_index = 2048, /* .gdb_index */
215 section_macro = 4096, /* .debug_macro */
216 section_all = (section_abbrev | section_aranges | section_frame
217 | section_info | section_line | section_loc
218 | section_pubnames | section_str | section_macinfo
219 | section_ranges | section_exception | section_gdb_index
220 | section_macro)
221 } print_debug_sections, implicit_debug_sections;
222
223 /* Select hex dumping of sections. */
224 static struct section_argument *dump_data_sections;
225 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
226
227 /* Select string dumping of sections. */
228 static struct section_argument *string_sections;
229 static struct section_argument **string_sections_tail = &string_sections;
230
231 struct section_argument
232 {
233 struct section_argument *next;
234 const char *arg;
235 bool implicit;
236 };
237
238 /* Numbers of sections and program headers in the file. */
239 static size_t shnum;
240 static size_t phnum;
241
242
243 /* Declarations of local functions. */
244 static void process_file (int fd, const char *fname, bool only_one);
245 static void process_elf_file (Dwfl_Module *dwflmod, int fd);
246 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
247 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
248 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
249 static void print_scngrp (Ebl *ebl);
250 static void print_dynamic (Ebl *ebl);
251 static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
252 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
253 GElf_Shdr *shdr);
254 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
255 GElf_Shdr *shdr);
256 static void print_symtab (Ebl *ebl, int type);
257 static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
258 static void print_verinfo (Ebl *ebl);
259 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
260 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
261 static void handle_versym (Ebl *ebl, Elf_Scn *scn,
262 GElf_Shdr *shdr);
263 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
264 static void handle_hash (Ebl *ebl);
265 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
266 static void print_liblist (Ebl *ebl);
267 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
268 static void dump_data (Ebl *ebl);
269 static void dump_strings (Ebl *ebl);
270 static void print_strings (Ebl *ebl);
271 static void dump_archive_index (Elf *, const char *);
272
273
274 int
main(int argc,char * argv[])275 main (int argc, char *argv[])
276 {
277 /* Set locale. */
278 setlocale (LC_ALL, "");
279
280 /* Initialize the message catalog. */
281 textdomain (PACKAGE_TARNAME);
282
283 /* Parse and process arguments. */
284 int remaining;
285 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
286
287 /* Before we start tell the ELF library which version we are using. */
288 elf_version (EV_CURRENT);
289
290 /* Now process all the files given at the command line. */
291 bool only_one = remaining + 1 == argc;
292 do
293 {
294 /* Open the file. */
295 int fd = open (argv[remaining], O_RDONLY);
296 if (fd == -1)
297 {
298 error (0, errno, gettext ("cannot open input file"));
299 continue;
300 }
301
302 process_file (fd, argv[remaining], only_one);
303
304 close (fd);
305 }
306 while (++remaining < argc);
307
308 return error_message_count != 0;
309 }
310
311
312 /* Handle program arguments. */
313 static error_t
parse_opt(int key,char * arg,struct argp_state * state)314 parse_opt (int key, char *arg,
315 struct argp_state *state __attribute__ ((unused)))
316 {
317 void add_dump_section (const char *name, bool implicit)
318 {
319 struct section_argument *a = xmalloc (sizeof *a);
320 a->arg = name;
321 a->next = NULL;
322 a->implicit = implicit;
323 struct section_argument ***tailp
324 = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
325 **tailp = a;
326 *tailp = &a->next;
327 }
328
329 switch (key)
330 {
331 case 'a':
332 print_file_header = true;
333 print_program_header = true;
334 print_relocations = true;
335 print_section_header = true;
336 print_symbol_table = true;
337 print_version_info = true;
338 print_dynamic_table = true;
339 print_section_groups = true;
340 print_histogram = true;
341 print_arch = true;
342 print_notes = true;
343 implicit_debug_sections |= section_exception;
344 add_dump_section (".strtab", true);
345 add_dump_section (".dynstr", true);
346 add_dump_section (".comment", true);
347 any_control_option = true;
348 break;
349 case 'A':
350 print_arch = true;
351 any_control_option = true;
352 break;
353 case 'd':
354 print_dynamic_table = true;
355 any_control_option = true;
356 break;
357 case 'e':
358 print_debug_sections |= section_exception;
359 any_control_option = true;
360 break;
361 case 'g':
362 print_section_groups = true;
363 any_control_option = true;
364 break;
365 case 'h':
366 print_file_header = true;
367 any_control_option = true;
368 break;
369 case 'I':
370 print_histogram = true;
371 any_control_option = true;
372 break;
373 case 'l':
374 print_program_header = true;
375 any_control_option = true;
376 break;
377 case 'n':
378 print_notes = true;
379 any_control_option = true;
380 break;
381 case 'r':
382 print_relocations = true;
383 any_control_option = true;
384 break;
385 case 'S':
386 print_section_header = true;
387 any_control_option = true;
388 break;
389 case 's':
390 print_symbol_table = true;
391 any_control_option = true;
392 break;
393 case 'V':
394 print_version_info = true;
395 any_control_option = true;
396 break;
397 case 'c':
398 print_archive_index = true;
399 break;
400 case 'w':
401 if (arg == NULL)
402 print_debug_sections = section_all;
403 else if (strcmp (arg, "abbrev") == 0)
404 print_debug_sections |= section_abbrev;
405 else if (strcmp (arg, "aranges") == 0)
406 print_debug_sections |= section_aranges;
407 else if (strcmp (arg, "decodedaranges") == 0)
408 {
409 print_debug_sections |= section_aranges;
410 decodedaranges = true;
411 }
412 else if (strcmp (arg, "ranges") == 0)
413 {
414 print_debug_sections |= section_ranges;
415 implicit_debug_sections |= section_info;
416 }
417 else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
418 print_debug_sections |= section_frame;
419 else if (strcmp (arg, "info") == 0)
420 print_debug_sections |= section_info;
421 else if (strcmp (arg, "loc") == 0)
422 {
423 print_debug_sections |= section_loc;
424 implicit_debug_sections |= section_info;
425 }
426 else if (strcmp (arg, "line") == 0)
427 print_debug_sections |= section_line;
428 else if (strcmp (arg, "decodedline") == 0)
429 {
430 print_debug_sections |= section_line;
431 decodedline = true;
432 }
433 else if (strcmp (arg, "pubnames") == 0)
434 print_debug_sections |= section_pubnames;
435 else if (strcmp (arg, "str") == 0)
436 print_debug_sections |= section_str;
437 else if (strcmp (arg, "macinfo") == 0)
438 print_debug_sections |= section_macinfo;
439 else if (strcmp (arg, "macro") == 0)
440 print_debug_sections |= section_macro;
441 else if (strcmp (arg, "exception") == 0)
442 print_debug_sections |= section_exception;
443 else if (strcmp (arg, "gdb_index") == 0)
444 print_debug_sections |= section_gdb_index;
445 else
446 {
447 fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"),
448 arg);
449 argp_help (&argp, stderr, ARGP_HELP_SEE,
450 program_invocation_short_name);
451 exit (1);
452 }
453 any_control_option = true;
454 break;
455 case 'p':
456 any_control_option = true;
457 if (arg == NULL)
458 {
459 print_string_sections = true;
460 break;
461 }
462 /* Fall through. */
463 case 'x':
464 add_dump_section (arg, false);
465 any_control_option = true;
466 break;
467 case 'N':
468 print_address_names = false;
469 break;
470 case 'U':
471 print_unresolved_addresses = true;
472 break;
473 case ARGP_KEY_NO_ARGS:
474 fputs (gettext ("Missing file name.\n"), stderr);
475 goto do_argp_help;
476 case ARGP_KEY_FINI:
477 if (! any_control_option && ! print_archive_index)
478 {
479 fputs (gettext ("No operation specified.\n"), stderr);
480 do_argp_help:
481 argp_help (&argp, stderr, ARGP_HELP_SEE,
482 program_invocation_short_name);
483 exit (EXIT_FAILURE);
484 }
485 break;
486 case 'W': /* Ignored. */
487 break;
488 case 'z':
489 print_decompress = true;
490 break;
491 case ELF_INPUT_SECTION:
492 if (arg == NULL)
493 elf_input_section = ".gnu_debugdata";
494 else
495 elf_input_section = arg;
496 break;
497 default:
498 return ARGP_ERR_UNKNOWN;
499 }
500 return 0;
501 }
502
503
504 /* Print the version information. */
505 static void
print_version(FILE * stream,struct argp_state * state)506 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
507 {
508 fprintf (stream, "readelf (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
509 fprintf (stream, gettext ("\
510 Copyright (C) %s Red Hat, Inc.\n\
511 This is free software; see the source for copying conditions. There is NO\n\
512 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
513 "), "2012");
514 fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
515 }
516
517
518 /* Create a file descriptor to read the data from the
519 elf_input_section given a file descriptor to an ELF file. */
520 static int
open_input_section(int fd)521 open_input_section (int fd)
522 {
523 size_t shnums;
524 size_t cnt;
525 size_t shstrndx;
526 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
527 if (elf == NULL)
528 {
529 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
530 elf_errmsg (-1));
531 return -1;
532 }
533
534 if (elf_getshdrnum (elf, &shnums) < 0)
535 {
536 error (0, 0, gettext ("cannot determine number of sections: %s"),
537 elf_errmsg (-1));
538 open_error:
539 elf_end (elf);
540 return -1;
541 }
542
543 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
544 {
545 error (0, 0, gettext ("cannot get section header string table index"));
546 goto open_error;
547 }
548
549 for (cnt = 0; cnt < shnums; ++cnt)
550 {
551 Elf_Scn *scn = elf_getscn (elf, cnt);
552 if (scn == NULL)
553 {
554 error (0, 0, gettext ("cannot get section: %s"),
555 elf_errmsg (-1));
556 goto open_error;
557 }
558
559 GElf_Shdr shdr_mem;
560 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
561 if (unlikely (shdr == NULL))
562 {
563 error (0, 0, gettext ("cannot get section header: %s"),
564 elf_errmsg (-1));
565 goto open_error;
566 }
567
568 const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
569 if (sname == NULL)
570 {
571 error (0, 0, gettext ("cannot get section name"));
572 goto open_error;
573 }
574
575 if (strcmp (sname, elf_input_section) == 0)
576 {
577 Elf_Data *data = elf_rawdata (scn, NULL);
578 if (data == NULL)
579 {
580 error (0, 0, gettext ("cannot get %s content: %s"),
581 sname, elf_errmsg (-1));
582 goto open_error;
583 }
584
585 /* Create (and immediately unlink) a temporary file to store
586 section data in to create a file descriptor for it. */
587 const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
588 static const char suffix[] = "/readelfXXXXXX";
589 int tmplen = strlen (tmpdir) + sizeof (suffix);
590 char *tempname = alloca (tmplen);
591 sprintf (tempname, "%s%s", tmpdir, suffix);
592
593 int sfd = mkstemp (tempname);
594 if (sfd == -1)
595 {
596 error (0, 0, gettext ("cannot create temp file '%s'"),
597 tempname);
598 goto open_error;
599 }
600 unlink (tempname);
601
602 ssize_t size = data->d_size;
603 if (write_retry (sfd, data->d_buf, size) != size)
604 {
605 error (0, 0, gettext ("cannot write section data"));
606 goto open_error;
607 }
608
609 if (elf_end (elf) != 0)
610 {
611 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
612 elf_errmsg (-1));
613 return -1;
614 }
615
616 if (lseek (sfd, 0, SEEK_SET) == -1)
617 {
618 error (0, 0, gettext ("error while rewinding file descriptor"));
619 return -1;
620 }
621
622 return sfd;
623 }
624 }
625
626 /* Named section not found. */
627 if (elf_end (elf) != 0)
628 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
629 elf_errmsg (-1));
630 return -1;
631 }
632
633 /* Check if the file is an archive, and if so dump its index. */
634 static void
check_archive_index(int fd,const char * fname,bool only_one)635 check_archive_index (int fd, const char *fname, bool only_one)
636 {
637 /* Create an `Elf' descriptor. */
638 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
639 if (elf == NULL)
640 error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
641 elf_errmsg (-1));
642 else
643 {
644 if (elf_kind (elf) == ELF_K_AR)
645 {
646 if (!only_one)
647 printf ("\n%s:\n\n", fname);
648 dump_archive_index (elf, fname);
649 }
650 else
651 error (0, 0,
652 gettext ("'%s' is not an archive, cannot print archive index"),
653 fname);
654
655 /* Now we can close the descriptor. */
656 if (elf_end (elf) != 0)
657 error (0, 0, gettext ("error while closing Elf descriptor: %s"),
658 elf_errmsg (-1));
659 }
660 }
661
662 /* Trivial callback used for checking if we opened an archive. */
663 static int
count_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)664 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
665 void **userdata __attribute__ ((unused)),
666 const char *name __attribute__ ((unused)),
667 Dwarf_Addr base __attribute__ ((unused)),
668 void *arg)
669 {
670 if (*(bool *) arg)
671 return DWARF_CB_ABORT;
672 *(bool *) arg = true;
673 return DWARF_CB_OK;
674 }
675
676 struct process_dwflmod_args
677 {
678 int fd;
679 bool only_one;
680 };
681
682 static int
process_dwflmod(Dwfl_Module * dwflmod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)683 process_dwflmod (Dwfl_Module *dwflmod,
684 void **userdata __attribute__ ((unused)),
685 const char *name __attribute__ ((unused)),
686 Dwarf_Addr base __attribute__ ((unused)),
687 void *arg)
688 {
689 const struct process_dwflmod_args *a = arg;
690
691 /* Print the file name. */
692 if (!a->only_one)
693 {
694 const char *fname;
695 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
696
697 printf ("\n%s:\n\n", fname);
698 }
699
700 process_elf_file (dwflmod, a->fd);
701
702 return DWARF_CB_OK;
703 }
704
705 /* Stub libdwfl callback, only the ELF handle already open is ever used.
706 Only used for finding the alternate debug file if the Dwarf comes from
707 the main file. We are not interested in separate debuginfo. */
708 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)709 find_no_debuginfo (Dwfl_Module *mod,
710 void **userdata,
711 const char *modname,
712 Dwarf_Addr base,
713 const char *file_name,
714 const char *debuglink_file,
715 GElf_Word debuglink_crc,
716 char **debuginfo_file_name)
717 {
718 Dwarf_Addr dwbias;
719 dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
720
721 /* We are only interested if the Dwarf has been setup on the main
722 elf file but is only missing the alternate debug link. If dwbias
723 hasn't even been setup, this is searching for separate debuginfo
724 for the main elf. We don't care in that case. */
725 if (dwbias == (Dwarf_Addr) -1)
726 return -1;
727
728 return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
729 file_name, debuglink_file,
730 debuglink_crc, debuginfo_file_name);
731 }
732
733 /* Process one input file. */
734 static void
process_file(int fd,const char * fname,bool only_one)735 process_file (int fd, const char *fname, bool only_one)
736 {
737 if (print_archive_index)
738 check_archive_index (fd, fname, only_one);
739
740 if (!any_control_option)
741 return;
742
743 if (elf_input_section != NULL)
744 {
745 /* Replace fname and fd with section content. */
746 char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
747 sprintf (fnname, "%s:%s", fname, elf_input_section);
748 fd = open_input_section (fd);
749 if (fd == -1)
750 {
751 error (0, 0, gettext ("No such section '%s' in '%s'"),
752 elf_input_section, fname);
753 return;
754 }
755 fname = fnname;
756 }
757
758 /* Duplicate an fd for dwfl_report_offline to swallow. */
759 int dwfl_fd = dup (fd);
760 if (unlikely (dwfl_fd < 0))
761 error (EXIT_FAILURE, errno, "dup");
762
763 /* Use libdwfl in a trivial way to open the libdw handle for us.
764 This takes care of applying relocations to DWARF data in ET_REL files. */
765 static const Dwfl_Callbacks callbacks =
766 {
767 .section_address = dwfl_offline_section_address,
768 .find_debuginfo = find_no_debuginfo
769 };
770 Dwfl *dwfl = dwfl_begin (&callbacks);
771 if (likely (dwfl != NULL))
772 /* Let 0 be the logical address of the file (or first in archive). */
773 dwfl->offline_next_address = 0;
774 if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
775 {
776 struct stat st;
777 if (fstat (dwfl_fd, &st) != 0)
778 error (0, errno, gettext ("cannot stat input file"));
779 else if (unlikely (st.st_size == 0))
780 error (0, 0, gettext ("input file is empty"));
781 else
782 error (0, 0, gettext ("failed reading '%s': %s"),
783 fname, dwfl_errmsg (-1));
784 close (dwfl_fd); /* Consumed on success, not on failure. */
785 }
786 else
787 {
788 dwfl_report_end (dwfl, NULL, NULL);
789
790 if (only_one)
791 {
792 /* Clear ONLY_ONE if we have multiple modules, from an archive. */
793 bool seen = false;
794 only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
795 }
796
797 /* Process the one or more modules gleaned from this file. */
798 struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
799 dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
800 }
801 dwfl_end (dwfl);
802
803 /* Need to close the replaced fd if we created it. Caller takes
804 care of original. */
805 if (elf_input_section != NULL)
806 close (fd);
807 }
808
809 /* Check whether there are any compressed sections in the ELF file. */
810 static bool
elf_contains_chdrs(Elf * elf)811 elf_contains_chdrs (Elf *elf)
812 {
813 Elf_Scn *scn = NULL;
814 while ((scn = elf_nextscn (elf, scn)) != NULL)
815 {
816 GElf_Shdr shdr_mem;
817 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
818 if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
819 return true;
820 }
821 return false;
822 }
823
824 /* Process one ELF file. */
825 static void
process_elf_file(Dwfl_Module * dwflmod,int fd)826 process_elf_file (Dwfl_Module *dwflmod, int fd)
827 {
828 GElf_Addr dwflbias;
829 Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
830
831 GElf_Ehdr ehdr_mem;
832 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
833
834 if (ehdr == NULL)
835 {
836 elf_error:
837 error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
838 return;
839 }
840
841 Ebl *ebl = ebl_openbackend (elf);
842 if (unlikely (ebl == NULL))
843 {
844 ebl_error:
845 error (0, errno, gettext ("cannot create EBL handle"));
846 return;
847 }
848
849 /* Determine the number of sections. */
850 if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
851 error (EXIT_FAILURE, 0,
852 gettext ("cannot determine number of sections: %s"),
853 elf_errmsg (-1));
854
855 /* Determine the number of phdrs. */
856 if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
857 error (EXIT_FAILURE, 0,
858 gettext ("cannot determine number of program headers: %s"),
859 elf_errmsg (-1));
860
861 /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
862 may have applied relocation to some sections. If there are any
863 compressed sections, any pass (or libdw/libdwfl) might have
864 uncompressed them. So we need to get a fresh Elf handle on the
865 file to display those. */
866 bool print_unchanged = ((print_section_header
867 || print_relocations
868 || dump_data_sections != NULL
869 || print_notes)
870 && (ehdr->e_type == ET_REL
871 || elf_contains_chdrs (ebl->elf)));
872
873 Elf *pure_elf = NULL;
874 Ebl *pure_ebl = ebl;
875 if (print_unchanged)
876 {
877 /* Read the file afresh. */
878 off_t aroff = elf_getaroff (elf);
879 pure_elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
880 if (aroff > 0)
881 {
882 /* Archive member. */
883 (void) elf_rand (pure_elf, aroff);
884 Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
885 elf_end (pure_elf);
886 pure_elf = armem;
887 }
888 if (pure_elf == NULL)
889 goto elf_error;
890 pure_ebl = ebl_openbackend (pure_elf);
891 if (pure_ebl == NULL)
892 goto ebl_error;
893 }
894
895 if (print_file_header)
896 print_ehdr (ebl, ehdr);
897 if (print_section_header)
898 print_shdr (pure_ebl, ehdr);
899 if (print_program_header)
900 print_phdr (ebl, ehdr);
901 if (print_section_groups)
902 print_scngrp (ebl);
903 if (print_dynamic_table)
904 print_dynamic (ebl);
905 if (print_relocations)
906 print_relocs (pure_ebl, ehdr);
907 if (print_histogram)
908 handle_hash (ebl);
909 if (print_symbol_table)
910 print_symtab (ebl, SHT_DYNSYM);
911 if (print_version_info)
912 print_verinfo (ebl);
913 if (print_symbol_table)
914 print_symtab (ebl, SHT_SYMTAB);
915 if (print_arch)
916 print_liblist (ebl);
917 if (print_arch)
918 print_attributes (ebl, ehdr);
919 if (dump_data_sections != NULL)
920 dump_data (pure_ebl);
921 if (string_sections != NULL)
922 dump_strings (ebl);
923 if ((print_debug_sections | implicit_debug_sections) != 0)
924 print_debug (dwflmod, ebl, ehdr);
925 if (print_notes)
926 handle_notes (pure_ebl, ehdr);
927 if (print_string_sections)
928 print_strings (ebl);
929
930 ebl_closebackend (ebl);
931
932 if (pure_ebl != ebl)
933 {
934 ebl_closebackend (pure_ebl);
935 elf_end (pure_elf);
936 }
937 }
938
939
940 /* Print file type. */
941 static void
print_file_type(unsigned short int e_type)942 print_file_type (unsigned short int e_type)
943 {
944 if (likely (e_type <= ET_CORE))
945 {
946 static const char *const knowntypes[] =
947 {
948 N_("NONE (None)"),
949 N_("REL (Relocatable file)"),
950 N_("EXEC (Executable file)"),
951 N_("DYN (Shared object file)"),
952 N_("CORE (Core file)")
953 };
954 puts (gettext (knowntypes[e_type]));
955 }
956 else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
957 printf (gettext ("OS Specific: (%x)\n"), e_type);
958 else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
959 printf (gettext ("Processor Specific: (%x)\n"), e_type);
960 else
961 puts ("???");
962 }
963
964
965 /* Print ELF header. */
966 static void
print_ehdr(Ebl * ebl,GElf_Ehdr * ehdr)967 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
968 {
969 fputs_unlocked (gettext ("ELF Header:\n Magic: "), stdout);
970 for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
971 printf (" %02hhx", ehdr->e_ident[cnt]);
972
973 printf (gettext ("\n Class: %s\n"),
974 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
975 : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
976 : "\?\?\?");
977
978 printf (gettext (" Data: %s\n"),
979 ehdr->e_ident[EI_DATA] == ELFDATA2LSB
980 ? "2's complement, little endian"
981 : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
982 ? "2's complement, big endian" : "\?\?\?");
983
984 printf (gettext (" Ident Version: %hhd %s\n"),
985 ehdr->e_ident[EI_VERSION],
986 ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
987 : "(\?\?\?)");
988
989 char buf[512];
990 printf (gettext (" OS/ABI: %s\n"),
991 ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
992
993 printf (gettext (" ABI Version: %hhd\n"),
994 ehdr->e_ident[EI_ABIVERSION]);
995
996 fputs_unlocked (gettext (" Type: "), stdout);
997 print_file_type (ehdr->e_type);
998
999 printf (gettext (" Machine: %s\n"), ebl->name);
1000
1001 printf (gettext (" Version: %d %s\n"),
1002 ehdr->e_version,
1003 ehdr->e_version == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
1004
1005 printf (gettext (" Entry point address: %#" PRIx64 "\n"),
1006 ehdr->e_entry);
1007
1008 printf (gettext (" Start of program headers: %" PRId64 " %s\n"),
1009 ehdr->e_phoff, gettext ("(bytes into file)"));
1010
1011 printf (gettext (" Start of section headers: %" PRId64 " %s\n"),
1012 ehdr->e_shoff, gettext ("(bytes into file)"));
1013
1014 printf (gettext (" Flags: %s\n"),
1015 ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
1016
1017 printf (gettext (" Size of this header: %" PRId16 " %s\n"),
1018 ehdr->e_ehsize, gettext ("(bytes)"));
1019
1020 printf (gettext (" Size of program header entries: %" PRId16 " %s\n"),
1021 ehdr->e_phentsize, gettext ("(bytes)"));
1022
1023 printf (gettext (" Number of program headers entries: %" PRId16),
1024 ehdr->e_phnum);
1025 if (ehdr->e_phnum == PN_XNUM)
1026 {
1027 GElf_Shdr shdr_mem;
1028 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1029 if (shdr != NULL)
1030 printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
1031 (uint32_t) shdr->sh_info);
1032 else
1033 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1034 }
1035 fputc_unlocked ('\n', stdout);
1036
1037 printf (gettext (" Size of section header entries: %" PRId16 " %s\n"),
1038 ehdr->e_shentsize, gettext ("(bytes)"));
1039
1040 printf (gettext (" Number of section headers entries: %" PRId16),
1041 ehdr->e_shnum);
1042 if (ehdr->e_shnum == 0)
1043 {
1044 GElf_Shdr shdr_mem;
1045 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1046 if (shdr != NULL)
1047 printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
1048 (uint32_t) shdr->sh_size);
1049 else
1050 fputs_unlocked (gettext (" ([0] not available)"), stdout);
1051 }
1052 fputc_unlocked ('\n', stdout);
1053
1054 if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
1055 {
1056 GElf_Shdr shdr_mem;
1057 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
1058 if (shdr != NULL)
1059 /* We managed to get the zeroth section. */
1060 snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
1061 (uint32_t) shdr->sh_link);
1062 else
1063 {
1064 strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
1065 buf[sizeof (buf) - 1] = '\0';
1066 }
1067
1068 printf (gettext (" Section header string table index: XINDEX%s\n\n"),
1069 buf);
1070 }
1071 else
1072 printf (gettext (" Section header string table index: %" PRId16 "\n\n"),
1073 ehdr->e_shstrndx);
1074 }
1075
1076
1077 static const char *
get_visibility_type(int value)1078 get_visibility_type (int value)
1079 {
1080 switch (value)
1081 {
1082 case STV_DEFAULT:
1083 return "DEFAULT";
1084 case STV_INTERNAL:
1085 return "INTERNAL";
1086 case STV_HIDDEN:
1087 return "HIDDEN";
1088 case STV_PROTECTED:
1089 return "PROTECTED";
1090 default:
1091 return "???";
1092 }
1093 }
1094
1095 static const char *
elf_ch_type_name(unsigned int code)1096 elf_ch_type_name (unsigned int code)
1097 {
1098 if (code == 0)
1099 return "NONE";
1100
1101 if (code == ELFCOMPRESS_ZLIB)
1102 return "ZLIB";
1103
1104 return "UNKNOWN";
1105 }
1106
1107 /* Print the section headers. */
1108 static void
print_shdr(Ebl * ebl,GElf_Ehdr * ehdr)1109 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
1110 {
1111 size_t cnt;
1112 size_t shstrndx;
1113
1114 if (! print_file_header)
1115 printf (gettext ("\
1116 There are %d section headers, starting at offset %#" PRIx64 ":\n\
1117 \n"),
1118 ehdr->e_shnum, ehdr->e_shoff);
1119
1120 /* Get the section header string table index. */
1121 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1122 error (EXIT_FAILURE, 0,
1123 gettext ("cannot get section header string table index"));
1124
1125 puts (gettext ("Section Headers:"));
1126
1127 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1128 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1129 else
1130 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al"));
1131
1132 if (print_decompress)
1133 {
1134 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1135 puts (gettext (" [Compression Size Al]"));
1136 else
1137 puts (gettext (" [Compression Size Al]"));
1138 }
1139
1140 for (cnt = 0; cnt < shnum; ++cnt)
1141 {
1142 Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
1143
1144 if (unlikely (scn == NULL))
1145 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1146 elf_errmsg (-1));
1147
1148 /* Get the section header. */
1149 GElf_Shdr shdr_mem;
1150 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1151 if (unlikely (shdr == NULL))
1152 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
1153 elf_errmsg (-1));
1154
1155 char flagbuf[20];
1156 char *cp = flagbuf;
1157 if (shdr->sh_flags & SHF_WRITE)
1158 *cp++ = 'W';
1159 if (shdr->sh_flags & SHF_ALLOC)
1160 *cp++ = 'A';
1161 if (shdr->sh_flags & SHF_EXECINSTR)
1162 *cp++ = 'X';
1163 if (shdr->sh_flags & SHF_MERGE)
1164 *cp++ = 'M';
1165 if (shdr->sh_flags & SHF_STRINGS)
1166 *cp++ = 'S';
1167 if (shdr->sh_flags & SHF_INFO_LINK)
1168 *cp++ = 'I';
1169 if (shdr->sh_flags & SHF_LINK_ORDER)
1170 *cp++ = 'L';
1171 if (shdr->sh_flags & SHF_OS_NONCONFORMING)
1172 *cp++ = 'N';
1173 if (shdr->sh_flags & SHF_GROUP)
1174 *cp++ = 'G';
1175 if (shdr->sh_flags & SHF_TLS)
1176 *cp++ = 'T';
1177 if (shdr->sh_flags & SHF_COMPRESSED)
1178 *cp++ = 'C';
1179 if (shdr->sh_flags & SHF_ORDERED)
1180 *cp++ = 'O';
1181 if (shdr->sh_flags & SHF_EXCLUDE)
1182 *cp++ = 'E';
1183 *cp = '\0';
1184
1185 const char *sname;
1186 char buf[128];
1187 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>";
1188 printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
1189 " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
1190 " %2" PRId64 "\n",
1191 cnt, sname,
1192 ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
1193 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
1194 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
1195 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
1196 shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
1197 shdr->sh_addralign);
1198
1199 if (print_decompress)
1200 {
1201 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1202 {
1203 GElf_Chdr chdr;
1204 if (gelf_getchdr (scn, &chdr) != NULL)
1205 printf (" [ELF %s (%" PRId32 ") %0*" PRIx64
1206 " %2" PRId64 "]\n",
1207 elf_ch_type_name (chdr.ch_type),
1208 chdr.ch_type,
1209 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8,
1210 chdr.ch_size, chdr.ch_addralign);
1211 else
1212 error (0, 0,
1213 gettext ("bad compression header for section %zd: %s"),
1214 elf_ndxscn (scn), elf_errmsg (-1));
1215 }
1216 else if (strncmp(".zdebug", sname, strlen (".zdebug")) == 0)
1217 {
1218 ssize_t size;
1219 if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0)
1220 printf (" [GNU ZLIB %0*zx ]\n",
1221 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size);
1222 else
1223 error (0, 0,
1224 gettext ("bad gnu compressed size for section %zd: %s"),
1225 elf_ndxscn (scn), elf_errmsg (-1));
1226 }
1227 }
1228 }
1229
1230 fputc_unlocked ('\n', stdout);
1231 }
1232
1233
1234 /* Print the program header. */
1235 static void
print_phdr(Ebl * ebl,GElf_Ehdr * ehdr)1236 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
1237 {
1238 if (phnum == 0)
1239 /* No program header, this is OK in relocatable objects. */
1240 return;
1241
1242 puts (gettext ("Program Headers:"));
1243 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
1244 puts (gettext ("\
1245 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1246 else
1247 puts (gettext ("\
1248 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align"));
1249
1250 /* Process all program headers. */
1251 bool has_relro = false;
1252 GElf_Addr relro_from = 0;
1253 GElf_Addr relro_to = 0;
1254 for (size_t cnt = 0; cnt < phnum; ++cnt)
1255 {
1256 char buf[128];
1257 GElf_Phdr mem;
1258 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
1259
1260 /* If for some reason the header cannot be returned show this. */
1261 if (unlikely (phdr == NULL))
1262 {
1263 puts (" ???");
1264 continue;
1265 }
1266
1267 printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
1268 " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
1269 ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
1270 phdr->p_offset,
1271 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
1272 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
1273 phdr->p_filesz,
1274 phdr->p_memsz,
1275 phdr->p_flags & PF_R ? 'R' : ' ',
1276 phdr->p_flags & PF_W ? 'W' : ' ',
1277 phdr->p_flags & PF_X ? 'E' : ' ',
1278 phdr->p_align);
1279
1280 if (phdr->p_type == PT_INTERP)
1281 {
1282 /* If we are sure the file offset is valid then we can show
1283 the user the name of the interpreter. We check whether
1284 there is a section at the file offset. Normally there
1285 would be a section called ".interp". But in separate
1286 .debug files it is a NOBITS section (and so doesn't match
1287 with gelf_offscn). Which probably means the offset is
1288 not valid another reason could be because the ELF file
1289 just doesn't contain any section headers, in that case
1290 just play it safe and don't display anything. */
1291
1292 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1293 GElf_Shdr shdr_mem;
1294 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1295
1296 size_t maxsize;
1297 char *filedata = elf_rawfile (ebl->elf, &maxsize);
1298
1299 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
1300 && filedata != NULL && phdr->p_offset < maxsize
1301 && phdr->p_filesz <= maxsize - phdr->p_offset
1302 && memchr (filedata + phdr->p_offset, '\0',
1303 phdr->p_filesz) != NULL)
1304 printf (gettext ("\t[Requesting program interpreter: %s]\n"),
1305 filedata + phdr->p_offset);
1306 }
1307 else if (phdr->p_type == PT_GNU_RELRO)
1308 {
1309 has_relro = true;
1310 relro_from = phdr->p_vaddr;
1311 relro_to = relro_from + phdr->p_memsz;
1312 }
1313 }
1314
1315 if (ehdr->e_shnum == 0)
1316 /* No sections in the file. Punt. */
1317 return;
1318
1319 /* Get the section header string table index. */
1320 size_t shstrndx;
1321 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1322 error (EXIT_FAILURE, 0,
1323 gettext ("cannot get section header string table index"));
1324
1325 puts (gettext ("\n Section to Segment mapping:\n Segment Sections..."));
1326
1327 for (size_t cnt = 0; cnt < phnum; ++cnt)
1328 {
1329 /* Print the segment number. */
1330 printf (" %2.2zu ", cnt);
1331
1332 GElf_Phdr phdr_mem;
1333 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
1334 /* This must not happen. */
1335 if (unlikely (phdr == NULL))
1336 error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
1337 elf_errmsg (-1));
1338
1339 /* Iterate over the sections. */
1340 bool in_relro = false;
1341 bool in_ro = false;
1342 for (size_t inner = 1; inner < shnum; ++inner)
1343 {
1344 Elf_Scn *scn = elf_getscn (ebl->elf, inner);
1345 /* This should not happen. */
1346 if (unlikely (scn == NULL))
1347 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
1348 elf_errmsg (-1));
1349
1350 /* Get the section header. */
1351 GElf_Shdr shdr_mem;
1352 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1353 if (unlikely (shdr == NULL))
1354 error (EXIT_FAILURE, 0,
1355 gettext ("cannot get section header: %s"),
1356 elf_errmsg (-1));
1357
1358 if (shdr->sh_size > 0
1359 /* Compare allocated sections by VMA, unallocated
1360 sections by file offset. */
1361 && (shdr->sh_flags & SHF_ALLOC
1362 ? (shdr->sh_addr >= phdr->p_vaddr
1363 && (shdr->sh_addr + shdr->sh_size
1364 <= phdr->p_vaddr + phdr->p_memsz))
1365 : (shdr->sh_offset >= phdr->p_offset
1366 && (shdr->sh_offset + shdr->sh_size
1367 <= phdr->p_offset + phdr->p_filesz))))
1368 {
1369 if (has_relro && !in_relro
1370 && shdr->sh_addr >= relro_from
1371 && shdr->sh_addr + shdr->sh_size <= relro_to)
1372 {
1373 fputs_unlocked (" [RELRO:", stdout);
1374 in_relro = true;
1375 }
1376 else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
1377 {
1378 fputs_unlocked ("]", stdout);
1379 in_relro = false;
1380 }
1381 else if (has_relro && in_relro
1382 && shdr->sh_addr + shdr->sh_size > relro_to)
1383 fputs_unlocked ("] <RELRO:", stdout);
1384 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
1385 {
1386 if (!in_ro)
1387 {
1388 fputs_unlocked (" [RO:", stdout);
1389 in_ro = true;
1390 }
1391 }
1392 else
1393 {
1394 /* Determine the segment this section is part of. */
1395 size_t cnt2;
1396 GElf_Phdr phdr2_mem;
1397 GElf_Phdr *phdr2 = NULL;
1398 for (cnt2 = 0; cnt2 < phnum; ++cnt2)
1399 {
1400 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
1401
1402 if (phdr2 != NULL && phdr2->p_type == PT_LOAD
1403 && shdr->sh_addr >= phdr2->p_vaddr
1404 && (shdr->sh_addr + shdr->sh_size
1405 <= phdr2->p_vaddr + phdr2->p_memsz))
1406 break;
1407 }
1408
1409 if (cnt2 < phnum)
1410 {
1411 if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
1412 {
1413 fputs_unlocked (" [RO:", stdout);
1414 in_ro = true;
1415 }
1416 else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
1417 {
1418 fputs_unlocked ("]", stdout);
1419 in_ro = false;
1420 }
1421 }
1422 }
1423
1424 printf (" %s",
1425 elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
1426
1427 /* Signal that this sectin is only partially covered. */
1428 if (has_relro && in_relro
1429 && shdr->sh_addr + shdr->sh_size > relro_to)
1430 {
1431 fputs_unlocked (">", stdout);
1432 in_relro = false;
1433 }
1434 }
1435 }
1436 if (in_relro || in_ro)
1437 fputs_unlocked ("]", stdout);
1438
1439 /* Finish the line. */
1440 fputc_unlocked ('\n', stdout);
1441 }
1442 }
1443
1444
1445 static const char *
section_name(Ebl * ebl,GElf_Ehdr * ehdr,GElf_Shdr * shdr)1446 section_name (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr)
1447 {
1448 return elf_strptr (ebl->elf, ehdr->e_shstrndx, shdr->sh_name) ?: "???";
1449 }
1450
1451
1452 static void
handle_scngrp(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1453 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1454 {
1455 /* Get the data of the section. */
1456 Elf_Data *data = elf_getdata (scn, NULL);
1457
1458 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1459 GElf_Shdr symshdr_mem;
1460 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1461 Elf_Data *symdata = elf_getdata (symscn, NULL);
1462
1463 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
1464 || symdata == NULL)
1465 return;
1466
1467 /* Get the section header string table index. */
1468 size_t shstrndx;
1469 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1470 error (EXIT_FAILURE, 0,
1471 gettext ("cannot get section header string table index"));
1472
1473 Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
1474
1475 GElf_Sym sym_mem;
1476 GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1477
1478 printf ((grpref[0] & GRP_COMDAT)
1479 ? ngettext ("\
1480 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
1481 "\
1482 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1483 data->d_size / sizeof (Elf32_Word) - 1)
1484 : ngettext ("\
1485 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
1486 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
1487 data->d_size / sizeof (Elf32_Word) - 1),
1488 elf_ndxscn (scn),
1489 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1490 (sym == NULL ? NULL
1491 : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
1492 ?: gettext ("<INVALID SYMBOL>"),
1493 data->d_size / sizeof (Elf32_Word) - 1);
1494
1495 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
1496 {
1497 GElf_Shdr grpshdr_mem;
1498 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
1499 &grpshdr_mem);
1500
1501 const char *str;
1502 printf (" [%2u] %s\n",
1503 grpref[cnt],
1504 grpshdr != NULL
1505 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
1506 ? str : gettext ("<INVALID SECTION>"));
1507 }
1508 }
1509
1510
1511 static void
print_scngrp(Ebl * ebl)1512 print_scngrp (Ebl *ebl)
1513 {
1514 /* Find all relocation sections and handle them. */
1515 Elf_Scn *scn = NULL;
1516
1517 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1518 {
1519 /* Handle the section if it is a symbol table. */
1520 GElf_Shdr shdr_mem;
1521 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1522
1523 if (shdr != NULL && shdr->sh_type == SHT_GROUP)
1524 {
1525 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1526 {
1527 if (elf_compress (scn, 0, 0) < 0)
1528 printf ("WARNING: %s [%zd]\n",
1529 gettext ("Couldn't uncompress section"),
1530 elf_ndxscn (scn));
1531 shdr = gelf_getshdr (scn, &shdr_mem);
1532 }
1533 handle_scngrp (ebl, scn, shdr);
1534 }
1535 }
1536 }
1537
1538
1539 static const struct flags
1540 {
1541 int mask;
1542 const char *str;
1543 } dt_flags[] =
1544 {
1545 { DF_ORIGIN, "ORIGIN" },
1546 { DF_SYMBOLIC, "SYMBOLIC" },
1547 { DF_TEXTREL, "TEXTREL" },
1548 { DF_BIND_NOW, "BIND_NOW" },
1549 { DF_STATIC_TLS, "STATIC_TLS" }
1550 };
1551 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
1552
1553 static const struct flags dt_flags_1[] =
1554 {
1555 { DF_1_NOW, "NOW" },
1556 { DF_1_GLOBAL, "GLOBAL" },
1557 { DF_1_GROUP, "GROUP" },
1558 { DF_1_NODELETE, "NODELETE" },
1559 { DF_1_LOADFLTR, "LOADFLTR" },
1560 { DF_1_INITFIRST, "INITFIRST" },
1561 { DF_1_NOOPEN, "NOOPEN" },
1562 { DF_1_ORIGIN, "ORIGIN" },
1563 { DF_1_DIRECT, "DIRECT" },
1564 { DF_1_TRANS, "TRANS" },
1565 { DF_1_INTERPOSE, "INTERPOSE" },
1566 { DF_1_NODEFLIB, "NODEFLIB" },
1567 { DF_1_NODUMP, "NODUMP" },
1568 { DF_1_CONFALT, "CONFALT" },
1569 { DF_1_ENDFILTEE, "ENDFILTEE" },
1570 { DF_1_DISPRELDNE, "DISPRELDNE" },
1571 { DF_1_DISPRELPND, "DISPRELPND" },
1572 };
1573 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
1574
1575 static const struct flags dt_feature_1[] =
1576 {
1577 { DTF_1_PARINIT, "PARINIT" },
1578 { DTF_1_CONFEXP, "CONFEXP" }
1579 };
1580 static const int ndt_feature_1 = (sizeof (dt_feature_1)
1581 / sizeof (dt_feature_1[0]));
1582
1583 static const struct flags dt_posflag_1[] =
1584 {
1585 { DF_P1_LAZYLOAD, "LAZYLOAD" },
1586 { DF_P1_GROUPPERM, "GROUPPERM" }
1587 };
1588 static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
1589 / sizeof (dt_posflag_1[0]));
1590
1591
1592 static void
print_flags(int class,GElf_Xword d_val,const struct flags * flags,int nflags)1593 print_flags (int class, GElf_Xword d_val, const struct flags *flags,
1594 int nflags)
1595 {
1596 bool first = true;
1597 int cnt;
1598
1599 for (cnt = 0; cnt < nflags; ++cnt)
1600 if (d_val & flags[cnt].mask)
1601 {
1602 if (!first)
1603 putchar_unlocked (' ');
1604 fputs_unlocked (flags[cnt].str, stdout);
1605 d_val &= ~flags[cnt].mask;
1606 first = false;
1607 }
1608
1609 if (d_val != 0)
1610 {
1611 if (!first)
1612 putchar_unlocked (' ');
1613 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
1614 }
1615
1616 putchar_unlocked ('\n');
1617 }
1618
1619
1620 static void
print_dt_flags(int class,GElf_Xword d_val)1621 print_dt_flags (int class, GElf_Xword d_val)
1622 {
1623 print_flags (class, d_val, dt_flags, ndt_flags);
1624 }
1625
1626
1627 static void
print_dt_flags_1(int class,GElf_Xword d_val)1628 print_dt_flags_1 (int class, GElf_Xword d_val)
1629 {
1630 print_flags (class, d_val, dt_flags_1, ndt_flags_1);
1631 }
1632
1633
1634 static void
print_dt_feature_1(int class,GElf_Xword d_val)1635 print_dt_feature_1 (int class, GElf_Xword d_val)
1636 {
1637 print_flags (class, d_val, dt_feature_1, ndt_feature_1);
1638 }
1639
1640
1641 static void
print_dt_posflag_1(int class,GElf_Xword d_val)1642 print_dt_posflag_1 (int class, GElf_Xword d_val)
1643 {
1644 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
1645 }
1646
1647
1648 static void
handle_dynamic(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)1649 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
1650 {
1651 int class = gelf_getclass (ebl->elf);
1652 GElf_Shdr glink_mem;
1653 GElf_Shdr *glink;
1654 Elf_Data *data;
1655 size_t cnt;
1656 size_t shstrndx;
1657 size_t sh_entsize;
1658
1659 /* Get the data of the section. */
1660 data = elf_getdata (scn, NULL);
1661 if (data == NULL)
1662 return;
1663
1664 /* Get the section header string table index. */
1665 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1666 error (EXIT_FAILURE, 0,
1667 gettext ("cannot get section header string table index"));
1668
1669 sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
1670
1671 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
1672 if (glink == NULL)
1673 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
1674 elf_ndxscn (scn));
1675
1676 printf (ngettext ("\
1677 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1678 "\
1679 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
1680 shdr->sh_size / sh_entsize),
1681 (unsigned long int) (shdr->sh_size / sh_entsize),
1682 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
1683 shdr->sh_offset,
1684 (int) shdr->sh_link,
1685 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
1686 fputs_unlocked (gettext (" Type Value\n"), stdout);
1687
1688 for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
1689 {
1690 GElf_Dyn dynmem;
1691 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
1692 if (dyn == NULL)
1693 break;
1694
1695 char buf[64];
1696 printf (" %-17s ",
1697 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
1698
1699 switch (dyn->d_tag)
1700 {
1701 case DT_NULL:
1702 case DT_DEBUG:
1703 case DT_BIND_NOW:
1704 case DT_TEXTREL:
1705 /* No further output. */
1706 fputc_unlocked ('\n', stdout);
1707 break;
1708
1709 case DT_NEEDED:
1710 printf (gettext ("Shared library: [%s]\n"),
1711 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1712 break;
1713
1714 case DT_SONAME:
1715 printf (gettext ("Library soname: [%s]\n"),
1716 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1717 break;
1718
1719 case DT_RPATH:
1720 printf (gettext ("Library rpath: [%s]\n"),
1721 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1722 break;
1723
1724 case DT_RUNPATH:
1725 printf (gettext ("Library runpath: [%s]\n"),
1726 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
1727 break;
1728
1729 case DT_PLTRELSZ:
1730 case DT_RELASZ:
1731 case DT_STRSZ:
1732 case DT_RELSZ:
1733 case DT_RELAENT:
1734 case DT_SYMENT:
1735 case DT_RELENT:
1736 case DT_PLTPADSZ:
1737 case DT_MOVEENT:
1738 case DT_MOVESZ:
1739 case DT_INIT_ARRAYSZ:
1740 case DT_FINI_ARRAYSZ:
1741 case DT_SYMINSZ:
1742 case DT_SYMINENT:
1743 case DT_GNU_CONFLICTSZ:
1744 case DT_GNU_LIBLISTSZ:
1745 printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
1746 break;
1747
1748 case DT_VERDEFNUM:
1749 case DT_VERNEEDNUM:
1750 case DT_RELACOUNT:
1751 case DT_RELCOUNT:
1752 printf ("%" PRId64 "\n", dyn->d_un.d_val);
1753 break;
1754
1755 case DT_PLTREL:;
1756 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
1757 NULL, 0);
1758 puts (tagname ?: "???");
1759 break;
1760
1761 case DT_FLAGS:
1762 print_dt_flags (class, dyn->d_un.d_val);
1763 break;
1764
1765 case DT_FLAGS_1:
1766 print_dt_flags_1 (class, dyn->d_un.d_val);
1767 break;
1768
1769 case DT_FEATURE_1:
1770 print_dt_feature_1 (class, dyn->d_un.d_val);
1771 break;
1772
1773 case DT_POSFLAG_1:
1774 print_dt_posflag_1 (class, dyn->d_un.d_val);
1775 break;
1776
1777 default:
1778 printf ("%#0*" PRIx64 "\n",
1779 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
1780 break;
1781 }
1782 }
1783 }
1784
1785
1786 /* Print the dynamic segment. */
1787 static void
print_dynamic(Ebl * ebl)1788 print_dynamic (Ebl *ebl)
1789 {
1790 for (size_t i = 0; i < phnum; ++i)
1791 {
1792 GElf_Phdr phdr_mem;
1793 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
1794
1795 if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
1796 {
1797 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
1798 GElf_Shdr shdr_mem;
1799 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1800 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
1801 handle_dynamic (ebl, scn, shdr);
1802 break;
1803 }
1804 }
1805 }
1806
1807
1808 /* Print relocations. */
1809 static void
print_relocs(Ebl * ebl,GElf_Ehdr * ehdr)1810 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
1811 {
1812 /* Find all relocation sections and handle them. */
1813 Elf_Scn *scn = NULL;
1814
1815 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
1816 {
1817 /* Handle the section if it is a symbol table. */
1818 GElf_Shdr shdr_mem;
1819 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1820
1821 if (likely (shdr != NULL))
1822 {
1823 if (shdr->sh_type == SHT_REL)
1824 handle_relocs_rel (ebl, ehdr, scn, shdr);
1825 else if (shdr->sh_type == SHT_RELA)
1826 handle_relocs_rela (ebl, ehdr, scn, shdr);
1827 }
1828 }
1829 }
1830
1831
1832 /* Handle a relocation section. */
1833 static void
handle_relocs_rel(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)1834 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
1835 {
1836 int class = gelf_getclass (ebl->elf);
1837 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
1838 int nentries = shdr->sh_size / sh_entsize;
1839
1840 /* Get the data of the section. */
1841 Elf_Data *data = elf_getdata (scn, NULL);
1842 if (data == NULL)
1843 return;
1844
1845 /* Get the symbol table information. */
1846 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
1847 GElf_Shdr symshdr_mem;
1848 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1849 Elf_Data *symdata = elf_getdata (symscn, NULL);
1850
1851 /* Get the section header of the section the relocations are for. */
1852 GElf_Shdr destshdr_mem;
1853 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
1854 &destshdr_mem);
1855
1856 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
1857 {
1858 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
1859 shdr->sh_offset);
1860 return;
1861 }
1862
1863 /* Search for the optional extended section index table. */
1864 Elf_Data *xndxdata = NULL;
1865 int xndxscnidx = elf_scnshndx (scn);
1866 if (unlikely (xndxscnidx > 0))
1867 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
1868
1869 /* Get the section header string table index. */
1870 size_t shstrndx;
1871 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
1872 error (EXIT_FAILURE, 0,
1873 gettext ("cannot get section header string table index"));
1874
1875 if (shdr->sh_info != 0)
1876 printf (ngettext ("\
1877 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1878 "\
1879 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1880 nentries),
1881 elf_ndxscn (scn),
1882 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1883 (unsigned int) shdr->sh_info,
1884 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
1885 shdr->sh_offset,
1886 nentries);
1887 else
1888 /* The .rel.dyn section does not refer to a specific section but
1889 instead of section index zero. Do not try to print a section
1890 name. */
1891 printf (ngettext ("\
1892 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
1893 "\
1894 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
1895 nentries),
1896 (unsigned int) elf_ndxscn (scn),
1897 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
1898 shdr->sh_offset,
1899 nentries);
1900 fputs_unlocked (class == ELFCLASS32
1901 ? gettext ("\
1902 Offset Type Value Name\n")
1903 : gettext ("\
1904 Offset Type Value Name\n"),
1905 stdout);
1906
1907 int is_statically_linked = 0;
1908 for (int cnt = 0; cnt < nentries; ++cnt)
1909 {
1910 GElf_Rel relmem;
1911 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
1912 if (likely (rel != NULL))
1913 {
1914 char buf[128];
1915 GElf_Sym symmem;
1916 Elf32_Word xndx;
1917 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1918 GELF_R_SYM (rel->r_info),
1919 &symmem, &xndx);
1920 if (unlikely (sym == NULL))
1921 {
1922 /* As a special case we have to handle relocations in static
1923 executables. This only happens for IRELATIVE relocations
1924 (so far). There is no symbol table. */
1925 if (is_statically_linked == 0)
1926 {
1927 /* Find the program header and look for a PT_INTERP entry. */
1928 is_statically_linked = -1;
1929 if (ehdr->e_type == ET_EXEC)
1930 {
1931 is_statically_linked = 1;
1932
1933 for (size_t inner = 0; inner < phnum; ++inner)
1934 {
1935 GElf_Phdr phdr_mem;
1936 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
1937 &phdr_mem);
1938 if (phdr != NULL && phdr->p_type == PT_INTERP)
1939 {
1940 is_statically_linked = -1;
1941 break;
1942 }
1943 }
1944 }
1945 }
1946
1947 if (is_statically_linked > 0 && shdr->sh_link == 0)
1948 printf ("\
1949 %#0*" PRIx64 " %-20s %*s %s\n",
1950 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1951 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1952 /* Avoid the leading R_ which isn't carrying any
1953 information. */
1954 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1955 buf, sizeof (buf)) + 2
1956 : gettext ("<INVALID RELOC>"),
1957 class == ELFCLASS32 ? 10 : 18, "",
1958 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
1959 else
1960 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
1961 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1962 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1963 /* Avoid the leading R_ which isn't carrying any
1964 information. */
1965 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1966 buf, sizeof (buf)) + 2
1967 : gettext ("<INVALID RELOC>"),
1968 gettext ("INVALID SYMBOL"),
1969 (long int) GELF_R_SYM (rel->r_info));
1970 }
1971 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
1972 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
1973 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1974 likely (ebl_reloc_type_check (ebl,
1975 GELF_R_TYPE (rel->r_info)))
1976 /* Avoid the leading R_ which isn't carrying any
1977 information. */
1978 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
1979 buf, sizeof (buf)) + 2
1980 : gettext ("<INVALID RELOC>"),
1981 class == ELFCLASS32 ? 10 : 18, sym->st_value,
1982 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
1983 else
1984 {
1985 /* This is a relocation against a STT_SECTION symbol. */
1986 GElf_Shdr secshdr_mem;
1987 GElf_Shdr *secshdr;
1988 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
1989 sym->st_shndx == SHN_XINDEX
1990 ? xndx : sym->st_shndx),
1991 &secshdr_mem);
1992
1993 if (unlikely (secshdr == NULL))
1994 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
1995 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
1996 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
1997 /* Avoid the leading R_ which isn't carrying any
1998 information. */
1999 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2000 buf, sizeof (buf)) + 2
2001 : gettext ("<INVALID RELOC>"),
2002 gettext ("INVALID SECTION"),
2003 (long int) (sym->st_shndx == SHN_XINDEX
2004 ? xndx : sym->st_shndx));
2005 else
2006 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n",
2007 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2008 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2009 /* Avoid the leading R_ which isn't carrying any
2010 information. */
2011 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2012 buf, sizeof (buf)) + 2
2013 : gettext ("<INVALID RELOC>"),
2014 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2015 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2016 }
2017 }
2018 }
2019 }
2020
2021
2022 /* Handle a relocation section. */
2023 static void
handle_relocs_rela(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr)2024 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
2025 {
2026 int class = gelf_getclass (ebl->elf);
2027 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
2028 int nentries = shdr->sh_size / sh_entsize;
2029
2030 /* Get the data of the section. */
2031 Elf_Data *data = elf_getdata (scn, NULL);
2032 if (data == NULL)
2033 return;
2034
2035 /* Get the symbol table information. */
2036 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
2037 GElf_Shdr symshdr_mem;
2038 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
2039 Elf_Data *symdata = elf_getdata (symscn, NULL);
2040
2041 /* Get the section header of the section the relocations are for. */
2042 GElf_Shdr destshdr_mem;
2043 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
2044 &destshdr_mem);
2045
2046 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
2047 {
2048 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
2049 shdr->sh_offset);
2050 return;
2051 }
2052
2053 /* Search for the optional extended section index table. */
2054 Elf_Data *xndxdata = NULL;
2055 int xndxscnidx = elf_scnshndx (scn);
2056 if (unlikely (xndxscnidx > 0))
2057 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
2058
2059 /* Get the section header string table index. */
2060 size_t shstrndx;
2061 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2062 error (EXIT_FAILURE, 0,
2063 gettext ("cannot get section header string table index"));
2064
2065 if (shdr->sh_info != 0)
2066 printf (ngettext ("\
2067 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2068 "\
2069 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2070 nentries),
2071 elf_ndxscn (scn),
2072 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2073 (unsigned int) shdr->sh_info,
2074 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
2075 shdr->sh_offset,
2076 nentries);
2077 else
2078 /* The .rela.dyn section does not refer to a specific section but
2079 instead of section index zero. Do not try to print a section
2080 name. */
2081 printf (ngettext ("\
2082 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
2083 "\
2084 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
2085 nentries),
2086 (unsigned int) elf_ndxscn (scn),
2087 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2088 shdr->sh_offset,
2089 nentries);
2090 fputs_unlocked (class == ELFCLASS32
2091 ? gettext ("\
2092 Offset Type Value Addend Name\n")
2093 : gettext ("\
2094 Offset Type Value Addend Name\n"),
2095 stdout);
2096
2097 int is_statically_linked = 0;
2098 for (int cnt = 0; cnt < nentries; ++cnt)
2099 {
2100 GElf_Rela relmem;
2101 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
2102 if (likely (rel != NULL))
2103 {
2104 char buf[64];
2105 GElf_Sym symmem;
2106 Elf32_Word xndx;
2107 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
2108 GELF_R_SYM (rel->r_info),
2109 &symmem, &xndx);
2110
2111 if (unlikely (sym == NULL))
2112 {
2113 /* As a special case we have to handle relocations in static
2114 executables. This only happens for IRELATIVE relocations
2115 (so far). There is no symbol table. */
2116 if (is_statically_linked == 0)
2117 {
2118 /* Find the program header and look for a PT_INTERP entry. */
2119 is_statically_linked = -1;
2120 if (ehdr->e_type == ET_EXEC)
2121 {
2122 is_statically_linked = 1;
2123
2124 for (size_t inner = 0; inner < phnum; ++inner)
2125 {
2126 GElf_Phdr phdr_mem;
2127 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
2128 &phdr_mem);
2129 if (phdr != NULL && phdr->p_type == PT_INTERP)
2130 {
2131 is_statically_linked = -1;
2132 break;
2133 }
2134 }
2135 }
2136 }
2137
2138 if (is_statically_linked > 0 && shdr->sh_link == 0)
2139 printf ("\
2140 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
2141 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2142 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2143 /* Avoid the leading R_ which isn't carrying any
2144 information. */
2145 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2146 buf, sizeof (buf)) + 2
2147 : gettext ("<INVALID RELOC>"),
2148 class == ELFCLASS32 ? 10 : 18, "",
2149 rel->r_addend,
2150 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
2151 else
2152 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2153 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2154 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2155 /* Avoid the leading R_ which isn't carrying any
2156 information. */
2157 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2158 buf, sizeof (buf)) + 2
2159 : gettext ("<INVALID RELOC>"),
2160 gettext ("INVALID SYMBOL"),
2161 (long int) GELF_R_SYM (rel->r_info));
2162 }
2163 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
2164 printf ("\
2165 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2166 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2167 likely (ebl_reloc_type_check (ebl,
2168 GELF_R_TYPE (rel->r_info)))
2169 /* Avoid the leading R_ which isn't carrying any
2170 information. */
2171 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2172 buf, sizeof (buf)) + 2
2173 : gettext ("<INVALID RELOC>"),
2174 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2175 rel->r_addend,
2176 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
2177 else
2178 {
2179 /* This is a relocation against a STT_SECTION symbol. */
2180 GElf_Shdr secshdr_mem;
2181 GElf_Shdr *secshdr;
2182 secshdr = gelf_getshdr (elf_getscn (ebl->elf,
2183 sym->st_shndx == SHN_XINDEX
2184 ? xndx : sym->st_shndx),
2185 &secshdr_mem);
2186
2187 if (unlikely (secshdr == NULL))
2188 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
2189 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2190 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2191 /* Avoid the leading R_ which isn't carrying any
2192 information. */
2193 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2194 buf, sizeof (buf)) + 2
2195 : gettext ("<INVALID RELOC>"),
2196 gettext ("INVALID SECTION"),
2197 (long int) (sym->st_shndx == SHN_XINDEX
2198 ? xndx : sym->st_shndx));
2199 else
2200 printf ("\
2201 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n",
2202 class == ELFCLASS32 ? 10 : 18, rel->r_offset,
2203 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
2204 /* Avoid the leading R_ which isn't carrying any
2205 information. */
2206 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
2207 buf, sizeof (buf)) + 2
2208 : gettext ("<INVALID RELOC>"),
2209 class == ELFCLASS32 ? 10 : 18, sym->st_value,
2210 rel->r_addend,
2211 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
2212 }
2213 }
2214 }
2215 }
2216
2217
2218 /* Print the program header. */
2219 static void
print_symtab(Ebl * ebl,int type)2220 print_symtab (Ebl *ebl, int type)
2221 {
2222 /* Find the symbol table(s). For this we have to search through the
2223 section table. */
2224 Elf_Scn *scn = NULL;
2225
2226 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2227 {
2228 /* Handle the section if it is a symbol table. */
2229 GElf_Shdr shdr_mem;
2230 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2231
2232 if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
2233 {
2234 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
2235 {
2236 if (elf_compress (scn, 0, 0) < 0)
2237 printf ("WARNING: %s [%zd]\n",
2238 gettext ("Couldn't uncompress section"),
2239 elf_ndxscn (scn));
2240 shdr = gelf_getshdr (scn, &shdr_mem);
2241 }
2242 handle_symtab (ebl, scn, shdr);
2243 }
2244 }
2245 }
2246
2247
2248 static void
handle_symtab(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2249 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2250 {
2251 Elf_Data *versym_data = NULL;
2252 Elf_Data *verneed_data = NULL;
2253 Elf_Data *verdef_data = NULL;
2254 Elf_Data *xndx_data = NULL;
2255 int class = gelf_getclass (ebl->elf);
2256 Elf32_Word verneed_stridx = 0;
2257 Elf32_Word verdef_stridx = 0;
2258
2259 /* Get the data of the section. */
2260 Elf_Data *data = elf_getdata (scn, NULL);
2261 if (data == NULL)
2262 return;
2263
2264 /* Find out whether we have other sections we might need. */
2265 Elf_Scn *runscn = NULL;
2266 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
2267 {
2268 GElf_Shdr runshdr_mem;
2269 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
2270
2271 if (likely (runshdr != NULL))
2272 {
2273 if (runshdr->sh_type == SHT_GNU_versym
2274 && runshdr->sh_link == elf_ndxscn (scn))
2275 /* Bingo, found the version information. Now get the data. */
2276 versym_data = elf_getdata (runscn, NULL);
2277 else if (runshdr->sh_type == SHT_GNU_verneed)
2278 {
2279 /* This is the information about the needed versions. */
2280 verneed_data = elf_getdata (runscn, NULL);
2281 verneed_stridx = runshdr->sh_link;
2282 }
2283 else if (runshdr->sh_type == SHT_GNU_verdef)
2284 {
2285 /* This is the information about the defined versions. */
2286 verdef_data = elf_getdata (runscn, NULL);
2287 verdef_stridx = runshdr->sh_link;
2288 }
2289 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
2290 && runshdr->sh_link == elf_ndxscn (scn))
2291 /* Extended section index. */
2292 xndx_data = elf_getdata (runscn, NULL);
2293 }
2294 }
2295
2296 /* Get the section header string table index. */
2297 size_t shstrndx;
2298 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2299 error (EXIT_FAILURE, 0,
2300 gettext ("cannot get section header string table index"));
2301
2302 GElf_Shdr glink_mem;
2303 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2304 &glink_mem);
2305 if (glink == NULL)
2306 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2307 elf_ndxscn (scn));
2308
2309 /* Now we can compute the number of entries in the section. */
2310 unsigned int nsyms = data->d_size / (class == ELFCLASS32
2311 ? sizeof (Elf32_Sym)
2312 : sizeof (Elf64_Sym));
2313
2314 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
2315 "\nSymbol table [%2u] '%s' contains %u entries:\n",
2316 nsyms),
2317 (unsigned int) elf_ndxscn (scn),
2318 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
2319 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n",
2320 " %lu local symbols String table: [%2u] '%s'\n",
2321 shdr->sh_info),
2322 (unsigned long int) shdr->sh_info,
2323 (unsigned int) shdr->sh_link,
2324 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2325
2326 fputs_unlocked (class == ELFCLASS32
2327 ? gettext ("\
2328 Num: Value Size Type Bind Vis Ndx Name\n")
2329 : gettext ("\
2330 Num: Value Size Type Bind Vis Ndx Name\n"),
2331 stdout);
2332
2333 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
2334 {
2335 char typebuf[64];
2336 char bindbuf[64];
2337 char scnbuf[64];
2338 Elf32_Word xndx;
2339 GElf_Sym sym_mem;
2340 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
2341
2342 if (unlikely (sym == NULL))
2343 continue;
2344
2345 /* Determine the real section index. */
2346 if (likely (sym->st_shndx != SHN_XINDEX))
2347 xndx = sym->st_shndx;
2348
2349 printf (gettext ("\
2350 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
2351 cnt,
2352 class == ELFCLASS32 ? 8 : 16,
2353 sym->st_value,
2354 sym->st_size,
2355 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
2356 typebuf, sizeof (typebuf)),
2357 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
2358 bindbuf, sizeof (bindbuf)),
2359 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
2360 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
2361 sizeof (scnbuf), NULL, shnum),
2362 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
2363
2364 if (versym_data != NULL)
2365 {
2366 /* Get the version information. */
2367 GElf_Versym versym_mem;
2368 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
2369
2370 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
2371 {
2372 bool is_nobits = false;
2373 bool check_def = xndx != SHN_UNDEF;
2374
2375 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
2376 {
2377 GElf_Shdr symshdr_mem;
2378 GElf_Shdr *symshdr =
2379 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
2380
2381 is_nobits = (symshdr != NULL
2382 && symshdr->sh_type == SHT_NOBITS);
2383 }
2384
2385 if (is_nobits || ! check_def)
2386 {
2387 /* We must test both. */
2388 GElf_Vernaux vernaux_mem;
2389 GElf_Vernaux *vernaux = NULL;
2390 size_t vn_offset = 0;
2391
2392 GElf_Verneed verneed_mem;
2393 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
2394 &verneed_mem);
2395 while (verneed != NULL)
2396 {
2397 size_t vna_offset = vn_offset;
2398
2399 vernaux = gelf_getvernaux (verneed_data,
2400 vna_offset += verneed->vn_aux,
2401 &vernaux_mem);
2402 while (vernaux != NULL
2403 && vernaux->vna_other != *versym
2404 && vernaux->vna_next != 0)
2405 {
2406 /* Update the offset. */
2407 vna_offset += vernaux->vna_next;
2408
2409 vernaux = (vernaux->vna_next == 0
2410 ? NULL
2411 : gelf_getvernaux (verneed_data,
2412 vna_offset,
2413 &vernaux_mem));
2414 }
2415
2416 /* Check whether we found the version. */
2417 if (vernaux != NULL && vernaux->vna_other == *versym)
2418 /* Found it. */
2419 break;
2420
2421 vn_offset += verneed->vn_next;
2422 verneed = (verneed->vn_next == 0
2423 ? NULL
2424 : gelf_getverneed (verneed_data, vn_offset,
2425 &verneed_mem));
2426 }
2427
2428 if (vernaux != NULL && vernaux->vna_other == *versym)
2429 {
2430 printf ("@%s (%u)",
2431 elf_strptr (ebl->elf, verneed_stridx,
2432 vernaux->vna_name),
2433 (unsigned int) vernaux->vna_other);
2434 check_def = 0;
2435 }
2436 else if (unlikely (! is_nobits))
2437 error (0, 0, gettext ("bad dynamic symbol"));
2438 else
2439 check_def = 1;
2440 }
2441
2442 if (check_def && *versym != 0x8001)
2443 {
2444 /* We must test both. */
2445 size_t vd_offset = 0;
2446
2447 GElf_Verdef verdef_mem;
2448 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
2449 &verdef_mem);
2450 while (verdef != NULL)
2451 {
2452 if (verdef->vd_ndx == (*versym & 0x7fff))
2453 /* Found the definition. */
2454 break;
2455
2456 vd_offset += verdef->vd_next;
2457 verdef = (verdef->vd_next == 0
2458 ? NULL
2459 : gelf_getverdef (verdef_data, vd_offset,
2460 &verdef_mem));
2461 }
2462
2463 if (verdef != NULL)
2464 {
2465 GElf_Verdaux verdaux_mem;
2466 GElf_Verdaux *verdaux
2467 = gelf_getverdaux (verdef_data,
2468 vd_offset + verdef->vd_aux,
2469 &verdaux_mem);
2470
2471 if (verdaux != NULL)
2472 printf ((*versym & 0x8000) ? "@%s" : "@@%s",
2473 elf_strptr (ebl->elf, verdef_stridx,
2474 verdaux->vda_name));
2475 }
2476 }
2477 }
2478 }
2479
2480 putchar_unlocked ('\n');
2481 }
2482 }
2483
2484
2485 /* Print version information. */
2486 static void
print_verinfo(Ebl * ebl)2487 print_verinfo (Ebl *ebl)
2488 {
2489 /* Find the version information sections. For this we have to
2490 search through the section table. */
2491 Elf_Scn *scn = NULL;
2492
2493 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
2494 {
2495 /* Handle the section if it is part of the versioning handling. */
2496 GElf_Shdr shdr_mem;
2497 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2498
2499 if (likely (shdr != NULL))
2500 {
2501 if (shdr->sh_type == SHT_GNU_verneed)
2502 handle_verneed (ebl, scn, shdr);
2503 else if (shdr->sh_type == SHT_GNU_verdef)
2504 handle_verdef (ebl, scn, shdr);
2505 else if (shdr->sh_type == SHT_GNU_versym)
2506 handle_versym (ebl, scn, shdr);
2507 }
2508 }
2509 }
2510
2511
2512 static const char *
get_ver_flags(unsigned int flags)2513 get_ver_flags (unsigned int flags)
2514 {
2515 static char buf[32];
2516 char *endp;
2517
2518 if (flags == 0)
2519 return gettext ("none");
2520
2521 if (flags & VER_FLG_BASE)
2522 endp = stpcpy (buf, "BASE ");
2523 else
2524 endp = buf;
2525
2526 if (flags & VER_FLG_WEAK)
2527 {
2528 if (endp != buf)
2529 endp = stpcpy (endp, "| ");
2530
2531 endp = stpcpy (endp, "WEAK ");
2532 }
2533
2534 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
2535 {
2536 strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
2537 buf[sizeof (buf) - 1] = '\0';
2538 }
2539
2540 return buf;
2541 }
2542
2543
2544 static void
handle_verneed(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2545 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2546 {
2547 int class = gelf_getclass (ebl->elf);
2548
2549 /* Get the data of the section. */
2550 Elf_Data *data = elf_getdata (scn, NULL);
2551 if (data == NULL)
2552 return;
2553
2554 /* Get the section header string table index. */
2555 size_t shstrndx;
2556 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2557 error (EXIT_FAILURE, 0,
2558 gettext ("cannot get section header string table index"));
2559
2560 GElf_Shdr glink_mem;
2561 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2562 &glink_mem);
2563 if (glink == NULL)
2564 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2565 elf_ndxscn (scn));
2566
2567 printf (ngettext ("\
2568 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2569 "\
2570 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2571 shdr->sh_info),
2572 (unsigned int) elf_ndxscn (scn),
2573 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
2574 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2575 shdr->sh_offset,
2576 (unsigned int) shdr->sh_link,
2577 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2578
2579 unsigned int offset = 0;
2580 for (int cnt = shdr->sh_info; --cnt >= 0; )
2581 {
2582 /* Get the data at the next offset. */
2583 GElf_Verneed needmem;
2584 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
2585 if (unlikely (need == NULL))
2586 break;
2587
2588 printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"),
2589 offset, (unsigned short int) need->vn_version,
2590 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
2591 (unsigned short int) need->vn_cnt);
2592
2593 unsigned int auxoffset = offset + need->vn_aux;
2594 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2595 {
2596 GElf_Vernaux auxmem;
2597 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
2598 if (unlikely (aux == NULL))
2599 break;
2600
2601 printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"),
2602 auxoffset,
2603 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
2604 get_ver_flags (aux->vna_flags),
2605 (unsigned short int) aux->vna_other);
2606
2607 if (aux->vna_next == 0)
2608 break;
2609
2610 auxoffset += aux->vna_next;
2611 }
2612
2613 /* Find the next offset. */
2614 if (need->vn_next == 0)
2615 break;
2616
2617 offset += need->vn_next;
2618 }
2619 }
2620
2621
2622 static void
handle_verdef(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2623 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2624 {
2625 /* Get the data of the section. */
2626 Elf_Data *data = elf_getdata (scn, NULL);
2627 if (data == NULL)
2628 return;
2629
2630 /* Get the section header string table index. */
2631 size_t shstrndx;
2632 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2633 error (EXIT_FAILURE, 0,
2634 gettext ("cannot get section header string table index"));
2635
2636 GElf_Shdr glink_mem;
2637 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2638 &glink_mem);
2639 if (glink == NULL)
2640 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2641 elf_ndxscn (scn));
2642
2643 int class = gelf_getclass (ebl->elf);
2644 printf (ngettext ("\
2645 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2646 "\
2647 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n",
2648 shdr->sh_info),
2649 (unsigned int) elf_ndxscn (scn),
2650 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2651 shdr->sh_info,
2652 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2653 shdr->sh_offset,
2654 (unsigned int) shdr->sh_link,
2655 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2656
2657 unsigned int offset = 0;
2658 for (int cnt = shdr->sh_info; --cnt >= 0; )
2659 {
2660 /* Get the data at the next offset. */
2661 GElf_Verdef defmem;
2662 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
2663 if (unlikely (def == NULL))
2664 break;
2665
2666 unsigned int auxoffset = offset + def->vd_aux;
2667 GElf_Verdaux auxmem;
2668 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
2669 if (unlikely (aux == NULL))
2670 break;
2671
2672 printf (gettext ("\
2673 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"),
2674 offset, def->vd_version,
2675 get_ver_flags (def->vd_flags),
2676 def->vd_ndx,
2677 def->vd_cnt,
2678 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2679
2680 auxoffset += aux->vda_next;
2681 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
2682 {
2683 aux = gelf_getverdaux (data, auxoffset, &auxmem);
2684 if (unlikely (aux == NULL))
2685 break;
2686
2687 printf (gettext (" %#06x: Parent %d: %s\n"),
2688 auxoffset, cnt2,
2689 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
2690
2691 if (aux->vda_next == 0)
2692 break;
2693
2694 auxoffset += aux->vda_next;
2695 }
2696
2697 /* Find the next offset. */
2698 if (def->vd_next == 0)
2699 break;
2700 offset += def->vd_next;
2701 }
2702 }
2703
2704
2705 static void
handle_versym(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr)2706 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
2707 {
2708 int class = gelf_getclass (ebl->elf);
2709 const char **vername;
2710 const char **filename;
2711
2712 /* Get the data of the section. */
2713 Elf_Data *data = elf_getdata (scn, NULL);
2714 if (data == NULL)
2715 return;
2716
2717 /* Get the section header string table index. */
2718 size_t shstrndx;
2719 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
2720 error (EXIT_FAILURE, 0,
2721 gettext ("cannot get section header string table index"));
2722
2723 /* We have to find the version definition section and extract the
2724 version names. */
2725 Elf_Scn *defscn = NULL;
2726 Elf_Scn *needscn = NULL;
2727
2728 Elf_Scn *verscn = NULL;
2729 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
2730 {
2731 GElf_Shdr vershdr_mem;
2732 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
2733
2734 if (likely (vershdr != NULL))
2735 {
2736 if (vershdr->sh_type == SHT_GNU_verdef)
2737 defscn = verscn;
2738 else if (vershdr->sh_type == SHT_GNU_verneed)
2739 needscn = verscn;
2740 }
2741 }
2742
2743 size_t nvername;
2744 if (defscn != NULL || needscn != NULL)
2745 {
2746 /* We have a version information (better should have). Now get
2747 the version names. First find the maximum version number. */
2748 nvername = 0;
2749 if (defscn != NULL)
2750 {
2751 /* Run through the version definitions and find the highest
2752 index. */
2753 unsigned int offset = 0;
2754 Elf_Data *defdata;
2755 GElf_Shdr defshdrmem;
2756 GElf_Shdr *defshdr;
2757
2758 defdata = elf_getdata (defscn, NULL);
2759 if (unlikely (defdata == NULL))
2760 return;
2761
2762 defshdr = gelf_getshdr (defscn, &defshdrmem);
2763 if (unlikely (defshdr == NULL))
2764 return;
2765
2766 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2767 {
2768 GElf_Verdef defmem;
2769 GElf_Verdef *def;
2770
2771 /* Get the data at the next offset. */
2772 def = gelf_getverdef (defdata, offset, &defmem);
2773 if (unlikely (def == NULL))
2774 break;
2775
2776 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
2777
2778 if (def->vd_next == 0)
2779 break;
2780 offset += def->vd_next;
2781 }
2782 }
2783 if (needscn != NULL)
2784 {
2785 unsigned int offset = 0;
2786 Elf_Data *needdata;
2787 GElf_Shdr needshdrmem;
2788 GElf_Shdr *needshdr;
2789
2790 needdata = elf_getdata (needscn, NULL);
2791 if (unlikely (needdata == NULL))
2792 return;
2793
2794 needshdr = gelf_getshdr (needscn, &needshdrmem);
2795 if (unlikely (needshdr == NULL))
2796 return;
2797
2798 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2799 {
2800 GElf_Verneed needmem;
2801 GElf_Verneed *need;
2802 unsigned int auxoffset;
2803 int cnt2;
2804
2805 /* Get the data at the next offset. */
2806 need = gelf_getverneed (needdata, offset, &needmem);
2807 if (unlikely (need == NULL))
2808 break;
2809
2810 /* Run through the auxiliary entries. */
2811 auxoffset = offset + need->vn_aux;
2812 for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
2813 {
2814 GElf_Vernaux auxmem;
2815 GElf_Vernaux *aux;
2816
2817 aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
2818 if (unlikely (aux == NULL))
2819 break;
2820
2821 nvername = MAX (nvername,
2822 (size_t) (aux->vna_other & 0x7fff));
2823
2824 if (aux->vna_next == 0)
2825 break;
2826 auxoffset += aux->vna_next;
2827 }
2828
2829 if (need->vn_next == 0)
2830 break;
2831 offset += need->vn_next;
2832 }
2833 }
2834
2835 /* This is the number of versions we know about. */
2836 ++nvername;
2837
2838 /* Allocate the array. */
2839 vername = (const char **) alloca (nvername * sizeof (const char *));
2840 memset(vername, 0, nvername * sizeof (const char *));
2841 filename = (const char **) alloca (nvername * sizeof (const char *));
2842 memset(filename, 0, nvername * sizeof (const char *));
2843
2844 /* Run through the data structures again and collect the strings. */
2845 if (defscn != NULL)
2846 {
2847 /* Run through the version definitions and find the highest
2848 index. */
2849 unsigned int offset = 0;
2850 Elf_Data *defdata;
2851 GElf_Shdr defshdrmem;
2852 GElf_Shdr *defshdr;
2853
2854 defdata = elf_getdata (defscn, NULL);
2855 if (unlikely (defdata == NULL))
2856 return;
2857
2858 defshdr = gelf_getshdr (defscn, &defshdrmem);
2859 if (unlikely (defshdr == NULL))
2860 return;
2861
2862 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
2863 {
2864
2865 /* Get the data at the next offset. */
2866 GElf_Verdef defmem;
2867 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
2868 if (unlikely (def == NULL))
2869 break;
2870
2871 GElf_Verdaux auxmem;
2872 GElf_Verdaux *aux = gelf_getverdaux (defdata,
2873 offset + def->vd_aux,
2874 &auxmem);
2875 if (unlikely (aux == NULL))
2876 break;
2877
2878 vername[def->vd_ndx & 0x7fff]
2879 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
2880 filename[def->vd_ndx & 0x7fff] = NULL;
2881
2882 if (def->vd_next == 0)
2883 break;
2884 offset += def->vd_next;
2885 }
2886 }
2887 if (needscn != NULL)
2888 {
2889 unsigned int offset = 0;
2890
2891 Elf_Data *needdata = elf_getdata (needscn, NULL);
2892 GElf_Shdr needshdrmem;
2893 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
2894 if (unlikely (needdata == NULL || needshdr == NULL))
2895 return;
2896
2897 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
2898 {
2899 /* Get the data at the next offset. */
2900 GElf_Verneed needmem;
2901 GElf_Verneed *need = gelf_getverneed (needdata, offset,
2902 &needmem);
2903 if (unlikely (need == NULL))
2904 break;
2905
2906 /* Run through the auxiliary entries. */
2907 unsigned int auxoffset = offset + need->vn_aux;
2908 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
2909 {
2910 GElf_Vernaux auxmem;
2911 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
2912 &auxmem);
2913 if (unlikely (aux == NULL))
2914 break;
2915
2916 vername[aux->vna_other & 0x7fff]
2917 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
2918 filename[aux->vna_other & 0x7fff]
2919 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
2920
2921 if (aux->vna_next == 0)
2922 break;
2923 auxoffset += aux->vna_next;
2924 }
2925
2926 if (need->vn_next == 0)
2927 break;
2928 offset += need->vn_next;
2929 }
2930 }
2931 }
2932 else
2933 {
2934 vername = NULL;
2935 nvername = 1;
2936 filename = NULL;
2937 }
2938
2939 GElf_Shdr glink_mem;
2940 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
2941 &glink_mem);
2942 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
2943 if (glink == NULL)
2944 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
2945 elf_ndxscn (scn));
2946
2947 /* Print the header. */
2948 printf (ngettext ("\
2949 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2950 "\
2951 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'",
2952 shdr->sh_size / sh_entsize),
2953 (unsigned int) elf_ndxscn (scn),
2954 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
2955 (int) (shdr->sh_size / sh_entsize),
2956 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
2957 shdr->sh_offset,
2958 (unsigned int) shdr->sh_link,
2959 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
2960
2961 /* Now we can finally look at the actual contents of this section. */
2962 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
2963 {
2964 if (cnt % 2 == 0)
2965 printf ("\n %4d:", cnt);
2966
2967 GElf_Versym symmem;
2968 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
2969 if (sym == NULL)
2970 break;
2971
2972 switch (*sym)
2973 {
2974 ssize_t n;
2975 case 0:
2976 fputs_unlocked (gettext (" 0 *local* "),
2977 stdout);
2978 break;
2979
2980 case 1:
2981 fputs_unlocked (gettext (" 1 *global* "),
2982 stdout);
2983 break;
2984
2985 default:
2986 n = printf ("%4d%c%s",
2987 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
2988 (vername != NULL
2989 && (unsigned int) (*sym & 0x7fff) < nvername)
2990 ? vername[*sym & 0x7fff] : "???");
2991 if ((unsigned int) (*sym & 0x7fff) < nvername
2992 && filename != NULL && filename[*sym & 0x7fff] != NULL)
2993 n += printf ("(%s)", filename[*sym & 0x7fff]);
2994 printf ("%*s", MAX (0, 33 - (int) n), " ");
2995 break;
2996 }
2997 }
2998 putchar_unlocked ('\n');
2999 }
3000
3001
3002 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)3003 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
3004 uint_fast32_t maxlength, Elf32_Word nbucket,
3005 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
3006 {
3007 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
3008
3009 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3010 ++counts[lengths[cnt]];
3011
3012 GElf_Shdr glink_mem;
3013 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
3014 shdr->sh_link),
3015 &glink_mem);
3016 if (glink == NULL)
3017 {
3018 error (0, 0, gettext ("invalid sh_link value in section %zu"),
3019 elf_ndxscn (scn));
3020 return;
3021 }
3022
3023 printf (ngettext ("\
3024 \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",
3025 "\
3026 \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",
3027 nbucket),
3028 (unsigned int) elf_ndxscn (scn),
3029 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3030 (int) nbucket,
3031 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
3032 shdr->sh_addr,
3033 shdr->sh_offset,
3034 (unsigned int) shdr->sh_link,
3035 elf_strptr (ebl->elf, shstrndx, glink->sh_name));
3036
3037 if (extrastr != NULL)
3038 fputs (extrastr, stdout);
3039
3040 if (likely (nbucket > 0))
3041 {
3042 uint64_t success = 0;
3043
3044 /* xgettext:no-c-format */
3045 fputs_unlocked (gettext ("\
3046 Length Number % of total Coverage\n"), stdout);
3047 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"),
3048 counts[0], (counts[0] * 100.0) / nbucket);
3049
3050 uint64_t nzero_counts = 0;
3051 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3052 {
3053 nzero_counts += counts[cnt] * cnt;
3054 printf (gettext ("\
3055 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"),
3056 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
3057 (nzero_counts * 100.0) / nsyms);
3058 }
3059
3060 Elf32_Word acc = 0;
3061 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
3062 {
3063 acc += cnt;
3064 success += counts[cnt] * acc;
3065 }
3066
3067 printf (gettext ("\
3068 Average number of tests: successful lookup: %f\n\
3069 unsuccessful lookup: %f\n"),
3070 (double) success / (double) nzero_counts,
3071 (double) nzero_counts / (double) nbucket);
3072 }
3073
3074 free (counts);
3075 }
3076
3077
3078 /* This function handles the traditional System V-style hash table format. */
3079 static void
handle_sysv_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3080 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3081 {
3082 Elf_Data *data = elf_getdata (scn, NULL);
3083 if (unlikely (data == NULL))
3084 {
3085 error (0, 0, gettext ("cannot get data for section %d: %s"),
3086 (int) elf_ndxscn (scn), elf_errmsg (-1));
3087 return;
3088 }
3089
3090 if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
3091 {
3092 invalid_data:
3093 error (0, 0, gettext ("invalid data in sysv.hash section %d"),
3094 (int) elf_ndxscn (scn));
3095 return;
3096 }
3097
3098 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3099 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
3100
3101 uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
3102 if (used_buf > data->d_size)
3103 goto invalid_data;
3104
3105 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
3106 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
3107
3108 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3109
3110 uint_fast32_t maxlength = 0;
3111 uint_fast32_t nsyms = 0;
3112 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3113 {
3114 Elf32_Word inner = bucket[cnt];
3115 while (inner > 0 && inner < nchain)
3116 {
3117 ++nsyms;
3118 if (maxlength < ++lengths[cnt])
3119 ++maxlength;
3120
3121 inner = chain[inner];
3122 }
3123 }
3124
3125 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3126 lengths, NULL);
3127
3128 free (lengths);
3129 }
3130
3131
3132 /* This function handles the incorrect, System V-style hash table
3133 format some 64-bit architectures use. */
3134 static void
handle_sysv_hash64(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3135 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3136 {
3137 Elf_Data *data = elf_getdata (scn, NULL);
3138 if (unlikely (data == NULL))
3139 {
3140 error (0, 0, gettext ("cannot get data for section %d: %s"),
3141 (int) elf_ndxscn (scn), elf_errmsg (-1));
3142 return;
3143 }
3144
3145 if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
3146 {
3147 invalid_data:
3148 error (0, 0, gettext ("invalid data in sysv.hash64 section %d"),
3149 (int) elf_ndxscn (scn));
3150 return;
3151 }
3152
3153 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
3154 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
3155
3156 uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
3157 if (maxwords < 2
3158 || maxwords - 2 < nbucket
3159 || maxwords - 2 - nbucket < nchain)
3160 goto invalid_data;
3161
3162 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
3163 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
3164
3165 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3166
3167 uint_fast32_t maxlength = 0;
3168 uint_fast32_t nsyms = 0;
3169 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
3170 {
3171 Elf64_Xword inner = bucket[cnt];
3172 while (inner > 0 && inner < nchain)
3173 {
3174 ++nsyms;
3175 if (maxlength < ++lengths[cnt])
3176 ++maxlength;
3177
3178 inner = chain[inner];
3179 }
3180 }
3181
3182 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3183 lengths, NULL);
3184
3185 free (lengths);
3186 }
3187
3188
3189 /* This function handles the GNU-style hash table format. */
3190 static void
handle_gnu_hash(Ebl * ebl,Elf_Scn * scn,GElf_Shdr * shdr,size_t shstrndx)3191 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
3192 {
3193 uint32_t *lengths = NULL;
3194 Elf_Data *data = elf_getdata (scn, NULL);
3195 if (unlikely (data == NULL))
3196 {
3197 error (0, 0, gettext ("cannot get data for section %d: %s"),
3198 (int) elf_ndxscn (scn), elf_errmsg (-1));
3199 return;
3200 }
3201
3202 if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
3203 {
3204 invalid_data:
3205 free (lengths);
3206 error (0, 0, gettext ("invalid data in gnu.hash section %d"),
3207 (int) elf_ndxscn (scn));
3208 return;
3209 }
3210
3211 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
3212 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
3213
3214 /* Next comes the size of the bitmap. It's measured in words for
3215 the architecture. It's 32 bits for 32 bit archs, and 64 bits for
3216 64 bit archs. There is always a bloom filter present, so zero is
3217 an invalid value. */
3218 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
3219 if (gelf_getclass (ebl->elf) == ELFCLASS64)
3220 bitmask_words *= 2;
3221
3222 if (bitmask_words == 0)
3223 goto invalid_data;
3224
3225 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
3226
3227 /* Is there still room for the sym chain?
3228 Use uint64_t calculation to prevent 32bit overlow. */
3229 uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
3230 uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
3231 if (used_buf > data->d_size)
3232 goto invalid_data;
3233
3234 lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
3235
3236 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
3237 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
3238 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
3239 + nbucket];
3240
3241 /* Compute distribution of chain lengths. */
3242 uint_fast32_t maxlength = 0;
3243 uint_fast32_t nsyms = 0;
3244 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
3245 if (bucket[cnt] != 0)
3246 {
3247 Elf32_Word inner = bucket[cnt] - symbias;
3248 do
3249 {
3250 ++nsyms;
3251 if (maxlength < ++lengths[cnt])
3252 ++maxlength;
3253 if (inner > max_nsyms)
3254 goto invalid_data;
3255 }
3256 while ((chain[inner++] & 1) == 0);
3257 }
3258
3259 /* Count bits in bitmask. */
3260 uint_fast32_t nbits = 0;
3261 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
3262 {
3263 uint_fast32_t word = bitmask[cnt];
3264
3265 word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
3266 word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
3267 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
3268 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
3269 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
3270 }
3271
3272 char *str;
3273 if (unlikely (asprintf (&str, gettext ("\
3274 Symbol Bias: %u\n\
3275 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"),
3276 (unsigned int) symbias,
3277 bitmask_words * sizeof (Elf32_Word),
3278 ((nbits * 100 + 50)
3279 / (uint_fast32_t) (bitmask_words
3280 * sizeof (Elf32_Word) * 8)),
3281 (unsigned int) shift) == -1))
3282 error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
3283
3284 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
3285 lengths, str);
3286
3287 free (str);
3288 free (lengths);
3289 }
3290
3291
3292 /* Find the symbol table(s). For this we have to search through the
3293 section table. */
3294 static void
handle_hash(Ebl * ebl)3295 handle_hash (Ebl *ebl)
3296 {
3297 /* Get the section header string table index. */
3298 size_t shstrndx;
3299 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3300 error (EXIT_FAILURE, 0,
3301 gettext ("cannot get section header string table index"));
3302
3303 Elf_Scn *scn = NULL;
3304 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3305 {
3306 /* Handle the section if it is a symbol table. */
3307 GElf_Shdr shdr_mem;
3308 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3309
3310 if (likely (shdr != NULL))
3311 {
3312 if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH)
3313 && (shdr->sh_flags & SHF_COMPRESSED) != 0)
3314 {
3315 if (elf_compress (scn, 0, 0) < 0)
3316 printf ("WARNING: %s [%zd]\n",
3317 gettext ("Couldn't uncompress section"),
3318 elf_ndxscn (scn));
3319 shdr = gelf_getshdr (scn, &shdr_mem);
3320 }
3321
3322 if (shdr->sh_type == SHT_HASH)
3323 {
3324 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
3325 handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
3326 else
3327 handle_sysv_hash (ebl, scn, shdr, shstrndx);
3328 }
3329 else if (shdr->sh_type == SHT_GNU_HASH)
3330 handle_gnu_hash (ebl, scn, shdr, shstrndx);
3331 }
3332 }
3333 }
3334
3335
3336 static void
print_liblist(Ebl * ebl)3337 print_liblist (Ebl *ebl)
3338 {
3339 /* Find the library list sections. For this we have to search
3340 through the section table. */
3341 Elf_Scn *scn = NULL;
3342
3343 /* Get the section header string table index. */
3344 size_t shstrndx;
3345 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3346 error (EXIT_FAILURE, 0,
3347 gettext ("cannot get section header string table index"));
3348
3349 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3350 {
3351 GElf_Shdr shdr_mem;
3352 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3353
3354 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
3355 {
3356 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
3357 int nentries = shdr->sh_size / sh_entsize;
3358 printf (ngettext ("\
3359 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
3360 "\
3361 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
3362 nentries),
3363 elf_ndxscn (scn),
3364 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3365 shdr->sh_offset,
3366 nentries);
3367
3368 Elf_Data *data = elf_getdata (scn, NULL);
3369 if (data == NULL)
3370 return;
3371
3372 puts (gettext ("\
3373 Library Time Stamp Checksum Version Flags"));
3374
3375 for (int cnt = 0; cnt < nentries; ++cnt)
3376 {
3377 GElf_Lib lib_mem;
3378 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
3379 if (unlikely (lib == NULL))
3380 continue;
3381
3382 time_t t = (time_t) lib->l_time_stamp;
3383 struct tm *tm = gmtime (&t);
3384 if (unlikely (tm == NULL))
3385 continue;
3386
3387 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
3388 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
3389 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
3390 tm->tm_hour, tm->tm_min, tm->tm_sec,
3391 (unsigned int) lib->l_checksum,
3392 (unsigned int) lib->l_version,
3393 (unsigned int) lib->l_flags);
3394 }
3395 }
3396 }
3397 }
3398
3399 static void
print_attributes(Ebl * ebl,const GElf_Ehdr * ehdr)3400 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
3401 {
3402 /* Find the object attributes sections. For this we have to search
3403 through the section table. */
3404 Elf_Scn *scn = NULL;
3405
3406 /* Get the section header string table index. */
3407 size_t shstrndx;
3408 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
3409 error (EXIT_FAILURE, 0,
3410 gettext ("cannot get section header string table index"));
3411
3412 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
3413 {
3414 GElf_Shdr shdr_mem;
3415 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3416
3417 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
3418 && (shdr->sh_type != SHT_ARM_ATTRIBUTES
3419 || ehdr->e_machine != EM_ARM)))
3420 continue;
3421
3422 printf (gettext ("\
3423 \nObject attributes section [%2zu] '%s' of %" PRIu64
3424 " bytes at offset %#0" PRIx64 ":\n"),
3425 elf_ndxscn (scn),
3426 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
3427 shdr->sh_size, shdr->sh_offset);
3428
3429 Elf_Data *data = elf_rawdata (scn, NULL);
3430 if (unlikely (data == NULL || data->d_size == 0))
3431 return;
3432
3433 const unsigned char *p = data->d_buf;
3434
3435 /* There is only one 'version', A. */
3436 if (unlikely (*p++ != 'A'))
3437 return;
3438
3439 fputs_unlocked (gettext (" Owner Size\n"), stdout);
3440
3441 inline size_t left (void)
3442 {
3443 return (const unsigned char *) data->d_buf + data->d_size - p;
3444 }
3445
3446 /* Loop over the sections. */
3447 while (left () >= 4)
3448 {
3449 /* Section length. */
3450 uint32_t len;
3451 memcpy (&len, p, sizeof len);
3452
3453 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3454 CONVERT (len);
3455
3456 if (unlikely (len > left ()))
3457 break;
3458
3459 /* Section vendor name. */
3460 const unsigned char *name = p + sizeof len;
3461 p += len;
3462
3463 unsigned const char *q = memchr (name, '\0', len);
3464 if (unlikely (q == NULL))
3465 break;
3466 ++q;
3467
3468 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len);
3469
3470 bool gnu_vendor = (q - name == sizeof "gnu"
3471 && !memcmp (name, "gnu", sizeof "gnu"));
3472
3473 /* Loop over subsections. */
3474 if (shdr->sh_type != SHT_GNU_ATTRIBUTES
3475 || gnu_vendor)
3476 while (q < p)
3477 {
3478 const unsigned char *const sub = q;
3479
3480 unsigned int subsection_tag;
3481 get_uleb128 (subsection_tag, q, p);
3482 if (unlikely (q >= p))
3483 break;
3484
3485 uint32_t subsection_len;
3486 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
3487 break;
3488
3489 memcpy (&subsection_len, q, sizeof subsection_len);
3490
3491 if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
3492 CONVERT (subsection_len);
3493
3494 /* Don't overflow, ptrdiff_t might be 32bits, but signed. */
3495 if (unlikely (subsection_len == 0
3496 || subsection_len >= (uint32_t) PTRDIFF_MAX
3497 || p - sub < (ptrdiff_t) subsection_len))
3498 break;
3499
3500 const unsigned char *r = q + sizeof subsection_len;
3501 q = sub + subsection_len;
3502
3503 switch (subsection_tag)
3504 {
3505 default:
3506 /* Unknown subsection, print and skip. */
3507 printf (gettext (" %-4u %12" PRIu32 "\n"),
3508 subsection_tag, subsection_len);
3509 break;
3510
3511 case 1: /* Tag_File */
3512 printf (gettext (" File: %11" PRIu32 "\n"),
3513 subsection_len);
3514
3515 while (r < q)
3516 {
3517 unsigned int tag;
3518 get_uleb128 (tag, r, q);
3519 if (unlikely (r >= q))
3520 break;
3521
3522 /* GNU style tags have either a uleb128 value,
3523 when lowest bit is not set, or a string
3524 when the lowest bit is set.
3525 "compatibility" (32) is special. It has
3526 both a string and a uleb128 value. For
3527 non-gnu we assume 6 till 31 only take ints.
3528 XXX see arm backend, do we need a separate
3529 hook? */
3530 uint64_t value = 0;
3531 const char *string = NULL;
3532 if (tag == 32 || (tag & 1) == 0
3533 || (! gnu_vendor && (tag > 5 && tag < 32)))
3534 {
3535 get_uleb128 (value, r, q);
3536 if (r > q)
3537 break;
3538 }
3539 if (tag == 32
3540 || ((tag & 1) != 0
3541 && (gnu_vendor
3542 || (! gnu_vendor && tag > 32)))
3543 || (! gnu_vendor && tag > 3 && tag < 6))
3544 {
3545 string = (const char *) r;
3546 r = memchr (r, '\0', q - r);
3547 if (r == NULL)
3548 break;
3549 ++r;
3550 }
3551
3552 const char *tag_name = NULL;
3553 const char *value_name = NULL;
3554 ebl_check_object_attribute (ebl, (const char *) name,
3555 tag, value,
3556 &tag_name, &value_name);
3557
3558 if (tag_name != NULL)
3559 {
3560 if (tag == 32)
3561 printf (gettext (" %s: %" PRId64 ", %s\n"),
3562 tag_name, value, string);
3563 else if (string == NULL && value_name == NULL)
3564 printf (gettext (" %s: %" PRId64 "\n"),
3565 tag_name, value);
3566 else
3567 printf (gettext (" %s: %s\n"),
3568 tag_name, string ?: value_name);
3569 }
3570 else
3571 {
3572 /* For "gnu" vendor 32 "compatibility" has
3573 already been handled above. */
3574 assert (tag != 32
3575 || strcmp ((const char *) name, "gnu"));
3576 if (string == NULL)
3577 printf (gettext (" %u: %" PRId64 "\n"),
3578 tag, value);
3579 else
3580 printf (gettext (" %u: %s\n"),
3581 tag, string);
3582 }
3583 }
3584 }
3585 }
3586 }
3587 }
3588 }
3589
3590
3591 static char *
format_dwarf_addr(Dwfl_Module * dwflmod,int address_size,Dwarf_Addr address,Dwarf_Addr raw)3592 format_dwarf_addr (Dwfl_Module *dwflmod,
3593 int address_size, Dwarf_Addr address, Dwarf_Addr raw)
3594 {
3595 /* See if there is a name we can give for this address. */
3596 GElf_Sym sym;
3597 GElf_Off off = 0;
3598 const char *name = (print_address_names && ! print_unresolved_addresses)
3599 ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
3600 : NULL;
3601
3602 const char *scn;
3603 if (print_unresolved_addresses)
3604 {
3605 address = raw;
3606 scn = NULL;
3607 }
3608 else
3609 {
3610 /* Relativize the address. */
3611 int n = dwfl_module_relocations (dwflmod);
3612 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
3613
3614 /* In an ET_REL file there is a section name to refer to. */
3615 scn = (i < 0 ? NULL
3616 : dwfl_module_relocation_info (dwflmod, i, NULL));
3617 }
3618
3619 char *result;
3620 if ((name != NULL
3621 ? (off != 0
3622 ? (scn != NULL
3623 ? (address_size == 0
3624 ? asprintf (&result,
3625 gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
3626 scn, address, name, off)
3627 : asprintf (&result,
3628 gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3629 scn, 2 + address_size * 2, address,
3630 name, off))
3631 : (address_size == 0
3632 ? asprintf (&result,
3633 gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
3634 address, name, off)
3635 : asprintf (&result,
3636 gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
3637 2 + address_size * 2, address,
3638 name, off)))
3639 : (scn != NULL
3640 ? (address_size == 0
3641 ? asprintf (&result,
3642 gettext ("%s+%#" PRIx64 " <%s>"),
3643 scn, address, name)
3644 : asprintf (&result,
3645 gettext ("%s+%#0*" PRIx64 " <%s>"),
3646 scn, 2 + address_size * 2, address, name))
3647 : (address_size == 0
3648 ? asprintf (&result,
3649 gettext ("%#" PRIx64 " <%s>"),
3650 address, name)
3651 : asprintf (&result,
3652 gettext ("%#0*" PRIx64 " <%s>"),
3653 2 + address_size * 2, address, name))))
3654 : (scn != NULL
3655 ? (address_size == 0
3656 ? asprintf (&result,
3657 gettext ("%s+%#" PRIx64),
3658 scn, address)
3659 : asprintf (&result,
3660 gettext ("%s+%#0*" PRIx64),
3661 scn, 2 + address_size * 2, address))
3662 : (address_size == 0
3663 ? asprintf (&result,
3664 "%#" PRIx64,
3665 address)
3666 : asprintf (&result,
3667 "%#0*" PRIx64,
3668 2 + address_size * 2, address)))) < 0)
3669 error (EXIT_FAILURE, 0, _("memory exhausted"));
3670
3671 return result;
3672 }
3673
3674 static const char *
dwarf_tag_string(unsigned int tag)3675 dwarf_tag_string (unsigned int tag)
3676 {
3677 switch (tag)
3678 {
3679 #define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
3680 DWARF_ALL_KNOWN_DW_TAG
3681 #undef DWARF_ONE_KNOWN_DW_TAG
3682 default:
3683 return NULL;
3684 }
3685 }
3686
3687
3688 static const char *
dwarf_attr_string(unsigned int attrnum)3689 dwarf_attr_string (unsigned int attrnum)
3690 {
3691 switch (attrnum)
3692 {
3693 #define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
3694 DWARF_ALL_KNOWN_DW_AT
3695 #undef DWARF_ONE_KNOWN_DW_AT
3696 default:
3697 return NULL;
3698 }
3699 }
3700
3701
3702 static const char *
dwarf_form_string(unsigned int form)3703 dwarf_form_string (unsigned int form)
3704 {
3705 switch (form)
3706 {
3707 #define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
3708 DWARF_ALL_KNOWN_DW_FORM
3709 #undef DWARF_ONE_KNOWN_DW_FORM
3710 default:
3711 return NULL;
3712 }
3713 }
3714
3715
3716 static const char *
dwarf_lang_string(unsigned int lang)3717 dwarf_lang_string (unsigned int lang)
3718 {
3719 switch (lang)
3720 {
3721 #define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
3722 DWARF_ALL_KNOWN_DW_LANG
3723 #undef DWARF_ONE_KNOWN_DW_LANG
3724 default:
3725 return NULL;
3726 }
3727 }
3728
3729
3730 static const char *
dwarf_inline_string(unsigned int code)3731 dwarf_inline_string (unsigned int code)
3732 {
3733 static const char *const known[] =
3734 {
3735 #define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
3736 DWARF_ALL_KNOWN_DW_INL
3737 #undef DWARF_ONE_KNOWN_DW_INL
3738 };
3739
3740 if (likely (code < sizeof (known) / sizeof (known[0])))
3741 return known[code];
3742
3743 return NULL;
3744 }
3745
3746
3747 static const char *
dwarf_encoding_string(unsigned int code)3748 dwarf_encoding_string (unsigned int code)
3749 {
3750 static const char *const known[] =
3751 {
3752 #define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
3753 DWARF_ALL_KNOWN_DW_ATE
3754 #undef DWARF_ONE_KNOWN_DW_ATE
3755 };
3756
3757 if (likely (code < sizeof (known) / sizeof (known[0])))
3758 return known[code];
3759
3760 return NULL;
3761 }
3762
3763
3764 static const char *
dwarf_access_string(unsigned int code)3765 dwarf_access_string (unsigned int code)
3766 {
3767 static const char *const known[] =
3768 {
3769 #define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
3770 DWARF_ALL_KNOWN_DW_ACCESS
3771 #undef DWARF_ONE_KNOWN_DW_ACCESS
3772 };
3773
3774 if (likely (code < sizeof (known) / sizeof (known[0])))
3775 return known[code];
3776
3777 return NULL;
3778 }
3779
3780
3781 static const char *
dwarf_visibility_string(unsigned int code)3782 dwarf_visibility_string (unsigned int code)
3783 {
3784 static const char *const known[] =
3785 {
3786 #define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
3787 DWARF_ALL_KNOWN_DW_VIS
3788 #undef DWARF_ONE_KNOWN_DW_VIS
3789 };
3790
3791 if (likely (code < sizeof (known) / sizeof (known[0])))
3792 return known[code];
3793
3794 return NULL;
3795 }
3796
3797
3798 static const char *
dwarf_virtuality_string(unsigned int code)3799 dwarf_virtuality_string (unsigned int code)
3800 {
3801 static const char *const known[] =
3802 {
3803 #define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
3804 DWARF_ALL_KNOWN_DW_VIRTUALITY
3805 #undef DWARF_ONE_KNOWN_DW_VIRTUALITY
3806 };
3807
3808 if (likely (code < sizeof (known) / sizeof (known[0])))
3809 return known[code];
3810
3811 return NULL;
3812 }
3813
3814
3815 static const char *
dwarf_identifier_case_string(unsigned int code)3816 dwarf_identifier_case_string (unsigned int code)
3817 {
3818 static const char *const known[] =
3819 {
3820 #define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
3821 DWARF_ALL_KNOWN_DW_ID
3822 #undef DWARF_ONE_KNOWN_DW_ID
3823 };
3824
3825 if (likely (code < sizeof (known) / sizeof (known[0])))
3826 return known[code];
3827
3828 return NULL;
3829 }
3830
3831
3832 static const char *
dwarf_calling_convention_string(unsigned int code)3833 dwarf_calling_convention_string (unsigned int code)
3834 {
3835 static const char *const known[] =
3836 {
3837 #define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
3838 DWARF_ALL_KNOWN_DW_CC
3839 #undef DWARF_ONE_KNOWN_DW_CC
3840 };
3841
3842 if (likely (code < sizeof (known) / sizeof (known[0])))
3843 return known[code];
3844
3845 return NULL;
3846 }
3847
3848
3849 static const char *
dwarf_ordering_string(unsigned int code)3850 dwarf_ordering_string (unsigned int code)
3851 {
3852 static const char *const known[] =
3853 {
3854 #define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
3855 DWARF_ALL_KNOWN_DW_ORD
3856 #undef DWARF_ONE_KNOWN_DW_ORD
3857 };
3858
3859 if (likely (code < sizeof (known) / sizeof (known[0])))
3860 return known[code];
3861
3862 return NULL;
3863 }
3864
3865
3866 static const char *
dwarf_discr_list_string(unsigned int code)3867 dwarf_discr_list_string (unsigned int code)
3868 {
3869 static const char *const known[] =
3870 {
3871 #define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
3872 DWARF_ALL_KNOWN_DW_DSC
3873 #undef DWARF_ONE_KNOWN_DW_DSC
3874 };
3875
3876 if (likely (code < sizeof (known) / sizeof (known[0])))
3877 return known[code];
3878
3879 return NULL;
3880 }
3881
3882
3883 static const char *
dwarf_locexpr_opcode_string(unsigned int code)3884 dwarf_locexpr_opcode_string (unsigned int code)
3885 {
3886 static const char *const known[] =
3887 {
3888 /* Normally we can't affort building huge table of 64K entries,
3889 most of them zero, just because there are a couple defined
3890 values at the far end. In case of opcodes, it's OK. */
3891 #define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
3892 DWARF_ALL_KNOWN_DW_OP
3893 #undef DWARF_ONE_KNOWN_DW_OP
3894 };
3895
3896 if (likely (code < sizeof (known) / sizeof (known[0])))
3897 return known[code];
3898
3899 return NULL;
3900 }
3901
3902
3903 /* Used by all dwarf_foo_name functions. */
3904 static const char *
string_or_unknown(const char * known,unsigned int code,unsigned int lo_user,unsigned int hi_user,bool print_unknown_num)3905 string_or_unknown (const char *known, unsigned int code,
3906 unsigned int lo_user, unsigned int hi_user,
3907 bool print_unknown_num)
3908 {
3909 static char unknown_buf[20];
3910
3911 if (likely (known != NULL))
3912 return known;
3913
3914 if (lo_user != 0 && code >= lo_user && code <= hi_user)
3915 {
3916 snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
3917 code - lo_user);
3918 return unknown_buf;
3919 }
3920
3921 if (print_unknown_num)
3922 {
3923 snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
3924 return unknown_buf;
3925 }
3926
3927 return "???";
3928 }
3929
3930
3931 static const char *
dwarf_tag_name(unsigned int tag)3932 dwarf_tag_name (unsigned int tag)
3933 {
3934 const char *ret = dwarf_tag_string (tag);
3935 return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
3936 }
3937
3938 static const char *
dwarf_attr_name(unsigned int attr)3939 dwarf_attr_name (unsigned int attr)
3940 {
3941 const char *ret = dwarf_attr_string (attr);
3942 return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
3943 }
3944
3945
3946 static const char *
dwarf_form_name(unsigned int form)3947 dwarf_form_name (unsigned int form)
3948 {
3949 const char *ret = dwarf_form_string (form);
3950 return string_or_unknown (ret, form, 0, 0, true);
3951 }
3952
3953
3954 static const char *
dwarf_lang_name(unsigned int lang)3955 dwarf_lang_name (unsigned int lang)
3956 {
3957 const char *ret = dwarf_lang_string (lang);
3958 return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
3959 }
3960
3961
3962 static const char *
dwarf_inline_name(unsigned int code)3963 dwarf_inline_name (unsigned int code)
3964 {
3965 const char *ret = dwarf_inline_string (code);
3966 return string_or_unknown (ret, code, 0, 0, false);
3967 }
3968
3969
3970 static const char *
dwarf_encoding_name(unsigned int code)3971 dwarf_encoding_name (unsigned int code)
3972 {
3973 const char *ret = dwarf_encoding_string (code);
3974 return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
3975 }
3976
3977
3978 static const char *
dwarf_access_name(unsigned int code)3979 dwarf_access_name (unsigned int code)
3980 {
3981 const char *ret = dwarf_access_string (code);
3982 return string_or_unknown (ret, code, 0, 0, false);
3983 }
3984
3985
3986 static const char *
dwarf_visibility_name(unsigned int code)3987 dwarf_visibility_name (unsigned int code)
3988 {
3989 const char *ret = dwarf_visibility_string (code);
3990 return string_or_unknown (ret, code, 0, 0, false);
3991 }
3992
3993
3994 static const char *
dwarf_virtuality_name(unsigned int code)3995 dwarf_virtuality_name (unsigned int code)
3996 {
3997 const char *ret = dwarf_virtuality_string (code);
3998 return string_or_unknown (ret, code, 0, 0, false);
3999 }
4000
4001
4002 static const char *
dwarf_identifier_case_name(unsigned int code)4003 dwarf_identifier_case_name (unsigned int code)
4004 {
4005 const char *ret = dwarf_identifier_case_string (code);
4006 return string_or_unknown (ret, code, 0, 0, false);
4007 }
4008
4009
4010 static const char *
dwarf_calling_convention_name(unsigned int code)4011 dwarf_calling_convention_name (unsigned int code)
4012 {
4013 const char *ret = dwarf_calling_convention_string (code);
4014 return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
4015 }
4016
4017
4018 static const char *
dwarf_ordering_name(unsigned int code)4019 dwarf_ordering_name (unsigned int code)
4020 {
4021 const char *ret = dwarf_ordering_string (code);
4022 return string_or_unknown (ret, code, 0, 0, false);
4023 }
4024
4025
4026 static const char *
dwarf_discr_list_name(unsigned int code)4027 dwarf_discr_list_name (unsigned int code)
4028 {
4029 const char *ret = dwarf_discr_list_string (code);
4030 return string_or_unknown (ret, code, 0, 0, false);
4031 }
4032
4033
4034 static void
print_block(size_t n,const void * block)4035 print_block (size_t n, const void *block)
4036 {
4037 if (n == 0)
4038 puts (_("empty block"));
4039 else
4040 {
4041 printf (_("%zu byte block:"), n);
4042 const unsigned char *data = block;
4043 do
4044 printf (" %02x", *data++);
4045 while (--n > 0);
4046 putchar ('\n');
4047 }
4048 }
4049
4050 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)4051 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
4052 unsigned int vers, unsigned int addrsize, unsigned int offset_size,
4053 struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
4054 {
4055 const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
4056
4057 if (len == 0)
4058 {
4059 printf ("%*s(empty)\n", indent, "");
4060 return;
4061 }
4062
4063 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid
4064 #define CONSUME(n) NEED (n); else len -= (n)
4065
4066 Dwarf_Word offset = 0;
4067 while (len-- > 0)
4068 {
4069 uint_fast8_t op = *data++;
4070
4071 const char *op_name = dwarf_locexpr_opcode_string (op);
4072 if (unlikely (op_name == NULL))
4073 {
4074 static char buf[20];
4075 if (op >= DW_OP_lo_user)
4076 snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
4077 else
4078 snprintf (buf, sizeof buf, "??? (%#x)", op);
4079 op_name = buf;
4080 }
4081
4082 switch (op)
4083 {
4084 case DW_OP_addr:;
4085 /* Address operand. */
4086 Dwarf_Word addr;
4087 NEED (addrsize);
4088 if (addrsize == 4)
4089 addr = read_4ubyte_unaligned (dbg, data);
4090 else if (addrsize == 8)
4091 addr = read_8ubyte_unaligned (dbg, data);
4092 else
4093 goto invalid;
4094 data += addrsize;
4095 CONSUME (addrsize);
4096
4097 char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
4098 printf ("%*s[%4" PRIuMAX "] %s %s\n",
4099 indent, "", (uintmax_t) offset, op_name, a);
4100 free (a);
4101
4102 offset += 1 + addrsize;
4103 break;
4104
4105 case DW_OP_call_ref:
4106 /* Offset operand. */
4107 if (ref_size != 4 && ref_size != 8)
4108 goto invalid; /* Cannot be used in CFA. */
4109 NEED (ref_size);
4110 if (ref_size == 4)
4111 addr = read_4ubyte_unaligned (dbg, data);
4112 else
4113 addr = read_8ubyte_unaligned (dbg, data);
4114 data += ref_size;
4115 CONSUME (ref_size);
4116
4117 printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n",
4118 indent, "", (uintmax_t) offset,
4119 op_name, (uintmax_t) addr);
4120 offset += 1 + ref_size;
4121 break;
4122
4123 case DW_OP_deref_size:
4124 case DW_OP_xderef_size:
4125 case DW_OP_pick:
4126 case DW_OP_const1u:
4127 // XXX value might be modified by relocation
4128 NEED (1);
4129 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n",
4130 indent, "", (uintmax_t) offset,
4131 op_name, *((uint8_t *) data));
4132 ++data;
4133 --len;
4134 offset += 2;
4135 break;
4136
4137 case DW_OP_const2u:
4138 NEED (2);
4139 // XXX value might be modified by relocation
4140 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4141 indent, "", (uintmax_t) offset,
4142 op_name, read_2ubyte_unaligned (dbg, data));
4143 CONSUME (2);
4144 data += 2;
4145 offset += 3;
4146 break;
4147
4148 case DW_OP_const4u:
4149 NEED (4);
4150 // XXX value might be modified by relocation
4151 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4152 indent, "", (uintmax_t) offset,
4153 op_name, read_4ubyte_unaligned (dbg, data));
4154 CONSUME (4);
4155 data += 4;
4156 offset += 5;
4157 break;
4158
4159 case DW_OP_const8u:
4160 NEED (8);
4161 // XXX value might be modified by relocation
4162 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4163 indent, "", (uintmax_t) offset,
4164 op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
4165 CONSUME (8);
4166 data += 8;
4167 offset += 9;
4168 break;
4169
4170 case DW_OP_const1s:
4171 NEED (1);
4172 // XXX value might be modified by relocation
4173 printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n",
4174 indent, "", (uintmax_t) offset,
4175 op_name, *((int8_t *) data));
4176 ++data;
4177 --len;
4178 offset += 2;
4179 break;
4180
4181 case DW_OP_const2s:
4182 NEED (2);
4183 // XXX value might be modified by relocation
4184 printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n",
4185 indent, "", (uintmax_t) offset,
4186 op_name, read_2sbyte_unaligned (dbg, data));
4187 CONSUME (2);
4188 data += 2;
4189 offset += 3;
4190 break;
4191
4192 case DW_OP_const4s:
4193 NEED (4);
4194 // XXX value might be modified by relocation
4195 printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n",
4196 indent, "", (uintmax_t) offset,
4197 op_name, read_4sbyte_unaligned (dbg, data));
4198 CONSUME (4);
4199 data += 4;
4200 offset += 5;
4201 break;
4202
4203 case DW_OP_const8s:
4204 NEED (8);
4205 // XXX value might be modified by relocation
4206 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4207 indent, "", (uintmax_t) offset,
4208 op_name, read_8sbyte_unaligned (dbg, data));
4209 CONSUME (8);
4210 data += 8;
4211 offset += 9;
4212 break;
4213
4214 case DW_OP_piece:
4215 case DW_OP_regx:
4216 case DW_OP_plus_uconst:
4217 case DW_OP_constu:;
4218 const unsigned char *start = data;
4219 uint64_t uleb;
4220 NEED (1);
4221 get_uleb128 (uleb, data, data + len);
4222 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n",
4223 indent, "", (uintmax_t) offset, op_name, uleb);
4224 CONSUME (data - start);
4225 offset += 1 + (data - start);
4226 break;
4227
4228 case DW_OP_bit_piece:
4229 start = data;
4230 uint64_t uleb2;
4231 NEED (1);
4232 get_uleb128 (uleb, data, data + len);
4233 NEED (1);
4234 get_uleb128 (uleb2, data, data + len);
4235 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
4236 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4237 CONSUME (data - start);
4238 offset += 1 + (data - start);
4239 break;
4240
4241 case DW_OP_fbreg:
4242 case DW_OP_breg0 ... DW_OP_breg31:
4243 case DW_OP_consts:
4244 start = data;
4245 int64_t sleb;
4246 NEED (1);
4247 get_sleb128 (sleb, data, data + len);
4248 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n",
4249 indent, "", (uintmax_t) offset, op_name, sleb);
4250 CONSUME (data - start);
4251 offset += 1 + (data - start);
4252 break;
4253
4254 case DW_OP_bregx:
4255 start = data;
4256 NEED (1);
4257 get_uleb128 (uleb, data, data + len);
4258 NEED (1);
4259 get_sleb128 (sleb, data, data + len);
4260 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
4261 indent, "", (uintmax_t) offset, op_name, uleb, sleb);
4262 CONSUME (data - start);
4263 offset += 1 + (data - start);
4264 break;
4265
4266 case DW_OP_call2:
4267 NEED (2);
4268 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
4269 indent, "", (uintmax_t) offset, op_name,
4270 read_2ubyte_unaligned (dbg, data));
4271 CONSUME (2);
4272 offset += 3;
4273 break;
4274
4275 case DW_OP_call4:
4276 NEED (4);
4277 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n",
4278 indent, "", (uintmax_t) offset, op_name,
4279 read_4ubyte_unaligned (dbg, data));
4280 CONSUME (4);
4281 offset += 5;
4282 break;
4283
4284 case DW_OP_skip:
4285 case DW_OP_bra:
4286 NEED (2);
4287 printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n",
4288 indent, "", (uintmax_t) offset, op_name,
4289 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
4290 CONSUME (2);
4291 data += 2;
4292 offset += 3;
4293 break;
4294
4295 case DW_OP_implicit_value:
4296 start = data;
4297 NEED (1);
4298 get_uleb128 (uleb, data, data + len);
4299 printf ("%*s[%4" PRIuMAX "] %s: ",
4300 indent, "", (uintmax_t) offset, op_name);
4301 NEED (uleb);
4302 print_block (uleb, data);
4303 data += uleb;
4304 CONSUME (data - start);
4305 offset += 1 + (data - start);
4306 break;
4307
4308 case DW_OP_GNU_implicit_pointer:
4309 /* DIE offset operand. */
4310 start = data;
4311 NEED (ref_size);
4312 if (ref_size != 4 && ref_size != 8)
4313 goto invalid; /* Cannot be used in CFA. */
4314 if (ref_size == 4)
4315 addr = read_4ubyte_unaligned (dbg, data);
4316 else
4317 addr = read_8ubyte_unaligned (dbg, data);
4318 data += ref_size;
4319 /* Byte offset operand. */
4320 NEED (1);
4321 get_sleb128 (sleb, data, data + len);
4322
4323 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
4324 indent, "", (intmax_t) offset,
4325 op_name, (uintmax_t) addr, sleb);
4326 CONSUME (data - start);
4327 offset += 1 + (data - start);
4328 break;
4329
4330 case DW_OP_GNU_entry_value:
4331 /* Size plus expression block. */
4332 start = data;
4333 NEED (1);
4334 get_uleb128 (uleb, data, data + len);
4335 printf ("%*s[%4" PRIuMAX "] %s:\n",
4336 indent, "", (uintmax_t) offset, op_name);
4337 NEED (uleb);
4338 print_ops (dwflmod, dbg, indent + 6, indent + 6, vers,
4339 addrsize, offset_size, cu, uleb, data);
4340 data += uleb;
4341 CONSUME (data - start);
4342 offset += 1 + (data - start);
4343 break;
4344
4345 case DW_OP_GNU_const_type:
4346 /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
4347 unsigned size plus block. */
4348 start = data;
4349 NEED (1);
4350 get_uleb128 (uleb, data, data + len);
4351 if (! print_unresolved_addresses && cu != NULL)
4352 uleb += cu->start;
4353 NEED (1);
4354 uint8_t usize = *(uint8_t *) data++;
4355 NEED (usize);
4356 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ",
4357 indent, "", (uintmax_t) offset, op_name, uleb);
4358 print_block (usize, data);
4359 data += usize;
4360 CONSUME (data - start);
4361 offset += 1 + (data - start);
4362 break;
4363
4364 case DW_OP_GNU_regval_type:
4365 /* uleb128 register number, uleb128 CU relative
4366 DW_TAG_base_type DIE offset. */
4367 start = data;
4368 NEED (1);
4369 get_uleb128 (uleb, data, data + len);
4370 NEED (1);
4371 get_uleb128 (uleb2, data, data + len);
4372 if (! print_unresolved_addresses && cu != NULL)
4373 uleb2 += cu->start;
4374 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
4375 indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
4376 CONSUME (data - start);
4377 offset += 1 + (data - start);
4378 break;
4379
4380 case DW_OP_GNU_deref_type:
4381 /* 1-byte unsigned size of value, uleb128 CU relative
4382 DW_TAG_base_type DIE offset. */
4383 start = data;
4384 NEED (1);
4385 usize = *(uint8_t *) data++;
4386 NEED (1);
4387 get_uleb128 (uleb, data, data + len);
4388 if (! print_unresolved_addresses && cu != NULL)
4389 uleb += cu->start;
4390 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
4391 indent, "", (uintmax_t) offset,
4392 op_name, usize, uleb);
4393 CONSUME (data - start);
4394 offset += 1 + (data - start);
4395 break;
4396
4397 case DW_OP_GNU_convert:
4398 case DW_OP_GNU_reinterpret:
4399 /* uleb128 CU relative offset to DW_TAG_base_type, or zero
4400 for conversion to untyped. */
4401 start = data;
4402 NEED (1);
4403 get_uleb128 (uleb, data, data + len);
4404 if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
4405 uleb += cu->start;
4406 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4407 indent, "", (uintmax_t) offset, op_name, uleb);
4408 CONSUME (data - start);
4409 offset += 1 + (data - start);
4410 break;
4411
4412 case DW_OP_GNU_parameter_ref:
4413 /* 4 byte CU relative reference to the abstract optimized away
4414 DW_TAG_formal_parameter. */
4415 NEED (4);
4416 uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
4417 if (! print_unresolved_addresses && cu != NULL)
4418 param_off += cu->start;
4419 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n",
4420 indent, "", (uintmax_t) offset, op_name, param_off);
4421 CONSUME (4);
4422 data += 4;
4423 offset += 5;
4424 break;
4425
4426 default:
4427 /* No Operand. */
4428 printf ("%*s[%4" PRIuMAX "] %s\n",
4429 indent, "", (uintmax_t) offset, op_name);
4430 ++offset;
4431 break;
4432 }
4433
4434 indent = indentrest;
4435 continue;
4436
4437 invalid:
4438 printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"),
4439 indent, "", (uintmax_t) offset, op_name);
4440 break;
4441 }
4442 }
4443
4444
4445 struct listptr
4446 {
4447 Dwarf_Off offset:(64 - 3);
4448 bool addr64:1;
4449 bool dwarf64:1;
4450 bool warned:1;
4451 struct Dwarf_CU *cu;
4452 };
4453
4454 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4)
4455 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4)
4456
4457 static Dwarf_Addr
listptr_base(struct listptr * p)4458 listptr_base (struct listptr *p)
4459 {
4460 Dwarf_Addr base;
4461 Dwarf_Die cu = CUDIE (p->cu);
4462 /* Find the base address of the compilation unit. It will normally
4463 be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base
4464 address could be overridden by DW_AT_entry_pc. It's been
4465 removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
4466 compilation units with discontinuous ranges. */
4467 if (unlikely (dwarf_lowpc (&cu, &base) != 0))
4468 {
4469 Dwarf_Attribute attr_mem;
4470 if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
4471 &base) != 0)
4472 base = 0;
4473 }
4474 return base;
4475 }
4476
4477 static int
compare_listptr(const void * a,const void * b,void * arg)4478 compare_listptr (const void *a, const void *b, void *arg)
4479 {
4480 const char *name = arg;
4481 struct listptr *p1 = (void *) a;
4482 struct listptr *p2 = (void *) b;
4483
4484 if (p1->offset < p2->offset)
4485 return -1;
4486 if (p1->offset > p2->offset)
4487 return 1;
4488
4489 if (!p1->warned && !p2->warned)
4490 {
4491 if (p1->addr64 != p2->addr64)
4492 {
4493 p1->warned = p2->warned = true;
4494 error (0, 0,
4495 gettext ("%s %#" PRIx64 " used with different address sizes"),
4496 name, (uint64_t) p1->offset);
4497 }
4498 if (p1->dwarf64 != p2->dwarf64)
4499 {
4500 p1->warned = p2->warned = true;
4501 error (0, 0,
4502 gettext ("%s %#" PRIx64 " used with different offset sizes"),
4503 name, (uint64_t) p1->offset);
4504 }
4505 if (listptr_base (p1) != listptr_base (p2))
4506 {
4507 p1->warned = p2->warned = true;
4508 error (0, 0,
4509 gettext ("%s %#" PRIx64 " used with different base addresses"),
4510 name, (uint64_t) p1->offset);
4511 }
4512 }
4513
4514 return 0;
4515 }
4516
4517 struct listptr_table
4518 {
4519 size_t n;
4520 size_t alloc;
4521 struct listptr *table;
4522 };
4523
4524 static struct listptr_table known_loclistptr;
4525 static struct listptr_table known_rangelistptr;
4526
4527 static void
reset_listptr(struct listptr_table * table)4528 reset_listptr (struct listptr_table *table)
4529 {
4530 free (table->table);
4531 table->table = NULL;
4532 table->n = table->alloc = 0;
4533 }
4534
4535 /* Returns false if offset doesn't fit. See struct listptr. */
4536 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)4537 notice_listptr (enum section_e section, struct listptr_table *table,
4538 uint_fast8_t address_size, uint_fast8_t offset_size,
4539 struct Dwarf_CU *cu, Dwarf_Off offset)
4540 {
4541 if (print_debug_sections & section)
4542 {
4543 if (table->n == table->alloc)
4544 {
4545 if (table->alloc == 0)
4546 table->alloc = 128;
4547 else
4548 table->alloc *= 2;
4549 table->table = xrealloc (table->table,
4550 table->alloc * sizeof table->table[0]);
4551 }
4552
4553 struct listptr *p = &table->table[table->n++];
4554
4555 *p = (struct listptr)
4556 {
4557 .addr64 = address_size == 8,
4558 .dwarf64 = offset_size == 8,
4559 .offset = offset,
4560 .cu = cu
4561 };
4562
4563 if (p->offset != offset)
4564 {
4565 table->n--;
4566 return false;
4567 }
4568 }
4569 return true;
4570 }
4571
4572 static void
sort_listptr(struct listptr_table * table,const char * name)4573 sort_listptr (struct listptr_table *table, const char *name)
4574 {
4575 if (table->n > 0)
4576 qsort_r (table->table, table->n, sizeof table->table[0],
4577 &compare_listptr, (void *) name);
4578 }
4579
4580 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)4581 skip_listptr_hole (struct listptr_table *table, size_t *idxp,
4582 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
4583 Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
4584 unsigned char **readp, unsigned char *endp)
4585 {
4586 if (table->n == 0)
4587 return false;
4588
4589 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
4590 ++*idxp;
4591
4592 struct listptr *p = &table->table[*idxp];
4593
4594 if (*idxp == table->n
4595 || p->offset >= (Dwarf_Off) (endp - *readp + offset))
4596 {
4597 *readp = endp;
4598 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"),
4599 offset);
4600 return true;
4601 }
4602
4603 if (p->offset != (Dwarf_Off) offset)
4604 {
4605 *readp += p->offset - offset;
4606 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
4607 offset, (Dwarf_Off) p->offset - offset);
4608 return true;
4609 }
4610
4611 if (address_sizep != NULL)
4612 *address_sizep = listptr_address_size (p);
4613 if (offset_sizep != NULL)
4614 *offset_sizep = listptr_offset_size (p);
4615 if (base != NULL)
4616 *base = listptr_base (p);
4617 if (cu != NULL)
4618 *cu = p->cu;
4619
4620 return false;
4621 }
4622
4623
4624 static void
print_debug_abbrev_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)4625 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4626 Ebl *ebl, GElf_Ehdr *ehdr,
4627 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
4628 {
4629 const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
4630 dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
4631
4632 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
4633 " [ Code]\n"),
4634 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4635 (uint64_t) shdr->sh_offset);
4636
4637 Dwarf_Off offset = 0;
4638 while (offset < sh_size)
4639 {
4640 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
4641 offset);
4642
4643 while (1)
4644 {
4645 size_t length;
4646 Dwarf_Abbrev abbrev;
4647
4648 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
4649 if (res != 0)
4650 {
4651 if (unlikely (res < 0))
4652 {
4653 printf (gettext ("\
4654 *** error while reading abbreviation: %s\n"),
4655 dwarf_errmsg (-1));
4656 return;
4657 }
4658
4659 /* This is the NUL byte at the end of the section. */
4660 ++offset;
4661 break;
4662 }
4663
4664 /* We know these calls can never fail. */
4665 unsigned int code = dwarf_getabbrevcode (&abbrev);
4666 unsigned int tag = dwarf_getabbrevtag (&abbrev);
4667 int has_children = dwarf_abbrevhaschildren (&abbrev);
4668
4669 printf (gettext (" [%5u] offset: %" PRId64
4670 ", children: %s, tag: %s\n"),
4671 code, (int64_t) offset,
4672 has_children ? gettext ("yes") : gettext ("no"),
4673 dwarf_tag_name (tag));
4674
4675 size_t cnt = 0;
4676 unsigned int name;
4677 unsigned int form;
4678 Dwarf_Off enoffset;
4679 while (dwarf_getabbrevattr (&abbrev, cnt,
4680 &name, &form, &enoffset) == 0)
4681 {
4682 printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n",
4683 dwarf_attr_name (name), dwarf_form_name (form),
4684 (uint64_t) enoffset);
4685
4686 ++cnt;
4687 }
4688
4689 offset += length;
4690 }
4691 }
4692 }
4693
4694
4695 /* Print content of DWARF .debug_aranges section. We fortunately do
4696 not have to know a bit about the structure of the section, libdwarf
4697 takes care of it. */
4698 static void
print_decoded_aranges_section(Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)4699 print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4700 GElf_Shdr *shdr, Dwarf *dbg)
4701 {
4702 Dwarf_Aranges *aranges;
4703 size_t cnt;
4704 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
4705 {
4706 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4707 dwarf_errmsg (-1));
4708 return;
4709 }
4710
4711 GElf_Shdr glink_mem;
4712 GElf_Shdr *glink;
4713 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
4714 if (glink == NULL)
4715 {
4716 error (0, 0, gettext ("invalid sh_link value in section %zu"),
4717 elf_ndxscn (scn));
4718 return;
4719 }
4720
4721 printf (ngettext ("\
4722 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
4723 "\
4724 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
4725 cnt),
4726 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4727 (uint64_t) shdr->sh_offset, cnt);
4728
4729 /* Compute floor(log16(cnt)). */
4730 size_t tmp = cnt;
4731 int digits = 1;
4732 while (tmp >= 16)
4733 {
4734 ++digits;
4735 tmp >>= 4;
4736 }
4737
4738 for (size_t n = 0; n < cnt; ++n)
4739 {
4740 Dwarf_Arange *runp = dwarf_onearange (aranges, n);
4741 if (unlikely (runp == NULL))
4742 {
4743 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
4744 return;
4745 }
4746
4747 Dwarf_Addr start;
4748 Dwarf_Word length;
4749 Dwarf_Off offset;
4750
4751 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
4752 printf (gettext (" [%*zu] ???\n"), digits, n);
4753 else
4754 printf (gettext (" [%*zu] start: %0#*" PRIx64
4755 ", length: %5" PRIu64 ", CU DIE offset: %6"
4756 PRId64 "\n"),
4757 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
4758 (uint64_t) start, (uint64_t) length, (int64_t) offset);
4759 }
4760 }
4761
4762
4763 /* Print content of DWARF .debug_aranges section. */
4764 static void
print_debug_aranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)4765 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
4766 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
4767 GElf_Shdr *shdr, Dwarf *dbg)
4768 {
4769 if (decodedaranges)
4770 {
4771 print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
4772 return;
4773 }
4774
4775 Elf_Data *data = dbg->sectiondata[IDX_debug_aranges];
4776
4777 if (unlikely (data == NULL))
4778 {
4779 error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
4780 elf_errmsg (-1));
4781 return;
4782 }
4783
4784 printf (gettext ("\
4785 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4786 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4787 (uint64_t) shdr->sh_offset);
4788
4789 const unsigned char *readp = data->d_buf;
4790 const unsigned char *readendp = readp + data->d_size;
4791
4792 while (readp < readendp)
4793 {
4794 const unsigned char *hdrstart = readp;
4795 size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
4796
4797 printf (gettext ("\nTable at offset %zu:\n"), start_offset);
4798 if (readp + 4 > readendp)
4799 {
4800 invalid_data:
4801 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
4802 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
4803 return;
4804 }
4805
4806 Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
4807 unsigned int length_bytes = 4;
4808 if (length == DWARF3_LENGTH_64_BIT)
4809 {
4810 if (readp + 8 > readendp)
4811 goto invalid_data;
4812 length = read_8ubyte_unaligned_inc (dbg, readp);
4813 length_bytes = 8;
4814 }
4815
4816 const unsigned char *nexthdr = readp + length;
4817 printf (gettext ("\n Length: %6" PRIu64 "\n"),
4818 (uint64_t) length);
4819
4820 if (unlikely (length > (size_t) (readendp - readp)))
4821 goto invalid_data;
4822
4823 if (length == 0)
4824 continue;
4825
4826 if (readp + 2 > readendp)
4827 goto invalid_data;
4828 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
4829 printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
4830 version);
4831 if (version != 2)
4832 {
4833 error (0, 0, gettext ("unsupported aranges version"));
4834 goto next_table;
4835 }
4836
4837 Dwarf_Word offset;
4838 if (readp + length_bytes > readendp)
4839 goto invalid_data;
4840 if (length_bytes == 8)
4841 offset = read_8ubyte_unaligned_inc (dbg, readp);
4842 else
4843 offset = read_4ubyte_unaligned_inc (dbg, readp);
4844 printf (gettext (" CU offset: %6" PRIx64 "\n"),
4845 (uint64_t) offset);
4846
4847 if (readp + 1 > readendp)
4848 goto invalid_data;
4849 unsigned int address_size = *readp++;
4850 printf (gettext (" Address size: %6" PRIu64 "\n"),
4851 (uint64_t) address_size);
4852 if (address_size != 4 && address_size != 8)
4853 {
4854 error (0, 0, gettext ("unsupported address size"));
4855 goto next_table;
4856 }
4857
4858 unsigned int segment_size = *readp++;
4859 printf (gettext (" Segment size: %6" PRIu64 "\n\n"),
4860 (uint64_t) segment_size);
4861 if (segment_size != 0 && segment_size != 4 && segment_size != 8)
4862 {
4863 error (0, 0, gettext ("unsupported segment size"));
4864 goto next_table;
4865 }
4866
4867 /* Round the address to the next multiple of 2*address_size. */
4868 readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
4869 % (2 * address_size));
4870
4871 while (readp < nexthdr)
4872 {
4873 Dwarf_Word range_address;
4874 Dwarf_Word range_length;
4875 Dwarf_Word segment = 0;
4876 if (readp + 2 * address_size + segment_size > readendp)
4877 goto invalid_data;
4878 if (address_size == 4)
4879 {
4880 range_address = read_4ubyte_unaligned_inc (dbg, readp);
4881 range_length = read_4ubyte_unaligned_inc (dbg, readp);
4882 }
4883 else
4884 {
4885 range_address = read_8ubyte_unaligned_inc (dbg, readp);
4886 range_length = read_8ubyte_unaligned_inc (dbg, readp);
4887 }
4888
4889 if (segment_size == 4)
4890 segment = read_4ubyte_unaligned_inc (dbg, readp);
4891 else if (segment_size == 8)
4892 segment = read_8ubyte_unaligned_inc (dbg, readp);
4893
4894 if (range_address == 0 && range_length == 0 && segment == 0)
4895 break;
4896
4897 char *b = format_dwarf_addr (dwflmod, address_size, range_address,
4898 range_address);
4899 char *e = format_dwarf_addr (dwflmod, address_size,
4900 range_address + range_length - 1,
4901 range_length);
4902 if (segment_size != 0)
4903 printf (gettext (" %s..%s (%" PRIx64 ")\n"), b, e,
4904 (uint64_t) segment);
4905 else
4906 printf (gettext (" %s..%s\n"), b, e);
4907 free (b);
4908 free (e);
4909 }
4910
4911 next_table:
4912 if (readp != nexthdr)
4913 {
4914 size_t padding = nexthdr - readp;
4915 printf (gettext (" %zu padding bytes\n"), padding);
4916 readp = nexthdr;
4917 }
4918 }
4919 }
4920
4921
4922 /* Print content of DWARF .debug_ranges section. */
4923 static void
print_debug_ranges_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)4924 print_debug_ranges_section (Dwfl_Module *dwflmod,
4925 Ebl *ebl, GElf_Ehdr *ehdr,
4926 Elf_Scn *scn, GElf_Shdr *shdr,
4927 Dwarf *dbg)
4928 {
4929 Elf_Data *data = dbg->sectiondata[IDX_debug_ranges];
4930
4931 if (unlikely (data == NULL))
4932 {
4933 error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
4934 elf_errmsg (-1));
4935 return;
4936 }
4937
4938 printf (gettext ("\
4939 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
4940 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
4941 (uint64_t) shdr->sh_offset);
4942
4943 sort_listptr (&known_rangelistptr, "rangelistptr");
4944 size_t listptr_idx = 0;
4945
4946 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
4947
4948 bool first = true;
4949 Dwarf_Addr base = 0;
4950 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
4951 unsigned char *readp = data->d_buf;
4952 while (readp < endp)
4953 {
4954 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
4955
4956 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
4957 &address_size, NULL, &base, NULL,
4958 offset, &readp, endp))
4959 continue;
4960
4961 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
4962 {
4963 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
4964 break;
4965 }
4966
4967 Dwarf_Addr begin;
4968 Dwarf_Addr end;
4969 if (address_size == 8)
4970 {
4971 begin = read_8ubyte_unaligned_inc (dbg, readp);
4972 end = read_8ubyte_unaligned_inc (dbg, readp);
4973 }
4974 else
4975 {
4976 begin = read_4ubyte_unaligned_inc (dbg, readp);
4977 end = read_4ubyte_unaligned_inc (dbg, readp);
4978 if (begin == (Dwarf_Addr) (uint32_t) -1)
4979 begin = (Dwarf_Addr) -1l;
4980 }
4981
4982 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
4983 {
4984 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
4985 printf (gettext (" [%6tx] base address %s\n"), offset, b);
4986 free (b);
4987 base = end;
4988 }
4989 else if (begin == 0 && end == 0) /* End of list entry. */
4990 {
4991 if (first)
4992 printf (gettext (" [%6tx] empty list\n"), offset);
4993 first = true;
4994 }
4995 else
4996 {
4997 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
4998 begin);
4999 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
5000 end);
5001 /* We have an address range entry. */
5002 if (first) /* First address range entry in a list. */
5003 printf (gettext (" [%6tx] %s..%s\n"), offset, b, e);
5004 else
5005 printf (gettext (" %s..%s\n"), b, e);
5006 free (b);
5007 free (e);
5008
5009 first = false;
5010 }
5011 }
5012 }
5013
5014 #define REGNAMESZ 16
5015 static const char *
register_info(Ebl * ebl,unsigned int regno,const Ebl_Register_Location * loc,char name[REGNAMESZ],int * bits,int * type)5016 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
5017 char name[REGNAMESZ], int *bits, int *type)
5018 {
5019 const char *set;
5020 const char *pfx;
5021 int ignore;
5022 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
5023 bits ?: &ignore, type ?: &ignore);
5024 if (n <= 0)
5025 {
5026 if (loc != NULL)
5027 snprintf (name, REGNAMESZ, "reg%u", loc->regno);
5028 else
5029 snprintf (name, REGNAMESZ, "??? 0x%x", regno);
5030 if (bits != NULL)
5031 *bits = loc != NULL ? loc->bits : 0;
5032 if (type != NULL)
5033 *type = DW_ATE_unsigned;
5034 set = "??? unrecognized";
5035 }
5036 else
5037 {
5038 if (bits != NULL && *bits <= 0)
5039 *bits = loc != NULL ? loc->bits : 0;
5040 if (type != NULL && *type == DW_ATE_void)
5041 *type = DW_ATE_unsigned;
5042
5043 }
5044 return set;
5045 }
5046
5047 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,Dwfl_Module * dwflmod,Ebl * ebl,Dwarf * dbg)5048 print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
5049 Dwarf_Word vma_base, unsigned int code_align,
5050 int data_align,
5051 unsigned int version, unsigned int ptr_size,
5052 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
5053 {
5054 char regnamebuf[REGNAMESZ];
5055 const char *regname (unsigned int regno)
5056 {
5057 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
5058 return regnamebuf;
5059 }
5060
5061 puts ("\n Program:");
5062 Dwarf_Word pc = vma_base;
5063 while (readp < endp)
5064 {
5065 unsigned int opcode = *readp++;
5066
5067 if (opcode < DW_CFA_advance_loc)
5068 /* Extended opcode. */
5069 switch (opcode)
5070 {
5071 uint64_t op1;
5072 int64_t sop1;
5073 uint64_t op2;
5074 int64_t sop2;
5075
5076 case DW_CFA_nop:
5077 puts (" nop");
5078 break;
5079 case DW_CFA_set_loc:
5080 if ((uint64_t) (endp - readp) < 1)
5081 goto invalid;
5082 get_uleb128 (op1, readp, endp);
5083 op1 += vma_base;
5084 printf (" set_loc %" PRIu64 "\n", op1 * code_align);
5085 break;
5086 case DW_CFA_advance_loc1:
5087 if ((uint64_t) (endp - readp) < 1)
5088 goto invalid;
5089 printf (" advance_loc1 %u to %#" PRIx64 "\n",
5090 *readp, pc += *readp * code_align);
5091 ++readp;
5092 break;
5093 case DW_CFA_advance_loc2:
5094 if ((uint64_t) (endp - readp) < 2)
5095 goto invalid;
5096 op1 = read_2ubyte_unaligned_inc (dbg, readp);
5097 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
5098 op1, pc += op1 * code_align);
5099 break;
5100 case DW_CFA_advance_loc4:
5101 if ((uint64_t) (endp - readp) < 4)
5102 goto invalid;
5103 op1 = read_4ubyte_unaligned_inc (dbg, readp);
5104 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
5105 op1, pc += op1 * code_align);
5106 break;
5107 case DW_CFA_offset_extended:
5108 if ((uint64_t) (endp - readp) < 1)
5109 goto invalid;
5110 get_uleb128 (op1, readp, endp);
5111 if ((uint64_t) (endp - readp) < 1)
5112 goto invalid;
5113 get_uleb128 (op2, readp, endp);
5114 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
5115 "\n",
5116 op1, regname (op1), op2 * data_align);
5117 break;
5118 case DW_CFA_restore_extended:
5119 if ((uint64_t) (endp - readp) < 1)
5120 goto invalid;
5121 get_uleb128 (op1, readp, endp);
5122 printf (" restore_extended r%" PRIu64 " (%s)\n",
5123 op1, regname (op1));
5124 break;
5125 case DW_CFA_undefined:
5126 if ((uint64_t) (endp - readp) < 1)
5127 goto invalid;
5128 get_uleb128 (op1, readp, endp);
5129 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
5130 break;
5131 case DW_CFA_same_value:
5132 if ((uint64_t) (endp - readp) < 1)
5133 goto invalid;
5134 get_uleb128 (op1, readp, endp);
5135 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
5136 break;
5137 case DW_CFA_register:
5138 if ((uint64_t) (endp - readp) < 1)
5139 goto invalid;
5140 get_uleb128 (op1, readp, endp);
5141 if ((uint64_t) (endp - readp) < 1)
5142 goto invalid;
5143 get_uleb128 (op2, readp, endp);
5144 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
5145 op1, regname (op1), op2, regname (op2));
5146 break;
5147 case DW_CFA_remember_state:
5148 puts (" remember_state");
5149 break;
5150 case DW_CFA_restore_state:
5151 puts (" restore_state");
5152 break;
5153 case DW_CFA_def_cfa:
5154 if ((uint64_t) (endp - readp) < 1)
5155 goto invalid;
5156 get_uleb128 (op1, readp, endp);
5157 if ((uint64_t) (endp - readp) < 1)
5158 goto invalid;
5159 get_uleb128 (op2, readp, endp);
5160 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
5161 op1, regname (op1), op2);
5162 break;
5163 case DW_CFA_def_cfa_register:
5164 if ((uint64_t) (endp - readp) < 1)
5165 goto invalid;
5166 get_uleb128 (op1, readp, endp);
5167 printf (" def_cfa_register r%" PRIu64 " (%s)\n",
5168 op1, regname (op1));
5169 break;
5170 case DW_CFA_def_cfa_offset:
5171 if ((uint64_t) (endp - readp) < 1)
5172 goto invalid;
5173 get_uleb128 (op1, readp, endp);
5174 printf (" def_cfa_offset %" PRIu64 "\n", op1);
5175 break;
5176 case DW_CFA_def_cfa_expression:
5177 if ((uint64_t) (endp - readp) < 1)
5178 goto invalid;
5179 get_uleb128 (op1, readp, endp); /* Length of DW_FORM_block. */
5180 printf (" def_cfa_expression %" PRIu64 "\n", op1);
5181 if ((uint64_t) (endp - readp) < op1)
5182 {
5183 invalid:
5184 fputs (gettext (" <INVALID DATA>\n"), stdout);
5185 return;
5186 }
5187 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5188 op1, readp);
5189 readp += op1;
5190 break;
5191 case DW_CFA_expression:
5192 if ((uint64_t) (endp - readp) < 1)
5193 goto invalid;
5194 get_uleb128 (op1, readp, endp);
5195 if ((uint64_t) (endp - readp) < 1)
5196 goto invalid;
5197 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
5198 printf (" expression r%" PRIu64 " (%s) \n",
5199 op1, regname (op1));
5200 if ((uint64_t) (endp - readp) < op2)
5201 goto invalid;
5202 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
5203 op2, readp);
5204 readp += op2;
5205 break;
5206 case DW_CFA_offset_extended_sf:
5207 if ((uint64_t) (endp - readp) < 1)
5208 goto invalid;
5209 get_uleb128 (op1, readp, endp);
5210 if ((uint64_t) (endp - readp) < 1)
5211 goto invalid;
5212 get_sleb128 (sop2, readp, endp);
5213 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
5214 PRId64 "\n",
5215 op1, regname (op1), sop2 * data_align);
5216 break;
5217 case DW_CFA_def_cfa_sf:
5218 if ((uint64_t) (endp - readp) < 1)
5219 goto invalid;
5220 get_uleb128 (op1, readp, endp);
5221 if ((uint64_t) (endp - readp) < 1)
5222 goto invalid;
5223 get_sleb128 (sop2, readp, endp);
5224 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
5225 op1, regname (op1), sop2 * data_align);
5226 break;
5227 case DW_CFA_def_cfa_offset_sf:
5228 if ((uint64_t) (endp - readp) < 1)
5229 goto invalid;
5230 get_sleb128 (sop1, readp, endp);
5231 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
5232 break;
5233 case DW_CFA_val_offset:
5234 if ((uint64_t) (endp - readp) < 1)
5235 goto invalid;
5236 get_uleb128 (op1, readp, endp);
5237 if ((uint64_t) (endp - readp) < 1)
5238 goto invalid;
5239 get_uleb128 (op2, readp, endp);
5240 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n",
5241 op1, op2 * data_align);
5242 break;
5243 case DW_CFA_val_offset_sf:
5244 if ((uint64_t) (endp - readp) < 1)
5245 goto invalid;
5246 get_uleb128 (op1, readp, endp);
5247 if ((uint64_t) (endp - readp) < 1)
5248 goto invalid;
5249 get_sleb128 (sop2, readp, endp);
5250 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
5251 op1, sop2 * data_align);
5252 break;
5253 case DW_CFA_val_expression:
5254 if ((uint64_t) (endp - readp) < 1)
5255 goto invalid;
5256 get_uleb128 (op1, readp, endp);
5257 if ((uint64_t) (endp - readp) < 1)
5258 goto invalid;
5259 get_uleb128 (op2, readp, endp); /* Length of DW_FORM_block. */
5260 printf (" val_expression r%" PRIu64 " (%s)\n",
5261 op1, regname (op1));
5262 if ((uint64_t) (endp - readp) < op2)
5263 goto invalid;
5264 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
5265 NULL, op2, readp);
5266 readp += op2;
5267 break;
5268 case DW_CFA_MIPS_advance_loc8:
5269 if ((uint64_t) (endp - readp) < 8)
5270 goto invalid;
5271 op1 = read_8ubyte_unaligned_inc (dbg, readp);
5272 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
5273 op1, pc += op1 * code_align);
5274 break;
5275 case DW_CFA_GNU_window_save:
5276 puts (" GNU_window_save");
5277 break;
5278 case DW_CFA_GNU_args_size:
5279 if ((uint64_t) (endp - readp) < 1)
5280 goto invalid;
5281 get_uleb128 (op1, readp, endp);
5282 printf (" args_size %" PRIu64 "\n", op1);
5283 break;
5284 default:
5285 printf (" ??? (%u)\n", opcode);
5286 break;
5287 }
5288 else if (opcode < DW_CFA_offset)
5289 printf (" advance_loc %u to %#" PRIx64 "\n",
5290 opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
5291 else if (opcode < DW_CFA_restore)
5292 {
5293 uint64_t offset;
5294 if ((uint64_t) (endp - readp) < 1)
5295 goto invalid;
5296 get_uleb128 (offset, readp, endp);
5297 printf (" offset r%u (%s) at cfa%+" PRId64 "\n",
5298 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
5299 }
5300 else
5301 printf (" restore r%u (%s)\n",
5302 opcode & 0x3f, regname (opcode & 0x3f));
5303 }
5304 }
5305
5306
5307 static unsigned int
encoded_ptr_size(int encoding,unsigned int ptr_size)5308 encoded_ptr_size (int encoding, unsigned int ptr_size)
5309 {
5310 switch (encoding & 7)
5311 {
5312 case DW_EH_PE_udata4:
5313 return 4;
5314 case DW_EH_PE_udata8:
5315 return 8;
5316 case 0:
5317 return ptr_size;
5318 }
5319
5320 fprintf (stderr, "Unsupported pointer encoding: %#x, "
5321 "assuming pointer size of %d.\n", encoding, ptr_size);
5322 return ptr_size;
5323 }
5324
5325
5326 static unsigned int
print_encoding(unsigned int val)5327 print_encoding (unsigned int val)
5328 {
5329 switch (val & 0xf)
5330 {
5331 case DW_EH_PE_absptr:
5332 fputs ("absptr", stdout);
5333 break;
5334 case DW_EH_PE_uleb128:
5335 fputs ("uleb128", stdout);
5336 break;
5337 case DW_EH_PE_udata2:
5338 fputs ("udata2", stdout);
5339 break;
5340 case DW_EH_PE_udata4:
5341 fputs ("udata4", stdout);
5342 break;
5343 case DW_EH_PE_udata8:
5344 fputs ("udata8", stdout);
5345 break;
5346 case DW_EH_PE_sleb128:
5347 fputs ("sleb128", stdout);
5348 break;
5349 case DW_EH_PE_sdata2:
5350 fputs ("sdata2", stdout);
5351 break;
5352 case DW_EH_PE_sdata4:
5353 fputs ("sdata4", stdout);
5354 break;
5355 case DW_EH_PE_sdata8:
5356 fputs ("sdata8", stdout);
5357 break;
5358 default:
5359 /* We did not use any of the bits after all. */
5360 return val;
5361 }
5362
5363 return val & ~0xf;
5364 }
5365
5366
5367 static unsigned int
print_relinfo(unsigned int val)5368 print_relinfo (unsigned int val)
5369 {
5370 switch (val & 0x70)
5371 {
5372 case DW_EH_PE_pcrel:
5373 fputs ("pcrel", stdout);
5374 break;
5375 case DW_EH_PE_textrel:
5376 fputs ("textrel", stdout);
5377 break;
5378 case DW_EH_PE_datarel:
5379 fputs ("datarel", stdout);
5380 break;
5381 case DW_EH_PE_funcrel:
5382 fputs ("funcrel", stdout);
5383 break;
5384 case DW_EH_PE_aligned:
5385 fputs ("aligned", stdout);
5386 break;
5387 default:
5388 return val;
5389 }
5390
5391 return val & ~0x70;
5392 }
5393
5394
5395 static void
print_encoding_base(const char * pfx,unsigned int fde_encoding)5396 print_encoding_base (const char *pfx, unsigned int fde_encoding)
5397 {
5398 printf ("(%s", pfx);
5399
5400 if (fde_encoding == DW_EH_PE_omit)
5401 puts ("omit)");
5402 else
5403 {
5404 unsigned int w = fde_encoding;
5405
5406 w = print_encoding (w);
5407
5408 if (w & 0x70)
5409 {
5410 if (w != fde_encoding)
5411 fputc_unlocked (' ', stdout);
5412
5413 w = print_relinfo (w);
5414 }
5415
5416 if (w != 0)
5417 printf ("%s%x", w != fde_encoding ? " " : "", w);
5418
5419 puts (")");
5420 }
5421 }
5422
5423
5424 static const unsigned char *
read_encoded(unsigned int encoding,const unsigned char * readp,const unsigned char * const endp,uint64_t * res,Dwarf * dbg)5425 read_encoded (unsigned int encoding, const unsigned char *readp,
5426 const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
5427 {
5428 if ((encoding & 0xf) == DW_EH_PE_absptr)
5429 encoding = gelf_getclass (dbg->elf) == ELFCLASS32
5430 ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
5431
5432 switch (encoding & 0xf)
5433 {
5434 case DW_EH_PE_uleb128:
5435 get_uleb128 (*res, readp, endp);
5436 break;
5437 case DW_EH_PE_sleb128:
5438 get_sleb128 (*res, readp, endp);
5439 break;
5440 case DW_EH_PE_udata2:
5441 if (readp + 2 > endp)
5442 goto invalid;
5443 *res = read_2ubyte_unaligned_inc (dbg, readp);
5444 break;
5445 case DW_EH_PE_udata4:
5446 if (readp + 4 > endp)
5447 goto invalid;
5448 *res = read_4ubyte_unaligned_inc (dbg, readp);
5449 break;
5450 case DW_EH_PE_udata8:
5451 if (readp + 8 > endp)
5452 goto invalid;
5453 *res = read_8ubyte_unaligned_inc (dbg, readp);
5454 break;
5455 case DW_EH_PE_sdata2:
5456 if (readp + 2 > endp)
5457 goto invalid;
5458 *res = read_2sbyte_unaligned_inc (dbg, readp);
5459 break;
5460 case DW_EH_PE_sdata4:
5461 if (readp + 4 > endp)
5462 goto invalid;
5463 *res = read_4sbyte_unaligned_inc (dbg, readp);
5464 break;
5465 case DW_EH_PE_sdata8:
5466 if (readp + 8 > endp)
5467 goto invalid;
5468 *res = read_8sbyte_unaligned_inc (dbg, readp);
5469 break;
5470 default:
5471 invalid:
5472 error (1, 0,
5473 gettext ("invalid encoding"));
5474 }
5475
5476 return readp;
5477 }
5478
5479
5480 static void
print_debug_frame_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)5481 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
5482 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
5483 {
5484 size_t shstrndx;
5485 /* We know this call will succeed since it did in the caller. */
5486 (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
5487 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
5488
5489 /* Needed if we find PC-relative addresses. */
5490 GElf_Addr bias;
5491 if (dwfl_module_getelf (dwflmod, &bias) == NULL)
5492 {
5493 error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
5494 return;
5495 }
5496
5497 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
5498 Elf_Data *data = (is_eh_frame
5499 ? elf_rawdata (scn, NULL)
5500 : dbg->sectiondata[IDX_debug_frame]);
5501
5502 if (unlikely (data == NULL))
5503 {
5504 error (0, 0, gettext ("cannot get %s content: %s"),
5505 scnname, elf_errmsg (-1));
5506 return;
5507 }
5508
5509 if (is_eh_frame)
5510 printf (gettext ("\
5511 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5512 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5513 else
5514 printf (gettext ("\
5515 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
5516 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
5517
5518 struct cieinfo
5519 {
5520 ptrdiff_t cie_offset;
5521 const char *augmentation;
5522 unsigned int code_alignment_factor;
5523 unsigned int data_alignment_factor;
5524 uint8_t address_size;
5525 uint8_t fde_encoding;
5526 uint8_t lsda_encoding;
5527 struct cieinfo *next;
5528 } *cies = NULL;
5529
5530 const unsigned char *readp = data->d_buf;
5531 const unsigned char *const dataend = ((unsigned char *) data->d_buf
5532 + data->d_size);
5533 while (readp < dataend)
5534 {
5535 if (unlikely (readp + 4 > dataend))
5536 {
5537 invalid_data:
5538 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
5539 elf_ndxscn (scn), scnname);
5540 return;
5541 }
5542
5543 /* At the beginning there must be a CIE. There can be multiple,
5544 hence we test tis in a loop. */
5545 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
5546
5547 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
5548 unsigned int length = 4;
5549 if (unlikely (unit_length == 0xffffffff))
5550 {
5551 if (unlikely (readp + 8 > dataend))
5552 goto invalid_data;
5553
5554 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
5555 length = 8;
5556 }
5557
5558 if (unlikely (unit_length == 0))
5559 {
5560 printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
5561 continue;
5562 }
5563
5564 Dwarf_Word maxsize = dataend - readp;
5565 if (unlikely (unit_length > maxsize))
5566 goto invalid_data;
5567
5568 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5569
5570 ptrdiff_t start = readp - (unsigned char *) data->d_buf;
5571 const unsigned char *const cieend = readp + unit_length;
5572 if (unlikely (cieend > dataend || readp + 8 > dataend))
5573 goto invalid_data;
5574
5575 Dwarf_Off cie_id;
5576 if (length == 4)
5577 {
5578 cie_id = read_4ubyte_unaligned_inc (dbg, readp);
5579 if (!is_eh_frame && cie_id == DW_CIE_ID_32)
5580 cie_id = DW_CIE_ID_64;
5581 }
5582 else
5583 cie_id = read_8ubyte_unaligned_inc (dbg, readp);
5584
5585 uint_fast8_t version = 2;
5586 unsigned int code_alignment_factor;
5587 int data_alignment_factor;
5588 unsigned int fde_encoding = 0;
5589 unsigned int lsda_encoding = 0;
5590 Dwarf_Word initial_location = 0;
5591 Dwarf_Word vma_base = 0;
5592
5593 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
5594 {
5595 version = *readp++;
5596 const char *const augmentation = (const char *) readp;
5597 readp = memchr (readp, '\0', cieend - readp);
5598 if (unlikely (readp == NULL))
5599 goto invalid_data;
5600 ++readp;
5601
5602 uint_fast8_t segment_size = 0;
5603 if (version >= 4)
5604 {
5605 if (cieend - readp < 5)
5606 goto invalid_data;
5607 ptr_size = *readp++;
5608 segment_size = *readp++;
5609 }
5610
5611 if (cieend - readp < 1)
5612 goto invalid_data;
5613 get_uleb128 (code_alignment_factor, readp, cieend);
5614 if (cieend - readp < 1)
5615 goto invalid_data;
5616 get_sleb128 (data_alignment_factor, readp, cieend);
5617
5618 /* In some variant for unwind data there is another field. */
5619 if (strcmp (augmentation, "eh") == 0)
5620 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
5621
5622 unsigned int return_address_register;
5623 if (cieend - readp < 1)
5624 goto invalid_data;
5625 if (unlikely (version == 1))
5626 return_address_register = *readp++;
5627 else
5628 get_uleb128 (return_address_register, readp, cieend);
5629
5630 printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
5631 " CIE_id: %" PRIu64 "\n"
5632 " version: %u\n"
5633 " augmentation: \"%s\"\n",
5634 offset, (uint64_t) unit_length, (uint64_t) cie_id,
5635 version, augmentation);
5636 if (version >= 4)
5637 printf (" address_size: %u\n"
5638 " segment_size: %u\n",
5639 ptr_size, segment_size);
5640 printf (" code_alignment_factor: %u\n"
5641 " data_alignment_factor: %d\n"
5642 " return_address_register: %u\n",
5643 code_alignment_factor,
5644 data_alignment_factor, return_address_register);
5645
5646 if (augmentation[0] == 'z')
5647 {
5648 unsigned int augmentationlen;
5649 get_uleb128 (augmentationlen, readp, cieend);
5650
5651 if (augmentationlen > (size_t) (cieend - readp))
5652 {
5653 error (0, 0, gettext ("invalid augmentation length"));
5654 readp = cieend;
5655 continue;
5656 }
5657
5658 const char *hdr = "Augmentation data:";
5659 const char *cp = augmentation + 1;
5660 while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
5661 {
5662 printf (" %-26s%#x ", hdr, *readp);
5663 hdr = "";
5664
5665 if (*cp == 'R')
5666 {
5667 fde_encoding = *readp++;
5668 print_encoding_base (gettext ("FDE address encoding: "),
5669 fde_encoding);
5670 }
5671 else if (*cp == 'L')
5672 {
5673 lsda_encoding = *readp++;
5674 print_encoding_base (gettext ("LSDA pointer encoding: "),
5675 lsda_encoding);
5676 }
5677 else if (*cp == 'P')
5678 {
5679 /* Personality. This field usually has a relocation
5680 attached pointing to __gcc_personality_v0. */
5681 const unsigned char *startp = readp;
5682 unsigned int encoding = *readp++;
5683 uint64_t val = 0;
5684 readp = read_encoded (encoding, readp,
5685 readp - 1 + augmentationlen,
5686 &val, dbg);
5687
5688 while (++startp < readp)
5689 printf ("%#x ", *startp);
5690
5691 putchar ('(');
5692 print_encoding (encoding);
5693 putchar (' ');
5694 switch (encoding & 0xf)
5695 {
5696 case DW_EH_PE_sleb128:
5697 case DW_EH_PE_sdata2:
5698 case DW_EH_PE_sdata4:
5699 printf ("%" PRId64 ")\n", val);
5700 break;
5701 default:
5702 printf ("%#" PRIx64 ")\n", val);
5703 break;
5704 }
5705 }
5706 else
5707 printf ("(%x)\n", *readp++);
5708
5709 ++cp;
5710 }
5711 }
5712
5713 if (likely (ptr_size == 4 || ptr_size == 8))
5714 {
5715 struct cieinfo *newp = alloca (sizeof (*newp));
5716 newp->cie_offset = offset;
5717 newp->augmentation = augmentation;
5718 newp->fde_encoding = fde_encoding;
5719 newp->lsda_encoding = lsda_encoding;
5720 newp->address_size = ptr_size;
5721 newp->code_alignment_factor = code_alignment_factor;
5722 newp->data_alignment_factor = data_alignment_factor;
5723 newp->next = cies;
5724 cies = newp;
5725 }
5726 }
5727 else
5728 {
5729 struct cieinfo *cie = cies;
5730 while (cie != NULL)
5731 if (is_eh_frame
5732 ? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
5733 : cie_id == (Dwarf_Off) cie->cie_offset)
5734 break;
5735 else
5736 cie = cie->next;
5737 if (unlikely (cie == NULL))
5738 {
5739 puts ("invalid CIE reference in FDE");
5740 return;
5741 }
5742
5743 /* Initialize from CIE data. */
5744 fde_encoding = cie->fde_encoding;
5745 lsda_encoding = cie->lsda_encoding;
5746 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
5747 code_alignment_factor = cie->code_alignment_factor;
5748 data_alignment_factor = cie->data_alignment_factor;
5749
5750 const unsigned char *base = readp;
5751 // XXX There are sometimes relocations for this value
5752 initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
5753 Dwarf_Word address_range
5754 = read_addr_unaligned_inc (ptr_size, dbg, readp);
5755
5756 /* pcrel for an FDE address is relative to the runtime
5757 address of the start_address field itself. Sign extend
5758 if necessary to make sure the calculation is done on the
5759 full 64 bit address even when initial_location only holds
5760 the lower 32 bits. */
5761 Dwarf_Addr pc_start = initial_location;
5762 if (ptr_size == 4)
5763 pc_start = (uint64_t) (int32_t) pc_start;
5764 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5765 pc_start += ((uint64_t) shdr->sh_addr
5766 + (base - (const unsigned char *) data->d_buf)
5767 - bias);
5768
5769 char *a = format_dwarf_addr (dwflmod, cie->address_size,
5770 pc_start, initial_location);
5771 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
5772 " CIE_pointer: %" PRIu64 "\n"
5773 " initial_location: %s",
5774 offset, (uint64_t) unit_length,
5775 cie->cie_offset, (uint64_t) cie_id, a);
5776 free (a);
5777 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5778 {
5779 vma_base = (((uint64_t) shdr->sh_offset
5780 + (base - (const unsigned char *) data->d_buf)
5781 + (uint64_t) initial_location)
5782 & (ptr_size == 4
5783 ? UINT64_C (0xffffffff)
5784 : UINT64_C (0xffffffffffffffff)));
5785 printf (gettext (" (offset: %#" PRIx64 ")"),
5786 (uint64_t) vma_base);
5787 }
5788
5789 printf ("\n address_range: %#" PRIx64,
5790 (uint64_t) address_range);
5791 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
5792 printf (gettext (" (end offset: %#" PRIx64 ")"),
5793 ((uint64_t) vma_base + (uint64_t) address_range)
5794 & (ptr_size == 4
5795 ? UINT64_C (0xffffffff)
5796 : UINT64_C (0xffffffffffffffff)));
5797 putchar ('\n');
5798
5799 if (cie->augmentation[0] == 'z')
5800 {
5801 unsigned int augmentationlen;
5802 if (cieend - readp < 1)
5803 goto invalid_data;
5804 get_uleb128 (augmentationlen, readp, cieend);
5805
5806 if (augmentationlen > (size_t) (cieend - readp))
5807 {
5808 error (0, 0, gettext ("invalid augmentation length"));
5809 readp = cieend;
5810 continue;
5811 }
5812
5813 if (augmentationlen > 0)
5814 {
5815 const char *hdr = "Augmentation data:";
5816 const char *cp = cie->augmentation + 1;
5817 unsigned int u = 0;
5818 while (*cp != '\0'
5819 && cp < cie->augmentation + augmentationlen + 1)
5820 {
5821 if (*cp == 'L')
5822 {
5823 uint64_t lsda_pointer;
5824 const unsigned char *p
5825 = read_encoded (lsda_encoding, &readp[u],
5826 &readp[augmentationlen],
5827 &lsda_pointer, dbg);
5828 u = p - readp;
5829 printf (gettext ("\
5830 %-26sLSDA pointer: %#" PRIx64 "\n"),
5831 hdr, lsda_pointer);
5832 hdr = "";
5833 }
5834 ++cp;
5835 }
5836
5837 while (u < augmentationlen)
5838 {
5839 printf (" %-26s%#x\n", hdr, readp[u++]);
5840 hdr = "";
5841 }
5842 }
5843
5844 readp += augmentationlen;
5845 }
5846 }
5847
5848 /* Handle the initialization instructions. */
5849 if (ptr_size != 4 && ptr_size !=8)
5850 printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
5851 else
5852 print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
5853 data_alignment_factor, version, ptr_size,
5854 dwflmod, ebl, dbg);
5855 readp = cieend;
5856 }
5857 }
5858
5859
5860 struct attrcb_args
5861 {
5862 Dwfl_Module *dwflmod;
5863 Dwarf *dbg;
5864 Dwarf_Die *die;
5865 int level;
5866 bool silent;
5867 unsigned int version;
5868 unsigned int addrsize;
5869 unsigned int offset_size;
5870 struct Dwarf_CU *cu;
5871 };
5872
5873
5874 static int
attr_callback(Dwarf_Attribute * attrp,void * arg)5875 attr_callback (Dwarf_Attribute *attrp, void *arg)
5876 {
5877 struct attrcb_args *cbargs = (struct attrcb_args *) arg;
5878 const int level = cbargs->level;
5879
5880 unsigned int attr = dwarf_whatattr (attrp);
5881 if (unlikely (attr == 0))
5882 {
5883 if (!cbargs->silent)
5884 error (0, 0, gettext ("cannot get attribute code: %s"),
5885 dwarf_errmsg (-1));
5886 return DWARF_CB_ABORT;
5887 }
5888
5889 unsigned int form = dwarf_whatform (attrp);
5890 if (unlikely (form == 0))
5891 {
5892 if (!cbargs->silent)
5893 error (0, 0, gettext ("cannot get attribute form: %s"),
5894 dwarf_errmsg (-1));
5895 return DWARF_CB_ABORT;
5896 }
5897
5898 switch (form)
5899 {
5900 case DW_FORM_addr:
5901 if (!cbargs->silent)
5902 {
5903 Dwarf_Addr addr;
5904 if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
5905 {
5906 attrval_out:
5907 if (!cbargs->silent)
5908 error (0, 0, gettext ("cannot get attribute value: %s"),
5909 dwarf_errmsg (-1));
5910 return DWARF_CB_ABORT;
5911 }
5912 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
5913 addr, addr);
5914 printf (" %*s%-20s (%s) %s\n",
5915 (int) (level * 2), "", dwarf_attr_name (attr),
5916 dwarf_form_name (form), a);
5917 free (a);
5918 }
5919 break;
5920
5921 case DW_FORM_indirect:
5922 case DW_FORM_strp:
5923 case DW_FORM_string:
5924 case DW_FORM_GNU_strp_alt:
5925 if (cbargs->silent)
5926 break;
5927 const char *str = dwarf_formstring (attrp);
5928 if (unlikely (str == NULL))
5929 goto attrval_out;
5930 printf (" %*s%-20s (%s) \"%s\"\n",
5931 (int) (level * 2), "", dwarf_attr_name (attr),
5932 dwarf_form_name (form), str);
5933 break;
5934
5935 case DW_FORM_ref_addr:
5936 case DW_FORM_ref_udata:
5937 case DW_FORM_ref8:
5938 case DW_FORM_ref4:
5939 case DW_FORM_ref2:
5940 case DW_FORM_ref1:
5941 case DW_FORM_GNU_ref_alt:
5942 if (cbargs->silent)
5943 break;
5944 Dwarf_Die ref;
5945 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
5946 goto attrval_out;
5947
5948 printf (" %*s%-20s (%s) [%6" PRIxMAX "]\n",
5949 (int) (level * 2), "", dwarf_attr_name (attr),
5950 dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref));
5951 break;
5952
5953 case DW_FORM_ref_sig8:
5954 if (cbargs->silent)
5955 break;
5956 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n",
5957 (int) (level * 2), "", dwarf_attr_name (attr),
5958 dwarf_form_name (form),
5959 (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
5960 break;
5961
5962 case DW_FORM_sec_offset:
5963 case DW_FORM_udata:
5964 case DW_FORM_sdata:
5965 case DW_FORM_data8:
5966 case DW_FORM_data4:
5967 case DW_FORM_data2:
5968 case DW_FORM_data1:;
5969 Dwarf_Word num;
5970 if (unlikely (dwarf_formudata (attrp, &num) != 0))
5971 goto attrval_out;
5972
5973 const char *valuestr = NULL;
5974 switch (attr)
5975 {
5976 /* This case can take either a constant or a loclistptr. */
5977 case DW_AT_data_member_location:
5978 if (form != DW_FORM_sec_offset
5979 && (cbargs->version >= 4
5980 || (form != DW_FORM_data4 && form != DW_FORM_data8)))
5981 {
5982 if (!cbargs->silent)
5983 printf (" %*s%-20s (%s) %" PRIxMAX "\n",
5984 (int) (level * 2), "", dwarf_attr_name (attr),
5985 dwarf_form_name (form), (uintmax_t) num);
5986 return DWARF_CB_OK;
5987 }
5988 /* else fallthrough */
5989
5990 /* These cases always take a loclistptr and no constant. */
5991 case DW_AT_location:
5992 case DW_AT_data_location:
5993 case DW_AT_vtable_elem_location:
5994 case DW_AT_string_length:
5995 case DW_AT_use_location:
5996 case DW_AT_frame_base:
5997 case DW_AT_return_addr:
5998 case DW_AT_static_link:
5999 case DW_AT_GNU_call_site_value:
6000 case DW_AT_GNU_call_site_data_value:
6001 case DW_AT_GNU_call_site_target:
6002 case DW_AT_GNU_call_site_target_clobbered:
6003 {
6004 bool nlpt = notice_listptr (section_loc, &known_loclistptr,
6005 cbargs->addrsize, cbargs->offset_size,
6006 cbargs->cu, num);
6007 if (!cbargs->silent)
6008 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
6009 (int) (level * 2), "", dwarf_attr_name (attr),
6010 dwarf_form_name (form), (uintmax_t) num,
6011 nlpt ? "" : " <WARNING offset too big>");
6012 }
6013 return DWARF_CB_OK;
6014
6015 case DW_AT_ranges:
6016 {
6017 bool nlpt = notice_listptr (section_ranges, &known_rangelistptr,
6018 cbargs->addrsize, cbargs->offset_size,
6019 cbargs->cu, num);
6020 if (!cbargs->silent)
6021 printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]%s\n",
6022 (int) (level * 2), "", dwarf_attr_name (attr),
6023 dwarf_form_name (form), (uintmax_t) num,
6024 nlpt ? "" : " <WARNING offset too big>");
6025 }
6026 return DWARF_CB_OK;
6027
6028 case DW_AT_language:
6029 valuestr = dwarf_lang_name (num);
6030 break;
6031 case DW_AT_encoding:
6032 valuestr = dwarf_encoding_name (num);
6033 break;
6034 case DW_AT_accessibility:
6035 valuestr = dwarf_access_name (num);
6036 break;
6037 case DW_AT_visibility:
6038 valuestr = dwarf_visibility_name (num);
6039 break;
6040 case DW_AT_virtuality:
6041 valuestr = dwarf_virtuality_name (num);
6042 break;
6043 case DW_AT_identifier_case:
6044 valuestr = dwarf_identifier_case_name (num);
6045 break;
6046 case DW_AT_calling_convention:
6047 valuestr = dwarf_calling_convention_name (num);
6048 break;
6049 case DW_AT_inline:
6050 valuestr = dwarf_inline_name (num);
6051 break;
6052 case DW_AT_ordering:
6053 valuestr = dwarf_ordering_name (num);
6054 break;
6055 case DW_AT_discr_list:
6056 valuestr = dwarf_discr_list_name (num);
6057 break;
6058 default:
6059 /* Nothing. */
6060 break;
6061 }
6062
6063 if (cbargs->silent)
6064 break;
6065
6066 /* When highpc is in constant form it is relative to lowpc.
6067 In that case also show the address. */
6068 Dwarf_Addr highpc;
6069 if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
6070 {
6071 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
6072 highpc, highpc);
6073 printf (" %*s%-20s (%s) %" PRIuMAX " (%s)\n",
6074 (int) (level * 2), "", dwarf_attr_name (attr),
6075 dwarf_form_name (form), (uintmax_t) num, a);
6076 free (a);
6077 }
6078 else
6079 {
6080 Dwarf_Sword snum = 0;
6081 if (form == DW_FORM_sdata)
6082 if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
6083 goto attrval_out;
6084
6085 if (valuestr == NULL)
6086 {
6087 printf (" %*s%-20s (%s)",
6088 (int) (level * 2), "", dwarf_attr_name (attr),
6089 dwarf_form_name (form));
6090 if (form == DW_FORM_sdata)
6091 printf (" %" PRIdMAX "\n", (intmax_t) snum);
6092 else
6093 printf (" %" PRIuMAX "\n", (uintmax_t) num);
6094 }
6095 else
6096 {
6097 printf (" %*s%-20s (%s) %s",
6098 (int) (level * 2), "", dwarf_attr_name (attr),
6099 dwarf_form_name (form), valuestr);
6100 if (form == DW_FORM_sdata)
6101 printf (" (%" PRIdMAX ")\n", (intmax_t) snum);
6102 else
6103 printf (" (%" PRIuMAX ")\n", (uintmax_t) num);
6104 }
6105 }
6106 break;
6107
6108 case DW_FORM_flag:
6109 if (cbargs->silent)
6110 break;
6111 bool flag;
6112 if (unlikely (dwarf_formflag (attrp, &flag) != 0))
6113 goto attrval_out;
6114
6115 printf (" %*s%-20s (%s) %s\n",
6116 (int) (level * 2), "", dwarf_attr_name (attr),
6117 dwarf_form_name (form), nl_langinfo (flag ? YESSTR : NOSTR));
6118 break;
6119
6120 case DW_FORM_flag_present:
6121 if (cbargs->silent)
6122 break;
6123 printf (" %*s%-20s (%s) %s\n",
6124 (int) (level * 2), "", dwarf_attr_name (attr),
6125 dwarf_form_name (form), nl_langinfo (YESSTR));
6126 break;
6127
6128 case DW_FORM_exprloc:
6129 case DW_FORM_block4:
6130 case DW_FORM_block2:
6131 case DW_FORM_block1:
6132 case DW_FORM_block:
6133 if (cbargs->silent)
6134 break;
6135 Dwarf_Block block;
6136 if (unlikely (dwarf_formblock (attrp, &block) != 0))
6137 goto attrval_out;
6138
6139 printf (" %*s%-20s (%s) ",
6140 (int) (level * 2), "", dwarf_attr_name (attr),
6141 dwarf_form_name (form));
6142
6143 switch (attr)
6144 {
6145 default:
6146 if (form != DW_FORM_exprloc)
6147 {
6148 print_block (block.length, block.data);
6149 break;
6150 }
6151 /* Fall through. */
6152
6153 case DW_AT_location:
6154 case DW_AT_data_location:
6155 case DW_AT_data_member_location:
6156 case DW_AT_vtable_elem_location:
6157 case DW_AT_string_length:
6158 case DW_AT_use_location:
6159 case DW_AT_frame_base:
6160 case DW_AT_return_addr:
6161 case DW_AT_static_link:
6162 case DW_AT_allocated:
6163 case DW_AT_associated:
6164 case DW_AT_bit_size:
6165 case DW_AT_bit_offset:
6166 case DW_AT_bit_stride:
6167 case DW_AT_byte_size:
6168 case DW_AT_byte_stride:
6169 case DW_AT_count:
6170 case DW_AT_lower_bound:
6171 case DW_AT_upper_bound:
6172 case DW_AT_GNU_call_site_value:
6173 case DW_AT_GNU_call_site_data_value:
6174 case DW_AT_GNU_call_site_target:
6175 case DW_AT_GNU_call_site_target_clobbered:
6176 putchar ('\n');
6177 print_ops (cbargs->dwflmod, cbargs->dbg,
6178 12 + level * 2, 12 + level * 2,
6179 cbargs->version, cbargs->addrsize, cbargs->offset_size,
6180 attrp->cu, block.length, block.data);
6181 break;
6182 }
6183 break;
6184
6185 default:
6186 if (cbargs->silent)
6187 break;
6188 printf (" %*s%-20s (form: %#x) ???\n",
6189 (int) (level * 2), "", dwarf_attr_name (attr),
6190 (int) form);
6191 break;
6192 }
6193
6194 return DWARF_CB_OK;
6195 }
6196
6197 static void
print_debug_units(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg,bool debug_types)6198 print_debug_units (Dwfl_Module *dwflmod,
6199 Ebl *ebl, GElf_Ehdr *ehdr,
6200 Elf_Scn *scn, GElf_Shdr *shdr,
6201 Dwarf *dbg, bool debug_types)
6202 {
6203 const bool silent = !(print_debug_sections & section_info);
6204 const char *secname = section_name (ebl, ehdr, shdr);
6205
6206 if (!silent)
6207 printf (gettext ("\
6208 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
6209 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
6210
6211 /* If the section is empty we don't have to do anything. */
6212 if (!silent && shdr->sh_size == 0)
6213 return;
6214
6215 int maxdies = 20;
6216 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
6217
6218 Dwarf_Off offset = 0;
6219
6220 /* New compilation unit. */
6221 size_t cuhl;
6222 Dwarf_Half version;
6223 Dwarf_Off abbroffset;
6224 uint8_t addrsize;
6225 uint8_t offsize;
6226 Dwarf_Off nextcu;
6227 uint64_t typesig;
6228 Dwarf_Off typeoff;
6229 next_cu:
6230 if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
6231 &abbroffset, &addrsize, &offsize,
6232 debug_types ? &typesig : NULL,
6233 debug_types ? &typeoff : NULL) != 0)
6234 goto do_return;
6235
6236 if (!silent)
6237 {
6238 if (debug_types)
6239 printf (gettext (" Type unit at offset %" PRIu64 ":\n"
6240 " Version: %" PRIu16 ", Abbreviation section offset: %"
6241 PRIu64 ", Address size: %" PRIu8
6242 ", Offset size: %" PRIu8
6243 "\n Type signature: %#" PRIx64
6244 ", Type offset: %#" PRIx64 "\n"),
6245 (uint64_t) offset, version, abbroffset, addrsize, offsize,
6246 typesig, (uint64_t) typeoff);
6247 else
6248 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
6249 " Version: %" PRIu16 ", Abbreviation section offset: %"
6250 PRIu64 ", Address size: %" PRIu8
6251 ", Offset size: %" PRIu8 "\n"),
6252 (uint64_t) offset, version, abbroffset, addrsize, offsize);
6253 }
6254
6255 struct attrcb_args args =
6256 {
6257 .dwflmod = dwflmod,
6258 .dbg = dbg,
6259 .silent = silent,
6260 .version = version,
6261 .addrsize = addrsize,
6262 .offset_size = offsize
6263 };
6264
6265 offset += cuhl;
6266
6267 int level = 0;
6268
6269 if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
6270 (dbg, offset, &dies[level]) == NULL))
6271 {
6272 if (!silent)
6273 error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
6274 " in section '%s': %s"),
6275 (uint64_t) offset, secname, dwarf_errmsg (-1));
6276 goto do_return;
6277 }
6278
6279 args.cu = dies[0].cu;
6280
6281 do
6282 {
6283 offset = dwarf_dieoffset (&dies[level]);
6284 if (unlikely (offset == ~0ul))
6285 {
6286 if (!silent)
6287 error (0, 0, gettext ("cannot get DIE offset: %s"),
6288 dwarf_errmsg (-1));
6289 goto do_return;
6290 }
6291
6292 int tag = dwarf_tag (&dies[level]);
6293 if (unlikely (tag == DW_TAG_invalid))
6294 {
6295 if (!silent)
6296 error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64
6297 " in section '%s': %s"),
6298 (uint64_t) offset, secname, dwarf_errmsg (-1));
6299 goto do_return;
6300 }
6301
6302 if (!silent)
6303 printf (" [%6" PRIx64 "] %*s%s\n",
6304 (uint64_t) offset, (int) (level * 2), "",
6305 dwarf_tag_name (tag));
6306
6307 /* Print the attribute values. */
6308 args.level = level;
6309 args.die = &dies[level];
6310 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
6311
6312 /* Make room for the next level's DIE. */
6313 if (level + 1 == maxdies)
6314 dies = (Dwarf_Die *) xrealloc (dies,
6315 (maxdies += 10)
6316 * sizeof (Dwarf_Die));
6317
6318 int res = dwarf_child (&dies[level], &dies[level + 1]);
6319 if (res > 0)
6320 {
6321 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
6322 if (level-- == 0)
6323 break;
6324
6325 if (unlikely (res == -1))
6326 {
6327 if (!silent)
6328 error (0, 0, gettext ("cannot get next DIE: %s\n"),
6329 dwarf_errmsg (-1));
6330 goto do_return;
6331 }
6332 }
6333 else if (unlikely (res < 0))
6334 {
6335 if (!silent)
6336 error (0, 0, gettext ("cannot get next DIE: %s"),
6337 dwarf_errmsg (-1));
6338 goto do_return;
6339 }
6340 else
6341 ++level;
6342 }
6343 while (level >= 0);
6344
6345 offset = nextcu;
6346 if (offset != 0)
6347 goto next_cu;
6348
6349 do_return:
6350 free (dies);
6351 }
6352
6353 static void
print_debug_info_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6354 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6355 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6356 {
6357 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
6358 }
6359
6360 static void
print_debug_types_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6361 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6362 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6363 {
6364 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
6365 }
6366
6367
6368 static void
print_decoded_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6369 print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6370 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6371 {
6372 printf (gettext ("\
6373 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
6374 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6375 (uint64_t) shdr->sh_offset);
6376
6377 size_t address_size
6378 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6379
6380 Dwarf_Off cuoffset;
6381 Dwarf_Off ncuoffset = 0;
6382 size_t hsize;
6383 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6384 NULL, NULL, NULL) == 0)
6385 {
6386 Dwarf_Die cudie;
6387 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6388 continue;
6389
6390 size_t nlines;
6391 Dwarf_Lines *lines;
6392 if (dwarf_getsrclines (&cudie, &lines, &nlines) != 0)
6393 continue;
6394
6395 printf (" CU [%" PRIx64 "] %s\n",
6396 dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
6397 printf (" line:col SBPE* disc isa op address"
6398 " (Statement Block Prologue Epilogue *End)\n");
6399 const char *last_file = "";
6400 for (size_t n = 0; n < nlines; n++)
6401 {
6402 Dwarf_Line *line = dwarf_onesrcline (lines, n);
6403 if (line == NULL)
6404 {
6405 printf (" dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
6406 continue;
6407 }
6408 Dwarf_Word mtime, length;
6409 const char *file = dwarf_linesrc (line, &mtime, &length);
6410 if (file == NULL)
6411 {
6412 printf (" <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
6413 last_file = "";
6414 }
6415 else if (strcmp (last_file, file) != 0)
6416 {
6417 printf (" %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
6418 file, mtime, length);
6419 last_file = file;
6420 }
6421
6422 int lineno, colno;
6423 bool statement, endseq, block, prologue_end, epilogue_begin;
6424 unsigned int lineop, isa, disc;
6425 Dwarf_Addr address;
6426 dwarf_lineaddr (line, &address);
6427 dwarf_lineno (line, &lineno);
6428 dwarf_linecol (line, &colno);
6429 dwarf_lineop_index (line, &lineop);
6430 dwarf_linebeginstatement (line, &statement);
6431 dwarf_lineendsequence (line, &endseq);
6432 dwarf_lineblock (line, &block);
6433 dwarf_lineprologueend (line, &prologue_end);
6434 dwarf_lineepiloguebegin (line, &epilogue_begin);
6435 dwarf_lineisa (line, &isa);
6436 dwarf_linediscriminator (line, &disc);
6437
6438 /* End sequence is special, it is one byte past. */
6439 char *a = format_dwarf_addr (dwflmod, address_size,
6440 address - (endseq ? 1 : 0), address);
6441 printf (" %4d:%-3d %c%c%c%c%c %4d %3d %2d %s\n",
6442 lineno, colno,
6443 (statement ? 'S' : ' '),
6444 (block ? 'B' : ' '),
6445 (prologue_end ? 'P' : ' '),
6446 (epilogue_begin ? 'E' : ' '),
6447 (endseq ? '*' : ' '),
6448 disc, isa, lineop, a);
6449 free (a);
6450
6451 if (endseq)
6452 printf("\n");
6453 }
6454 }
6455 }
6456
6457
6458 static void
print_debug_line_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6459 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
6460 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6461 {
6462 if (decodedline)
6463 {
6464 print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
6465 return;
6466 }
6467
6468 printf (gettext ("\
6469 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
6470 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
6471 (uint64_t) shdr->sh_offset);
6472
6473 if (shdr->sh_size == 0)
6474 return;
6475
6476 /* There is no functionality in libdw to read the information in the
6477 way it is represented here. Hardcode the decoder. */
6478 Elf_Data *data = dbg->sectiondata[IDX_debug_line];
6479 if (unlikely (data == NULL || data->d_buf == NULL))
6480 {
6481 error (0, 0, gettext ("cannot get line data section data: %s"),
6482 elf_errmsg (-1));
6483 return;
6484 }
6485
6486 const unsigned char *linep = (const unsigned char *) data->d_buf;
6487 const unsigned char *lineendp;
6488
6489 while (linep
6490 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
6491 {
6492 size_t start_offset = linep - (const unsigned char *) data->d_buf;
6493
6494 printf (gettext ("\nTable at offset %zu:\n"), start_offset);
6495
6496 if (unlikely (linep + 4 > lineendp))
6497 goto invalid_data;
6498 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
6499 unsigned int length = 4;
6500 if (unlikely (unit_length == 0xffffffff))
6501 {
6502 if (unlikely (linep + 8 > lineendp))
6503 {
6504 invalid_data:
6505 error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
6506 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6507 return;
6508 }
6509 unit_length = read_8ubyte_unaligned_inc (dbg, linep);
6510 length = 8;
6511 }
6512
6513 /* Check whether we have enough room in the section. */
6514 if (unlikely (unit_length > (size_t) (lineendp - linep)
6515 || unit_length < 2 + length + 5 * 1))
6516 goto invalid_data;
6517 lineendp = linep + unit_length;
6518
6519 /* The next element of the header is the version identifier. */
6520 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
6521
6522 /* Next comes the header length. */
6523 Dwarf_Word header_length;
6524 if (length == 4)
6525 header_length = read_4ubyte_unaligned_inc (dbg, linep);
6526 else
6527 header_length = read_8ubyte_unaligned_inc (dbg, linep);
6528 //const unsigned char *header_start = linep;
6529
6530 /* Next the minimum instruction length. */
6531 uint_fast8_t minimum_instr_len = *linep++;
6532
6533 /* Next the maximum operations per instruction, in version 4 format. */
6534 uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
6535
6536 /* Then the flag determining the default value of the is_stmt
6537 register. */
6538 uint_fast8_t default_is_stmt = *linep++;
6539
6540 /* Now the line base. */
6541 int_fast8_t line_base = *((const int_fast8_t *) linep);
6542 ++linep;
6543
6544 /* And the line range. */
6545 uint_fast8_t line_range = *linep++;
6546
6547 /* The opcode base. */
6548 uint_fast8_t opcode_base = *linep++;
6549
6550 /* Print what we got so far. */
6551 printf (gettext ("\n"
6552 " Length: %" PRIu64 "\n"
6553 " DWARF version: %" PRIuFAST16 "\n"
6554 " Prologue length: %" PRIu64 "\n"
6555 " Minimum instruction length: %" PRIuFAST8 "\n"
6556 " Maximum operations per instruction: %" PRIuFAST8 "\n"
6557 " Initial value if '%s': %" PRIuFAST8 "\n"
6558 " Line base: %" PRIdFAST8 "\n"
6559 " Line range: %" PRIuFAST8 "\n"
6560 " Opcode base: %" PRIuFAST8 "\n"
6561 "\n"
6562 "Opcodes:\n"),
6563 (uint64_t) unit_length, version, (uint64_t) header_length,
6564 minimum_instr_len, max_ops_per_instr,
6565 "is_stmt", default_is_stmt, line_base,
6566 line_range, opcode_base);
6567
6568 if (unlikely (linep + opcode_base - 1 >= lineendp))
6569 {
6570 invalid_unit:
6571 error (0, 0,
6572 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
6573 linep - (const unsigned char *) data->d_buf,
6574 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
6575 linep = lineendp;
6576 continue;
6577 }
6578 int opcode_base_l10 = 1;
6579 unsigned int tmp = opcode_base;
6580 while (tmp > 10)
6581 {
6582 tmp /= 10;
6583 ++opcode_base_l10;
6584 }
6585 const uint8_t *standard_opcode_lengths = linep - 1;
6586 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
6587 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n",
6588 " [%*" PRIuFAST8 "] %hhu arguments\n",
6589 (int) linep[cnt - 1]),
6590 opcode_base_l10, cnt, linep[cnt - 1]);
6591 linep += opcode_base - 1;
6592 if (unlikely (linep >= lineendp))
6593 goto invalid_unit;
6594
6595 puts (gettext ("\nDirectory table:"));
6596 while (*linep != 0)
6597 {
6598 unsigned char *endp = memchr (linep, '\0', lineendp - linep);
6599 if (unlikely (endp == NULL))
6600 goto invalid_unit;
6601
6602 printf (" %s\n", (char *) linep);
6603
6604 linep = endp + 1;
6605 }
6606 /* Skip the final NUL byte. */
6607 ++linep;
6608
6609 if (unlikely (linep >= lineendp))
6610 goto invalid_unit;
6611 puts (gettext ("\nFile name table:\n"
6612 " Entry Dir Time Size Name"));
6613 for (unsigned int cnt = 1; *linep != 0; ++cnt)
6614 {
6615 /* First comes the file name. */
6616 char *fname = (char *) linep;
6617 unsigned char *endp = memchr (fname, '\0', lineendp - linep);
6618 if (unlikely (endp == NULL))
6619 goto invalid_unit;
6620 linep = endp + 1;
6621
6622 /* Then the index. */
6623 unsigned int diridx;
6624 if (lineendp - linep < 1)
6625 goto invalid_unit;
6626 get_uleb128 (diridx, linep, lineendp);
6627
6628 /* Next comes the modification time. */
6629 unsigned int mtime;
6630 if (lineendp - linep < 1)
6631 goto invalid_unit;
6632 get_uleb128 (mtime, linep, lineendp);
6633
6634 /* Finally the length of the file. */
6635 unsigned int fsize;
6636 if (lineendp - linep < 1)
6637 goto invalid_unit;
6638 get_uleb128 (fsize, linep, lineendp);
6639
6640 printf (" %-5u %-5u %-9u %-9u %s\n",
6641 cnt, diridx, mtime, fsize, fname);
6642 }
6643 /* Skip the final NUL byte. */
6644 ++linep;
6645
6646 puts (gettext ("\nLine number statements:"));
6647 Dwarf_Word address = 0;
6648 unsigned int op_index = 0;
6649 size_t line = 1;
6650 uint_fast8_t is_stmt = default_is_stmt;
6651
6652 /* Default address value, in case we do not find the CU. */
6653 size_t address_size
6654 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
6655
6656 /* Determine the CU this block is for. */
6657 Dwarf_Off cuoffset;
6658 Dwarf_Off ncuoffset = 0;
6659 size_t hsize;
6660 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
6661 NULL, NULL, NULL) == 0)
6662 {
6663 Dwarf_Die cudie;
6664 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
6665 continue;
6666 Dwarf_Attribute stmt_list;
6667 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
6668 continue;
6669 Dwarf_Word lineoff;
6670 if (dwarf_formudata (&stmt_list, &lineoff) != 0)
6671 continue;
6672 if (lineoff == start_offset)
6673 {
6674 /* Found the CU. */
6675 address_size = cudie.cu->address_size;
6676 break;
6677 }
6678 }
6679
6680 /* Apply the "operation advance" from a special opcode
6681 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */
6682 unsigned int op_addr_advance;
6683 bool show_op_index;
6684 inline void advance_pc (unsigned int op_advance)
6685 {
6686 op_addr_advance = minimum_instr_len * ((op_index + op_advance)
6687 / max_ops_per_instr);
6688 address += op_advance;
6689 show_op_index = (op_index > 0 ||
6690 (op_index + op_advance) % max_ops_per_instr > 0);
6691 op_index = (op_index + op_advance) % max_ops_per_instr;
6692 }
6693
6694 if (max_ops_per_instr == 0)
6695 {
6696 error (0, 0,
6697 gettext ("invalid maximum operations per instruction is zero"));
6698 linep = lineendp;
6699 continue;
6700 }
6701
6702 while (linep < lineendp)
6703 {
6704 size_t offset = linep - (const unsigned char *) data->d_buf;
6705 unsigned int u128;
6706 int s128;
6707
6708 /* Read the opcode. */
6709 unsigned int opcode = *linep++;
6710
6711 printf (" [%6" PRIx64 "]", (uint64_t)offset);
6712 /* Is this a special opcode? */
6713 if (likely (opcode >= opcode_base))
6714 {
6715 if (unlikely (line_range == 0))
6716 goto invalid_unit;
6717
6718 /* Yes. Handling this is quite easy since the opcode value
6719 is computed with
6720
6721 opcode = (desired line increment - line_base)
6722 + (line_range * address advance) + opcode_base
6723 */
6724 int line_increment = (line_base
6725 + (opcode - opcode_base) % line_range);
6726
6727 /* Perform the increments. */
6728 line += line_increment;
6729 advance_pc ((opcode - opcode_base) / line_range);
6730
6731 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6732 if (show_op_index)
6733 printf (gettext ("\
6734 special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
6735 opcode, op_addr_advance, a, op_index,
6736 line_increment, line);
6737 else
6738 printf (gettext ("\
6739 special opcode %u: address+%u = %s, line%+d = %zu\n"),
6740 opcode, op_addr_advance, a, line_increment, line);
6741 free (a);
6742 }
6743 else if (opcode == 0)
6744 {
6745 /* This an extended opcode. */
6746 if (unlikely (linep + 2 > lineendp))
6747 goto invalid_unit;
6748
6749 /* The length. */
6750 unsigned int len = *linep++;
6751
6752 if (unlikely (linep + len > lineendp))
6753 goto invalid_unit;
6754
6755 /* The sub-opcode. */
6756 opcode = *linep++;
6757
6758 printf (gettext (" extended opcode %u: "), opcode);
6759
6760 switch (opcode)
6761 {
6762 case DW_LNE_end_sequence:
6763 puts (gettext (" end of sequence"));
6764
6765 /* Reset the registers we care about. */
6766 address = 0;
6767 op_index = 0;
6768 line = 1;
6769 is_stmt = default_is_stmt;
6770 break;
6771
6772 case DW_LNE_set_address:
6773 op_index = 0;
6774 if (unlikely ((size_t) (lineendp - linep) < address_size))
6775 goto invalid_unit;
6776 if (address_size == 4)
6777 address = read_4ubyte_unaligned_inc (dbg, linep);
6778 else
6779 address = read_8ubyte_unaligned_inc (dbg, linep);
6780 {
6781 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6782 printf (gettext (" set address to %s\n"), a);
6783 free (a);
6784 }
6785 break;
6786
6787 case DW_LNE_define_file:
6788 {
6789 char *fname = (char *) linep;
6790 unsigned char *endp = memchr (linep, '\0',
6791 lineendp - linep);
6792 if (unlikely (endp == NULL))
6793 goto invalid_unit;
6794 linep = endp + 1;
6795
6796 unsigned int diridx;
6797 if (lineendp - linep < 1)
6798 goto invalid_unit;
6799 get_uleb128 (diridx, linep, lineendp);
6800 Dwarf_Word mtime;
6801 if (lineendp - linep < 1)
6802 goto invalid_unit;
6803 get_uleb128 (mtime, linep, lineendp);
6804 Dwarf_Word filelength;
6805 if (lineendp - linep < 1)
6806 goto invalid_unit;
6807 get_uleb128 (filelength, linep, lineendp);
6808
6809 printf (gettext ("\
6810 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
6811 diridx, (uint64_t) mtime, (uint64_t) filelength,
6812 fname);
6813 }
6814 break;
6815
6816 case DW_LNE_set_discriminator:
6817 /* Takes one ULEB128 parameter, the discriminator. */
6818 if (unlikely (standard_opcode_lengths[opcode] != 1))
6819 goto invalid_unit;
6820
6821 get_uleb128 (u128, linep, lineendp);
6822 printf (gettext (" set discriminator to %u\n"), u128);
6823 break;
6824
6825 default:
6826 /* Unknown, ignore it. */
6827 puts (gettext (" unknown opcode"));
6828 linep += len - 1;
6829 break;
6830 }
6831 }
6832 else if (opcode <= DW_LNS_set_isa)
6833 {
6834 /* This is a known standard opcode. */
6835 switch (opcode)
6836 {
6837 case DW_LNS_copy:
6838 /* Takes no argument. */
6839 puts (gettext (" copy"));
6840 break;
6841
6842 case DW_LNS_advance_pc:
6843 /* Takes one uleb128 parameter which is added to the
6844 address. */
6845 get_uleb128 (u128, linep, lineendp);
6846 advance_pc (u128);
6847 {
6848 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6849 if (show_op_index)
6850 printf (gettext ("\
6851 advance address by %u to %s, op_index to %u\n"),
6852 op_addr_advance, a, op_index);
6853 else
6854 printf (gettext (" advance address by %u to %s\n"),
6855 op_addr_advance, a);
6856 free (a);
6857 }
6858 break;
6859
6860 case DW_LNS_advance_line:
6861 /* Takes one sleb128 parameter which is added to the
6862 line. */
6863 get_sleb128 (s128, linep, lineendp);
6864 line += s128;
6865 printf (gettext ("\
6866 advance line by constant %d to %" PRId64 "\n"),
6867 s128, (int64_t) line);
6868 break;
6869
6870 case DW_LNS_set_file:
6871 /* Takes one uleb128 parameter which is stored in file. */
6872 get_uleb128 (u128, linep, lineendp);
6873 printf (gettext (" set file to %" PRIu64 "\n"),
6874 (uint64_t) u128);
6875 break;
6876
6877 case DW_LNS_set_column:
6878 /* Takes one uleb128 parameter which is stored in column. */
6879 if (unlikely (standard_opcode_lengths[opcode] != 1))
6880 goto invalid_unit;
6881
6882 get_uleb128 (u128, linep, lineendp);
6883 printf (gettext (" set column to %" PRIu64 "\n"),
6884 (uint64_t) u128);
6885 break;
6886
6887 case DW_LNS_negate_stmt:
6888 /* Takes no argument. */
6889 is_stmt = 1 - is_stmt;
6890 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
6891 "is_stmt", is_stmt);
6892 break;
6893
6894 case DW_LNS_set_basic_block:
6895 /* Takes no argument. */
6896 puts (gettext (" set basic block flag"));
6897 break;
6898
6899 case DW_LNS_const_add_pc:
6900 /* Takes no argument. */
6901
6902 if (unlikely (line_range == 0))
6903 goto invalid_unit;
6904
6905 advance_pc ((255 - opcode_base) / line_range);
6906 {
6907 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6908 if (show_op_index)
6909 printf (gettext ("\
6910 advance address by constant %u to %s, op_index to %u\n"),
6911 op_addr_advance, a, op_index);
6912 else
6913 printf (gettext ("\
6914 advance address by constant %u to %s\n"),
6915 op_addr_advance, a);
6916 free (a);
6917 }
6918 break;
6919
6920 case DW_LNS_fixed_advance_pc:
6921 /* Takes one 16 bit parameter which is added to the
6922 address. */
6923 if (unlikely (standard_opcode_lengths[opcode] != 1))
6924 goto invalid_unit;
6925
6926 u128 = read_2ubyte_unaligned_inc (dbg, linep);
6927 address += u128;
6928 op_index = 0;
6929 {
6930 char *a = format_dwarf_addr (dwflmod, 0, address, address);
6931 printf (gettext ("\
6932 advance address by fixed value %u to %s\n"),
6933 u128, a);
6934 free (a);
6935 }
6936 break;
6937
6938 case DW_LNS_set_prologue_end:
6939 /* Takes no argument. */
6940 puts (gettext (" set prologue end flag"));
6941 break;
6942
6943 case DW_LNS_set_epilogue_begin:
6944 /* Takes no argument. */
6945 puts (gettext (" set epilogue begin flag"));
6946 break;
6947
6948 case DW_LNS_set_isa:
6949 /* Takes one uleb128 parameter which is stored in isa. */
6950 if (unlikely (standard_opcode_lengths[opcode] != 1))
6951 goto invalid_unit;
6952
6953 get_uleb128 (u128, linep, lineendp);
6954 printf (gettext (" set isa to %u\n"), u128);
6955 break;
6956 }
6957 }
6958 else
6959 {
6960 /* This is a new opcode the generator but not we know about.
6961 Read the parameters associated with it but then discard
6962 everything. Read all the parameters for this opcode. */
6963 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
6964 " unknown opcode with %" PRIu8 " parameters:",
6965 standard_opcode_lengths[opcode]),
6966 standard_opcode_lengths[opcode]);
6967 for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
6968 {
6969 get_uleb128 (u128, linep, lineendp);
6970 if (n != standard_opcode_lengths[opcode])
6971 putc_unlocked (',', stdout);
6972 printf (" %u", u128);
6973 }
6974
6975 /* Next round, ignore this opcode. */
6976 continue;
6977 }
6978 }
6979 }
6980
6981 /* There must only be one data block. */
6982 assert (elf_getdata (scn, data) == NULL);
6983 }
6984
6985
6986 static void
print_debug_loc_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)6987 print_debug_loc_section (Dwfl_Module *dwflmod,
6988 Ebl *ebl, GElf_Ehdr *ehdr,
6989 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
6990 {
6991 Elf_Data *data = dbg->sectiondata[IDX_debug_loc];
6992
6993 if (unlikely (data == NULL))
6994 {
6995 error (0, 0, gettext ("cannot get .debug_loc content: %s"),
6996 elf_errmsg (-1));
6997 return;
6998 }
6999
7000 printf (gettext ("\
7001 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7002 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7003 (uint64_t) shdr->sh_offset);
7004
7005 sort_listptr (&known_loclistptr, "loclistptr");
7006 size_t listptr_idx = 0;
7007
7008 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
7009 uint_fast8_t offset_size = 4;
7010
7011 bool first = true;
7012 struct Dwarf_CU *cu = NULL;
7013 Dwarf_Addr base = 0;
7014 unsigned char *readp = data->d_buf;
7015 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
7016 while (readp < endp)
7017 {
7018 ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
7019
7020 if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
7021 &address_size, &offset_size, &base,
7022 &cu, offset, &readp, endp))
7023 continue;
7024
7025 if (unlikely (data->d_size - offset < (size_t) address_size * 2))
7026 {
7027 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
7028 break;
7029 }
7030
7031 Dwarf_Addr begin;
7032 Dwarf_Addr end;
7033 if (address_size == 8)
7034 {
7035 begin = read_8ubyte_unaligned_inc (dbg, readp);
7036 end = read_8ubyte_unaligned_inc (dbg, readp);
7037 }
7038 else
7039 {
7040 begin = read_4ubyte_unaligned_inc (dbg, readp);
7041 end = read_4ubyte_unaligned_inc (dbg, readp);
7042 if (begin == (Dwarf_Addr) (uint32_t) -1)
7043 begin = (Dwarf_Addr) -1l;
7044 }
7045
7046 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
7047 {
7048 char *b = format_dwarf_addr (dwflmod, address_size, end, end);
7049 printf (gettext (" [%6tx] base address %s\n"), offset, b);
7050 free (b);
7051 base = end;
7052 }
7053 else if (begin == 0 && end == 0) /* End of list entry. */
7054 {
7055 if (first)
7056 printf (gettext (" [%6tx] empty list\n"), offset);
7057 first = true;
7058 }
7059 else
7060 {
7061 /* We have a location expression entry. */
7062 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
7063
7064 char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
7065 begin);
7066 char *e = format_dwarf_addr (dwflmod, address_size, base + end,
7067 end);
7068
7069 if (first) /* First entry in a list. */
7070 printf (gettext (" [%6tx] %s..%s"), offset, b, e);
7071 else
7072 printf (gettext (" %s..%s"), b, e);
7073
7074 free (b);
7075 free (e);
7076
7077 if (endp - readp <= (ptrdiff_t) len)
7078 {
7079 fputs (gettext (" <INVALID DATA>\n"), stdout);
7080 break;
7081 }
7082
7083 print_ops (dwflmod, dbg, 1, 18 + (address_size * 4),
7084 3 /*XXX*/, address_size, offset_size, cu, len, readp);
7085
7086 first = false;
7087 readp += len;
7088 }
7089 }
7090 }
7091
7092 struct mac_culist
7093 {
7094 Dwarf_Die die;
7095 Dwarf_Off offset;
7096 Dwarf_Files *files;
7097 struct mac_culist *next;
7098 };
7099
7100
7101 static int
mac_compare(const void * p1,const void * p2)7102 mac_compare (const void *p1, const void *p2)
7103 {
7104 struct mac_culist *m1 = (struct mac_culist *) p1;
7105 struct mac_culist *m2 = (struct mac_culist *) p2;
7106
7107 if (m1->offset < m2->offset)
7108 return -1;
7109 if (m1->offset > m2->offset)
7110 return 1;
7111 return 0;
7112 }
7113
7114
7115 static void
print_debug_macinfo_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7116 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7117 Ebl *ebl, GElf_Ehdr *ehdr,
7118 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7119 {
7120 printf (gettext ("\
7121 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7122 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7123 (uint64_t) shdr->sh_offset);
7124 putc_unlocked ('\n', stdout);
7125
7126 /* There is no function in libdw to iterate over the raw content of
7127 the section but it is easy enough to do. */
7128 Elf_Data *data = dbg->sectiondata[IDX_debug_macinfo];
7129 if (unlikely (data == NULL || data->d_buf == NULL))
7130 {
7131 error (0, 0, gettext ("cannot get macro information section data: %s"),
7132 elf_errmsg (-1));
7133 return;
7134 }
7135
7136 /* Get the source file information for all CUs. */
7137 Dwarf_Off offset;
7138 Dwarf_Off ncu = 0;
7139 size_t hsize;
7140 struct mac_culist *culist = NULL;
7141 size_t nculist = 0;
7142 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
7143 {
7144 Dwarf_Die cudie;
7145 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7146 continue;
7147
7148 Dwarf_Attribute attr;
7149 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
7150 continue;
7151
7152 Dwarf_Word macoff;
7153 if (dwarf_formudata (&attr, &macoff) != 0)
7154 continue;
7155
7156 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7157 newp->die = cudie;
7158 newp->offset = macoff;
7159 newp->files = NULL;
7160 newp->next = culist;
7161 culist = newp;
7162 ++nculist;
7163 }
7164
7165 /* Convert the list into an array for easier consumption. */
7166 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
7167 * sizeof (*cus));
7168 /* Add sentinel. */
7169 cus[nculist].offset = data->d_size;
7170 cus[nculist].files = (Dwarf_Files *) -1l;
7171 if (nculist > 0)
7172 {
7173 for (size_t cnt = nculist - 1; culist != NULL; --cnt)
7174 {
7175 assert (cnt < nculist);
7176 cus[cnt] = *culist;
7177 culist = culist->next;
7178 }
7179
7180 /* Sort the array according to the offset in the .debug_macinfo
7181 section. Note we keep the sentinel at the end. */
7182 qsort (cus, nculist, sizeof (*cus), mac_compare);
7183 }
7184
7185 const unsigned char *readp = (const unsigned char *) data->d_buf;
7186 const unsigned char *readendp = readp + data->d_size;
7187 int level = 1;
7188
7189 while (readp < readendp)
7190 {
7191 unsigned int opcode = *readp++;
7192 unsigned int u128;
7193 unsigned int u128_2;
7194 const unsigned char *endp;
7195
7196 switch (opcode)
7197 {
7198 case DW_MACINFO_define:
7199 case DW_MACINFO_undef:
7200 case DW_MACINFO_vendor_ext:
7201 /* For the first two opcodes the parameters are
7202 line, string
7203 For the latter
7204 number, string.
7205 We can treat these cases together. */
7206 get_uleb128 (u128, readp, readendp);
7207
7208 endp = memchr (readp, '\0', readendp - readp);
7209 if (unlikely (endp == NULL))
7210 {
7211 printf (gettext ("\
7212 %*s*** non-terminated string at end of section"),
7213 level, "");
7214 return;
7215 }
7216
7217 if (opcode == DW_MACINFO_define)
7218 printf ("%*s#define %s, line %u\n",
7219 level, "", (char *) readp, u128);
7220 else if (opcode == DW_MACINFO_undef)
7221 printf ("%*s#undef %s, line %u\n",
7222 level, "", (char *) readp, u128);
7223 else
7224 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
7225
7226 readp = endp + 1;
7227 break;
7228
7229 case DW_MACINFO_start_file:
7230 /* The two parameters are line and file index, in this order. */
7231 get_uleb128 (u128, readp, readendp);
7232 if (readendp - readp < 1)
7233 {
7234 printf (gettext ("\
7235 %*s*** missing DW_MACINFO_start_file argument at end of section"),
7236 level, "");
7237 return;
7238 }
7239 get_uleb128 (u128_2, readp, readendp);
7240
7241 /* Find the CU DIE for this file. */
7242 size_t macoff = readp - (const unsigned char *) data->d_buf;
7243 const char *fname = "???";
7244 if (macoff >= cus[0].offset)
7245 {
7246 while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
7247 ++cus;
7248
7249 if (cus[0].files == NULL
7250 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
7251 cus[0].files = (Dwarf_Files *) -1l;
7252
7253 if (cus[0].files != (Dwarf_Files *) -1l)
7254 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
7255 ?: "???");
7256 }
7257
7258 printf ("%*sstart_file %u, [%u] %s\n",
7259 level, "", u128, u128_2, fname);
7260 ++level;
7261 break;
7262
7263 case DW_MACINFO_end_file:
7264 --level;
7265 printf ("%*send_file\n", level, "");
7266 /* Nothing more to do. */
7267 break;
7268
7269 default:
7270 // XXX gcc seems to generate files with a trailing zero.
7271 if (unlikely (opcode != 0 || readp != readendp))
7272 printf ("%*s*** invalid opcode %u\n", level, "", opcode);
7273 break;
7274 }
7275 }
7276 }
7277
7278
7279 static void
print_debug_macro_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7280 print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7281 Ebl *ebl, GElf_Ehdr *ehdr,
7282 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7283 {
7284 printf (gettext ("\
7285 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7286 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7287 (uint64_t) shdr->sh_offset);
7288 putc_unlocked ('\n', stdout);
7289
7290 Elf_Data *data = dbg->sectiondata[IDX_debug_macro];
7291 if (unlikely (data == NULL || data->d_buf == NULL))
7292 {
7293 error (0, 0, gettext ("cannot get macro information section data: %s"),
7294 elf_errmsg (-1));
7295 return;
7296 }
7297
7298 /* Get the source file information for all CUs. Uses same
7299 datastructure as macinfo. But uses offset field to directly
7300 match .debug_line offset. And just stored in a list. */
7301 Dwarf_Off offset;
7302 Dwarf_Off ncu = 0;
7303 size_t hsize;
7304 struct mac_culist *culist = NULL;
7305 size_t nculist = 0;
7306 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
7307 {
7308 Dwarf_Die cudie;
7309 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
7310 continue;
7311
7312 Dwarf_Attribute attr;
7313 if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
7314 continue;
7315
7316 Dwarf_Word lineoff;
7317 if (dwarf_formudata (&attr, &lineoff) != 0)
7318 continue;
7319
7320 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
7321 newp->die = cudie;
7322 newp->offset = lineoff;
7323 newp->files = NULL;
7324 newp->next = culist;
7325 culist = newp;
7326 ++nculist;
7327 }
7328
7329 const unsigned char *readp = (const unsigned char *) data->d_buf;
7330 const unsigned char *readendp = readp + data->d_size;
7331
7332 while (readp < readendp)
7333 {
7334 printf (gettext (" Offset: 0x%" PRIx64 "\n"),
7335 (uint64_t) (readp - (const unsigned char *) data->d_buf));
7336
7337 // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
7338 // optional vendor extension macro entry table.
7339 if (readp + 2 > readendp)
7340 {
7341 invalid_data:
7342 error (0, 0, gettext ("invalid data"));
7343 return;
7344 }
7345 const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
7346 printf (gettext (" Version: %" PRIu16 "\n"), vers);
7347
7348 // Version 4 is the GNU extension for DWARF4. DWARF5 will use version
7349 // 5 when it gets standardized.
7350 if (vers != 4)
7351 {
7352 printf (gettext (" unknown version, cannot parse section\n"));
7353 return;
7354 }
7355
7356 if (readp + 1 > readendp)
7357 goto invalid_data;
7358 const unsigned char flag = *readp++;
7359 printf (gettext (" Flag: 0x%" PRIx8 "\n"), flag);
7360
7361 unsigned int offset_len = (flag & 0x01) ? 8 : 4;
7362 printf (gettext (" Offset length: %" PRIu8 "\n"), offset_len);
7363 Dwarf_Off line_offset = -1;
7364 if (flag & 0x02)
7365 {
7366 if (offset_len == 8)
7367 line_offset = read_8ubyte_unaligned_inc (dbg, readp);
7368 else
7369 line_offset = read_4ubyte_unaligned_inc (dbg, readp);
7370 printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
7371 line_offset);
7372 }
7373
7374 const unsigned char *vendor[DW_MACRO_GNU_hi_user - DW_MACRO_GNU_lo_user];
7375 memset (vendor, 0, sizeof vendor);
7376 if (flag & 0x04)
7377 {
7378 // 1 byte length, for each item, 1 byte opcode, uleb128 number
7379 // of arguments, for each argument 1 byte form code.
7380 if (readp + 1 > readendp)
7381 goto invalid_data;
7382 unsigned int tlen = *readp++;
7383 printf (gettext (" extension opcode table, %" PRIu8 " items:\n"),
7384 tlen);
7385 for (unsigned int i = 0; i < tlen; i++)
7386 {
7387 if (readp + 1 > readendp)
7388 goto invalid_data;
7389 unsigned int opcode = *readp++;
7390 printf (gettext (" [%" PRIx8 "]"), opcode);
7391 if (opcode < DW_MACRO_GNU_lo_user
7392 || opcode > DW_MACRO_GNU_hi_user)
7393 goto invalid_data;
7394 // Record the start of description for this vendor opcode.
7395 // uleb128 nr args, 1 byte per arg form.
7396 vendor[opcode - DW_MACRO_GNU_lo_user] = readp;
7397 if (readp + 1 > readendp)
7398 goto invalid_data;
7399 unsigned int args = *readp++;
7400 if (args > 0)
7401 {
7402 printf (gettext (" %" PRIu8 " arguments:"), args);
7403 while (args > 0)
7404 {
7405 if (readp + 1 > readendp)
7406 goto invalid_data;
7407 unsigned int form = *readp++;
7408 printf (" %s", dwarf_form_string (form));
7409 if (form != DW_FORM_data1
7410 && form != DW_FORM_data2
7411 && form != DW_FORM_data4
7412 && form != DW_FORM_data8
7413 && form != DW_FORM_sdata
7414 && form != DW_FORM_udata
7415 && form != DW_FORM_block
7416 && form != DW_FORM_block1
7417 && form != DW_FORM_block2
7418 && form != DW_FORM_block4
7419 && form != DW_FORM_flag
7420 && form != DW_FORM_string
7421 && form != DW_FORM_strp
7422 && form != DW_FORM_sec_offset)
7423 goto invalid_data;
7424 args--;
7425 if (args > 0)
7426 putchar_unlocked (',');
7427 }
7428 }
7429 else
7430 printf (gettext (" no arguments."));
7431 putchar_unlocked ('\n');
7432 }
7433 }
7434 putchar_unlocked ('\n');
7435
7436 int level = 1;
7437 if (readp + 1 > readendp)
7438 goto invalid_data;
7439 unsigned int opcode = *readp++;
7440 while (opcode != 0)
7441 {
7442 unsigned int u128;
7443 unsigned int u128_2;
7444 const unsigned char *endp;
7445 uint64_t off;
7446
7447 switch (opcode)
7448 {
7449 case DW_MACRO_GNU_start_file:
7450 get_uleb128 (u128, readp, readendp);
7451 if (readp >= readendp)
7452 goto invalid_data;
7453 get_uleb128 (u128_2, readp, readendp);
7454
7455 /* Find the CU DIE that matches this line offset. */
7456 const char *fname = "???";
7457 if (line_offset != (Dwarf_Off) -1)
7458 {
7459 struct mac_culist *cu = culist;
7460 while (cu != NULL && line_offset != cu->offset)
7461 cu = cu->next;
7462 if (cu != NULL)
7463 {
7464 if (cu->files == NULL
7465 && dwarf_getsrcfiles (&cu->die, &cu->files,
7466 NULL) != 0)
7467 cu->files = (Dwarf_Files *) -1l;
7468
7469 if (cu->files != (Dwarf_Files *) -1l)
7470 fname = (dwarf_filesrc (cu->files, u128_2,
7471 NULL, NULL) ?: "???");
7472 }
7473 }
7474 printf ("%*sstart_file %u, [%u] %s\n",
7475 level, "", u128, u128_2, fname);
7476 ++level;
7477 break;
7478
7479 case DW_MACRO_GNU_end_file:
7480 --level;
7481 printf ("%*send_file\n", level, "");
7482 break;
7483
7484 case DW_MACRO_GNU_define:
7485 get_uleb128 (u128, readp, readendp);
7486 endp = memchr (readp, '\0', readendp - readp);
7487 if (endp == NULL)
7488 goto invalid_data;
7489 printf ("%*s#define %s, line %u\n",
7490 level, "", readp, u128);
7491 readp = endp + 1;
7492 break;
7493
7494 case DW_MACRO_GNU_undef:
7495 get_uleb128 (u128, readp, readendp);
7496 endp = memchr (readp, '\0', readendp - readp);
7497 if (endp == NULL)
7498 goto invalid_data;
7499 printf ("%*s#undef %s, line %u\n",
7500 level, "", readp, u128);
7501 readp = endp + 1;
7502 break;
7503
7504 case DW_MACRO_GNU_define_indirect:
7505 get_uleb128 (u128, readp, readendp);
7506 if (readp + offset_len > readendp)
7507 goto invalid_data;
7508 if (offset_len == 8)
7509 off = read_8ubyte_unaligned_inc (dbg, readp);
7510 else
7511 off = read_4ubyte_unaligned_inc (dbg, readp);
7512 printf ("%*s#define %s, line %u (indirect)\n",
7513 level, "", dwarf_getstring (dbg, off, NULL), u128);
7514 break;
7515
7516 case DW_MACRO_GNU_undef_indirect:
7517 get_uleb128 (u128, readp, readendp);
7518 if (readp + offset_len > readendp)
7519 goto invalid_data;
7520 if (offset_len == 8)
7521 off = read_8ubyte_unaligned_inc (dbg, readp);
7522 else
7523 off = read_4ubyte_unaligned_inc (dbg, readp);
7524 printf ("%*s#undef %s, line %u (indirect)\n",
7525 level, "", dwarf_getstring (dbg, off, NULL), u128);
7526 break;
7527
7528 case DW_MACRO_GNU_transparent_include:
7529 if (readp + offset_len > readendp)
7530 goto invalid_data;
7531 if (offset_len == 8)
7532 off = read_8ubyte_unaligned_inc (dbg, readp);
7533 else
7534 off = read_4ubyte_unaligned_inc (dbg, readp);
7535 printf ("%*s#include offset 0x%" PRIx64 "\n",
7536 level, "", off);
7537 break;
7538
7539 default:
7540 printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
7541 if (opcode < DW_MACRO_GNU_lo_user
7542 || opcode > DW_MACRO_GNU_lo_user
7543 || vendor[opcode - DW_MACRO_GNU_lo_user] == NULL)
7544 goto invalid_data;
7545
7546 const unsigned char *op_desc;
7547 op_desc = vendor[opcode - DW_MACRO_GNU_lo_user];
7548
7549 // Just skip the arguments, we cannot really interpret them,
7550 // but print as much as we can.
7551 unsigned int args = *op_desc++;
7552 while (args > 0)
7553 {
7554 unsigned int form = *op_desc++;
7555 Dwarf_Word val;
7556 switch (form)
7557 {
7558 case DW_FORM_data1:
7559 if (readp + 1 > readendp)
7560 goto invalid_data;
7561 val = *readp++;
7562 printf (" %" PRIx8, (unsigned int) val);
7563 break;
7564
7565 case DW_FORM_data2:
7566 if (readp + 2 > readendp)
7567 goto invalid_data;
7568 val = read_2ubyte_unaligned_inc (dbg, readp);
7569 printf(" %" PRIx16, (unsigned int) val);
7570 break;
7571
7572 case DW_FORM_data4:
7573 if (readp + 4 > readendp)
7574 goto invalid_data;
7575 val = read_4ubyte_unaligned_inc (dbg, readp);
7576 printf (" %" PRIx32, (unsigned int) val);
7577 break;
7578
7579 case DW_FORM_data8:
7580 if (readp + 8 > readendp)
7581 goto invalid_data;
7582 val = read_8ubyte_unaligned_inc (dbg, readp);
7583 printf (" %" PRIx64, val);
7584 break;
7585
7586 case DW_FORM_sdata:
7587 get_sleb128 (val, readp, readendp);
7588 printf (" %" PRIx64, val);
7589 break;
7590
7591 case DW_FORM_udata:
7592 get_uleb128 (val, readp, readendp);
7593 printf (" %" PRIx64, val);
7594 break;
7595
7596 case DW_FORM_block:
7597 get_uleb128 (val, readp, readendp);
7598 printf (" block[%" PRIu64 "]", val);
7599 if (readp + val > readendp)
7600 goto invalid_data;
7601 readp += val;
7602 break;
7603
7604 case DW_FORM_block1:
7605 if (readp + 1 > readendp)
7606 goto invalid_data;
7607 val = *readp++;
7608 printf (" block[%" PRIu64 "]", val);
7609 if (readp + val > readendp)
7610 goto invalid_data;
7611 break;
7612
7613 case DW_FORM_block2:
7614 if (readp + 2 > readendp)
7615 goto invalid_data;
7616 val = read_2ubyte_unaligned_inc (dbg, readp);
7617 printf (" block[%" PRIu64 "]", val);
7618 if (readp + val > readendp)
7619 goto invalid_data;
7620 break;
7621
7622 case DW_FORM_block4:
7623 if (readp + 2 > readendp)
7624 goto invalid_data;
7625 val =read_4ubyte_unaligned_inc (dbg, readp);
7626 printf (" block[%" PRIu64 "]", val);
7627 if (readp + val > readendp)
7628 goto invalid_data;
7629 break;
7630
7631 case DW_FORM_flag:
7632 if (readp + 1 > readendp)
7633 goto invalid_data;
7634 val = *readp++;
7635 printf (" %s", nl_langinfo (val != 0 ? YESSTR : NOSTR));
7636 break;
7637
7638 case DW_FORM_string:
7639 endp = memchr (readp, '\0', readendp - readp);
7640 if (endp == NULL)
7641 goto invalid_data;
7642 printf (" %s", readp);
7643 readp = endp + 1;
7644 break;
7645
7646 case DW_FORM_strp:
7647 if (readp + offset_len > readendp)
7648 goto invalid_data;
7649 if (offset_len == 8)
7650 val = read_8ubyte_unaligned_inc (dbg, readp);
7651 else
7652 val = read_4ubyte_unaligned_inc (dbg, readp);
7653 printf (" %s", dwarf_getstring (dbg, val, NULL));
7654 break;
7655
7656 case DW_FORM_sec_offset:
7657 if (readp + offset_len > readendp)
7658 goto invalid_data;
7659 if (offset_len == 8)
7660 val = read_8ubyte_unaligned_inc (dbg, readp);
7661 else
7662 val = read_4ubyte_unaligned_inc (dbg, readp);
7663 printf (" %" PRIx64, val);
7664 break;
7665
7666 default:
7667 error (0, 0, gettext ("vendor opcode not verified?"));
7668 return;
7669 }
7670
7671 args--;
7672 if (args > 0)
7673 putchar_unlocked (',');
7674 }
7675 putchar_unlocked ('\n');
7676 }
7677
7678 if (readp + 1 > readendp)
7679 goto invalid_data;
7680 opcode = *readp++;
7681 if (opcode == 0)
7682 putchar_unlocked ('\n');
7683 }
7684 }
7685 }
7686
7687
7688 /* Callback for printing global names. */
7689 static int
print_pubnames(Dwarf * dbg,Dwarf_Global * global,void * arg)7690 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
7691 void *arg)
7692 {
7693 int *np = (int *) arg;
7694
7695 printf (gettext (" [%5d] DIE offset: %6" PRId64
7696 ", CU DIE offset: %6" PRId64 ", name: %s\n"),
7697 (*np)++, global->die_offset, global->cu_offset, global->name);
7698
7699 return 0;
7700 }
7701
7702
7703 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */
7704 static void
print_debug_pubnames_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7705 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7706 Ebl *ebl, GElf_Ehdr *ehdr,
7707 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7708 {
7709 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
7710 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
7711 (uint64_t) shdr->sh_offset);
7712
7713 int n = 0;
7714 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
7715 }
7716
7717 /* Print the content of the DWARF string section '.debug_str'. */
7718 static void
print_debug_str_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7719 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7720 Ebl *ebl, GElf_Ehdr *ehdr,
7721 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7722 {
7723 const size_t sh_size = (dbg->sectiondata[IDX_debug_str] ?
7724 dbg->sectiondata[IDX_debug_str]->d_size : 0);
7725
7726 /* Compute floor(log16(shdr->sh_size)). */
7727 GElf_Addr tmp = sh_size;
7728 int digits = 1;
7729 while (tmp >= 16)
7730 {
7731 ++digits;
7732 tmp >>= 4;
7733 }
7734 digits = MAX (4, digits);
7735
7736 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
7737 " %*s String\n"),
7738 elf_ndxscn (scn),
7739 section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
7740 /* TRANS: the debugstr| prefix makes the string unique. */
7741 digits + 2, sgettext ("debugstr|Offset"));
7742
7743 Dwarf_Off offset = 0;
7744 while (offset < sh_size)
7745 {
7746 size_t len;
7747 const char *str = dwarf_getstring (dbg, offset, &len);
7748 if (unlikely (str == NULL))
7749 {
7750 printf (gettext (" *** error while reading strings: %s\n"),
7751 dwarf_errmsg (-1));
7752 break;
7753 }
7754
7755 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str);
7756
7757 offset += len + 1;
7758 }
7759 }
7760
7761
7762 /* Print the content of the call frame search table section
7763 '.eh_frame_hdr'. */
7764 static void
print_debug_frame_hdr_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7765 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
7766 Ebl *ebl __attribute__ ((unused)),
7767 GElf_Ehdr *ehdr __attribute__ ((unused)),
7768 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
7769 {
7770 printf (gettext ("\
7771 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
7772 elf_ndxscn (scn));
7773
7774 Elf_Data *data = elf_rawdata (scn, NULL);
7775
7776 if (unlikely (data == NULL))
7777 {
7778 error (0, 0, gettext ("cannot get %s content: %s"),
7779 ".eh_frame_hdr", elf_errmsg (-1));
7780 return;
7781 }
7782
7783 const unsigned char *readp = data->d_buf;
7784 const unsigned char *const dataend = ((unsigned char *) data->d_buf
7785 + data->d_size);
7786
7787 if (unlikely (readp + 4 > dataend))
7788 {
7789 invalid_data:
7790 error (0, 0, gettext ("invalid data"));
7791 return;
7792 }
7793
7794 unsigned int version = *readp++;
7795 unsigned int eh_frame_ptr_enc = *readp++;
7796 unsigned int fde_count_enc = *readp++;
7797 unsigned int table_enc = *readp++;
7798
7799 printf (" version: %u\n"
7800 " eh_frame_ptr_enc: %#x ",
7801 version, eh_frame_ptr_enc);
7802 print_encoding_base ("", eh_frame_ptr_enc);
7803 printf (" fde_count_enc: %#x ", fde_count_enc);
7804 print_encoding_base ("", fde_count_enc);
7805 printf (" table_enc: %#x ", table_enc);
7806 print_encoding_base ("", table_enc);
7807
7808 uint64_t eh_frame_ptr = 0;
7809 if (eh_frame_ptr_enc != DW_EH_PE_omit)
7810 {
7811 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
7812 dbg);
7813 if (unlikely (readp == NULL))
7814 goto invalid_data;
7815
7816 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr);
7817 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
7818 printf (" (offset: %#" PRIx64 ")",
7819 /* +4 because of the 4 byte header of the section. */
7820 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
7821
7822 putchar_unlocked ('\n');
7823 }
7824
7825 uint64_t fde_count = 0;
7826 if (fde_count_enc != DW_EH_PE_omit)
7827 {
7828 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
7829 if (unlikely (readp == NULL))
7830 goto invalid_data;
7831
7832 printf (" fde_count: %" PRIu64 "\n", fde_count);
7833 }
7834
7835 if (fde_count == 0 || table_enc == DW_EH_PE_omit)
7836 return;
7837
7838 puts (" Table:");
7839
7840 /* Optimize for the most common case. */
7841 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
7842 while (fde_count > 0 && readp + 8 <= dataend)
7843 {
7844 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
7845 uint64_t initial_offset = ((uint64_t) shdr->sh_offset
7846 + (int64_t) initial_location);
7847 int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
7848 // XXX Possibly print symbol name or section offset for initial_offset
7849 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
7850 " fde=[%6" PRIx64 "]\n",
7851 initial_location, initial_offset,
7852 address, address - (eh_frame_ptr + 4));
7853 }
7854 else
7855 while (0 && readp < dataend)
7856 {
7857
7858 }
7859 }
7860
7861
7862 /* Print the content of the exception handling table section
7863 '.eh_frame_hdr'. */
7864 static void
print_debug_exception_table(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)7865 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
7866 Ebl *ebl __attribute__ ((unused)),
7867 GElf_Ehdr *ehdr __attribute__ ((unused)),
7868 Elf_Scn *scn,
7869 GElf_Shdr *shdr __attribute__ ((unused)),
7870 Dwarf *dbg __attribute__ ((unused)))
7871 {
7872 printf (gettext ("\
7873 \nException handling table section [%2zu] '.gcc_except_table':\n"),
7874 elf_ndxscn (scn));
7875
7876 Elf_Data *data = elf_rawdata (scn, NULL);
7877
7878 if (unlikely (data == NULL))
7879 {
7880 error (0, 0, gettext ("cannot get %s content: %s"),
7881 ".gcc_except_table", elf_errmsg (-1));
7882 return;
7883 }
7884
7885 const unsigned char *readp = data->d_buf;
7886 const unsigned char *const dataend = readp + data->d_size;
7887
7888 if (unlikely (readp + 1 > dataend))
7889 {
7890 invalid_data:
7891 error (0, 0, gettext ("invalid data"));
7892 return;
7893 }
7894 unsigned int lpstart_encoding = *readp++;
7895 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding);
7896 print_encoding_base ("", lpstart_encoding);
7897 if (lpstart_encoding != DW_EH_PE_omit)
7898 {
7899 uint64_t lpstart;
7900 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
7901 printf (" LPStart: %#" PRIx64 "\n", lpstart);
7902 }
7903
7904 if (unlikely (readp + 1 > dataend))
7905 goto invalid_data;
7906 unsigned int ttype_encoding = *readp++;
7907 printf (gettext (" TType encoding: %#x "), ttype_encoding);
7908 print_encoding_base ("", ttype_encoding);
7909 const unsigned char *ttype_base = NULL;
7910 if (ttype_encoding != DW_EH_PE_omit)
7911 {
7912 unsigned int ttype_base_offset;
7913 get_uleb128 (ttype_base_offset, readp, dataend);
7914 printf (" TType base offset: %#x\n", ttype_base_offset);
7915 if ((size_t) (dataend - readp) > ttype_base_offset)
7916 ttype_base = readp + ttype_base_offset;
7917 }
7918
7919 if (unlikely (readp + 1 > dataend))
7920 goto invalid_data;
7921 unsigned int call_site_encoding = *readp++;
7922 printf (gettext (" Call site encoding: %#x "), call_site_encoding);
7923 print_encoding_base ("", call_site_encoding);
7924 unsigned int call_site_table_len;
7925 get_uleb128 (call_site_table_len, readp, dataend);
7926
7927 const unsigned char *const action_table = readp + call_site_table_len;
7928 if (unlikely (action_table > dataend))
7929 goto invalid_data;
7930 unsigned int u = 0;
7931 unsigned int max_action = 0;
7932 while (readp < action_table)
7933 {
7934 if (u == 0)
7935 puts (gettext ("\n Call site table:"));
7936
7937 uint64_t call_site_start;
7938 readp = read_encoded (call_site_encoding, readp, dataend,
7939 &call_site_start, dbg);
7940 uint64_t call_site_length;
7941 readp = read_encoded (call_site_encoding, readp, dataend,
7942 &call_site_length, dbg);
7943 uint64_t landing_pad;
7944 readp = read_encoded (call_site_encoding, readp, dataend,
7945 &landing_pad, dbg);
7946 unsigned int action;
7947 get_uleb128 (action, readp, dataend);
7948 max_action = MAX (action, max_action);
7949 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n"
7950 " Call site length: %" PRIu64 "\n"
7951 " Landing pad: %#" PRIx64 "\n"
7952 " Action: %u\n"),
7953 u++, call_site_start, call_site_length, landing_pad, action);
7954 }
7955 if (readp != action_table)
7956 goto invalid_data;
7957
7958 unsigned int max_ar_filter = 0;
7959 if (max_action > 0)
7960 {
7961 puts ("\n Action table:");
7962
7963 size_t maxdata = (size_t) (dataend - action_table);
7964 if (max_action > maxdata || maxdata - max_action < 1)
7965 {
7966 invalid_action_table:
7967 fputs (gettext (" <INVALID DATA>\n"), stdout);
7968 return;
7969 }
7970
7971 const unsigned char *const action_table_end
7972 = action_table + max_action + 1;
7973
7974 u = 0;
7975 do
7976 {
7977 int ar_filter;
7978 get_sleb128 (ar_filter, readp, action_table_end);
7979 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
7980 max_ar_filter = ar_filter;
7981 int ar_disp;
7982 if (readp >= action_table_end)
7983 goto invalid_action_table;
7984 get_sleb128 (ar_disp, readp, action_table_end);
7985
7986 printf (" [%4u] ar_filter: % d\n"
7987 " ar_disp: % -5d",
7988 u, ar_filter, ar_disp);
7989 if (abs (ar_disp) & 1)
7990 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
7991 else if (ar_disp != 0)
7992 puts (" -> ???");
7993 else
7994 putchar_unlocked ('\n');
7995 ++u;
7996 }
7997 while (readp < action_table_end);
7998 }
7999
8000 if (max_ar_filter > 0 && ttype_base != NULL)
8001 {
8002 unsigned char dsize;
8003 puts ("\n TType table:");
8004
8005 // XXX Not *4, size of encoding;
8006 switch (ttype_encoding & 7)
8007 {
8008 case DW_EH_PE_udata2:
8009 case DW_EH_PE_sdata2:
8010 dsize = 2;
8011 break;
8012 case DW_EH_PE_udata4:
8013 case DW_EH_PE_sdata4:
8014 dsize = 4;
8015 break;
8016 case DW_EH_PE_udata8:
8017 case DW_EH_PE_sdata8:
8018 dsize = 8;
8019 break;
8020 default:
8021 dsize = 0;
8022 error (1, 0, gettext ("invalid TType encoding"));
8023 }
8024
8025 if (max_ar_filter
8026 > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
8027 goto invalid_data;
8028
8029 readp = ttype_base - max_ar_filter * dsize;
8030 do
8031 {
8032 uint64_t ttype;
8033 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
8034 dbg);
8035 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
8036 }
8037 while (readp < ttype_base);
8038 }
8039 }
8040
8041 /* Print the content of the '.gdb_index' section.
8042 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
8043 */
8044 static void
print_gdb_index_section(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr,Elf_Scn * scn,GElf_Shdr * shdr,Dwarf * dbg)8045 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
8046 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
8047 {
8048 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
8049 " contains %" PRId64 " bytes :\n"),
8050 elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
8051 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
8052
8053 Elf_Data *data = elf_rawdata (scn, NULL);
8054
8055 if (unlikely (data == NULL))
8056 {
8057 error (0, 0, gettext ("cannot get %s content: %s"),
8058 ".gdb_index", elf_errmsg (-1));
8059 return;
8060 }
8061
8062 // .gdb_index is always in little endian.
8063 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
8064 dbg = &dummy_dbg;
8065
8066 const unsigned char *readp = data->d_buf;
8067 const unsigned char *const dataend = readp + data->d_size;
8068
8069 if (unlikely (readp + 4 > dataend))
8070 {
8071 invalid_data:
8072 error (0, 0, gettext ("invalid data"));
8073 return;
8074 }
8075
8076 int32_t vers = read_4ubyte_unaligned (dbg, readp);
8077 printf (gettext (" Version: %" PRId32 "\n"), vers);
8078
8079 // The only difference between version 4 and version 5 is the
8080 // hash used for generating the table. Version 6 contains symbols
8081 // for inlined functions, older versions didn't. Version 7 adds
8082 // symbol kinds. Version 8 just indicates that it correctly includes
8083 // TUs for symbols.
8084 if (vers < 4 || vers > 8)
8085 {
8086 printf (gettext (" unknown version, cannot parse section\n"));
8087 return;
8088 }
8089
8090 readp += 4;
8091 if (unlikely (readp + 4 > dataend))
8092 goto invalid_data;
8093
8094 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
8095 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off);
8096
8097 readp += 4;
8098 if (unlikely (readp + 4 > dataend))
8099 goto invalid_data;
8100
8101 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
8102 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off);
8103
8104 readp += 4;
8105 if (unlikely (readp + 4 > dataend))
8106 goto invalid_data;
8107
8108 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
8109 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off);
8110
8111 readp += 4;
8112 if (unlikely (readp + 4 > dataend))
8113 goto invalid_data;
8114
8115 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
8116 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off);
8117
8118 readp += 4;
8119 if (unlikely (readp + 4 > dataend))
8120 goto invalid_data;
8121
8122 uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
8123 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
8124
8125 if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
8126 < const_off))
8127 goto invalid_data;
8128
8129 readp = data->d_buf + cu_off;
8130
8131 const unsigned char *nextp = data->d_buf + tu_off;
8132 if (tu_off >= data->d_size)
8133 goto invalid_data;
8134
8135 size_t cu_nr = (nextp - readp) / 16;
8136
8137 printf (gettext ("\n CU list at offset %#" PRIx32
8138 " contains %zu entries:\n"),
8139 cu_off, cu_nr);
8140
8141 size_t n = 0;
8142 while (dataend - readp >= 16 && n < cu_nr)
8143 {
8144 uint64_t off = read_8ubyte_unaligned (dbg, readp);
8145 readp += 8;
8146
8147 uint64_t len = read_8ubyte_unaligned (dbg, readp);
8148 readp += 8;
8149
8150 printf (" [%4zu] start: %0#8" PRIx64
8151 ", length: %5" PRIu64 "\n", n, off, len);
8152 n++;
8153 }
8154
8155 readp = data->d_buf + tu_off;
8156 nextp = data->d_buf + addr_off;
8157 if (addr_off >= data->d_size)
8158 goto invalid_data;
8159
8160 size_t tu_nr = (nextp - readp) / 24;
8161
8162 printf (gettext ("\n TU list at offset %#" PRIx32
8163 " contains %zu entries:\n"),
8164 tu_off, tu_nr);
8165
8166 n = 0;
8167 while (dataend - readp >= 24 && n < tu_nr)
8168 {
8169 uint64_t off = read_8ubyte_unaligned (dbg, readp);
8170 readp += 8;
8171
8172 uint64_t type = read_8ubyte_unaligned (dbg, readp);
8173 readp += 8;
8174
8175 uint64_t sig = read_8ubyte_unaligned (dbg, readp);
8176 readp += 8;
8177
8178 printf (" [%4zu] CU offset: %5" PRId64
8179 ", type offset: %5" PRId64
8180 ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
8181 n++;
8182 }
8183
8184 readp = data->d_buf + addr_off;
8185 nextp = data->d_buf + sym_off;
8186 if (sym_off >= data->d_size)
8187 goto invalid_data;
8188
8189 size_t addr_nr = (nextp - readp) / 20;
8190
8191 printf (gettext ("\n Address list at offset %#" PRIx32
8192 " contains %zu entries:\n"),
8193 addr_off, addr_nr);
8194
8195 n = 0;
8196 while (dataend - readp >= 20 && n < addr_nr)
8197 {
8198 uint64_t low = read_8ubyte_unaligned (dbg, readp);
8199 readp += 8;
8200
8201 uint64_t high = read_8ubyte_unaligned (dbg, readp);
8202 readp += 8;
8203
8204 uint32_t idx = read_4ubyte_unaligned (dbg, readp);
8205 readp += 4;
8206
8207 char *l = format_dwarf_addr (dwflmod, 8, low, low);
8208 char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
8209 printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
8210 n, l, h, idx);
8211 free (l);
8212 free (h);
8213 n++;
8214 }
8215
8216 const unsigned char *const_start = data->d_buf + const_off;
8217 if (const_off >= data->d_size)
8218 goto invalid_data;
8219
8220 readp = data->d_buf + sym_off;
8221 nextp = const_start;
8222 size_t sym_nr = (nextp - readp) / 8;
8223
8224 printf (gettext ("\n Symbol table at offset %#" PRIx32
8225 " contains %zu slots:\n"),
8226 addr_off, sym_nr);
8227
8228 n = 0;
8229 while (dataend - readp >= 8 && n < sym_nr)
8230 {
8231 uint32_t name = read_4ubyte_unaligned (dbg, readp);
8232 readp += 4;
8233
8234 uint32_t vector = read_4ubyte_unaligned (dbg, readp);
8235 readp += 4;
8236
8237 if (name != 0 || vector != 0)
8238 {
8239 const unsigned char *sym = const_start + name;
8240 if (unlikely ((size_t) (dataend - const_start) < name
8241 || memchr (sym, '\0', dataend - sym) == NULL))
8242 goto invalid_data;
8243
8244 printf (" [%4zu] symbol: %s, CUs: ", n, sym);
8245
8246 const unsigned char *readcus = const_start + vector;
8247 if (unlikely ((size_t) (dataend - const_start) < vector))
8248 goto invalid_data;
8249 uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
8250 while (cus--)
8251 {
8252 uint32_t cu_kind, cu, kind;
8253 bool is_static;
8254 readcus += 4;
8255 if (unlikely (readcus + 4 > dataend))
8256 goto invalid_data;
8257 cu_kind = read_4ubyte_unaligned (dbg, readcus);
8258 cu = cu_kind & ((1 << 24) - 1);
8259 kind = (cu_kind >> 28) & 7;
8260 is_static = cu_kind & (1U << 31);
8261 if (cu > cu_nr - 1)
8262 printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
8263 else
8264 printf ("%" PRId32, cu);
8265 if (kind != 0)
8266 {
8267 printf (" (");
8268 switch (kind)
8269 {
8270 case 1:
8271 printf ("type");
8272 break;
8273 case 2:
8274 printf ("var");
8275 break;
8276 case 3:
8277 printf ("func");
8278 break;
8279 case 4:
8280 printf ("other");
8281 break;
8282 default:
8283 printf ("unknown-0x%" PRIx32, kind);
8284 break;
8285 }
8286 printf (":%c)", (is_static ? 'S' : 'G'));
8287 }
8288 if (cus > 0)
8289 printf (", ");
8290 }
8291 printf ("\n");
8292 }
8293 n++;
8294 }
8295 }
8296
8297 static void
print_debug(Dwfl_Module * dwflmod,Ebl * ebl,GElf_Ehdr * ehdr)8298 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
8299 {
8300 /* Before we start the real work get a debug context descriptor. */
8301 Dwarf_Addr dwbias;
8302 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
8303 Dwarf dummy_dbg =
8304 {
8305 .elf = ebl->elf,
8306 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
8307 };
8308 if (dbg == NULL)
8309 {
8310 if ((print_debug_sections & ~section_exception) != 0)
8311 error (0, 0, gettext ("cannot get debug context descriptor: %s"),
8312 dwfl_errmsg (-1));
8313 dbg = &dummy_dbg;
8314 }
8315
8316 /* Get the section header string table index. */
8317 size_t shstrndx;
8318 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
8319 error (EXIT_FAILURE, 0,
8320 gettext ("cannot get section header string table index"));
8321
8322 /* Look through all the sections for the debugging sections to print. */
8323 Elf_Scn *scn = NULL;
8324 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
8325 {
8326 GElf_Shdr shdr_mem;
8327 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
8328
8329 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
8330 {
8331 static const struct
8332 {
8333 const char *name;
8334 enum section_e bitmask;
8335 void (*fp) (Dwfl_Module *, Ebl *,
8336 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
8337 } debug_sections[] =
8338 {
8339 #define NEW_SECTION(name) \
8340 { ".debug_" #name, section_##name, print_debug_##name##_section }
8341 NEW_SECTION (abbrev),
8342 NEW_SECTION (aranges),
8343 NEW_SECTION (frame),
8344 NEW_SECTION (info),
8345 NEW_SECTION (types),
8346 NEW_SECTION (line),
8347 NEW_SECTION (loc),
8348 NEW_SECTION (pubnames),
8349 NEW_SECTION (str),
8350 NEW_SECTION (macinfo),
8351 NEW_SECTION (macro),
8352 NEW_SECTION (ranges),
8353 { ".eh_frame", section_frame | section_exception,
8354 print_debug_frame_section },
8355 { ".eh_frame_hdr", section_frame | section_exception,
8356 print_debug_frame_hdr_section },
8357 { ".gcc_except_table", section_frame | section_exception,
8358 print_debug_exception_table },
8359 { ".gdb_index", section_gdb_index, print_gdb_index_section }
8360 };
8361 const int ndebug_sections = (sizeof (debug_sections)
8362 / sizeof (debug_sections[0]));
8363 const char *name = elf_strptr (ebl->elf, shstrndx,
8364 shdr->sh_name);
8365 if (name == NULL)
8366 continue;
8367
8368 int n;
8369 for (n = 0; n < ndebug_sections; ++n)
8370 if (strcmp (name, debug_sections[n].name) == 0
8371 || (name[0] == '.' && name[1] == 'z'
8372 && debug_sections[n].name[1] == 'd'
8373 && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
8374 )
8375 {
8376 if ((print_debug_sections | implicit_debug_sections)
8377 & debug_sections[n].bitmask)
8378 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
8379 break;
8380 }
8381 }
8382 }
8383
8384 reset_listptr (&known_loclistptr);
8385 reset_listptr (&known_rangelistptr);
8386 }
8387
8388
8389 #define ITEM_INDENT 4
8390 #define WRAP_COLUMN 75
8391
8392 /* Print "NAME: FORMAT", wrapping when output text would make the line
8393 exceed WRAP_COLUMN. Unpadded numbers look better for the core items
8394 but this function is also used for registers which should be printed
8395 aligned. Fortunately registers output uses fixed fields width (such
8396 as %11d) for the alignment.
8397
8398 Line breaks should not depend on the particular values although that
8399 may happen in some cases of the core items. */
8400
8401 static unsigned int
8402 __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,...)8403 print_core_item (unsigned int colno, char sep, unsigned int wrap,
8404 size_t name_width, const char *name, const char *format, ...)
8405 {
8406 size_t len = strlen (name);
8407 if (name_width < len)
8408 name_width = len;
8409
8410 char *out;
8411 va_list ap;
8412 va_start (ap, format);
8413 int out_len = vasprintf (&out, format, ap);
8414 va_end (ap);
8415 if (out_len == -1)
8416 error (EXIT_FAILURE, 0, _("memory exhausted"));
8417
8418 size_t n = name_width + sizeof ": " - 1 + out_len;
8419
8420 if (colno == 0)
8421 {
8422 printf ("%*s", ITEM_INDENT, "");
8423 colno = ITEM_INDENT + n;
8424 }
8425 else if (colno + 2 + n < wrap)
8426 {
8427 printf ("%c ", sep);
8428 colno += 2 + n;
8429 }
8430 else
8431 {
8432 printf ("\n%*s", ITEM_INDENT, "");
8433 colno = ITEM_INDENT + n;
8434 }
8435
8436 printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
8437
8438 free (out);
8439
8440 return colno;
8441 }
8442
8443 static const void *
convert(Elf * core,Elf_Type type,uint_fast16_t count,void * value,const void * data,size_t size)8444 convert (Elf *core, Elf_Type type, uint_fast16_t count,
8445 void *value, const void *data, size_t size)
8446 {
8447 Elf_Data valuedata =
8448 {
8449 .d_type = type,
8450 .d_buf = value,
8451 .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
8452 .d_version = EV_CURRENT,
8453 };
8454 Elf_Data indata =
8455 {
8456 .d_type = type,
8457 .d_buf = (void *) data,
8458 .d_size = valuedata.d_size,
8459 .d_version = EV_CURRENT,
8460 };
8461
8462 Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
8463 ? elf32_xlatetom : elf64_xlatetom)
8464 (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
8465 if (d == NULL)
8466 error (EXIT_FAILURE, 0,
8467 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
8468
8469 return data + indata.d_size;
8470 }
8471
8472 typedef uint8_t GElf_Byte;
8473
8474 static unsigned int
handle_core_item(Elf * core,const Ebl_Core_Item * item,const void * desc,unsigned int colno,size_t * repeated_size)8475 handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
8476 unsigned int colno, size_t *repeated_size)
8477 {
8478 uint_fast16_t count = item->count ?: 1;
8479 /* Ebl_Core_Item count is always a small number.
8480 Make sure the backend didn't put in some large bogus value. */
8481 assert (count < 128);
8482
8483 #define TYPES \
8484 DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8); \
8485 DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16); \
8486 DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32); \
8487 DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32); \
8488 DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64); \
8489 DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
8490
8491 #define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
8492 typedef union { TYPES; } value_t;
8493 void *data = alloca (count * sizeof (value_t));
8494 #undef DO_TYPE
8495
8496 #define DO_TYPE(NAME, Name, hex, dec) \
8497 GElf_##Name *value_##Name __attribute__((unused)) = data
8498 TYPES;
8499 #undef DO_TYPE
8500
8501 size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
8502 size_t convsize = size;
8503 if (repeated_size != NULL)
8504 {
8505 if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
8506 {
8507 data = alloca (*repeated_size);
8508 count *= *repeated_size / size;
8509 convsize = count * size;
8510 *repeated_size -= convsize;
8511 }
8512 else if (item->count != 0 || item->format != '\n')
8513 *repeated_size -= size;
8514 }
8515
8516 convert (core, item->type, count, data, desc + item->offset, convsize);
8517
8518 Elf_Type type = item->type;
8519 if (type == ELF_T_ADDR)
8520 type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
8521
8522 switch (item->format)
8523 {
8524 case 'd':
8525 assert (count == 1);
8526 switch (type)
8527 {
8528 #define DO_TYPE(NAME, Name, hex, dec) \
8529 case ELF_T_##NAME: \
8530 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8531 0, item->name, dec, value_##Name[0]); \
8532 break
8533 TYPES;
8534 #undef DO_TYPE
8535 default:
8536 abort ();
8537 }
8538 break;
8539
8540 case 'x':
8541 assert (count == 1);
8542 switch (type)
8543 {
8544 #define DO_TYPE(NAME, Name, hex, dec) \
8545 case ELF_T_##NAME: \
8546 colno = print_core_item (colno, ',', WRAP_COLUMN, \
8547 0, item->name, hex, value_##Name[0]); \
8548 break
8549 TYPES;
8550 #undef DO_TYPE
8551 default:
8552 abort ();
8553 }
8554 break;
8555
8556 case 'b':
8557 case 'B':
8558 assert (size % sizeof (unsigned int) == 0);
8559 unsigned int nbits = count * size * 8;
8560 unsigned int pop = 0;
8561 for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
8562 pop += __builtin_popcount (*i);
8563 bool negate = pop > nbits / 2;
8564 const unsigned int bias = item->format == 'b';
8565
8566 {
8567 char printed[(negate ? nbits - pop : pop) * 16 + 1];
8568 char *p = printed;
8569 *p = '\0';
8570
8571 if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
8572 {
8573 assert (size == sizeof (unsigned int) * 2);
8574 for (unsigned int *i = data;
8575 (void *) i < data + count * size; i += 2)
8576 {
8577 unsigned int w = i[1];
8578 i[1] = i[0];
8579 i[0] = w;
8580 }
8581 }
8582
8583 unsigned int lastbit = 0;
8584 unsigned int run = 0;
8585 for (const unsigned int *i = data;
8586 (void *) i < data + count * size; ++i)
8587 {
8588 unsigned int bit = ((void *) i - data) * 8;
8589 unsigned int w = negate ? ~*i : *i;
8590 while (w != 0)
8591 {
8592 /* Note that a right shift equal to (or greater than)
8593 the number of bits of w is undefined behaviour. In
8594 particular when the least significant bit is bit 32
8595 (w = 0x8000000) then w >>= n is undefined. So
8596 explicitly handle that case separately. */
8597 unsigned int n = ffs (w);
8598 if (n < sizeof (w) * 8)
8599 w >>= n;
8600 else
8601 w = 0;
8602 bit += n;
8603
8604 if (lastbit != 0 && lastbit + 1 == bit)
8605 ++run;
8606 else
8607 {
8608 if (lastbit == 0)
8609 p += sprintf (p, "%u", bit - bias);
8610 else if (run == 0)
8611 p += sprintf (p, ",%u", bit - bias);
8612 else
8613 p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
8614 run = 0;
8615 }
8616
8617 lastbit = bit;
8618 }
8619 }
8620 if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
8621 p += sprintf (p, "-%u", lastbit - bias);
8622
8623 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8624 negate ? "~<%s>" : "<%s>", printed);
8625 }
8626 break;
8627
8628 case 'T':
8629 case (char) ('T'|0x80):
8630 assert (count == 2);
8631 Dwarf_Word sec;
8632 Dwarf_Word usec;
8633 switch (type)
8634 {
8635 #define DO_TYPE(NAME, Name, hex, dec) \
8636 case ELF_T_##NAME: \
8637 sec = value_##Name[0]; \
8638 usec = value_##Name[1]; \
8639 break
8640 TYPES;
8641 #undef DO_TYPE
8642 default:
8643 abort ();
8644 }
8645 if (unlikely (item->format == (char) ('T'|0x80)))
8646 {
8647 /* This is a hack for an ill-considered 64-bit ABI where
8648 tv_usec is actually a 32-bit field with 32 bits of padding
8649 rounding out struct timeval. We've already converted it as
8650 a 64-bit field. For little-endian, this just means the
8651 high half is the padding; it's presumably zero, but should
8652 be ignored anyway. For big-endian, it means the 32-bit
8653 field went into the high half of USEC. */
8654 GElf_Ehdr ehdr_mem;
8655 GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
8656 if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
8657 usec >>= 32;
8658 else
8659 usec &= UINT32_MAX;
8660 }
8661 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8662 "%" PRIu64 ".%.6" PRIu64, sec, usec);
8663 break;
8664
8665 case 'c':
8666 assert (count == 1);
8667 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8668 "%c", value_Byte[0]);
8669 break;
8670
8671 case 's':
8672 colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
8673 "%.*s", (int) count, value_Byte);
8674 break;
8675
8676 case '\n':
8677 /* This is a list of strings separated by '\n'. */
8678 assert (item->count == 0);
8679 assert (repeated_size != NULL);
8680 assert (item->name == NULL);
8681 if (unlikely (item->offset >= *repeated_size))
8682 break;
8683
8684 const char *s = desc + item->offset;
8685 size = *repeated_size - item->offset;
8686 *repeated_size = 0;
8687 while (size > 0)
8688 {
8689 const char *eol = memchr (s, '\n', size);
8690 int len = size;
8691 if (eol != NULL)
8692 len = eol - s;
8693 printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
8694 if (eol == NULL)
8695 break;
8696 size -= eol + 1 - s;
8697 s = eol + 1;
8698 }
8699
8700 colno = WRAP_COLUMN;
8701 break;
8702
8703 case 'h':
8704 break;
8705
8706 default:
8707 error (0, 0, "XXX not handling format '%c' for %s",
8708 item->format, item->name);
8709 break;
8710 }
8711
8712 #undef TYPES
8713
8714 return colno;
8715 }
8716
8717
8718 /* Sort items by group, and by layout offset within each group. */
8719 static int
compare_core_items(const void * a,const void * b)8720 compare_core_items (const void *a, const void *b)
8721 {
8722 const Ebl_Core_Item *const *p1 = a;
8723 const Ebl_Core_Item *const *p2 = b;
8724 const Ebl_Core_Item *item1 = *p1;
8725 const Ebl_Core_Item *item2 = *p2;
8726
8727 return ((item1->group == item2->group ? 0
8728 : strcmp (item1->group, item2->group))
8729 ?: (int) item1->offset - (int) item2->offset);
8730 }
8731
8732 /* Sort item groups by layout offset of the first item in the group. */
8733 static int
compare_core_item_groups(const void * a,const void * b)8734 compare_core_item_groups (const void *a, const void *b)
8735 {
8736 const Ebl_Core_Item *const *const *p1 = a;
8737 const Ebl_Core_Item *const *const *p2 = b;
8738 const Ebl_Core_Item *const *group1 = *p1;
8739 const Ebl_Core_Item *const *group2 = *p2;
8740 const Ebl_Core_Item *item1 = *group1;
8741 const Ebl_Core_Item *item2 = *group2;
8742
8743 return (int) item1->offset - (int) item2->offset;
8744 }
8745
8746 static unsigned int
handle_core_items(Elf * core,const void * desc,size_t descsz,const Ebl_Core_Item * items,size_t nitems)8747 handle_core_items (Elf *core, const void *desc, size_t descsz,
8748 const Ebl_Core_Item *items, size_t nitems)
8749 {
8750 if (nitems == 0)
8751 return 0;
8752 unsigned int colno = 0;
8753
8754 /* FORMAT '\n' makes sense to be present only as a single item as it
8755 processes all the data of a note. FORMATs 'b' and 'B' have a special case
8756 if present as a single item but they can be also processed with other
8757 items below. */
8758 if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
8759 || items[0].format == 'B'))
8760 {
8761 assert (items[0].offset == 0);
8762 size_t size = descsz;
8763 colno = handle_core_item (core, items, desc, colno, &size);
8764 /* If SIZE is not zero here there is some remaining data. But we do not
8765 know how to process it anyway. */
8766 return colno;
8767 }
8768 for (size_t i = 0; i < nitems; ++i)
8769 assert (items[i].format != '\n');
8770
8771 /* Sort to collect the groups together. */
8772 const Ebl_Core_Item *sorted_items[nitems];
8773 for (size_t i = 0; i < nitems; ++i)
8774 sorted_items[i] = &items[i];
8775 qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
8776
8777 /* Collect the unique groups and sort them. */
8778 const Ebl_Core_Item **groups[nitems];
8779 groups[0] = &sorted_items[0];
8780 size_t ngroups = 1;
8781 for (size_t i = 1; i < nitems; ++i)
8782 if (sorted_items[i]->group != sorted_items[i - 1]->group
8783 && strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
8784 groups[ngroups++] = &sorted_items[i];
8785 qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
8786
8787 /* Write out all the groups. */
8788 const void *last = desc;
8789 do
8790 {
8791 for (size_t i = 0; i < ngroups; ++i)
8792 {
8793 for (const Ebl_Core_Item **item = groups[i];
8794 (item < &sorted_items[nitems]
8795 && ((*item)->group == groups[i][0]->group
8796 || !strcmp ((*item)->group, groups[i][0]->group)));
8797 ++item)
8798 colno = handle_core_item (core, *item, desc, colno, NULL);
8799
8800 /* Force a line break at the end of the group. */
8801 colno = WRAP_COLUMN;
8802 }
8803
8804 if (descsz == 0)
8805 break;
8806
8807 /* This set of items consumed a certain amount of the note's data.
8808 If there is more data there, we have another unit of the same size.
8809 Loop to print that out too. */
8810 const Ebl_Core_Item *item = &items[nitems - 1];
8811 size_t eltsz = item->offset + gelf_fsize (core, item->type,
8812 item->count ?: 1, EV_CURRENT);
8813
8814 int reps = -1;
8815 do
8816 {
8817 ++reps;
8818 desc += eltsz;
8819 descsz -= eltsz;
8820 }
8821 while (descsz >= eltsz && !memcmp (desc, last, eltsz));
8822
8823 if (reps == 1)
8824 {
8825 /* For just one repeat, print it unabridged twice. */
8826 desc -= eltsz;
8827 descsz += eltsz;
8828 }
8829 else if (reps > 1)
8830 printf (gettext ("\n%*s... <repeats %u more times> ..."),
8831 ITEM_INDENT, "", reps);
8832
8833 last = desc;
8834 }
8835 while (descsz > 0);
8836
8837 return colno;
8838 }
8839
8840 static unsigned int
handle_bit_registers(const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)8841 handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
8842 unsigned int colno)
8843 {
8844 desc += regloc->offset;
8845
8846 abort (); /* XXX */
8847 return colno;
8848 }
8849
8850
8851 static unsigned int
handle_core_register(Ebl * ebl,Elf * core,int maxregname,const Ebl_Register_Location * regloc,const void * desc,unsigned int colno)8852 handle_core_register (Ebl *ebl, Elf *core, int maxregname,
8853 const Ebl_Register_Location *regloc, const void *desc,
8854 unsigned int colno)
8855 {
8856 if (regloc->bits % 8 != 0)
8857 return handle_bit_registers (regloc, desc, colno);
8858
8859 desc += regloc->offset;
8860
8861 for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
8862 {
8863 char name[REGNAMESZ];
8864 int bits;
8865 int type;
8866 register_info (ebl, reg, regloc, name, &bits, &type);
8867
8868 #define TYPES \
8869 BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8); \
8870 BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16); \
8871 BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32); \
8872 BITS (64, XWORD, "%20" PRId64, " 0x%.16" PRIx64)
8873
8874 #define BITS(bits, xtype, sfmt, ufmt) \
8875 uint##bits##_t b##bits; int##bits##_t b##bits##s
8876 union { TYPES; uint64_t b128[2]; } value;
8877 #undef BITS
8878
8879 switch (type)
8880 {
8881 case DW_ATE_unsigned:
8882 case DW_ATE_signed:
8883 case DW_ATE_address:
8884 switch (bits)
8885 {
8886 #define BITS(bits, xtype, sfmt, ufmt) \
8887 case bits: \
8888 desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0); \
8889 if (type == DW_ATE_signed) \
8890 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8891 maxregname, name, \
8892 sfmt, value.b##bits##s); \
8893 else \
8894 colno = print_core_item (colno, ' ', WRAP_COLUMN, \
8895 maxregname, name, \
8896 ufmt, value.b##bits); \
8897 break
8898
8899 TYPES;
8900
8901 case 128:
8902 assert (type == DW_ATE_unsigned);
8903 desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
8904 int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
8905 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8906 maxregname, name,
8907 "0x%.16" PRIx64 "%.16" PRIx64,
8908 value.b128[!be], value.b128[be]);
8909 break;
8910
8911 default:
8912 abort ();
8913 #undef BITS
8914 }
8915 break;
8916
8917 default:
8918 /* Print each byte in hex, the whole thing in native byte order. */
8919 assert (bits % 8 == 0);
8920 const uint8_t *bytes = desc;
8921 desc += bits / 8;
8922 char hex[bits / 4 + 1];
8923 hex[bits / 4] = '\0';
8924 int incr = 1;
8925 if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
8926 {
8927 bytes += bits / 8 - 1;
8928 incr = -1;
8929 }
8930 size_t idx = 0;
8931 for (char *h = hex; bits > 0; bits -= 8, idx += incr)
8932 {
8933 *h++ = "0123456789abcdef"[bytes[idx] >> 4];
8934 *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
8935 }
8936 colno = print_core_item (colno, ' ', WRAP_COLUMN,
8937 maxregname, name, "0x%s", hex);
8938 break;
8939 }
8940 desc += regloc->pad;
8941
8942 #undef TYPES
8943 }
8944
8945 return colno;
8946 }
8947
8948
8949 struct register_info
8950 {
8951 const Ebl_Register_Location *regloc;
8952 const char *set;
8953 char name[REGNAMESZ];
8954 int regno;
8955 int bits;
8956 int type;
8957 };
8958
8959 static int
register_bitpos(const struct register_info * r)8960 register_bitpos (const struct register_info *r)
8961 {
8962 return (r->regloc->offset * 8
8963 + ((r->regno - r->regloc->regno)
8964 * (r->regloc->bits + r->regloc->pad * 8)));
8965 }
8966
8967 static int
compare_sets_by_info(const struct register_info * r1,const struct register_info * r2)8968 compare_sets_by_info (const struct register_info *r1,
8969 const struct register_info *r2)
8970 {
8971 return ((int) r2->bits - (int) r1->bits
8972 ?: register_bitpos (r1) - register_bitpos (r2));
8973 }
8974
8975 /* Sort registers by set, and by size and layout offset within each set. */
8976 static int
compare_registers(const void * a,const void * b)8977 compare_registers (const void *a, const void *b)
8978 {
8979 const struct register_info *r1 = a;
8980 const struct register_info *r2 = b;
8981
8982 /* Unused elements sort last. */
8983 if (r1->regloc == NULL)
8984 return r2->regloc == NULL ? 0 : 1;
8985 if (r2->regloc == NULL)
8986 return -1;
8987
8988 return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
8989 ?: compare_sets_by_info (r1, r2));
8990 }
8991
8992 /* Sort register sets by layout offset of the first register in the set. */
8993 static int
compare_register_sets(const void * a,const void * b)8994 compare_register_sets (const void *a, const void *b)
8995 {
8996 const struct register_info *const *p1 = a;
8997 const struct register_info *const *p2 = b;
8998 return compare_sets_by_info (*p1, *p2);
8999 }
9000
9001 static unsigned int
handle_core_registers(Ebl * ebl,Elf * core,const void * desc,const Ebl_Register_Location * reglocs,size_t nregloc)9002 handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
9003 const Ebl_Register_Location *reglocs, size_t nregloc)
9004 {
9005 if (nregloc == 0)
9006 return 0;
9007
9008 ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
9009 if (maxnreg <= 0)
9010 {
9011 for (size_t i = 0; i < nregloc; ++i)
9012 if (maxnreg < reglocs[i].regno + reglocs[i].count)
9013 maxnreg = reglocs[i].regno + reglocs[i].count;
9014 assert (maxnreg > 0);
9015 }
9016
9017 struct register_info regs[maxnreg];
9018 memset (regs, 0, sizeof regs);
9019
9020 /* Sort to collect the sets together. */
9021 int maxreg = 0;
9022 for (size_t i = 0; i < nregloc; ++i)
9023 for (int reg = reglocs[i].regno;
9024 reg < reglocs[i].regno + reglocs[i].count;
9025 ++reg)
9026 {
9027 assert (reg < maxnreg);
9028 if (reg > maxreg)
9029 maxreg = reg;
9030 struct register_info *info = ®s[reg];
9031 info->regloc = ®locs[i];
9032 info->regno = reg;
9033 info->set = register_info (ebl, reg, ®locs[i],
9034 info->name, &info->bits, &info->type);
9035 }
9036 qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
9037
9038 /* Collect the unique sets and sort them. */
9039 inline bool same_set (const struct register_info *a,
9040 const struct register_info *b)
9041 {
9042 return (a < ®s[maxnreg] && a->regloc != NULL
9043 && b < ®s[maxnreg] && b->regloc != NULL
9044 && a->bits == b->bits
9045 && (a->set == b->set || !strcmp (a->set, b->set)));
9046 }
9047 struct register_info *sets[maxreg + 1];
9048 sets[0] = ®s[0];
9049 size_t nsets = 1;
9050 for (int i = 1; i <= maxreg; ++i)
9051 if (regs[i].regloc != NULL && !same_set (®s[i], ®s[i - 1]))
9052 sets[nsets++] = ®s[i];
9053 qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
9054
9055 /* Write out all the sets. */
9056 unsigned int colno = 0;
9057 for (size_t i = 0; i < nsets; ++i)
9058 {
9059 /* Find the longest name of a register in this set. */
9060 size_t maxname = 0;
9061 const struct register_info *end;
9062 for (end = sets[i]; same_set (sets[i], end); ++end)
9063 {
9064 size_t len = strlen (end->name);
9065 if (len > maxname)
9066 maxname = len;
9067 }
9068
9069 for (const struct register_info *reg = sets[i];
9070 reg < end;
9071 reg += reg->regloc->count ?: 1)
9072 colno = handle_core_register (ebl, core, maxname,
9073 reg->regloc, desc, colno);
9074
9075 /* Force a line break at the end of the group. */
9076 colno = WRAP_COLUMN;
9077 }
9078
9079 return colno;
9080 }
9081
9082 static void
handle_auxv_note(Ebl * ebl,Elf * core,GElf_Word descsz,GElf_Off desc_pos)9083 handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9084 {
9085 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
9086 if (data == NULL)
9087 elf_error:
9088 error (EXIT_FAILURE, 0,
9089 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9090
9091 const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
9092 for (size_t i = 0; i < nauxv; ++i)
9093 {
9094 GElf_auxv_t av_mem;
9095 GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
9096 if (av == NULL)
9097 goto elf_error;
9098
9099 const char *name;
9100 const char *fmt;
9101 if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
9102 {
9103 /* Unknown type. */
9104 if (av->a_un.a_val == 0)
9105 printf (" %" PRIu64 "\n", av->a_type);
9106 else
9107 printf (" %" PRIu64 ": %#" PRIx64 "\n",
9108 av->a_type, av->a_un.a_val);
9109 }
9110 else
9111 switch (fmt[0])
9112 {
9113 case '\0': /* Normally zero. */
9114 if (av->a_un.a_val == 0)
9115 {
9116 printf (" %s\n", name);
9117 break;
9118 }
9119 /* Fall through */
9120 case 'x': /* hex */
9121 case 'p': /* address */
9122 case 's': /* address of string */
9123 printf (" %s: %#" PRIx64 "\n", name, av->a_un.a_val);
9124 break;
9125 case 'u':
9126 printf (" %s: %" PRIu64 "\n", name, av->a_un.a_val);
9127 break;
9128 case 'd':
9129 printf (" %s: %" PRId64 "\n", name, av->a_un.a_val);
9130 break;
9131
9132 case 'b':
9133 printf (" %s: %#" PRIx64 " ", name, av->a_un.a_val);
9134 GElf_Xword bit = 1;
9135 const char *pfx = "<";
9136 for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
9137 {
9138 if (av->a_un.a_val & bit)
9139 {
9140 printf ("%s%s", pfx, p);
9141 pfx = " ";
9142 }
9143 bit <<= 1;
9144 }
9145 printf (">\n");
9146 break;
9147
9148 default:
9149 abort ();
9150 }
9151 }
9152 }
9153
9154 static bool
buf_has_data(unsigned char const * ptr,unsigned char const * end,size_t sz)9155 buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
9156 {
9157 return ptr < end && (size_t) (end - ptr) >= sz;
9158 }
9159
9160 static bool
buf_read_int(Elf * core,unsigned char const ** ptrp,unsigned char const * end,int * retp)9161 buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
9162 int *retp)
9163 {
9164 if (! buf_has_data (*ptrp, end, 4))
9165 return false;
9166
9167 *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
9168 return true;
9169 }
9170
9171 static bool
buf_read_ulong(Elf * core,unsigned char const ** ptrp,unsigned char const * end,uint64_t * retp)9172 buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
9173 uint64_t *retp)
9174 {
9175 size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
9176 if (! buf_has_data (*ptrp, end, sz))
9177 return false;
9178
9179 union
9180 {
9181 uint64_t u64;
9182 uint32_t u32;
9183 } u;
9184
9185 *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
9186
9187 if (sz == 4)
9188 *retp = u.u32;
9189 else
9190 *retp = u.u64;
9191 return true;
9192 }
9193
9194 static void
handle_siginfo_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)9195 handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9196 {
9197 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
9198 if (data == NULL)
9199 error (EXIT_FAILURE, 0,
9200 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9201
9202 unsigned char const *ptr = data->d_buf;
9203 unsigned char const *const end = data->d_buf + data->d_size;
9204
9205 /* Siginfo head is three ints: signal number, error number, origin
9206 code. */
9207 int si_signo, si_errno, si_code;
9208 if (! buf_read_int (core, &ptr, end, &si_signo)
9209 || ! buf_read_int (core, &ptr, end, &si_errno)
9210 || ! buf_read_int (core, &ptr, end, &si_code))
9211 {
9212 fail:
9213 printf (" Not enough data in NT_SIGINFO note.\n");
9214 return;
9215 }
9216
9217 /* Next is a pointer-aligned union of structures. On 64-bit
9218 machines, that implies a word of padding. */
9219 if (gelf_getclass (core) == ELFCLASS64)
9220 ptr += 4;
9221
9222 printf (" si_signo: %d, si_errno: %d, si_code: %d\n",
9223 si_signo, si_errno, si_code);
9224
9225 if (si_code > 0)
9226 switch (si_signo)
9227 {
9228 case SIGILL:
9229 case SIGFPE:
9230 case SIGSEGV:
9231 case SIGBUS:
9232 {
9233 uint64_t addr;
9234 if (! buf_read_ulong (core, &ptr, end, &addr))
9235 goto fail;
9236 printf (" fault address: %#" PRIx64 "\n", addr);
9237 break;
9238 }
9239 default:
9240 ;
9241 }
9242 else if (si_code == SI_USER)
9243 {
9244 int pid, uid;
9245 if (! buf_read_int (core, &ptr, end, &pid)
9246 || ! buf_read_int (core, &ptr, end, &uid))
9247 goto fail;
9248 printf (" sender PID: %d, sender UID: %d\n", pid, uid);
9249 }
9250 }
9251
9252 static void
handle_file_note(Elf * core,GElf_Word descsz,GElf_Off desc_pos)9253 handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
9254 {
9255 Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
9256 if (data == NULL)
9257 error (EXIT_FAILURE, 0,
9258 gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
9259
9260 unsigned char const *ptr = data->d_buf;
9261 unsigned char const *const end = data->d_buf + data->d_size;
9262
9263 uint64_t count, page_size;
9264 if (! buf_read_ulong (core, &ptr, end, &count)
9265 || ! buf_read_ulong (core, &ptr, end, &page_size))
9266 {
9267 fail:
9268 printf (" Not enough data in NT_FILE note.\n");
9269 return;
9270 }
9271
9272 size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
9273 uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
9274 if (count > maxcount)
9275 goto fail;
9276
9277 /* Where file names are stored. */
9278 unsigned char const *const fstart = ptr + 3 * count * addrsize;
9279 char const *fptr = (char *) fstart;
9280
9281 printf (" %" PRId64 " files:\n", count);
9282 for (uint64_t i = 0; i < count; ++i)
9283 {
9284 uint64_t mstart, mend, moffset;
9285 if (! buf_read_ulong (core, &ptr, fstart, &mstart)
9286 || ! buf_read_ulong (core, &ptr, fstart, &mend)
9287 || ! buf_read_ulong (core, &ptr, fstart, &moffset))
9288 goto fail;
9289
9290 const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
9291 if (fnext == NULL)
9292 goto fail;
9293
9294 int ct = printf (" %08" PRIx64 "-%08" PRIx64
9295 " %08" PRIx64 " %" PRId64,
9296 mstart, mend, moffset * page_size, mend - mstart);
9297 printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
9298
9299 fptr = fnext + 1;
9300 }
9301 }
9302
9303 static void
handle_core_note(Ebl * ebl,const GElf_Nhdr * nhdr,const char * name,const void * desc)9304 handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
9305 const char *name, const void *desc)
9306 {
9307 GElf_Word regs_offset;
9308 size_t nregloc;
9309 const Ebl_Register_Location *reglocs;
9310 size_t nitems;
9311 const Ebl_Core_Item *items;
9312
9313 if (! ebl_core_note (ebl, nhdr, name,
9314 ®s_offset, &nregloc, ®locs, &nitems, &items))
9315 return;
9316
9317 /* Pass 0 for DESCSZ when there are registers in the note,
9318 so that the ITEMS array does not describe the whole thing.
9319 For non-register notes, the actual descsz might be a multiple
9320 of the unit size, not just exactly the unit size. */
9321 unsigned int colno = handle_core_items (ebl->elf, desc,
9322 nregloc == 0 ? nhdr->n_descsz : 0,
9323 items, nitems);
9324 if (colno != 0)
9325 putchar_unlocked ('\n');
9326
9327 colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
9328 reglocs, nregloc);
9329 if (colno != 0)
9330 putchar_unlocked ('\n');
9331 }
9332
9333 static void
handle_notes_data(Ebl * ebl,const GElf_Ehdr * ehdr,GElf_Off start,Elf_Data * data)9334 handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
9335 GElf_Off start, Elf_Data *data)
9336 {
9337 fputs_unlocked (gettext (" Owner Data size Type\n"), stdout);
9338
9339 if (data == NULL)
9340 goto bad_note;
9341
9342 size_t offset = 0;
9343 GElf_Nhdr nhdr;
9344 size_t name_offset;
9345 size_t desc_offset;
9346 while (offset < data->d_size
9347 && (offset = gelf_getnote (data, offset,
9348 &nhdr, &name_offset, &desc_offset)) > 0)
9349 {
9350 const char *name = data->d_buf + name_offset;
9351 const char *desc = data->d_buf + desc_offset;
9352
9353 char buf[100];
9354 char buf2[100];
9355 printf (gettext (" %-13.*s %9" PRId32 " %s\n"),
9356 (int) nhdr.n_namesz, name, nhdr.n_descsz,
9357 ehdr->e_type == ET_CORE
9358 ? ebl_core_note_type_name (ebl, nhdr.n_type,
9359 buf, sizeof (buf))
9360 : ebl_object_note_type_name (ebl, name, nhdr.n_type,
9361 buf2, sizeof (buf2)));
9362
9363 /* Filter out invalid entries. */
9364 if (memchr (name, '\0', nhdr.n_namesz) != NULL
9365 /* XXX For now help broken Linux kernels. */
9366 || 1)
9367 {
9368 if (ehdr->e_type == ET_CORE)
9369 {
9370 if (nhdr.n_type == NT_AUXV
9371 && (nhdr.n_namesz == 4 /* Broken old Linux kernels. */
9372 || (nhdr.n_namesz == 5 && name[4] == '\0'))
9373 && !memcmp (name, "CORE", 4))
9374 handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
9375 start + desc_offset);
9376 else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
9377 switch (nhdr.n_type)
9378 {
9379 case NT_SIGINFO:
9380 handle_siginfo_note (ebl->elf, nhdr.n_descsz,
9381 start + desc_offset);
9382 break;
9383
9384 case NT_FILE:
9385 handle_file_note (ebl->elf, nhdr.n_descsz,
9386 start + desc_offset);
9387 break;
9388
9389 default:
9390 handle_core_note (ebl, &nhdr, name, desc);
9391 }
9392 else
9393 handle_core_note (ebl, &nhdr, name, desc);
9394 }
9395 else
9396 ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
9397 }
9398 }
9399
9400 if (offset == data->d_size)
9401 return;
9402
9403 bad_note:
9404 error (EXIT_FAILURE, 0,
9405 gettext ("cannot get content of note section: %s"),
9406 elf_errmsg (-1));
9407 }
9408
9409 static void
handle_notes(Ebl * ebl,GElf_Ehdr * ehdr)9410 handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
9411 {
9412 /* If we have section headers, just look for SHT_NOTE sections.
9413 In a debuginfo file, the program headers are not reliable. */
9414 if (shnum != 0)
9415 {
9416 /* Get the section header string table index. */
9417 size_t shstrndx;
9418 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
9419 error (EXIT_FAILURE, 0,
9420 gettext ("cannot get section header string table index"));
9421
9422 Elf_Scn *scn = NULL;
9423 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9424 {
9425 GElf_Shdr shdr_mem;
9426 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
9427
9428 if (shdr == NULL || shdr->sh_type != SHT_NOTE)
9429 /* Not what we are looking for. */
9430 continue;
9431
9432 printf (gettext ("\
9433 \nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9434 elf_ndxscn (scn),
9435 elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
9436 shdr->sh_size, shdr->sh_offset);
9437
9438 handle_notes_data (ebl, ehdr, shdr->sh_offset,
9439 elf_getdata (scn, NULL));
9440 }
9441 return;
9442 }
9443
9444 /* We have to look through the program header to find the note
9445 sections. There can be more than one. */
9446 for (size_t cnt = 0; cnt < phnum; ++cnt)
9447 {
9448 GElf_Phdr mem;
9449 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
9450
9451 if (phdr == NULL || phdr->p_type != PT_NOTE)
9452 /* Not what we are looking for. */
9453 continue;
9454
9455 printf (gettext ("\
9456 \nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
9457 phdr->p_filesz, phdr->p_offset);
9458
9459 handle_notes_data (ebl, ehdr, phdr->p_offset,
9460 elf_getdata_rawchunk (ebl->elf,
9461 phdr->p_offset, phdr->p_filesz,
9462 ELF_T_NHDR));
9463 }
9464 }
9465
9466
9467 static void
hex_dump(const uint8_t * data,size_t len)9468 hex_dump (const uint8_t *data, size_t len)
9469 {
9470 size_t pos = 0;
9471 while (pos < len)
9472 {
9473 printf (" 0x%08zx ", pos);
9474
9475 const size_t chunk = MIN (len - pos, 16);
9476
9477 for (size_t i = 0; i < chunk; ++i)
9478 if (i % 4 == 3)
9479 printf ("%02x ", data[pos + i]);
9480 else
9481 printf ("%02x", data[pos + i]);
9482
9483 if (chunk < 16)
9484 printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
9485
9486 for (size_t i = 0; i < chunk; ++i)
9487 {
9488 unsigned char b = data[pos + i];
9489 printf ("%c", isprint (b) ? b : '.');
9490 }
9491
9492 putchar ('\n');
9493 pos += chunk;
9494 }
9495 }
9496
9497 static void
dump_data_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)9498 dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9499 {
9500 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9501 printf (gettext ("\nSection [%zu] '%s' has no data to dump.\n"),
9502 elf_ndxscn (scn), name);
9503 else
9504 {
9505 if (print_decompress)
9506 {
9507 /* We try to decompress the section, but keep the old shdr around
9508 so we can show both the original shdr size and the uncompressed
9509 data size. */
9510 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
9511 elf_compress (scn, 0, 0);
9512 else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
9513 elf_compress_gnu (scn, 0, 0);
9514 }
9515
9516 Elf_Data *data = elf_rawdata (scn, NULL);
9517 if (data == NULL)
9518 error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
9519 elf_ndxscn (scn), name, elf_errmsg (-1));
9520 else
9521 {
9522 if (data->d_size == shdr->sh_size)
9523 printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
9524 " bytes at offset %#0" PRIx64 ":\n"),
9525 elf_ndxscn (scn), name,
9526 shdr->sh_size, shdr->sh_offset);
9527 else
9528 printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
9529 " bytes (%zd uncompressed) at offset %#0"
9530 PRIx64 ":\n"),
9531 elf_ndxscn (scn), name,
9532 shdr->sh_size, data->d_size, shdr->sh_offset);
9533 hex_dump (data->d_buf, data->d_size);
9534 }
9535 }
9536 }
9537
9538 static void
print_string_section(Elf_Scn * scn,const GElf_Shdr * shdr,const char * name)9539 print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
9540 {
9541 if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
9542 printf (gettext ("\nSection [%zu] '%s' has no strings to dump.\n"),
9543 elf_ndxscn (scn), name);
9544 else
9545 {
9546 if (print_decompress)
9547 {
9548 /* We try to decompress the section, but keep the old shdr around
9549 so we can show both the original shdr size and the uncompressed
9550 data size. */
9551 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
9552 elf_compress (scn, 0, 0);
9553 else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
9554 elf_compress_gnu (scn, 0, 0);
9555 }
9556
9557 Elf_Data *data = elf_rawdata (scn, NULL);
9558 if (data == NULL)
9559 error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
9560 elf_ndxscn (scn), name, elf_errmsg (-1));
9561 else
9562 {
9563 if (data->d_size == shdr->sh_size)
9564 printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
9565 " bytes at offset %#0" PRIx64 ":\n"),
9566 elf_ndxscn (scn), name,
9567 shdr->sh_size, shdr->sh_offset);
9568 else
9569 printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
9570 " bytes (%zd uncompressed) at offset %#0"
9571 PRIx64 ":\n"),
9572 elf_ndxscn (scn), name,
9573 shdr->sh_size, data->d_size, shdr->sh_offset);
9574
9575 const char *start = data->d_buf;
9576 const char *const limit = start + data->d_size;
9577 do
9578 {
9579 const char *end = memchr (start, '\0', limit - start);
9580 const size_t pos = start - (const char *) data->d_buf;
9581 if (unlikely (end == NULL))
9582 {
9583 printf (" [%6zx]- %.*s\n",
9584 pos, (int) (limit - start), start);
9585 break;
9586 }
9587 printf (" [%6zx] %s\n", pos, start);
9588 start = end + 1;
9589 } while (start < limit);
9590 }
9591 }
9592 }
9593
9594 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))9595 for_each_section_argument (Elf *elf, const struct section_argument *list,
9596 void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
9597 const char *name))
9598 {
9599 /* Get the section header string table index. */
9600 size_t shstrndx;
9601 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
9602 error (EXIT_FAILURE, 0,
9603 gettext ("cannot get section header string table index"));
9604
9605 for (const struct section_argument *a = list; a != NULL; a = a->next)
9606 {
9607 Elf_Scn *scn;
9608 GElf_Shdr shdr_mem;
9609 const char *name = NULL;
9610
9611 char *endp = NULL;
9612 unsigned long int shndx = strtoul (a->arg, &endp, 0);
9613 if (endp != a->arg && *endp == '\0')
9614 {
9615 scn = elf_getscn (elf, shndx);
9616 if (scn == NULL)
9617 {
9618 error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
9619 continue;
9620 }
9621
9622 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9623 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
9624 elf_errmsg (-1));
9625 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9626 }
9627 else
9628 {
9629 /* Need to look up the section by name. */
9630 scn = NULL;
9631 bool found = false;
9632 while ((scn = elf_nextscn (elf, scn)) != NULL)
9633 {
9634 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9635 continue;
9636 name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
9637 if (name == NULL)
9638 continue;
9639 if (!strcmp (name, a->arg))
9640 {
9641 found = true;
9642 (*dump) (scn, &shdr_mem, name);
9643 }
9644 }
9645
9646 if (unlikely (!found) && !a->implicit)
9647 error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
9648 }
9649 }
9650 }
9651
9652 static void
dump_data(Ebl * ebl)9653 dump_data (Ebl *ebl)
9654 {
9655 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
9656 }
9657
9658 static void
dump_strings(Ebl * ebl)9659 dump_strings (Ebl *ebl)
9660 {
9661 for_each_section_argument (ebl->elf, string_sections, &print_string_section);
9662 }
9663
9664 static void
print_strings(Ebl * ebl)9665 print_strings (Ebl *ebl)
9666 {
9667 /* Get the section header string table index. */
9668 size_t shstrndx;
9669 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
9670 error (EXIT_FAILURE, 0,
9671 gettext ("cannot get section header string table index"));
9672
9673 Elf_Scn *scn;
9674 GElf_Shdr shdr_mem;
9675 const char *name;
9676 scn = NULL;
9677 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
9678 {
9679 if (gelf_getshdr (scn, &shdr_mem) == NULL)
9680 continue;
9681
9682 if (shdr_mem.sh_type != SHT_PROGBITS
9683 || !(shdr_mem.sh_flags & SHF_STRINGS))
9684 continue;
9685
9686 name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
9687 if (name == NULL)
9688 continue;
9689
9690 print_string_section (scn, &shdr_mem, name);
9691 }
9692 }
9693
9694 static void
dump_archive_index(Elf * elf,const char * fname)9695 dump_archive_index (Elf *elf, const char *fname)
9696 {
9697 size_t narsym;
9698 const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
9699 if (arsym == NULL)
9700 {
9701 int result = elf_errno ();
9702 if (unlikely (result != ELF_E_NO_INDEX))
9703 error (EXIT_FAILURE, 0,
9704 gettext ("cannot get symbol index of archive '%s': %s"),
9705 fname, elf_errmsg (result));
9706 else
9707 printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
9708 return;
9709 }
9710
9711 printf (gettext ("\nIndex of archive '%s' has %zu entries:\n"),
9712 fname, narsym);
9713
9714 size_t as_off = 0;
9715 for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
9716 {
9717 if (s->as_off != as_off)
9718 {
9719 as_off = s->as_off;
9720
9721 Elf *subelf = NULL;
9722 if (unlikely (elf_rand (elf, as_off) == 0)
9723 || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
9724 == NULL))
9725 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
9726 while (1)
9727 #endif
9728 error (EXIT_FAILURE, 0,
9729 gettext ("cannot extract member at offset %zu in '%s': %s"),
9730 as_off, fname, elf_errmsg (-1));
9731
9732 const Elf_Arhdr *h = elf_getarhdr (subelf);
9733
9734 printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
9735
9736 elf_end (subelf);
9737 }
9738
9739 printf ("\t%s\n", s->as_name);
9740 }
9741 }
9742
9743 #include "debugpred.h"
9744