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