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. */ 60static void print_version (FILE *stream, struct argp_state *state); 61ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; 62 63/* Bug report address. */ 64ARGP_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. */ 70static 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. */ 122static const char doc[] = N_("\ 123Print information from ELF file in human-readable form."); 124 125/* Strings for arguments in help texts. */ 126static const char args_doc[] = N_("FILE..."); 127 128/* Prototype for option handler. */ 129static error_t parse_opt (int key, char *arg, struct argp_state *state); 130 131/* Data structure to communicate with argp functions. */ 132static 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. */ 138static 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. */ 143static bool print_dynamic_table; 144 145/* True if the file header should be printed. */ 146static bool print_file_header; 147 148/* True if the program headers should be printed. */ 149static bool print_program_header; 150 151/* True if relocations should be printed. */ 152static bool print_relocations; 153 154/* True if the section headers should be printed. */ 155static bool print_section_header; 156 157/* True if the symbol table should be printed. */ 158static bool print_symbol_table; 159 160/* True if the version information should be printed. */ 161static bool print_version_info; 162 163/* True if section groups should be printed. */ 164static bool print_section_groups; 165 166/* True if bucket list length histogram should be printed. */ 167static bool print_histogram; 168 169/* True if the architecture specific data should be printed. */ 170static bool print_arch; 171 172/* True if note section content should be printed. */ 173static bool print_notes; 174 175/* True if SHF_STRINGS section content should be printed. */ 176static bool print_string_sections; 177 178/* True if archive index should be printed. */ 179static bool print_archive_index; 180 181/* True if any of the control options except print_archive_index is set. */ 182static bool any_control_option; 183 184/* True if we should print addresses from DWARF in symbolic form. */ 185static bool print_address_names = true; 186 187/* True if we should print raw values instead of relativized addresses. */ 188static bool print_unresolved_addresses = false; 189 190/* True if we should print the .debug_aranges section using libdw. */ 191static bool decodedaranges = false; 192 193/* True if we should print the .debug_aranges section using libdw. */ 194static bool decodedline = false; 195 196/* True if we want to show more information about compressed sections. */ 197static bool print_decompress = false; 198 199/* Select printing of debugging sections. */ 200static 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. */ 224static struct section_argument *dump_data_sections; 225static struct section_argument **dump_data_sections_tail = &dump_data_sections; 226 227/* Select string dumping of sections. */ 228static struct section_argument *string_sections; 229static struct section_argument **string_sections_tail = &string_sections; 230 231struct 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. */ 239static size_t shnum; 240static size_t phnum; 241 242 243/* Declarations of local functions. */ 244static void process_file (int fd, const char *fname, bool only_one); 245static void process_elf_file (Dwfl_Module *dwflmod, int fd); 246static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr); 247static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr); 248static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr); 249static void print_scngrp (Ebl *ebl); 250static void print_dynamic (Ebl *ebl); 251static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr); 252static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, 253 GElf_Shdr *shdr); 254static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, 255 GElf_Shdr *shdr); 256static void print_symtab (Ebl *ebl, int type); 257static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 258static void print_verinfo (Ebl *ebl); 259static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 260static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 261static void handle_versym (Ebl *ebl, Elf_Scn *scn, 262 GElf_Shdr *shdr); 263static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr); 264static void handle_hash (Ebl *ebl); 265static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr); 266static void print_liblist (Ebl *ebl); 267static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr); 268static void dump_data (Ebl *ebl); 269static void dump_strings (Ebl *ebl); 270static void print_strings (Ebl *ebl); 271static void dump_archive_index (Elf *, const char *); 272 273 274int 275main (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. */ 313static error_t 314parse_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. */ 505static void 506print_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 ("\ 510Copyright (C) %s Red Hat, Inc.\n\ 511This is free software; see the source for copying conditions. There is NO\n\ 512warranty; 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. */ 520static int 521open_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. */ 634static void 635check_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. */ 663static int 664count_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 676struct process_dwflmod_args 677{ 678 int fd; 679 bool only_one; 680}; 681 682static int 683process_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. */ 708static int 709find_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. */ 734static void 735process_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. */ 810static bool 811elf_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. */ 825static void 826process_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. */ 941static void 942print_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. */ 966static void 967print_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 1077static const char * 1078get_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 1095static const char * 1096elf_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. */ 1108static void 1109print_shdr (Ebl *ebl, GElf_Ehdr *ehdr) 1110{ 1111 size_t cnt; 1112 size_t shstrndx; 1113 1114 if (! print_file_header) 1115 printf (gettext ("\ 1116There 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. */ 1235static void 1236print_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 1445static const char * 1446section_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 1452static void 1453handle_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 1511static void 1512print_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 1539static 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 }; 1551static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]); 1552 1553static 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 }; 1573static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]); 1574 1575static const struct flags dt_feature_1[] = 1576 { 1577 { DTF_1_PARINIT, "PARINIT" }, 1578 { DTF_1_CONFEXP, "CONFEXP" } 1579 }; 1580static const int ndt_feature_1 = (sizeof (dt_feature_1) 1581 / sizeof (dt_feature_1[0])); 1582 1583static const struct flags dt_posflag_1[] = 1584 { 1585 { DF_P1_LAZYLOAD, "LAZYLOAD" }, 1586 { DF_P1_GROUPPERM, "GROUPPERM" } 1587 }; 1588static const int ndt_posflag_1 = (sizeof (dt_posflag_1) 1589 / sizeof (dt_posflag_1[0])); 1590 1591 1592static void 1593print_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 1620static void 1621print_dt_flags (int class, GElf_Xword d_val) 1622{ 1623 print_flags (class, d_val, dt_flags, ndt_flags); 1624} 1625 1626 1627static void 1628print_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 1634static void 1635print_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 1641static void 1642print_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 1648static void 1649handle_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. */ 1787static void 1788print_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. */ 1809static void 1810print_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. */ 1833static void 1834handle_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. */ 2023static void 2024handle_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. */ 2219static void 2220print_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 2248static void 2249handle_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. */ 2486static void 2487print_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 2512static const char * 2513get_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 2544static void 2545handle_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 2622static void 2623handle_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 2705static void 2706handle_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 3002static void 3003print_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. */ 3079static void 3080handle_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. */ 3134static void 3135handle_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. */ 3190static void 3191handle_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. */ 3294static void 3295handle_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 3336static void 3337print_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 3399static void 3400print_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 3591static char * 3592format_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 3674static const char * 3675dwarf_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 3688static const char * 3689dwarf_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 3702static const char * 3703dwarf_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 3716static const char * 3717dwarf_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 3730static const char * 3731dwarf_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 3747static const char * 3748dwarf_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 3764static const char * 3765dwarf_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 3781static const char * 3782dwarf_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 3798static const char * 3799dwarf_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 3815static const char * 3816dwarf_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 3832static const char * 3833dwarf_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 3849static const char * 3850dwarf_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 3866static const char * 3867dwarf_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 3883static const char * 3884dwarf_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. */ 3904static const char * 3905string_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 3931static const char * 3932dwarf_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 3938static const char * 3939dwarf_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 3946static const char * 3947dwarf_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 3954static const char * 3955dwarf_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 3962static const char * 3963dwarf_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 3970static const char * 3971dwarf_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 3978static const char * 3979dwarf_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 3986static const char * 3987dwarf_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 3994static const char * 3995dwarf_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 4002static const char * 4003dwarf_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 4010static const char * 4011dwarf_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 4018static const char * 4019dwarf_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 4026static const char * 4027dwarf_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 4034static void 4035print_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 4050static void 4051print_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 4445struct 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 4457static Dwarf_Addr 4458listptr_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 4477static int 4478compare_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 4517struct listptr_table 4518{ 4519 size_t n; 4520 size_t alloc; 4521 struct listptr *table; 4522}; 4523 4524static struct listptr_table known_loclistptr; 4525static struct listptr_table known_rangelistptr; 4526 4527static void 4528reset_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. */ 4536static bool 4537notice_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 4572static void 4573sort_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 4580static bool 4581skip_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 4624static void 4625print_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. */ 4698static void 4699print_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. */ 4764static void 4765print_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. */ 4923static void 4924print_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 5015static const char * 5016register_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 5047static void 5048print_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 5307static unsigned int 5308encoded_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 5326static unsigned int 5327print_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 5367static unsigned int 5368print_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 5395static void 5396print_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 5424static const unsigned char * 5425read_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 5480static void 5481print_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 5860struct 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 5874static int 5875attr_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 6197static void 6198print_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 6353static void 6354print_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 6360static void 6361print_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 6368static void 6369print_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 6458static void 6459print_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 6986static void 6987print_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 7092struct mac_culist 7093{ 7094 Dwarf_Die die; 7095 Dwarf_Off offset; 7096 Dwarf_Files *files; 7097 struct mac_culist *next; 7098}; 7099 7100 7101static int 7102mac_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 7115static void 7116print_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 7279static void 7280print_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. */ 7689static int 7690print_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'. */ 7704static void 7705print_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'. */ 7718static void 7719print_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'. */ 7764static void 7765print_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'. */ 7864static void 7865print_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*/ 8044static void 8045print_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 8297static void 8298print_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 8401static unsigned int 8402__attribute__ ((format (printf, 6, 7))) 8403print_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 8443static const void * 8444convert (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 8472typedef uint8_t GElf_Byte; 8473 8474static unsigned int 8475handle_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. */ 8719static int 8720compare_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. */ 8733static int 8734compare_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 8746static unsigned int 8747handle_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 8840static unsigned int 8841handle_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 8851static unsigned int 8852handle_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 8949struct 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 8959static int 8960register_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 8967static int 8968compare_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. */ 8976static int 8977compare_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. */ 8993static int 8994compare_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 9001static unsigned int 9002handle_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 9082static void 9083handle_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 9154static bool 9155buf_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 9160static bool 9161buf_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 9171static bool 9172buf_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 9194static void 9195handle_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 9252static void 9253handle_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 9303static void 9304handle_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 9333static void 9334handle_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 9409static void 9410handle_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 9467static void 9468hex_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 9497static void 9498dump_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 9538static void 9539print_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 9594static void 9595for_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 9652static void 9653dump_data (Ebl *ebl) 9654{ 9655 for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section); 9656} 9657 9658static void 9659dump_strings (Ebl *ebl) 9660{ 9661 for_each_section_argument (ebl->elf, string_sections, &print_string_section); 9662} 9663 9664static void 9665print_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 9694static void 9695dump_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