1 /* Print information from ELF file in human-readable form. 2 Copyright (C) 1999-2012 Red Hat, Inc. 3 This file is part of Red Hat elfutils. 4 Written by Ulrich Drepper <drepper (at) redhat.com>, 1999. 5 6 Red Hat elfutils is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by the 8 Free Software Foundation; version 2 of the License. 9 10 Red Hat elfutils is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License along 16 with Red Hat elfutils; if not, write to the Free Software Foundation, 17 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 18 19 Red Hat elfutils is an included package of the Open Invention Network. 20 An included package of the Open Invention Network is a package for which 21 Open Invention Network licensees cross-license their patents. No patent 22 license is granted, either expressly or impliedly, by designation as an 23 included package. Should you wish to participate in the Open Invention 24 Network licensing program, please visit www.openinventionnetwork.com 25 <http://www.openinventionnetwork.com>. */ 26 27 #ifdef HAVE_CONFIG_H 28 # include <config.h> 29 #endif 30 31 #include <argp.h> 32 #include <assert.h> 33 #include <ctype.h> 34 #include <dwarf.h> 35 #include <errno.h> 36 #include <error.h> 37 #include <fcntl.h> 38 #include <gelf.h> 39 #include <inttypes.h> 40 #include <langinfo.h> 41 #include <libdw.h> 42 #include <libdwfl.h> 43 #include <libintl.h> 44 #include <locale.h> 45 #include <stdarg.h> 46 #include <stdbool.h> 47 #include <stdlib.h> 48 #include <string.h> 49 #include <time.h> 50 #include <unistd.h> 51 #include <sys/param.h> 52 #include <sys/stat.h> 53 54 #include <system.h> 55 #include "../libelf/libelfP.h" 56 #include "../libelf/common.h" 57 #include "../libebl/libeblP.h" 58 #include "../libdw/libdwP.h" 59 #include "../libdwfl/libdwflP.h" 60 #include "../libdw/memory-access.h" 61 62 63 /* Name and version of program. */ 64 static void print_version (FILE *stream, struct argp_state *state); 65 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; 66 67 /* Bug report address. */ 68 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; 69 70 /* Definitions of arguments for argp functions. */ 71 static const struct argp_option options[] = 72 { 73 { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 }, 74 { "all", 'a', NULL, 0, 75 N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 }, 76 { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 }, 77 { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 }, 78 { "histogram", 'I', NULL, 0, 79 N_("Display histogram of bucket list lengths"), 0 }, 80 { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 }, 81 { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, 82 { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 }, 83 { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 }, 84 { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, 85 { "symbols", 's', NULL, 0, N_("Display the symbol table"), 0 }, 86 { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 }, 87 { "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 }, 88 { "arch-specific", 'A', NULL, 0, 89 N_("Display architecture specific information, if any"), 0 }, 90 { "exception", 'e', NULL, 0, 91 N_("Display sections for exception handling"), 0 }, 92 93 { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 }, 94 { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL, 95 N_("Display DWARF section content. SECTION can be one of abbrev, " 96 "aranges, frame, gdb_index, info, loc, line, ranges, pubnames, str, " 97 "macinfo, or exception"), 0 }, 98 { "hex-dump", 'x', "SECTION", 0, 99 N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 }, 100 { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL, 101 N_("Print string contents of sections"), 0 }, 102 { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, 103 { "archive-index", 'c', NULL, 0, 104 N_("Display the symbol index of an archive"), 0 }, 105 106 { NULL, 0, NULL, 0, N_("Output control:"), 0 }, 107 { "numeric-addresses", 'N', NULL, 0, 108 N_("Do not find symbol names for addresses in DWARF data"), 0 }, 109 { "wide", 'W', NULL, 0, 110 N_("Ignored for compatibility (lines always wide)"), 0 }, 111 { NULL, 0, NULL, 0, NULL, 0 } 112 }; 113 114 /* Short description of program. */ 115 static const char doc[] = N_("\ 116 Print information from ELF file in human-readable form."); 117 118 /* Strings for arguments in help texts. */ 119 static const char args_doc[] = N_("FILE..."); 120 121 /* Prototype for option handler. */ 122 static error_t parse_opt (int key, char *arg, struct argp_state *state); 123 124 /* Data structure to communicate with argp functions. */ 125 static struct argp argp = 126 { 127 options, parse_opt, args_doc, doc, NULL, NULL, NULL 128 }; 129 130 131 /* Flags set by the option controlling the output. */ 132 133 /* True if dynamic segment should be printed. */ 134 static bool print_dynamic_table; 135 136 /* True if the file header should be printed. */ 137 static bool print_file_header; 138 139 /* True if the program headers should be printed. */ 140 static bool print_program_header; 141 142 /* True if relocations should be printed. */ 143 static bool print_relocations; 144 145 /* True if the section headers should be printed. */ 146 static bool print_section_header; 147 148 /* True if the symbol table should be printed. */ 149 static bool print_symbol_table; 150 151 /* True if the version information should be printed. */ 152 static bool print_version_info; 153 154 /* True if section groups should be printed. */ 155 static bool print_section_groups; 156 157 /* True if bucket list length histogram should be printed. */ 158 static bool print_histogram; 159 160 /* True if the architecture specific data should be printed. */ 161 static bool print_arch; 162 163 /* True if note section content should be printed. */ 164 static bool print_notes; 165 166 /* True if SHF_STRINGS section content should be printed. */ 167 static bool print_string_sections; 168 169 /* True if archive index should be printed. */ 170 static bool print_archive_index; 171 172 /* True if any of the control options except print_archive_index is set. */ 173 static bool any_control_option; 174 175 /* True if we should print addresses from DWARF in symbolic form. */ 176 static bool print_address_names = true; 177 178 /* Select printing of debugging sections. */ 179 static enum section_e 180 { 181 section_abbrev = 1, /* .debug_abbrev */ 182 section_aranges = 2, /* .debug_aranges */ 183 section_frame = 4, /* .debug_frame or .eh_frame & al. */ 184 section_info = 8, /* .debug_info, .debug_types */ 185 section_types = section_info, 186 section_line = 16, /* .debug_line */ 187 section_loc = 32, /* .debug_loc */ 188 section_pubnames = 64, /* .debug_pubnames */ 189 section_str = 128, /* .debug_str */ 190 section_macinfo = 256, /* .debug_macinfo */ 191 section_ranges = 512, /* .debug_ranges */ 192 section_exception = 1024, /* .eh_frame & al. */ 193 section_gdb_index = 2048, /* .gdb_index */ 194 section_all = (section_abbrev | section_aranges | section_frame 195 | section_info | section_line | section_loc 196 | section_pubnames | section_str | section_macinfo 197 | section_ranges | section_exception | section_gdb_index) 198 } print_debug_sections, implicit_debug_sections; 199 200 /* Select hex dumping of sections. */ 201 static struct section_argument *dump_data_sections; 202 static struct section_argument **dump_data_sections_tail = &dump_data_sections; 203 204 /* Select string dumping of sections. */ 205 static struct section_argument *string_sections; 206 static struct section_argument **string_sections_tail = &string_sections; 207 208 struct section_argument 209 { 210 struct section_argument *next; 211 const char *arg; 212 bool implicit; 213 }; 214 215 /* Numbers of sections and program headers in the file. */ 216 static size_t shnum; 217 static size_t phnum; 218 219 220 /* Declarations of local functions. */ 221 static void process_file (int fd, const char *fname, bool only_one); 222 static void process_elf_file (Dwfl_Module *dwflmod, int fd); 223 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr); 224 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr); 225 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr); 226 static void print_scngrp (Ebl *ebl); 227 static void print_dynamic (Ebl *ebl); 228 static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr); 229 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, 230 GElf_Shdr *shdr); 231 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, 232 GElf_Shdr *shdr); 233 static void print_symtab (Ebl *ebl, int type); 234 static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 235 static void print_verinfo (Ebl *ebl); 236 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 237 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 238 static void handle_versym (Ebl *ebl, Elf_Scn *scn, 239 GElf_Shdr *shdr); 240 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr); 241 static void handle_hash (Ebl *ebl); 242 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr); 243 static void print_liblist (Ebl *ebl); 244 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr); 245 static void dump_data (Ebl *ebl); 246 static void dump_strings (Ebl *ebl); 247 static void print_strings (Ebl *ebl); 248 static void dump_archive_index (Elf *, const char *); 249 250 251 int 252 main (int argc, char *argv[]) 253 { 254 /* Set locale. */ 255 setlocale (LC_ALL, ""); 256 257 /* Initialize the message catalog. */ 258 textdomain (PACKAGE_TARNAME); 259 260 /* Parse and process arguments. */ 261 int remaining; 262 argp_parse (&argp, argc, argv, 0, &remaining, NULL); 263 264 /* Before we start tell the ELF library which version we are using. */ 265 elf_version (EV_CURRENT); 266 267 /* Now process all the files given at the command line. */ 268 bool only_one = remaining + 1 == argc; 269 do 270 { 271 /* Open the file. */ 272 int fd = open (argv[remaining], O_RDONLY); 273 if (fd == -1) 274 { 275 error (0, errno, gettext ("cannot open input file")); 276 continue; 277 } 278 279 process_file (fd, argv[remaining], only_one); 280 281 close (fd); 282 } 283 while (++remaining < argc); 284 285 return error_message_count != 0; 286 } 287 288 289 /* Handle program arguments. */ 290 static error_t 291 parse_opt (int key, char *arg, 292 struct argp_state *state __attribute__ ((unused))) 293 { 294 void add_dump_section (const char *name, bool implicit) 295 { 296 struct section_argument *a = xmalloc (sizeof *a); 297 a->arg = name; 298 a->next = NULL; 299 a->implicit = implicit; 300 struct section_argument ***tailp 301 = key == 'x' ? &dump_data_sections_tail : &string_sections_tail; 302 **tailp = a; 303 *tailp = &a->next; 304 } 305 306 switch (key) 307 { 308 case 'a': 309 print_file_header = true; 310 print_program_header = true; 311 print_relocations = true; 312 print_section_header = true; 313 print_symbol_table = true; 314 print_version_info = true; 315 print_dynamic_table = true; 316 print_section_groups = true; 317 print_histogram = true; 318 print_arch = true; 319 print_notes = true; 320 implicit_debug_sections |= section_exception; 321 add_dump_section (".strtab", true); 322 add_dump_section (".dynstr", true); 323 add_dump_section (".comment", true); 324 any_control_option = true; 325 break; 326 case 'A': 327 print_arch = true; 328 any_control_option = true; 329 break; 330 case 'd': 331 print_dynamic_table = true; 332 any_control_option = true; 333 break; 334 case 'e': 335 print_debug_sections |= section_exception; 336 any_control_option = true; 337 break; 338 case 'g': 339 print_section_groups = true; 340 any_control_option = true; 341 break; 342 case 'h': 343 print_file_header = true; 344 any_control_option = true; 345 break; 346 case 'I': 347 print_histogram = true; 348 any_control_option = true; 349 break; 350 case 'l': 351 print_program_header = true; 352 any_control_option = true; 353 break; 354 case 'n': 355 print_notes = true; 356 any_control_option = true; 357 break; 358 case 'r': 359 print_relocations = true; 360 any_control_option = true; 361 break; 362 case 'S': 363 print_section_header = true; 364 any_control_option = true; 365 break; 366 case 's': 367 print_symbol_table = true; 368 any_control_option = true; 369 break; 370 case 'V': 371 print_version_info = true; 372 any_control_option = true; 373 break; 374 case 'c': 375 print_archive_index = true; 376 break; 377 case 'w': 378 if (arg == NULL) 379 print_debug_sections = section_all; 380 else if (strcmp (arg, "abbrev") == 0) 381 print_debug_sections |= section_abbrev; 382 else if (strcmp (arg, "aranges") == 0) 383 print_debug_sections |= section_aranges; 384 else if (strcmp (arg, "ranges") == 0) 385 { 386 print_debug_sections |= section_ranges; 387 implicit_debug_sections |= section_info; 388 } 389 else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0) 390 print_debug_sections |= section_frame; 391 else if (strcmp (arg, "info") == 0) 392 print_debug_sections |= section_info; 393 else if (strcmp (arg, "loc") == 0) 394 { 395 print_debug_sections |= section_loc; 396 implicit_debug_sections |= section_info; 397 } 398 else if (strcmp (arg, "line") == 0) 399 print_debug_sections |= section_line; 400 else if (strcmp (arg, "pubnames") == 0) 401 print_debug_sections |= section_pubnames; 402 else if (strcmp (arg, "str") == 0) 403 print_debug_sections |= section_str; 404 else if (strcmp (arg, "macinfo") == 0) 405 print_debug_sections |= section_macinfo; 406 else if (strcmp (arg, "exception") == 0) 407 print_debug_sections |= section_exception; 408 else if (strcmp (arg, "gdb_index") == 0) 409 print_debug_sections |= section_gdb_index; 410 else 411 { 412 fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"), 413 arg); 414 argp_help (&argp, stderr, ARGP_HELP_SEE, 415 program_invocation_short_name); 416 exit (1); 417 } 418 any_control_option = true; 419 break; 420 case 'p': 421 any_control_option = true; 422 if (arg == NULL) 423 { 424 print_string_sections = true; 425 break; 426 } 427 /* Fall through. */ 428 case 'x': 429 add_dump_section (arg, false); 430 any_control_option = true; 431 break; 432 case 'N': 433 print_address_names = false; 434 break; 435 case ARGP_KEY_NO_ARGS: 436 fputs (gettext ("Missing file name.\n"), stderr); 437 goto do_argp_help; 438 case ARGP_KEY_FINI: 439 if (! any_control_option && ! print_archive_index) 440 { 441 fputs (gettext ("No operation specified.\n"), stderr); 442 do_argp_help: 443 argp_help (&argp, stderr, ARGP_HELP_SEE, 444 program_invocation_short_name); 445 exit (EXIT_FAILURE); 446 } 447 break; 448 case 'W': /* Ignored. */ 449 break; 450 default: 451 return ARGP_ERR_UNKNOWN; 452 } 453 return 0; 454 } 455 456 457 /* Print the version information. */ 458 static void 459 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 460 { 461 fprintf (stream, "readelf (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 462 fprintf (stream, gettext ("\ 463 Copyright (C) %s Red Hat, Inc.\n\ 464 This is free software; see the source for copying conditions. There is NO\n\ 465 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 466 "), "2012"); 467 fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 468 } 469 470 471 /* Check if the file is an archive, and if so dump its index. */ 472 static void 473 check_archive_index (int fd, const char *fname, bool only_one) 474 { 475 /* Create an `Elf' descriptor. */ 476 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 477 if (elf == NULL) 478 error (0, 0, gettext ("cannot generate Elf descriptor: %s"), 479 elf_errmsg (-1)); 480 else 481 { 482 if (elf_kind (elf) == ELF_K_AR) 483 { 484 if (!only_one) 485 printf ("\n%s:\n\n", fname); 486 dump_archive_index (elf, fname); 487 } 488 else 489 error (0, 0, 490 gettext ("'%s' is not an archive, cannot print archive index"), 491 fname); 492 493 /* Now we can close the descriptor. */ 494 if (elf_end (elf) != 0) 495 error (0, 0, gettext ("error while closing Elf descriptor: %s"), 496 elf_errmsg (-1)); 497 } 498 } 499 500 /* Trivial callback used for checking if we opened an archive. */ 501 static int 502 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)), 503 void **userdata __attribute__ ((unused)), 504 const char *name __attribute__ ((unused)), 505 Dwarf_Addr base __attribute__ ((unused)), 506 void *arg) 507 { 508 if (*(bool *) arg) 509 return DWARF_CB_ABORT; 510 *(bool *) arg = true; 511 return DWARF_CB_OK; 512 } 513 514 struct process_dwflmod_args 515 { 516 int fd; 517 bool only_one; 518 }; 519 520 static int 521 process_dwflmod (Dwfl_Module *dwflmod, 522 void **userdata __attribute__ ((unused)), 523 const char *name __attribute__ ((unused)), 524 Dwarf_Addr base __attribute__ ((unused)), 525 void *arg) 526 { 527 const struct process_dwflmod_args *a = arg; 528 529 /* Print the file name. */ 530 if (!a->only_one) 531 { 532 const char *fname; 533 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL); 534 535 printf ("\n%s:\n\n", fname); 536 } 537 538 process_elf_file (dwflmod, a->fd); 539 540 return DWARF_CB_OK; 541 } 542 543 /* Stub libdwfl callback, only the ELF handle already open is ever used. */ 544 static int 545 find_no_debuginfo (Dwfl_Module *mod __attribute__ ((unused)), 546 void **userdata __attribute__ ((unused)), 547 const char *modname __attribute__ ((unused)), 548 Dwarf_Addr base __attribute__ ((unused)), 549 const char *file_name __attribute__ ((unused)), 550 const char *debuglink_file __attribute__ ((unused)), 551 GElf_Word debuglink_crc __attribute__ ((unused)), 552 char **debuginfo_file_name __attribute__ ((unused))) 553 { 554 return -1; 555 } 556 557 /* Process one input file. */ 558 static void 559 process_file (int fd, const char *fname, bool only_one) 560 { 561 if (print_archive_index) 562 check_archive_index (fd, fname, only_one); 563 564 if (!any_control_option) 565 return; 566 567 /* Duplicate an fd for dwfl_report_offline to swallow. */ 568 int dwfl_fd = dup (fd); 569 if (unlikely (dwfl_fd < 0)) 570 error (EXIT_FAILURE, errno, "dup"); 571 572 /* Use libdwfl in a trivial way to open the libdw handle for us. 573 This takes care of applying relocations to DWARF data in ET_REL files. */ 574 static const Dwfl_Callbacks callbacks = 575 { 576 .section_address = dwfl_offline_section_address, 577 .find_debuginfo = find_no_debuginfo 578 }; 579 Dwfl *dwfl = dwfl_begin (&callbacks); 580 if (likely (dwfl != NULL)) 581 /* Let 0 be the logical address of the file (or first in archive). */ 582 dwfl->offline_next_address = 0; 583 if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL) 584 { 585 struct stat64 st; 586 if (fstat64 (dwfl_fd, &st) != 0) 587 error (0, errno, gettext ("cannot stat input file")); 588 else if (unlikely (st.st_size == 0)) 589 error (0, 0, gettext ("input file is empty")); 590 else 591 error (0, 0, gettext ("failed reading '%s': %s"), 592 fname, dwfl_errmsg (-1)); 593 close (dwfl_fd); /* Consumed on success, not on failure. */ 594 } 595 else 596 { 597 dwfl_report_end (dwfl, NULL, NULL); 598 599 if (only_one) 600 { 601 /* Clear ONLY_ONE if we have multiple modules, from an archive. */ 602 bool seen = false; 603 only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0; 604 } 605 606 /* Process the one or more modules gleaned from this file. */ 607 struct process_dwflmod_args a = { .fd = fd, .only_one = only_one }; 608 dwfl_getmodules (dwfl, &process_dwflmod, &a, 0); 609 } 610 dwfl_end (dwfl); 611 } 612 613 614 /* Process one ELF file. */ 615 static void 616 process_elf_file (Dwfl_Module *dwflmod, int fd) 617 { 618 GElf_Addr dwflbias; 619 Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias); 620 621 GElf_Ehdr ehdr_mem; 622 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 623 624 if (ehdr == NULL) 625 { 626 elf_error: 627 error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1)); 628 return; 629 } 630 631 Ebl *ebl = ebl_openbackend (elf); 632 if (unlikely (ebl == NULL)) 633 { 634 ebl_error: 635 error (0, errno, gettext ("cannot create EBL handle")); 636 return; 637 } 638 639 /* Determine the number of sections. */ 640 if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0)) 641 error (EXIT_FAILURE, 0, 642 gettext ("cannot determine number of sections: %s"), 643 elf_errmsg (-1)); 644 645 /* Determine the number of phdrs. */ 646 if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0)) 647 error (EXIT_FAILURE, 0, 648 gettext ("cannot determine number of program headers: %s"), 649 elf_errmsg (-1)); 650 651 /* For an ET_REL file, libdwfl has adjusted the in-core shdrs 652 and may have applied relocation to some sections. 653 So we need to get a fresh Elf handle on the file to display those. */ 654 bool print_unrelocated = (print_section_header 655 || print_relocations 656 || dump_data_sections != NULL 657 || print_notes); 658 659 Elf *pure_elf = NULL; 660 Ebl *pure_ebl = ebl; 661 if (ehdr->e_type == ET_REL && print_unrelocated) 662 { 663 /* Read the file afresh. */ 664 off64_t aroff = elf_getaroff (elf); 665 pure_elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 666 if (aroff > 0) 667 { 668 /* Archive member. */ 669 (void) elf_rand (pure_elf, aroff); 670 Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf); 671 elf_end (pure_elf); 672 pure_elf = armem; 673 } 674 if (pure_elf == NULL) 675 goto elf_error; 676 pure_ebl = ebl_openbackend (pure_elf); 677 if (pure_ebl == NULL) 678 goto ebl_error; 679 } 680 681 if (print_file_header) 682 print_ehdr (ebl, ehdr); 683 if (print_section_header) 684 print_shdr (pure_ebl, ehdr); 685 if (print_program_header) 686 print_phdr (ebl, ehdr); 687 if (print_section_groups) 688 print_scngrp (ebl); 689 if (print_dynamic_table) 690 print_dynamic (ebl); 691 if (print_relocations) 692 print_relocs (pure_ebl, ehdr); 693 if (print_histogram) 694 handle_hash (ebl); 695 if (print_symbol_table) 696 print_symtab (ebl, SHT_DYNSYM); 697 if (print_version_info) 698 print_verinfo (ebl); 699 if (print_symbol_table) 700 print_symtab (ebl, SHT_SYMTAB); 701 if (print_arch) 702 print_liblist (ebl); 703 if (print_arch) 704 print_attributes (ebl, ehdr); 705 if (dump_data_sections != NULL) 706 dump_data (pure_ebl); 707 if (string_sections != NULL) 708 dump_strings (ebl); 709 if ((print_debug_sections | implicit_debug_sections) != 0) 710 print_debug (dwflmod, ebl, ehdr); 711 if (print_notes) 712 handle_notes (pure_ebl, ehdr); 713 if (print_string_sections) 714 print_strings (ebl); 715 716 ebl_closebackend (ebl); 717 718 if (pure_ebl != ebl) 719 { 720 ebl_closebackend (pure_ebl); 721 elf_end (pure_elf); 722 } 723 } 724 725 726 /* Print file type. */ 727 static void 728 print_file_type (unsigned short int e_type) 729 { 730 if (likely (e_type <= ET_CORE)) 731 { 732 static const char *const knowntypes[] = 733 { 734 N_("NONE (None)"), 735 N_("REL (Relocatable file)"), 736 N_("EXEC (Executable file)"), 737 N_("DYN (Shared object file)"), 738 N_("CORE (Core file)") 739 }; 740 puts (gettext (knowntypes[e_type])); 741 } 742 else if (e_type >= ET_LOOS && e_type <= ET_HIOS) 743 printf (gettext ("OS Specific: (%x)\n"), e_type); 744 else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */) 745 printf (gettext ("Processor Specific: (%x)\n"), e_type); 746 else 747 puts ("???"); 748 } 749 750 751 /* Print ELF header. */ 752 static void 753 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr) 754 { 755 fputs_unlocked (gettext ("ELF Header:\n Magic: "), stdout); 756 for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt) 757 printf (" %02hhx", ehdr->e_ident[cnt]); 758 759 printf (gettext ("\n Class: %s\n"), 760 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32" 761 : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64" 762 : "\?\?\?"); 763 764 printf (gettext (" Data: %s\n"), 765 ehdr->e_ident[EI_DATA] == ELFDATA2LSB 766 ? "2's complement, little endian" 767 : ehdr->e_ident[EI_DATA] == ELFDATA2MSB 768 ? "2's complement, big endian" : "\?\?\?"); 769 770 printf (gettext (" Ident Version: %hhd %s\n"), 771 ehdr->e_ident[EI_VERSION], 772 ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)") 773 : "(\?\?\?)"); 774 775 char buf[512]; 776 printf (gettext (" OS/ABI: %s\n"), 777 ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf))); 778 779 printf (gettext (" ABI Version: %hhd\n"), 780 ehdr->e_ident[EI_ABIVERSION]); 781 782 fputs_unlocked (gettext (" Type: "), stdout); 783 print_file_type (ehdr->e_type); 784 785 printf (gettext (" Machine: %s\n"), ebl->name); 786 787 printf (gettext (" Version: %d %s\n"), 788 ehdr->e_version, 789 ehdr->e_version == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)"); 790 791 printf (gettext (" Entry point address: %#" PRIx64 "\n"), 792 ehdr->e_entry); 793 794 printf (gettext (" Start of program headers: %" PRId64 " %s\n"), 795 ehdr->e_phoff, gettext ("(bytes into file)")); 796 797 printf (gettext (" Start of section headers: %" PRId64 " %s\n"), 798 ehdr->e_shoff, gettext ("(bytes into file)")); 799 800 printf (gettext (" Flags: %s\n"), 801 ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf))); 802 803 printf (gettext (" Size of this header: %" PRId16 " %s\n"), 804 ehdr->e_ehsize, gettext ("(bytes)")); 805 806 printf (gettext (" Size of program header entries: %" PRId16 " %s\n"), 807 ehdr->e_phentsize, gettext ("(bytes)")); 808 809 printf (gettext (" Number of program headers entries: %" PRId16), 810 ehdr->e_phnum); 811 if (ehdr->e_phnum == PN_XNUM) 812 { 813 GElf_Shdr shdr_mem; 814 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 815 if (shdr != NULL) 816 printf (gettext (" (%" PRIu32 " in [0].sh_info)"), 817 (uint32_t) shdr->sh_info); 818 else 819 fputs_unlocked (gettext (" ([0] not available)"), stdout); 820 } 821 fputc_unlocked ('\n', stdout); 822 823 printf (gettext (" Size of section header entries: %" PRId16 " %s\n"), 824 ehdr->e_shentsize, gettext ("(bytes)")); 825 826 printf (gettext (" Number of section headers entries: %" PRId16), 827 ehdr->e_shnum); 828 if (ehdr->e_shnum == 0) 829 { 830 GElf_Shdr shdr_mem; 831 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 832 if (shdr != NULL) 833 printf (gettext (" (%" PRIu32 " in [0].sh_size)"), 834 (uint32_t) shdr->sh_size); 835 else 836 fputs_unlocked (gettext (" ([0] not available)"), stdout); 837 } 838 fputc_unlocked ('\n', stdout); 839 840 if (unlikely (ehdr->e_shstrndx == SHN_XINDEX)) 841 { 842 GElf_Shdr shdr_mem; 843 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 844 if (shdr != NULL) 845 /* We managed to get the zeroth section. */ 846 snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"), 847 (uint32_t) shdr->sh_link); 848 else 849 { 850 strncpy (buf, gettext (" ([0] not available)"), sizeof (buf)); 851 buf[sizeof (buf) - 1] = '\0'; 852 } 853 854 printf (gettext (" Section header string table index: XINDEX%s\n\n"), 855 buf); 856 } 857 else 858 printf (gettext (" Section header string table index: %" PRId16 "\n\n"), 859 ehdr->e_shstrndx); 860 } 861 862 863 static const char * 864 get_visibility_type (int value) 865 { 866 switch (value) 867 { 868 case STV_DEFAULT: 869 return "DEFAULT"; 870 case STV_INTERNAL: 871 return "INTERNAL"; 872 case STV_HIDDEN: 873 return "HIDDEN"; 874 case STV_PROTECTED: 875 return "PROTECTED"; 876 default: 877 return "???"; 878 } 879 } 880 881 882 /* Print the section headers. */ 883 static void 884 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr) 885 { 886 size_t cnt; 887 size_t shstrndx; 888 889 if (! print_file_header) 890 printf (gettext ("\ 891 There are %d section headers, starting at offset %#" PRIx64 ":\n\ 892 \n"), 893 ehdr->e_shnum, ehdr->e_shoff); 894 895 /* Get the section header string table index. */ 896 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 897 error (EXIT_FAILURE, 0, 898 gettext ("cannot get section header string table index")); 899 900 puts (gettext ("Section Headers:")); 901 902 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32) 903 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al")); 904 else 905 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al")); 906 907 for (cnt = 0; cnt < shnum; ++cnt) 908 { 909 Elf_Scn *scn = elf_getscn (ebl->elf, cnt); 910 911 if (unlikely (scn == NULL)) 912 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"), 913 elf_errmsg (-1)); 914 915 /* Get the section header. */ 916 GElf_Shdr shdr_mem; 917 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 918 if (unlikely (shdr == NULL)) 919 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"), 920 elf_errmsg (-1)); 921 922 char flagbuf[20]; 923 char *cp = flagbuf; 924 if (shdr->sh_flags & SHF_WRITE) 925 *cp++ = 'W'; 926 if (shdr->sh_flags & SHF_ALLOC) 927 *cp++ = 'A'; 928 if (shdr->sh_flags & SHF_EXECINSTR) 929 *cp++ = 'X'; 930 if (shdr->sh_flags & SHF_MERGE) 931 *cp++ = 'M'; 932 if (shdr->sh_flags & SHF_STRINGS) 933 *cp++ = 'S'; 934 if (shdr->sh_flags & SHF_INFO_LINK) 935 *cp++ = 'I'; 936 if (shdr->sh_flags & SHF_LINK_ORDER) 937 *cp++ = 'L'; 938 if (shdr->sh_flags & SHF_OS_NONCONFORMING) 939 *cp++ = 'N'; 940 if (shdr->sh_flags & SHF_GROUP) 941 *cp++ = 'G'; 942 if (shdr->sh_flags & SHF_TLS) 943 *cp++ = 'T'; 944 if (shdr->sh_flags & SHF_ORDERED) 945 *cp++ = 'O'; 946 if (shdr->sh_flags & SHF_EXCLUDE) 947 *cp++ = 'E'; 948 *cp = '\0'; 949 950 char buf[128]; 951 printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64 952 " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32 953 " %2" PRId64 "\n", 954 cnt, 955 elf_strptr (ebl->elf, shstrndx, shdr->sh_name) 956 ?: "<corrupt>", 957 ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)), 958 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr, 959 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset, 960 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size, 961 shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info, 962 shdr->sh_addralign); 963 } 964 965 fputc_unlocked ('\n', stdout); 966 } 967 968 969 /* Print the program header. */ 970 static void 971 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr) 972 { 973 if (ehdr->e_phnum == 0) 974 /* No program header, this is OK in relocatable objects. */ 975 return; 976 977 puts (gettext ("Program Headers:")); 978 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32) 979 puts (gettext ("\ 980 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align")); 981 else 982 puts (gettext ("\ 983 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align")); 984 985 /* Process all program headers. */ 986 bool has_relro = false; 987 GElf_Addr relro_from = 0; 988 GElf_Addr relro_to = 0; 989 for (size_t cnt = 0; cnt < phnum; ++cnt) 990 { 991 char buf[128]; 992 GElf_Phdr mem; 993 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem); 994 995 /* If for some reason the header cannot be returned show this. */ 996 if (unlikely (phdr == NULL)) 997 { 998 puts (" ???"); 999 continue; 1000 } 1001 1002 printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64 1003 " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n", 1004 ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)), 1005 phdr->p_offset, 1006 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr, 1007 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr, 1008 phdr->p_filesz, 1009 phdr->p_memsz, 1010 phdr->p_flags & PF_R ? 'R' : ' ', 1011 phdr->p_flags & PF_W ? 'W' : ' ', 1012 phdr->p_flags & PF_X ? 'E' : ' ', 1013 phdr->p_align); 1014 1015 if (phdr->p_type == PT_INTERP) 1016 { 1017 /* We can show the user the name of the interpreter. */ 1018 size_t maxsize; 1019 char *filedata = elf_rawfile (ebl->elf, &maxsize); 1020 1021 if (filedata != NULL && phdr->p_offset < maxsize) 1022 printf (gettext ("\t[Requesting program interpreter: %s]\n"), 1023 filedata + phdr->p_offset); 1024 } 1025 else if (phdr->p_type == PT_GNU_RELRO) 1026 { 1027 has_relro = true; 1028 relro_from = phdr->p_vaddr; 1029 relro_to = relro_from + phdr->p_memsz; 1030 } 1031 } 1032 1033 if (ehdr->e_shnum == 0) 1034 /* No sections in the file. Punt. */ 1035 return; 1036 1037 /* Get the section header string table index. */ 1038 size_t shstrndx; 1039 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 1040 error (EXIT_FAILURE, 0, 1041 gettext ("cannot get section header string table index")); 1042 1043 puts (gettext ("\n Section to Segment mapping:\n Segment Sections...")); 1044 1045 for (size_t cnt = 0; cnt < phnum; ++cnt) 1046 { 1047 /* Print the segment number. */ 1048 printf (" %2.2zu ", cnt); 1049 1050 GElf_Phdr phdr_mem; 1051 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem); 1052 /* This must not happen. */ 1053 if (unlikely (phdr == NULL)) 1054 error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"), 1055 elf_errmsg (-1)); 1056 1057 /* Iterate over the sections. */ 1058 bool in_relro = false; 1059 bool in_ro = false; 1060 for (size_t inner = 1; inner < shnum; ++inner) 1061 { 1062 Elf_Scn *scn = elf_getscn (ebl->elf, inner); 1063 /* This should not happen. */ 1064 if (unlikely (scn == NULL)) 1065 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"), 1066 elf_errmsg (-1)); 1067 1068 /* Get the section header. */ 1069 GElf_Shdr shdr_mem; 1070 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1071 if (unlikely (shdr == NULL)) 1072 error (EXIT_FAILURE, 0, 1073 gettext ("cannot get section header: %s"), 1074 elf_errmsg (-1)); 1075 1076 if (shdr->sh_size > 0 1077 /* Compare allocated sections by VMA, unallocated 1078 sections by file offset. */ 1079 && (shdr->sh_flags & SHF_ALLOC 1080 ? (shdr->sh_addr >= phdr->p_vaddr 1081 && (shdr->sh_addr + shdr->sh_size 1082 <= phdr->p_vaddr + phdr->p_memsz)) 1083 : (shdr->sh_offset >= phdr->p_offset 1084 && (shdr->sh_offset + shdr->sh_size 1085 <= phdr->p_offset + phdr->p_filesz)))) 1086 { 1087 if (has_relro && !in_relro 1088 && shdr->sh_addr >= relro_from 1089 && shdr->sh_addr + shdr->sh_size <= relro_to) 1090 { 1091 fputs_unlocked (" [RELRO:", stdout); 1092 in_relro = true; 1093 } 1094 else if (has_relro && in_relro && shdr->sh_addr >= relro_to) 1095 { 1096 fputs_unlocked ("]", stdout); 1097 in_relro = false; 1098 } 1099 else if (has_relro && in_relro 1100 && shdr->sh_addr + shdr->sh_size > relro_to) 1101 fputs_unlocked ("] <RELRO:", stdout); 1102 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0) 1103 { 1104 if (!in_ro) 1105 { 1106 fputs_unlocked (" [RO:", stdout); 1107 in_ro = true; 1108 } 1109 } 1110 else 1111 { 1112 /* Determine the segment this section is part of. */ 1113 size_t cnt2; 1114 GElf_Phdr *phdr2 = NULL; 1115 for (cnt2 = 0; cnt2 < phnum; ++cnt2) 1116 { 1117 GElf_Phdr phdr2_mem; 1118 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem); 1119 1120 if (phdr2 != NULL && phdr2->p_type == PT_LOAD 1121 && shdr->sh_addr >= phdr2->p_vaddr 1122 && (shdr->sh_addr + shdr->sh_size 1123 <= phdr2->p_vaddr + phdr2->p_memsz)) 1124 break; 1125 } 1126 1127 if (cnt2 < phnum) 1128 { 1129 if ((phdr2->p_flags & PF_W) == 0 && !in_ro) 1130 { 1131 fputs_unlocked (" [RO:", stdout); 1132 in_ro = true; 1133 } 1134 else if ((phdr2->p_flags & PF_W) != 0 && in_ro) 1135 { 1136 fputs_unlocked ("]", stdout); 1137 in_ro = false; 1138 } 1139 } 1140 } 1141 1142 printf (" %s", 1143 elf_strptr (ebl->elf, shstrndx, shdr->sh_name)); 1144 1145 /* Signal that this sectin is only partially covered. */ 1146 if (has_relro && in_relro 1147 && shdr->sh_addr + shdr->sh_size > relro_to) 1148 { 1149 fputs_unlocked (">", stdout); 1150 in_relro = false; 1151 } 1152 } 1153 } 1154 if (in_relro || in_ro) 1155 fputs_unlocked ("]", stdout); 1156 1157 /* Finish the line. */ 1158 fputc_unlocked ('\n', stdout); 1159 } 1160 } 1161 1162 1163 static const char * 1164 section_name (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr) 1165 { 1166 return elf_strptr (ebl->elf, ehdr->e_shstrndx, shdr->sh_name) ?: "???"; 1167 } 1168 1169 1170 static void 1171 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 1172 { 1173 /* Get the data of the section. */ 1174 Elf_Data *data = elf_getdata (scn, NULL); 1175 1176 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1177 GElf_Shdr symshdr_mem; 1178 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1179 Elf_Data *symdata = elf_getdata (symscn, NULL); 1180 1181 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL 1182 || symdata == NULL) 1183 return; 1184 1185 /* Get the section header string table index. */ 1186 size_t shstrndx; 1187 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 1188 error (EXIT_FAILURE, 0, 1189 gettext ("cannot get section header string table index")); 1190 1191 Elf32_Word *grpref = (Elf32_Word *) data->d_buf; 1192 1193 GElf_Sym sym_mem; 1194 printf ((grpref[0] & GRP_COMDAT) 1195 ? ngettext ("\ 1196 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n", 1197 "\ 1198 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n", 1199 data->d_size / sizeof (Elf32_Word) - 1) 1200 : ngettext ("\ 1201 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\ 1202 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n", 1203 data->d_size / sizeof (Elf32_Word) - 1), 1204 elf_ndxscn (scn), 1205 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 1206 elf_strptr (ebl->elf, symshdr->sh_link, 1207 gelf_getsym (symdata, shdr->sh_info, &sym_mem)->st_name) 1208 ?: gettext ("<INVALID SYMBOL>"), 1209 data->d_size / sizeof (Elf32_Word) - 1); 1210 1211 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt) 1212 { 1213 GElf_Shdr grpshdr_mem; 1214 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]), 1215 &grpshdr_mem); 1216 1217 const char *str; 1218 printf (" [%2u] %s\n", 1219 grpref[cnt], 1220 grpshdr != NULL 1221 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name)) 1222 ? str : gettext ("<INVALID SECTION>")); 1223 } 1224 } 1225 1226 1227 static void 1228 print_scngrp (Ebl *ebl) 1229 { 1230 /* Find all relocation sections and handle them. */ 1231 Elf_Scn *scn = NULL; 1232 1233 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 1234 { 1235 /* Handle the section if it is a symbol table. */ 1236 GElf_Shdr shdr_mem; 1237 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1238 1239 if (shdr != NULL && shdr->sh_type == SHT_GROUP) 1240 handle_scngrp (ebl, scn, shdr); 1241 } 1242 } 1243 1244 1245 static const struct flags 1246 { 1247 int mask; 1248 const char *str; 1249 } dt_flags[] = 1250 { 1251 { DF_ORIGIN, "ORIGIN" }, 1252 { DF_SYMBOLIC, "SYMBOLIC" }, 1253 { DF_TEXTREL, "TEXTREL" }, 1254 { DF_BIND_NOW, "BIND_NOW" }, 1255 { DF_STATIC_TLS, "STATIC_TLS" } 1256 }; 1257 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]); 1258 1259 static const struct flags dt_flags_1[] = 1260 { 1261 { DF_1_NOW, "NOW" }, 1262 { DF_1_GLOBAL, "GLOBAL" }, 1263 { DF_1_GROUP, "GROUP" }, 1264 { DF_1_NODELETE, "NODELETE" }, 1265 { DF_1_LOADFLTR, "LOADFLTR" }, 1266 { DF_1_INITFIRST, "INITFIRST" }, 1267 { DF_1_NOOPEN, "NOOPEN" }, 1268 { DF_1_ORIGIN, "ORIGIN" }, 1269 { DF_1_DIRECT, "DIRECT" }, 1270 { DF_1_TRANS, "TRANS" }, 1271 { DF_1_INTERPOSE, "INTERPOSE" }, 1272 { DF_1_NODEFLIB, "NODEFLIB" }, 1273 { DF_1_NODUMP, "NODUMP" }, 1274 { DF_1_CONFALT, "CONFALT" }, 1275 { DF_1_ENDFILTEE, "ENDFILTEE" }, 1276 { DF_1_DISPRELDNE, "DISPRELDNE" }, 1277 { DF_1_DISPRELPND, "DISPRELPND" }, 1278 }; 1279 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]); 1280 1281 static const struct flags dt_feature_1[] = 1282 { 1283 { DTF_1_PARINIT, "PARINIT" }, 1284 { DTF_1_CONFEXP, "CONFEXP" } 1285 }; 1286 static const int ndt_feature_1 = (sizeof (dt_feature_1) 1287 / sizeof (dt_feature_1[0])); 1288 1289 static const struct flags dt_posflag_1[] = 1290 { 1291 { DF_P1_LAZYLOAD, "LAZYLOAD" }, 1292 { DF_P1_GROUPPERM, "GROUPPERM" } 1293 }; 1294 static const int ndt_posflag_1 = (sizeof (dt_posflag_1) 1295 / sizeof (dt_posflag_1[0])); 1296 1297 1298 static void 1299 print_flags (int class, GElf_Xword d_val, const struct flags *flags, 1300 int nflags) 1301 { 1302 bool first = true; 1303 int cnt; 1304 1305 for (cnt = 0; cnt < nflags; ++cnt) 1306 if (d_val & flags[cnt].mask) 1307 { 1308 if (!first) 1309 putchar_unlocked (' '); 1310 fputs_unlocked (flags[cnt].str, stdout); 1311 d_val &= ~flags[cnt].mask; 1312 first = false; 1313 } 1314 1315 if (d_val != 0) 1316 { 1317 if (!first) 1318 putchar_unlocked (' '); 1319 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val); 1320 } 1321 1322 putchar_unlocked ('\n'); 1323 } 1324 1325 1326 static void 1327 print_dt_flags (int class, GElf_Xword d_val) 1328 { 1329 print_flags (class, d_val, dt_flags, ndt_flags); 1330 } 1331 1332 1333 static void 1334 print_dt_flags_1 (int class, GElf_Xword d_val) 1335 { 1336 print_flags (class, d_val, dt_flags_1, ndt_flags_1); 1337 } 1338 1339 1340 static void 1341 print_dt_feature_1 (int class, GElf_Xword d_val) 1342 { 1343 print_flags (class, d_val, dt_feature_1, ndt_feature_1); 1344 } 1345 1346 1347 static void 1348 print_dt_posflag_1 (int class, GElf_Xword d_val) 1349 { 1350 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1); 1351 } 1352 1353 1354 static void 1355 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 1356 { 1357 int class = gelf_getclass (ebl->elf); 1358 GElf_Shdr glink; 1359 Elf_Data *data; 1360 size_t cnt; 1361 size_t shstrndx; 1362 1363 /* Get the data of the section. */ 1364 data = elf_getdata (scn, NULL); 1365 if (data == NULL) 1366 return; 1367 1368 /* Get the section header string table index. */ 1369 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 1370 error (EXIT_FAILURE, 0, 1371 gettext ("cannot get section header string table index")); 1372 1373 printf (ngettext ("\ 1374 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 1375 "\ 1376 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 1377 shdr->sh_size / shdr->sh_entsize), 1378 (unsigned long int) (shdr->sh_size / shdr->sh_entsize), 1379 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 1380 shdr->sh_offset, 1381 (int) shdr->sh_link, 1382 elf_strptr (ebl->elf, shstrndx, 1383 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 1384 &glink)->sh_name)); 1385 fputs_unlocked (gettext (" Type Value\n"), stdout); 1386 1387 for (cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 1388 { 1389 GElf_Dyn dynmem; 1390 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem); 1391 if (dyn == NULL) 1392 break; 1393 1394 char buf[64]; 1395 printf (" %-17s ", 1396 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf))); 1397 1398 switch (dyn->d_tag) 1399 { 1400 case DT_NULL: 1401 case DT_DEBUG: 1402 case DT_BIND_NOW: 1403 case DT_TEXTREL: 1404 /* No further output. */ 1405 fputc_unlocked ('\n', stdout); 1406 break; 1407 1408 case DT_NEEDED: 1409 printf (gettext ("Shared library: [%s]\n"), 1410 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 1411 break; 1412 1413 case DT_SONAME: 1414 printf (gettext ("Library soname: [%s]\n"), 1415 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 1416 break; 1417 1418 case DT_RPATH: 1419 printf (gettext ("Library rpath: [%s]\n"), 1420 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 1421 break; 1422 1423 case DT_RUNPATH: 1424 printf (gettext ("Library runpath: [%s]\n"), 1425 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 1426 break; 1427 1428 case DT_PLTRELSZ: 1429 case DT_RELASZ: 1430 case DT_STRSZ: 1431 case DT_RELSZ: 1432 case DT_RELAENT: 1433 case DT_SYMENT: 1434 case DT_RELENT: 1435 case DT_PLTPADSZ: 1436 case DT_MOVEENT: 1437 case DT_MOVESZ: 1438 case DT_INIT_ARRAYSZ: 1439 case DT_FINI_ARRAYSZ: 1440 case DT_SYMINSZ: 1441 case DT_SYMINENT: 1442 case DT_GNU_CONFLICTSZ: 1443 case DT_GNU_LIBLISTSZ: 1444 printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val); 1445 break; 1446 1447 case DT_VERDEFNUM: 1448 case DT_VERNEEDNUM: 1449 case DT_RELACOUNT: 1450 case DT_RELCOUNT: 1451 printf ("%" PRId64 "\n", dyn->d_un.d_val); 1452 break; 1453 1454 case DT_PLTREL:; 1455 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val, 1456 NULL, 0); 1457 puts (tagname ?: "???"); 1458 break; 1459 1460 case DT_FLAGS: 1461 print_dt_flags (class, dyn->d_un.d_val); 1462 break; 1463 1464 case DT_FLAGS_1: 1465 print_dt_flags_1 (class, dyn->d_un.d_val); 1466 break; 1467 1468 case DT_FEATURE_1: 1469 print_dt_feature_1 (class, dyn->d_un.d_val); 1470 break; 1471 1472 case DT_POSFLAG_1: 1473 print_dt_posflag_1 (class, dyn->d_un.d_val); 1474 break; 1475 1476 default: 1477 printf ("%#0*" PRIx64 "\n", 1478 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val); 1479 break; 1480 } 1481 } 1482 } 1483 1484 1485 /* Print the dynamic segment. */ 1486 static void 1487 print_dynamic (Ebl *ebl) 1488 { 1489 for (size_t i = 0; i < phnum; ++i) 1490 { 1491 GElf_Phdr phdr_mem; 1492 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem); 1493 1494 if (phdr != NULL && phdr->p_type == PT_DYNAMIC) 1495 { 1496 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset); 1497 GElf_Shdr shdr_mem; 1498 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1499 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC) 1500 handle_dynamic (ebl, scn, shdr); 1501 break; 1502 } 1503 } 1504 } 1505 1506 1507 /* Print relocations. */ 1508 static void 1509 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr) 1510 { 1511 /* Find all relocation sections and handle them. */ 1512 Elf_Scn *scn = NULL; 1513 1514 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 1515 { 1516 /* Handle the section if it is a symbol table. */ 1517 GElf_Shdr shdr_mem; 1518 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1519 1520 if (likely (shdr != NULL)) 1521 { 1522 if (shdr->sh_type == SHT_REL) 1523 handle_relocs_rel (ebl, ehdr, scn, shdr); 1524 else if (shdr->sh_type == SHT_RELA) 1525 handle_relocs_rela (ebl, ehdr, scn, shdr); 1526 } 1527 } 1528 } 1529 1530 1531 /* Handle a relocation section. */ 1532 static void 1533 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr) 1534 { 1535 int class = gelf_getclass (ebl->elf); 1536 int nentries = shdr->sh_size / shdr->sh_entsize; 1537 1538 /* Get the data of the section. */ 1539 Elf_Data *data = elf_getdata (scn, NULL); 1540 if (data == NULL) 1541 return; 1542 1543 /* Get the symbol table information. */ 1544 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1545 GElf_Shdr symshdr_mem; 1546 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1547 Elf_Data *symdata = elf_getdata (symscn, NULL); 1548 1549 /* Get the section header of the section the relocations are for. */ 1550 GElf_Shdr destshdr_mem; 1551 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), 1552 &destshdr_mem); 1553 1554 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL)) 1555 { 1556 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"), 1557 shdr->sh_offset); 1558 return; 1559 } 1560 1561 /* Search for the optional extended section index table. */ 1562 Elf_Data *xndxdata = NULL; 1563 int xndxscnidx = elf_scnshndx (scn); 1564 if (unlikely (xndxscnidx > 0)) 1565 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL); 1566 1567 /* Get the section header string table index. */ 1568 size_t shstrndx; 1569 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 1570 error (EXIT_FAILURE, 0, 1571 gettext ("cannot get section header string table index")); 1572 1573 if (shdr->sh_info != 0) 1574 printf (ngettext ("\ 1575 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 1576 "\ 1577 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 1578 nentries), 1579 elf_ndxscn (scn), 1580 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 1581 (unsigned int) shdr->sh_info, 1582 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name), 1583 shdr->sh_offset, 1584 nentries); 1585 else 1586 /* The .rel.dyn section does not refer to a specific section but 1587 instead of section index zero. Do not try to print a section 1588 name. */ 1589 printf (ngettext ("\ 1590 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 1591 "\ 1592 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 1593 nentries), 1594 (unsigned int) elf_ndxscn (scn), 1595 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 1596 shdr->sh_offset, 1597 nentries); 1598 fputs_unlocked (class == ELFCLASS32 1599 ? gettext ("\ 1600 Offset Type Value Name\n") 1601 : gettext ("\ 1602 Offset Type Value Name\n"), 1603 stdout); 1604 1605 int is_statically_linked = 0; 1606 for (int cnt = 0; cnt < nentries; ++cnt) 1607 { 1608 GElf_Rel relmem; 1609 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem); 1610 if (likely (rel != NULL)) 1611 { 1612 char buf[128]; 1613 GElf_Sym symmem; 1614 Elf32_Word xndx; 1615 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, 1616 GELF_R_SYM (rel->r_info), 1617 &symmem, &xndx); 1618 if (unlikely (sym == NULL)) 1619 { 1620 /* As a special case we have to handle relocations in static 1621 executables. This only happens for IRELATIVE relocations 1622 (so far). There is no symbol table. */ 1623 if (is_statically_linked == 0) 1624 { 1625 /* Find the program header and look for a PT_INTERP entry. */ 1626 is_statically_linked = -1; 1627 if (ehdr->e_type == ET_EXEC) 1628 { 1629 is_statically_linked = 1; 1630 1631 for (size_t inner = 0; inner < phnum; ++inner) 1632 { 1633 GElf_Phdr phdr_mem; 1634 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner, 1635 &phdr_mem); 1636 if (phdr != NULL && phdr->p_type == PT_INTERP) 1637 { 1638 is_statically_linked = -1; 1639 break; 1640 } 1641 } 1642 } 1643 } 1644 1645 if (is_statically_linked > 0 && shdr->sh_link == 0) 1646 printf ("\ 1647 %#0*" PRIx64 " %-20s %*s %s\n", 1648 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1649 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 1650 /* Avoid the leading R_ which isn't carrying any 1651 information. */ 1652 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1653 buf, sizeof (buf)) + 2 1654 : gettext ("<INVALID RELOC>"), 1655 class == ELFCLASS32 ? 10 : 18, "", 1656 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name)); 1657 else 1658 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n", 1659 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1660 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 1661 /* Avoid the leading R_ which isn't carrying any 1662 information. */ 1663 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1664 buf, sizeof (buf)) + 2 1665 : gettext ("<INVALID RELOC>"), 1666 gettext ("INVALID SYMBOL"), 1667 (long int) GELF_R_SYM (rel->r_info)); 1668 } 1669 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION) 1670 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n", 1671 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1672 likely (ebl_reloc_type_check (ebl, 1673 GELF_R_TYPE (rel->r_info))) 1674 /* Avoid the leading R_ which isn't carrying any 1675 information. */ 1676 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1677 buf, sizeof (buf)) + 2 1678 : gettext ("<INVALID RELOC>"), 1679 class == ELFCLASS32 ? 10 : 18, sym->st_value, 1680 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)); 1681 else 1682 { 1683 destshdr = gelf_getshdr (elf_getscn (ebl->elf, 1684 sym->st_shndx == SHN_XINDEX 1685 ? xndx : sym->st_shndx), 1686 &destshdr_mem); 1687 1688 if (unlikely (destshdr == NULL)) 1689 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n", 1690 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1691 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 1692 /* Avoid the leading R_ which isn't carrying any 1693 information. */ 1694 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1695 buf, sizeof (buf)) + 2 1696 : gettext ("<INVALID RELOC>"), 1697 gettext ("INVALID SECTION"), 1698 (long int) (sym->st_shndx == SHN_XINDEX 1699 ? xndx : sym->st_shndx)); 1700 else 1701 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n", 1702 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1703 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 1704 /* Avoid the leading R_ which isn't carrying any 1705 information. */ 1706 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1707 buf, sizeof (buf)) + 2 1708 : gettext ("<INVALID RELOC>"), 1709 class == ELFCLASS32 ? 10 : 18, sym->st_value, 1710 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name)); 1711 } 1712 } 1713 } 1714 } 1715 1716 1717 /* Handle a relocation section. */ 1718 static void 1719 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr) 1720 { 1721 int class = gelf_getclass (ebl->elf); 1722 int nentries = shdr->sh_size / shdr->sh_entsize; 1723 1724 /* Get the data of the section. */ 1725 Elf_Data *data = elf_getdata (scn, NULL); 1726 if (data == NULL) 1727 return; 1728 1729 /* Get the symbol table information. */ 1730 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1731 GElf_Shdr symshdr_mem; 1732 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1733 Elf_Data *symdata = elf_getdata (symscn, NULL); 1734 1735 /* Get the section header of the section the relocations are for. */ 1736 GElf_Shdr destshdr_mem; 1737 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), 1738 &destshdr_mem); 1739 1740 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL)) 1741 { 1742 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"), 1743 shdr->sh_offset); 1744 return; 1745 } 1746 1747 /* Search for the optional extended section index table. */ 1748 Elf_Data *xndxdata = NULL; 1749 int xndxscnidx = elf_scnshndx (scn); 1750 if (unlikely (xndxscnidx > 0)) 1751 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL); 1752 1753 /* Get the section header string table index. */ 1754 size_t shstrndx; 1755 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 1756 error (EXIT_FAILURE, 0, 1757 gettext ("cannot get section header string table index")); 1758 1759 printf (ngettext ("\ 1760 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 1761 "\ 1762 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 1763 nentries), 1764 elf_ndxscn (scn), 1765 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 1766 (unsigned int) shdr->sh_info, 1767 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name), 1768 shdr->sh_offset, 1769 nentries); 1770 fputs_unlocked (class == ELFCLASS32 1771 ? gettext ("\ 1772 Offset Type Value Addend Name\n") 1773 : gettext ("\ 1774 Offset Type Value Addend Name\n"), 1775 stdout); 1776 1777 int is_statically_linked = 0; 1778 for (int cnt = 0; cnt < nentries; ++cnt) 1779 { 1780 GElf_Rela relmem; 1781 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem); 1782 if (likely (rel != NULL)) 1783 { 1784 char buf[64]; 1785 GElf_Sym symmem; 1786 Elf32_Word xndx; 1787 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, 1788 GELF_R_SYM (rel->r_info), 1789 &symmem, &xndx); 1790 1791 if (unlikely (sym == NULL)) 1792 { 1793 /* As a special case we have to handle relocations in static 1794 executables. This only happens for IRELATIVE relocations 1795 (so far). There is no symbol table. */ 1796 if (is_statically_linked == 0) 1797 { 1798 /* Find the program header and look for a PT_INTERP entry. */ 1799 is_statically_linked = -1; 1800 if (ehdr->e_type == ET_EXEC) 1801 { 1802 is_statically_linked = 1; 1803 1804 for (size_t inner = 0; inner < phnum; ++inner) 1805 { 1806 GElf_Phdr phdr_mem; 1807 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner, 1808 &phdr_mem); 1809 if (phdr != NULL && phdr->p_type == PT_INTERP) 1810 { 1811 is_statically_linked = -1; 1812 break; 1813 } 1814 } 1815 } 1816 } 1817 1818 if (is_statically_linked > 0 && shdr->sh_link == 0) 1819 printf ("\ 1820 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n", 1821 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1822 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 1823 /* Avoid the leading R_ which isn't carrying any 1824 information. */ 1825 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1826 buf, sizeof (buf)) + 2 1827 : gettext ("<INVALID RELOC>"), 1828 class == ELFCLASS32 ? 10 : 18, "", 1829 rel->r_addend, 1830 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name)); 1831 else 1832 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n", 1833 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1834 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 1835 /* Avoid the leading R_ which isn't carrying any 1836 information. */ 1837 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1838 buf, sizeof (buf)) + 2 1839 : gettext ("<INVALID RELOC>"), 1840 gettext ("INVALID SYMBOL"), 1841 (long int) GELF_R_SYM (rel->r_info)); 1842 } 1843 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION) 1844 printf ("\ 1845 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n", 1846 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1847 likely (ebl_reloc_type_check (ebl, 1848 GELF_R_TYPE (rel->r_info))) 1849 /* Avoid the leading R_ which isn't carrying any 1850 information. */ 1851 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1852 buf, sizeof (buf)) + 2 1853 : gettext ("<INVALID RELOC>"), 1854 class == ELFCLASS32 ? 10 : 18, sym->st_value, 1855 rel->r_addend, 1856 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)); 1857 else 1858 { 1859 destshdr = gelf_getshdr (elf_getscn (ebl->elf, 1860 sym->st_shndx == SHN_XINDEX 1861 ? xndx : sym->st_shndx), 1862 &destshdr_mem); 1863 1864 if (unlikely (shdr == NULL)) 1865 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n", 1866 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1867 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 1868 /* Avoid the leading R_ which isn't carrying any 1869 information. */ 1870 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1871 buf, sizeof (buf)) + 2 1872 : gettext ("<INVALID RELOC>"), 1873 gettext ("INVALID SECTION"), 1874 (long int) (sym->st_shndx == SHN_XINDEX 1875 ? xndx : sym->st_shndx)); 1876 else 1877 printf ("\ 1878 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n", 1879 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 1880 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 1881 /* Avoid the leading R_ which isn't carrying any 1882 information. */ 1883 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 1884 buf, sizeof (buf)) + 2 1885 : gettext ("<INVALID RELOC>"), 1886 class == ELFCLASS32 ? 10 : 18, sym->st_value, 1887 rel->r_addend, 1888 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name)); 1889 } 1890 } 1891 } 1892 } 1893 1894 1895 /* Print the program header. */ 1896 static void 1897 print_symtab (Ebl *ebl, int type) 1898 { 1899 /* Find the symbol table(s). For this we have to search through the 1900 section table. */ 1901 Elf_Scn *scn = NULL; 1902 1903 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 1904 { 1905 /* Handle the section if it is a symbol table. */ 1906 GElf_Shdr shdr_mem; 1907 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1908 1909 if (shdr != NULL && shdr->sh_type == (GElf_Word) type) 1910 handle_symtab (ebl, scn, shdr); 1911 } 1912 } 1913 1914 1915 static void 1916 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 1917 { 1918 Elf_Data *versym_data = NULL; 1919 Elf_Data *verneed_data = NULL; 1920 Elf_Data *verdef_data = NULL; 1921 Elf_Data *xndx_data = NULL; 1922 int class = gelf_getclass (ebl->elf); 1923 Elf32_Word verneed_stridx = 0; 1924 Elf32_Word verdef_stridx = 0; 1925 1926 /* Get the data of the section. */ 1927 Elf_Data *data = elf_getdata (scn, NULL); 1928 if (data == NULL) 1929 return; 1930 1931 /* Find out whether we have other sections we might need. */ 1932 Elf_Scn *runscn = NULL; 1933 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL) 1934 { 1935 GElf_Shdr runshdr_mem; 1936 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem); 1937 1938 if (likely (runshdr != NULL)) 1939 { 1940 if (runshdr->sh_type == SHT_GNU_versym 1941 && runshdr->sh_link == elf_ndxscn (scn)) 1942 /* Bingo, found the version information. Now get the data. */ 1943 versym_data = elf_getdata (runscn, NULL); 1944 else if (runshdr->sh_type == SHT_GNU_verneed) 1945 { 1946 /* This is the information about the needed versions. */ 1947 verneed_data = elf_getdata (runscn, NULL); 1948 verneed_stridx = runshdr->sh_link; 1949 } 1950 else if (runshdr->sh_type == SHT_GNU_verdef) 1951 { 1952 /* This is the information about the defined versions. */ 1953 verdef_data = elf_getdata (runscn, NULL); 1954 verdef_stridx = runshdr->sh_link; 1955 } 1956 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX 1957 && runshdr->sh_link == elf_ndxscn (scn)) 1958 /* Extended section index. */ 1959 xndx_data = elf_getdata (runscn, NULL); 1960 } 1961 } 1962 1963 /* Get the section header string table index. */ 1964 size_t shstrndx; 1965 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 1966 error (EXIT_FAILURE, 0, 1967 gettext ("cannot get section header string table index")); 1968 1969 /* Now we can compute the number of entries in the section. */ 1970 unsigned int nsyms = data->d_size / (class == ELFCLASS32 1971 ? sizeof (Elf32_Sym) 1972 : sizeof (Elf64_Sym)); 1973 1974 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n", 1975 "\nSymbol table [%2u] '%s' contains %u entries:\n", 1976 nsyms), 1977 (unsigned int) elf_ndxscn (scn), 1978 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms); 1979 GElf_Shdr glink; 1980 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n", 1981 " %lu local symbols String table: [%2u] '%s'\n", 1982 shdr->sh_info), 1983 (unsigned long int) shdr->sh_info, 1984 (unsigned int) shdr->sh_link, 1985 elf_strptr (ebl->elf, shstrndx, 1986 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 1987 &glink)->sh_name)); 1988 1989 fputs_unlocked (class == ELFCLASS32 1990 ? gettext ("\ 1991 Num: Value Size Type Bind Vis Ndx Name\n") 1992 : gettext ("\ 1993 Num: Value Size Type Bind Vis Ndx Name\n"), 1994 stdout); 1995 1996 for (unsigned int cnt = 0; cnt < nsyms; ++cnt) 1997 { 1998 char typebuf[64]; 1999 char bindbuf[64]; 2000 char scnbuf[64]; 2001 Elf32_Word xndx; 2002 GElf_Sym sym_mem; 2003 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx); 2004 2005 if (unlikely (sym == NULL)) 2006 continue; 2007 2008 /* Determine the real section index. */ 2009 if (likely (sym->st_shndx != SHN_XINDEX)) 2010 xndx = sym->st_shndx; 2011 2012 printf (gettext ("\ 2013 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"), 2014 cnt, 2015 class == ELFCLASS32 ? 8 : 16, 2016 sym->st_value, 2017 sym->st_size, 2018 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), 2019 typebuf, sizeof (typebuf)), 2020 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info), 2021 bindbuf, sizeof (bindbuf)), 2022 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)), 2023 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf, 2024 sizeof (scnbuf), NULL, shnum), 2025 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name)); 2026 2027 if (versym_data != NULL) 2028 { 2029 /* Get the version information. */ 2030 GElf_Versym versym_mem; 2031 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem); 2032 2033 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1)) 2034 { 2035 bool is_nobits = false; 2036 bool check_def = xndx != SHN_UNDEF; 2037 2038 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX) 2039 { 2040 GElf_Shdr symshdr_mem; 2041 GElf_Shdr *symshdr = 2042 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem); 2043 2044 is_nobits = (symshdr != NULL 2045 && symshdr->sh_type == SHT_NOBITS); 2046 } 2047 2048 if (is_nobits || ! check_def) 2049 { 2050 /* We must test both. */ 2051 GElf_Vernaux vernaux_mem; 2052 GElf_Vernaux *vernaux = NULL; 2053 size_t vn_offset = 0; 2054 2055 GElf_Verneed verneed_mem; 2056 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0, 2057 &verneed_mem); 2058 while (verneed != NULL) 2059 { 2060 size_t vna_offset = vn_offset; 2061 2062 vernaux = gelf_getvernaux (verneed_data, 2063 vna_offset += verneed->vn_aux, 2064 &vernaux_mem); 2065 while (vernaux != NULL 2066 && vernaux->vna_other != *versym 2067 && vernaux->vna_next != 0) 2068 { 2069 /* Update the offset. */ 2070 vna_offset += vernaux->vna_next; 2071 2072 vernaux = (vernaux->vna_next == 0 2073 ? NULL 2074 : gelf_getvernaux (verneed_data, 2075 vna_offset, 2076 &vernaux_mem)); 2077 } 2078 2079 /* Check whether we found the version. */ 2080 if (vernaux != NULL && vernaux->vna_other == *versym) 2081 /* Found it. */ 2082 break; 2083 2084 vn_offset += verneed->vn_next; 2085 verneed = (verneed->vn_next == 0 2086 ? NULL 2087 : gelf_getverneed (verneed_data, vn_offset, 2088 &verneed_mem)); 2089 } 2090 2091 if (vernaux != NULL && vernaux->vna_other == *versym) 2092 { 2093 printf ("@%s (%u)", 2094 elf_strptr (ebl->elf, verneed_stridx, 2095 vernaux->vna_name), 2096 (unsigned int) vernaux->vna_other); 2097 check_def = 0; 2098 } 2099 else if (unlikely (! is_nobits)) 2100 error (0, 0, gettext ("bad dynamic symbol")); 2101 else 2102 check_def = 1; 2103 } 2104 2105 if (check_def && *versym != 0x8001) 2106 { 2107 /* We must test both. */ 2108 size_t vd_offset = 0; 2109 2110 GElf_Verdef verdef_mem; 2111 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0, 2112 &verdef_mem); 2113 while (verdef != NULL) 2114 { 2115 if (verdef->vd_ndx == (*versym & 0x7fff)) 2116 /* Found the definition. */ 2117 break; 2118 2119 vd_offset += verdef->vd_next; 2120 verdef = (verdef->vd_next == 0 2121 ? NULL 2122 : gelf_getverdef (verdef_data, vd_offset, 2123 &verdef_mem)); 2124 } 2125 2126 if (verdef != NULL) 2127 { 2128 GElf_Verdaux verdaux_mem; 2129 GElf_Verdaux *verdaux 2130 = gelf_getverdaux (verdef_data, 2131 vd_offset + verdef->vd_aux, 2132 &verdaux_mem); 2133 2134 if (verdaux != NULL) 2135 printf ((*versym & 0x8000) ? "@%s" : "@@%s", 2136 elf_strptr (ebl->elf, verdef_stridx, 2137 verdaux->vda_name)); 2138 } 2139 } 2140 } 2141 } 2142 2143 putchar_unlocked ('\n'); 2144 } 2145 } 2146 2147 2148 /* Print version information. */ 2149 static void 2150 print_verinfo (Ebl *ebl) 2151 { 2152 /* Find the version information sections. For this we have to 2153 search through the section table. */ 2154 Elf_Scn *scn = NULL; 2155 2156 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 2157 { 2158 /* Handle the section if it is part of the versioning handling. */ 2159 GElf_Shdr shdr_mem; 2160 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2161 2162 if (likely (shdr != NULL)) 2163 { 2164 if (shdr->sh_type == SHT_GNU_verneed) 2165 handle_verneed (ebl, scn, shdr); 2166 else if (shdr->sh_type == SHT_GNU_verdef) 2167 handle_verdef (ebl, scn, shdr); 2168 else if (shdr->sh_type == SHT_GNU_versym) 2169 handle_versym (ebl, scn, shdr); 2170 } 2171 } 2172 } 2173 2174 2175 static const char * 2176 get_ver_flags (unsigned int flags) 2177 { 2178 static char buf[32]; 2179 char *endp; 2180 2181 if (flags == 0) 2182 return gettext ("none"); 2183 2184 if (flags & VER_FLG_BASE) 2185 endp = stpcpy (buf, "BASE "); 2186 else 2187 endp = buf; 2188 2189 if (flags & VER_FLG_WEAK) 2190 { 2191 if (endp != buf) 2192 endp = stpcpy (endp, "| "); 2193 2194 endp = stpcpy (endp, "WEAK "); 2195 } 2196 2197 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))) 2198 { 2199 strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp); 2200 buf[sizeof (buf) - 1] = '\0'; 2201 } 2202 2203 return buf; 2204 } 2205 2206 2207 static void 2208 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 2209 { 2210 int class = gelf_getclass (ebl->elf); 2211 2212 /* Get the data of the section. */ 2213 Elf_Data *data = elf_getdata (scn, NULL); 2214 if (data == NULL) 2215 return; 2216 2217 /* Get the section header string table index. */ 2218 size_t shstrndx; 2219 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 2220 error (EXIT_FAILURE, 0, 2221 gettext ("cannot get section header string table index")); 2222 2223 GElf_Shdr glink; 2224 printf (ngettext ("\ 2225 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 2226 "\ 2227 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 2228 shdr->sh_info), 2229 (unsigned int) elf_ndxscn (scn), 2230 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info, 2231 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 2232 shdr->sh_offset, 2233 (unsigned int) shdr->sh_link, 2234 elf_strptr (ebl->elf, shstrndx, 2235 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2236 &glink)->sh_name)); 2237 2238 unsigned int offset = 0; 2239 for (int cnt = shdr->sh_info; --cnt >= 0; ) 2240 { 2241 /* Get the data at the next offset. */ 2242 GElf_Verneed needmem; 2243 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem); 2244 if (unlikely (need == NULL)) 2245 break; 2246 2247 printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"), 2248 offset, (unsigned short int) need->vn_version, 2249 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file), 2250 (unsigned short int) need->vn_cnt); 2251 2252 unsigned int auxoffset = offset + need->vn_aux; 2253 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) 2254 { 2255 GElf_Vernaux auxmem; 2256 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem); 2257 if (unlikely (aux == NULL)) 2258 break; 2259 2260 printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"), 2261 auxoffset, 2262 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name), 2263 get_ver_flags (aux->vna_flags), 2264 (unsigned short int) aux->vna_other); 2265 2266 auxoffset += aux->vna_next; 2267 } 2268 2269 /* Find the next offset. */ 2270 offset += need->vn_next; 2271 } 2272 } 2273 2274 2275 static void 2276 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 2277 { 2278 /* Get the data of the section. */ 2279 Elf_Data *data = elf_getdata (scn, NULL); 2280 if (data == NULL) 2281 return; 2282 2283 /* Get the section header string table index. */ 2284 size_t shstrndx; 2285 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 2286 error (EXIT_FAILURE, 0, 2287 gettext ("cannot get section header string table index")); 2288 2289 int class = gelf_getclass (ebl->elf); 2290 GElf_Shdr glink; 2291 printf (ngettext ("\ 2292 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 2293 "\ 2294 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 2295 shdr->sh_info), 2296 (unsigned int) elf_ndxscn (scn), 2297 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 2298 shdr->sh_info, 2299 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 2300 shdr->sh_offset, 2301 (unsigned int) shdr->sh_link, 2302 elf_strptr (ebl->elf, shstrndx, 2303 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2304 &glink)->sh_name)); 2305 2306 unsigned int offset = 0; 2307 for (int cnt = shdr->sh_info; --cnt >= 0; ) 2308 { 2309 /* Get the data at the next offset. */ 2310 GElf_Verdef defmem; 2311 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem); 2312 if (unlikely (def == NULL)) 2313 break; 2314 2315 unsigned int auxoffset = offset + def->vd_aux; 2316 GElf_Verdaux auxmem; 2317 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem); 2318 if (unlikely (aux == NULL)) 2319 break; 2320 2321 printf (gettext ("\ 2322 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"), 2323 offset, def->vd_version, 2324 get_ver_flags (def->vd_flags), 2325 def->vd_ndx, 2326 def->vd_cnt, 2327 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name)); 2328 2329 auxoffset += aux->vda_next; 2330 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2) 2331 { 2332 aux = gelf_getverdaux (data, auxoffset, &auxmem); 2333 if (unlikely (aux == NULL)) 2334 break; 2335 2336 printf (gettext (" %#06x: Parent %d: %s\n"), 2337 auxoffset, cnt2, 2338 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name)); 2339 2340 auxoffset += aux->vda_next; 2341 } 2342 2343 /* Find the next offset. */ 2344 offset += def->vd_next; 2345 } 2346 } 2347 2348 2349 static void 2350 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 2351 { 2352 int class = gelf_getclass (ebl->elf); 2353 const char **vername; 2354 const char **filename; 2355 2356 /* Get the data of the section. */ 2357 Elf_Data *data = elf_getdata (scn, NULL); 2358 if (data == NULL) 2359 return; 2360 2361 /* Get the section header string table index. */ 2362 size_t shstrndx; 2363 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 2364 error (EXIT_FAILURE, 0, 2365 gettext ("cannot get section header string table index")); 2366 2367 /* We have to find the version definition section and extract the 2368 version names. */ 2369 Elf_Scn *defscn = NULL; 2370 Elf_Scn *needscn = NULL; 2371 2372 Elf_Scn *verscn = NULL; 2373 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL) 2374 { 2375 GElf_Shdr vershdr_mem; 2376 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem); 2377 2378 if (likely (vershdr != NULL)) 2379 { 2380 if (vershdr->sh_type == SHT_GNU_verdef) 2381 defscn = verscn; 2382 else if (vershdr->sh_type == SHT_GNU_verneed) 2383 needscn = verscn; 2384 } 2385 } 2386 2387 size_t nvername; 2388 if (defscn != NULL || needscn != NULL) 2389 { 2390 /* We have a version information (better should have). Now get 2391 the version names. First find the maximum version number. */ 2392 nvername = 0; 2393 if (defscn != NULL) 2394 { 2395 /* Run through the version definitions and find the highest 2396 index. */ 2397 unsigned int offset = 0; 2398 Elf_Data *defdata; 2399 GElf_Shdr defshdrmem; 2400 GElf_Shdr *defshdr; 2401 2402 defdata = elf_getdata (defscn, NULL); 2403 if (unlikely (defdata == NULL)) 2404 return; 2405 2406 defshdr = gelf_getshdr (defscn, &defshdrmem); 2407 if (unlikely (defshdr == NULL)) 2408 return; 2409 2410 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt) 2411 { 2412 GElf_Verdef defmem; 2413 GElf_Verdef *def; 2414 2415 /* Get the data at the next offset. */ 2416 def = gelf_getverdef (defdata, offset, &defmem); 2417 if (unlikely (def == NULL)) 2418 break; 2419 2420 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff)); 2421 2422 offset += def->vd_next; 2423 } 2424 } 2425 if (needscn != NULL) 2426 { 2427 unsigned int offset = 0; 2428 Elf_Data *needdata; 2429 GElf_Shdr needshdrmem; 2430 GElf_Shdr *needshdr; 2431 2432 needdata = elf_getdata (needscn, NULL); 2433 if (unlikely (needdata == NULL)) 2434 return; 2435 2436 needshdr = gelf_getshdr (needscn, &needshdrmem); 2437 if (unlikely (needshdr == NULL)) 2438 return; 2439 2440 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt) 2441 { 2442 GElf_Verneed needmem; 2443 GElf_Verneed *need; 2444 unsigned int auxoffset; 2445 int cnt2; 2446 2447 /* Get the data at the next offset. */ 2448 need = gelf_getverneed (needdata, offset, &needmem); 2449 if (unlikely (need == NULL)) 2450 break; 2451 2452 /* Run through the auxiliary entries. */ 2453 auxoffset = offset + need->vn_aux; 2454 for (cnt2 = need->vn_cnt; --cnt2 >= 0; ) 2455 { 2456 GElf_Vernaux auxmem; 2457 GElf_Vernaux *aux; 2458 2459 aux = gelf_getvernaux (needdata, auxoffset, &auxmem); 2460 if (unlikely (aux == NULL)) 2461 break; 2462 2463 nvername = MAX (nvername, 2464 (size_t) (aux->vna_other & 0x7fff)); 2465 2466 auxoffset += aux->vna_next; 2467 } 2468 2469 offset += need->vn_next; 2470 } 2471 } 2472 2473 /* This is the number of versions we know about. */ 2474 ++nvername; 2475 2476 /* Allocate the array. */ 2477 vername = (const char **) alloca (nvername * sizeof (const char *)); 2478 filename = (const char **) alloca (nvername * sizeof (const char *)); 2479 2480 /* Run through the data structures again and collect the strings. */ 2481 if (defscn != NULL) 2482 { 2483 /* Run through the version definitions and find the highest 2484 index. */ 2485 unsigned int offset = 0; 2486 Elf_Data *defdata; 2487 GElf_Shdr defshdrmem; 2488 GElf_Shdr *defshdr; 2489 2490 defdata = elf_getdata (defscn, NULL); 2491 if (unlikely (defdata == NULL)) 2492 return; 2493 2494 defshdr = gelf_getshdr (defscn, &defshdrmem); 2495 if (unlikely (defshdr == NULL)) 2496 return; 2497 2498 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt) 2499 { 2500 2501 /* Get the data at the next offset. */ 2502 GElf_Verdef defmem; 2503 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem); 2504 GElf_Verdaux auxmem; 2505 GElf_Verdaux *aux = gelf_getverdaux (defdata, 2506 offset + def->vd_aux, 2507 &auxmem); 2508 if (unlikely (def == NULL || aux == NULL)) 2509 break; 2510 2511 vername[def->vd_ndx & 0x7fff] 2512 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name); 2513 filename[def->vd_ndx & 0x7fff] = NULL; 2514 2515 offset += def->vd_next; 2516 } 2517 } 2518 if (needscn != NULL) 2519 { 2520 unsigned int offset = 0; 2521 2522 Elf_Data *needdata = elf_getdata (needscn, NULL); 2523 GElf_Shdr needshdrmem; 2524 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem); 2525 if (unlikely (needdata == NULL || needshdr == NULL)) 2526 return; 2527 2528 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt) 2529 { 2530 /* Get the data at the next offset. */ 2531 GElf_Verneed needmem; 2532 GElf_Verneed *need = gelf_getverneed (needdata, offset, 2533 &needmem); 2534 if (unlikely (need == NULL)) 2535 break; 2536 2537 /* Run through the auxiliary entries. */ 2538 unsigned int auxoffset = offset + need->vn_aux; 2539 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) 2540 { 2541 GElf_Vernaux auxmem; 2542 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset, 2543 &auxmem); 2544 if (unlikely (aux == NULL)) 2545 break; 2546 2547 vername[aux->vna_other & 0x7fff] 2548 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name); 2549 filename[aux->vna_other & 0x7fff] 2550 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file); 2551 2552 auxoffset += aux->vna_next; 2553 } 2554 2555 offset += need->vn_next; 2556 } 2557 } 2558 } 2559 else 2560 { 2561 vername = NULL; 2562 nvername = 1; 2563 filename = NULL; 2564 } 2565 2566 /* Print the header. */ 2567 GElf_Shdr glink; 2568 printf (ngettext ("\ 2569 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'", 2570 "\ 2571 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'", 2572 shdr->sh_size / shdr->sh_entsize), 2573 (unsigned int) elf_ndxscn (scn), 2574 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 2575 (int) (shdr->sh_size / shdr->sh_entsize), 2576 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 2577 shdr->sh_offset, 2578 (unsigned int) shdr->sh_link, 2579 elf_strptr (ebl->elf, shstrndx, 2580 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2581 &glink)->sh_name)); 2582 2583 /* Now we can finally look at the actual contents of this section. */ 2584 for (unsigned int cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize; ++cnt) 2585 { 2586 if (cnt % 2 == 0) 2587 printf ("\n %4d:", cnt); 2588 2589 GElf_Versym symmem; 2590 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem); 2591 if (sym == NULL) 2592 break; 2593 2594 switch (*sym) 2595 { 2596 ssize_t n; 2597 case 0: 2598 fputs_unlocked (gettext (" 0 *local* "), 2599 stdout); 2600 break; 2601 2602 case 1: 2603 fputs_unlocked (gettext (" 1 *global* "), 2604 stdout); 2605 break; 2606 2607 default: 2608 n = printf ("%4d%c%s", 2609 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ', 2610 (unsigned int) (*sym & 0x7fff) < nvername 2611 ? vername[*sym & 0x7fff] : "???"); 2612 if ((unsigned int) (*sym & 0x7fff) < nvername 2613 && filename[*sym & 0x7fff] != NULL) 2614 n += printf ("(%s)", filename[*sym & 0x7fff]); 2615 printf ("%*s", MAX (0, 33 - (int) n), " "); 2616 break; 2617 } 2618 } 2619 putchar_unlocked ('\n'); 2620 } 2621 2622 2623 static void 2624 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx, 2625 uint_fast32_t maxlength, Elf32_Word nbucket, 2626 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr) 2627 { 2628 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t)); 2629 2630 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) 2631 ++counts[lengths[cnt]]; 2632 2633 GElf_Shdr glink; 2634 printf (ngettext ("\ 2635 \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", 2636 "\ 2637 \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", 2638 nbucket), 2639 (unsigned int) elf_ndxscn (scn), 2640 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 2641 (int) nbucket, 2642 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18, 2643 shdr->sh_addr, 2644 shdr->sh_offset, 2645 (unsigned int) shdr->sh_link, 2646 elf_strptr (ebl->elf, shstrndx, 2647 gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2648 &glink)->sh_name)); 2649 2650 if (extrastr != NULL) 2651 fputs (extrastr, stdout); 2652 2653 if (likely (nbucket > 0)) 2654 { 2655 uint64_t success = 0; 2656 2657 /* xgettext:no-c-format */ 2658 fputs_unlocked (gettext ("\ 2659 Length Number % of total Coverage\n"), stdout); 2660 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"), 2661 counts[0], (counts[0] * 100.0) / nbucket); 2662 2663 uint64_t nzero_counts = 0; 2664 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt) 2665 { 2666 nzero_counts += counts[cnt] * cnt; 2667 printf (gettext ("\ 2668 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"), 2669 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket, 2670 (nzero_counts * 100.0) / nsyms); 2671 } 2672 2673 Elf32_Word acc = 0; 2674 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt) 2675 { 2676 acc += cnt; 2677 success += counts[cnt] * acc; 2678 } 2679 2680 printf (gettext ("\ 2681 Average number of tests: successful lookup: %f\n\ 2682 unsuccessful lookup: %f\n"), 2683 (double) success / (double) nzero_counts, 2684 (double) nzero_counts / (double) nbucket); 2685 } 2686 2687 free (counts); 2688 } 2689 2690 2691 /* This function handles the traditional System V-style hash table format. */ 2692 static void 2693 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx) 2694 { 2695 Elf_Data *data = elf_getdata (scn, NULL); 2696 if (unlikely (data == NULL)) 2697 { 2698 error (0, 0, gettext ("cannot get data for section %d: %s"), 2699 (int) elf_ndxscn (scn), elf_errmsg (-1)); 2700 return; 2701 } 2702 2703 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; 2704 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1]; 2705 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2]; 2706 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket]; 2707 2708 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); 2709 2710 uint_fast32_t maxlength = 0; 2711 uint_fast32_t nsyms = 0; 2712 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) 2713 { 2714 Elf32_Word inner = bucket[cnt]; 2715 while (inner > 0 && inner < nchain) 2716 { 2717 ++nsyms; 2718 if (maxlength < ++lengths[cnt]) 2719 ++maxlength; 2720 2721 inner = chain[inner]; 2722 } 2723 } 2724 2725 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms, 2726 lengths, NULL); 2727 2728 free (lengths); 2729 } 2730 2731 2732 /* This function handles the incorrect, System V-style hash table 2733 format some 64-bit architectures use. */ 2734 static void 2735 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx) 2736 { 2737 Elf_Data *data = elf_getdata (scn, NULL); 2738 if (unlikely (data == NULL)) 2739 { 2740 error (0, 0, gettext ("cannot get data for section %d: %s"), 2741 (int) elf_ndxscn (scn), elf_errmsg (-1)); 2742 return; 2743 } 2744 2745 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0]; 2746 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1]; 2747 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2]; 2748 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket]; 2749 2750 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); 2751 2752 uint_fast32_t maxlength = 0; 2753 uint_fast32_t nsyms = 0; 2754 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt) 2755 { 2756 Elf64_Xword inner = bucket[cnt]; 2757 while (inner > 0 && inner < nchain) 2758 { 2759 ++nsyms; 2760 if (maxlength < ++lengths[cnt]) 2761 ++maxlength; 2762 2763 inner = chain[inner]; 2764 } 2765 } 2766 2767 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms, 2768 lengths, NULL); 2769 2770 free (lengths); 2771 } 2772 2773 2774 /* This function handles the GNU-style hash table format. */ 2775 static void 2776 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx) 2777 { 2778 Elf_Data *data = elf_getdata (scn, NULL); 2779 if (unlikely (data == NULL)) 2780 { 2781 error (0, 0, gettext ("cannot get data for section %d: %s"), 2782 (int) elf_ndxscn (scn), elf_errmsg (-1)); 2783 return; 2784 } 2785 2786 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; 2787 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1]; 2788 2789 /* Next comes the size of the bitmap. It's measured in words for 2790 the architecture. It's 32 bits for 32 bit archs, and 64 bits for 2791 64 bit archs. */ 2792 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2]; 2793 if (gelf_getclass (ebl->elf) == ELFCLASS64) 2794 bitmask_words *= 2; 2795 2796 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3]; 2797 2798 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); 2799 2800 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4]; 2801 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words]; 2802 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words 2803 + nbucket]; 2804 2805 /* Compute distribution of chain lengths. */ 2806 uint_fast32_t maxlength = 0; 2807 uint_fast32_t nsyms = 0; 2808 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) 2809 if (bucket[cnt] != 0) 2810 { 2811 Elf32_Word inner = bucket[cnt] - symbias; 2812 do 2813 { 2814 ++nsyms; 2815 if (maxlength < ++lengths[cnt]) 2816 ++maxlength; 2817 } 2818 while ((chain[inner++] & 1) == 0); 2819 } 2820 2821 /* Count bits in bitmask. */ 2822 uint_fast32_t nbits = 0; 2823 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt) 2824 { 2825 uint_fast32_t word = bitmask[cnt]; 2826 2827 word = (word & 0x55555555) + ((word >> 1) & 0x55555555); 2828 word = (word & 0x33333333) + ((word >> 2) & 0x33333333); 2829 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f); 2830 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff); 2831 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff); 2832 } 2833 2834 char *str; 2835 if (unlikely (asprintf (&str, gettext ("\ 2836 Symbol Bias: %u\n\ 2837 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"), 2838 (unsigned int) symbias, 2839 bitmask_words * sizeof (Elf32_Word), 2840 ((nbits * 100 + 50) 2841 / (uint_fast32_t) (bitmask_words 2842 * sizeof (Elf32_Word) * 8)), 2843 (unsigned int) shift) == -1)) 2844 error (EXIT_FAILURE, 0, gettext ("memory exhausted")); 2845 2846 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms, 2847 lengths, str); 2848 2849 free (str); 2850 free (lengths); 2851 } 2852 2853 2854 /* Find the symbol table(s). For this we have to search through the 2855 section table. */ 2856 static void 2857 handle_hash (Ebl *ebl) 2858 { 2859 /* Get the section header string table index. */ 2860 size_t shstrndx; 2861 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 2862 error (EXIT_FAILURE, 0, 2863 gettext ("cannot get section header string table index")); 2864 2865 Elf_Scn *scn = NULL; 2866 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 2867 { 2868 /* Handle the section if it is a symbol table. */ 2869 GElf_Shdr shdr_mem; 2870 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2871 2872 if (likely (shdr != NULL)) 2873 { 2874 if (shdr->sh_type == SHT_HASH) 2875 { 2876 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword)) 2877 handle_sysv_hash64 (ebl, scn, shdr, shstrndx); 2878 else 2879 handle_sysv_hash (ebl, scn, shdr, shstrndx); 2880 } 2881 else if (shdr->sh_type == SHT_GNU_HASH) 2882 handle_gnu_hash (ebl, scn, shdr, shstrndx); 2883 } 2884 } 2885 } 2886 2887 2888 static void 2889 print_liblist (Ebl *ebl) 2890 { 2891 /* Find the library list sections. For this we have to search 2892 through the section table. */ 2893 Elf_Scn *scn = NULL; 2894 2895 /* Get the section header string table index. */ 2896 size_t shstrndx; 2897 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 2898 error (EXIT_FAILURE, 0, 2899 gettext ("cannot get section header string table index")); 2900 2901 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 2902 { 2903 GElf_Shdr shdr_mem; 2904 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2905 2906 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST) 2907 { 2908 int nentries = shdr->sh_size / shdr->sh_entsize; 2909 printf (ngettext ("\ 2910 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 2911 "\ 2912 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 2913 nentries), 2914 elf_ndxscn (scn), 2915 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 2916 shdr->sh_offset, 2917 nentries); 2918 2919 Elf_Data *data = elf_getdata (scn, NULL); 2920 if (data == NULL) 2921 return; 2922 2923 puts (gettext ("\ 2924 Library Time Stamp Checksum Version Flags")); 2925 2926 for (int cnt = 0; cnt < nentries; ++cnt) 2927 { 2928 GElf_Lib lib_mem; 2929 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem); 2930 if (unlikely (lib == NULL)) 2931 continue; 2932 2933 time_t t = (time_t) lib->l_time_stamp; 2934 struct tm *tm = gmtime (&t); 2935 if (unlikely (tm == NULL)) 2936 continue; 2937 2938 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n", 2939 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name), 2940 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 2941 tm->tm_hour, tm->tm_min, tm->tm_sec, 2942 (unsigned int) lib->l_checksum, 2943 (unsigned int) lib->l_version, 2944 (unsigned int) lib->l_flags); 2945 } 2946 } 2947 } 2948 } 2949 2950 static void 2951 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr) 2952 { 2953 /* Find the object attributes sections. For this we have to search 2954 through the section table. */ 2955 Elf_Scn *scn = NULL; 2956 2957 /* Get the section header string table index. */ 2958 size_t shstrndx; 2959 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 2960 error (EXIT_FAILURE, 0, 2961 gettext ("cannot get section header string table index")); 2962 2963 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 2964 { 2965 GElf_Shdr shdr_mem; 2966 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2967 2968 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES 2969 && (shdr->sh_type != SHT_ARM_ATTRIBUTES 2970 || ehdr->e_machine != EM_ARM))) 2971 continue; 2972 2973 printf (gettext ("\ 2974 \nObject attributes section [%2zu] '%s' of %" PRIu64 2975 " bytes at offset %#0" PRIx64 ":\n"), 2976 elf_ndxscn (scn), 2977 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 2978 shdr->sh_size, shdr->sh_offset); 2979 2980 Elf_Data *data = elf_rawdata (scn, NULL); 2981 if (data == NULL) 2982 return; 2983 2984 const unsigned char *p = data->d_buf; 2985 2986 if (unlikely (*p++ != 'A')) 2987 return; 2988 2989 fputs_unlocked (gettext (" Owner Size\n"), stdout); 2990 2991 inline size_t left (void) 2992 { 2993 return (const unsigned char *) data->d_buf + data->d_size - p; 2994 } 2995 2996 while (left () >= 4) 2997 { 2998 uint32_t len; 2999 memcpy (&len, p, sizeof len); 3000 3001 if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) 3002 CONVERT (len); 3003 3004 if (unlikely (len > left ())) 3005 break; 3006 3007 const unsigned char *name = p + sizeof len; 3008 p += len; 3009 3010 unsigned const char *q = memchr (name, '\0', len); 3011 if (unlikely (q == NULL)) 3012 continue; 3013 ++q; 3014 3015 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len); 3016 3017 if (shdr->sh_type != SHT_GNU_ATTRIBUTES 3018 || (q - name == sizeof "gnu" 3019 && !memcmp (name, "gnu", sizeof "gnu"))) 3020 while (q < p) 3021 { 3022 const unsigned char *const sub = q; 3023 3024 unsigned int subsection_tag; 3025 get_uleb128 (subsection_tag, q); 3026 if (unlikely (q >= p)) 3027 break; 3028 3029 uint32_t subsection_len; 3030 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len)) 3031 break; 3032 3033 memcpy (&subsection_len, q, sizeof subsection_len); 3034 3035 if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) 3036 CONVERT (subsection_len); 3037 3038 if (unlikely (p - sub < (ptrdiff_t) subsection_len)) 3039 break; 3040 3041 const unsigned char *r = q + sizeof subsection_len; 3042 q = sub + subsection_len; 3043 3044 switch (subsection_tag) 3045 { 3046 default: 3047 printf (gettext (" %-4u %12" PRIu32 "\n"), 3048 subsection_tag, subsection_len); 3049 break; 3050 3051 case 1: /* Tag_File */ 3052 printf (gettext (" File: %11" PRIu32 "\n"), 3053 subsection_len); 3054 3055 while (r < q) 3056 { 3057 unsigned int tag; 3058 get_uleb128 (tag, r); 3059 if (unlikely (r >= q)) 3060 break; 3061 3062 uint64_t value = 0; 3063 const char *string = NULL; 3064 if (tag == 32 || (tag & 1) == 0) 3065 { 3066 get_uleb128 (value, r); 3067 if (r > q) 3068 break; 3069 } 3070 if (tag == 32 || (tag & 1) != 0) 3071 { 3072 r = memchr (r, '\0', q - r); 3073 if (r == NULL) 3074 break; 3075 ++r; 3076 } 3077 3078 const char *tag_name = NULL; 3079 const char *value_name = NULL; 3080 ebl_check_object_attribute (ebl, (const char *) name, 3081 tag, value, 3082 &tag_name, &value_name); 3083 3084 if (tag_name != NULL) 3085 { 3086 if (tag == 32) 3087 printf (gettext (" %s: %" PRId64 ", %s\n"), 3088 tag_name, value, string); 3089 else if (string == NULL && value_name == NULL) 3090 printf (gettext (" %s: %" PRId64 "\n"), 3091 tag_name, value); 3092 else 3093 printf (gettext (" %s: %s\n"), 3094 tag_name, string ?: value_name); 3095 } 3096 else 3097 { 3098 assert (tag != 32); 3099 if (string == NULL) 3100 printf (gettext (" %u: %" PRId64 "\n"), 3101 tag, value); 3102 else 3103 printf (gettext (" %u: %s\n"), 3104 tag, string); 3105 } 3106 } 3107 } 3108 } 3109 } 3110 } 3111 } 3112 3113 3114 static char * 3115 format_dwarf_addr (Dwfl_Module *dwflmod, 3116 int address_size, Dwarf_Addr address) 3117 { 3118 /* See if there is a name we can give for this address. */ 3119 GElf_Sym sym; 3120 const char *name = print_address_names 3121 ? dwfl_module_addrsym (dwflmod, address, &sym, NULL) : NULL; 3122 if (name != NULL) 3123 sym.st_value = address - sym.st_value; 3124 3125 /* Relativize the address. */ 3126 int n = dwfl_module_relocations (dwflmod); 3127 int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address); 3128 3129 /* In an ET_REL file there is a section name to refer to. */ 3130 const char *scn = (i < 0 ? NULL 3131 : dwfl_module_relocation_info (dwflmod, i, NULL)); 3132 3133 char *result; 3134 if ((name != NULL 3135 ? (sym.st_value != 0 3136 ? (scn != NULL 3137 ? (address_size == 0 3138 ? asprintf (&result, 3139 gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"), 3140 scn, address, name, sym.st_value) 3141 : asprintf (&result, 3142 gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"), 3143 scn, 2 + address_size * 2, address, 3144 name, sym.st_value)) 3145 : (address_size == 0 3146 ? asprintf (&result, 3147 gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"), 3148 address, name, sym.st_value) 3149 : asprintf (&result, 3150 gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"), 3151 2 + address_size * 2, address, 3152 name, sym.st_value))) 3153 : (scn != NULL 3154 ? (address_size == 0 3155 ? asprintf (&result, 3156 gettext ("%s+%#" PRIx64 " <%s>"), 3157 scn, address, name) 3158 : asprintf (&result, 3159 gettext ("%s+%#0*" PRIx64 " <%s>"), 3160 scn, 2 + address_size * 2, address, name)) 3161 : (address_size == 0 3162 ? asprintf (&result, 3163 gettext ("%#" PRIx64 " <%s>"), 3164 address, name) 3165 : asprintf (&result, 3166 gettext ("%#0*" PRIx64 " <%s>"), 3167 2 + address_size * 2, address, name)))) 3168 : (scn != NULL 3169 ? (address_size == 0 3170 ? asprintf (&result, 3171 gettext ("%s+%#" PRIx64), 3172 scn, address) 3173 : asprintf (&result, 3174 gettext ("%s+%#0*" PRIx64), 3175 scn, 2 + address_size * 2, address)) 3176 : (address_size == 0 3177 ? asprintf (&result, 3178 "%#" PRIx64, 3179 address) 3180 : asprintf (&result, 3181 "%#0*" PRIx64, 3182 2 + address_size * 2, address)))) < 0) 3183 error (EXIT_FAILURE, 0, _("memory exhausted")); 3184 3185 return result; 3186 } 3187 3188 static const char * 3189 dwarf_tag_string (unsigned int tag) 3190 { 3191 static const char *const known_tags[] = 3192 { 3193 [DW_TAG_array_type] = "array_type", 3194 [DW_TAG_class_type] = "class_type", 3195 [DW_TAG_entry_point] = "entry_point", 3196 [DW_TAG_enumeration_type] = "enumeration_type", 3197 [DW_TAG_formal_parameter] = "formal_parameter", 3198 [DW_TAG_imported_declaration] = "imported_declaration", 3199 [DW_TAG_label] = "label", 3200 [DW_TAG_lexical_block] = "lexical_block", 3201 [DW_TAG_member] = "member", 3202 [DW_TAG_pointer_type] = "pointer_type", 3203 [DW_TAG_reference_type] = "reference_type", 3204 [DW_TAG_compile_unit] = "compile_unit", 3205 [DW_TAG_string_type] = "string_type", 3206 [DW_TAG_structure_type] = "structure_type", 3207 [DW_TAG_subroutine_type] = "subroutine_type", 3208 [DW_TAG_typedef] = "typedef", 3209 [DW_TAG_union_type] = "union_type", 3210 [DW_TAG_unspecified_parameters] = "unspecified_parameters", 3211 [DW_TAG_variant] = "variant", 3212 [DW_TAG_common_block] = "common_block", 3213 [DW_TAG_common_inclusion] = "common_inclusion", 3214 [DW_TAG_inheritance] = "inheritance", 3215 [DW_TAG_inlined_subroutine] = "inlined_subroutine", 3216 [DW_TAG_module] = "module", 3217 [DW_TAG_ptr_to_member_type] = "ptr_to_member_type", 3218 [DW_TAG_set_type] = "set_type", 3219 [DW_TAG_subrange_type] = "subrange_type", 3220 [DW_TAG_with_stmt] = "with_stmt", 3221 [DW_TAG_access_declaration] = "access_declaration", 3222 [DW_TAG_base_type] = "base_type", 3223 [DW_TAG_catch_block] = "catch_block", 3224 [DW_TAG_const_type] = "const_type", 3225 [DW_TAG_constant] = "constant", 3226 [DW_TAG_enumerator] = "enumerator", 3227 [DW_TAG_file_type] = "file_type", 3228 [DW_TAG_friend] = "friend", 3229 [DW_TAG_namelist] = "namelist", 3230 [DW_TAG_namelist_item] = "namelist_item", 3231 [DW_TAG_packed_type] = "packed_type", 3232 [DW_TAG_subprogram] = "subprogram", 3233 [DW_TAG_template_type_parameter] = "template_type_parameter", 3234 [DW_TAG_template_value_parameter] = "template_value_parameter", 3235 [DW_TAG_thrown_type] = "thrown_type", 3236 [DW_TAG_try_block] = "try_block", 3237 [DW_TAG_variant_part] = "variant_part", 3238 [DW_TAG_variable] = "variable", 3239 [DW_TAG_volatile_type] = "volatile_type", 3240 [DW_TAG_dwarf_procedure] = "dwarf_procedure", 3241 [DW_TAG_restrict_type] = "restrict_type", 3242 [DW_TAG_interface_type] = "interface_type", 3243 [DW_TAG_namespace] = "namespace", 3244 [DW_TAG_imported_module] = "imported_module", 3245 [DW_TAG_unspecified_type] = "unspecified_type", 3246 [DW_TAG_partial_unit] = "partial_unit", 3247 [DW_TAG_imported_unit] = "imported_unit", 3248 [DW_TAG_mutable_type] = "mutable_type", 3249 [DW_TAG_condition] = "condition", 3250 [DW_TAG_shared_type] = "shared_type", 3251 [DW_TAG_type_unit] = "type_unit", 3252 [DW_TAG_rvalue_reference_type] = "rvalue_reference_type", 3253 [DW_TAG_template_alias] = "template_alias", 3254 }; 3255 const unsigned int nknown_tags = (sizeof (known_tags) 3256 / sizeof (known_tags[0])); 3257 static char buf[40]; 3258 const char *result = NULL; 3259 3260 if (likely (tag < nknown_tags)) 3261 result = known_tags[tag]; 3262 3263 if (unlikely (result == NULL)) 3264 /* There are a few known extensions. */ 3265 switch (tag) 3266 { 3267 case DW_TAG_MIPS_loop: 3268 result = "MIPS_loop"; 3269 break; 3270 3271 case DW_TAG_format_label: 3272 result = "format_label"; 3273 break; 3274 3275 case DW_TAG_function_template: 3276 result = "function_template"; 3277 break; 3278 3279 case DW_TAG_class_template: 3280 result = "class_template"; 3281 break; 3282 3283 case DW_TAG_GNU_BINCL: 3284 result = "GNU_BINCL"; 3285 break; 3286 3287 case DW_TAG_GNU_EINCL: 3288 result = "GNU_EINCL"; 3289 break; 3290 3291 case DW_TAG_GNU_template_template_param: 3292 result = "GNU_template_template_param"; 3293 break; 3294 3295 case DW_TAG_GNU_template_parameter_pack: 3296 result = "GNU_template_parameter_pack"; 3297 break; 3298 3299 case DW_TAG_GNU_formal_parameter_pack: 3300 result = "GNU_formal_parameter_pack"; 3301 break; 3302 3303 case DW_TAG_GNU_call_site: 3304 result = "GNU_call_site"; 3305 break; 3306 3307 case DW_TAG_GNU_call_site_parameter: 3308 result = "GNU_call_site_parameter"; 3309 break; 3310 3311 default: 3312 if (tag < DW_TAG_lo_user) 3313 snprintf (buf, sizeof buf, gettext ("unknown tag %hx"), tag); 3314 else 3315 snprintf (buf, sizeof buf, gettext ("unknown user tag %hx"), tag); 3316 result = buf; 3317 break; 3318 } 3319 3320 return result; 3321 } 3322 3323 3324 static const char * 3325 dwarf_attr_string (unsigned int attrnum) 3326 { 3327 static const char *const known_attrs[] = 3328 { 3329 [DW_AT_sibling] = "sibling", 3330 [DW_AT_location] = "location", 3331 [DW_AT_name] = "name", 3332 [DW_AT_ordering] = "ordering", 3333 [DW_AT_subscr_data] = "subscr_data", 3334 [DW_AT_byte_size] = "byte_size", 3335 [DW_AT_bit_offset] = "bit_offset", 3336 [DW_AT_bit_size] = "bit_size", 3337 [DW_AT_element_list] = "element_list", 3338 [DW_AT_stmt_list] = "stmt_list", 3339 [DW_AT_low_pc] = "low_pc", 3340 [DW_AT_high_pc] = "high_pc", 3341 [DW_AT_language] = "language", 3342 [DW_AT_member] = "member", 3343 [DW_AT_discr] = "discr", 3344 [DW_AT_discr_value] = "discr_value", 3345 [DW_AT_visibility] = "visibility", 3346 [DW_AT_import] = "import", 3347 [DW_AT_string_length] = "string_length", 3348 [DW_AT_common_reference] = "common_reference", 3349 [DW_AT_comp_dir] = "comp_dir", 3350 [DW_AT_const_value] = "const_value", 3351 [DW_AT_containing_type] = "containing_type", 3352 [DW_AT_default_value] = "default_value", 3353 [DW_AT_inline] = "inline", 3354 [DW_AT_is_optional] = "is_optional", 3355 [DW_AT_lower_bound] = "lower_bound", 3356 [DW_AT_producer] = "producer", 3357 [DW_AT_prototyped] = "prototyped", 3358 [DW_AT_return_addr] = "return_addr", 3359 [DW_AT_start_scope] = "start_scope", 3360 [DW_AT_bit_stride] = "bit_stride", 3361 [DW_AT_upper_bound] = "upper_bound", 3362 [DW_AT_abstract_origin] = "abstract_origin", 3363 [DW_AT_accessibility] = "accessibility", 3364 [DW_AT_address_class] = "address_class", 3365 [DW_AT_artificial] = "artificial", 3366 [DW_AT_base_types] = "base_types", 3367 [DW_AT_calling_convention] = "calling_convention", 3368 [DW_AT_count] = "count", 3369 [DW_AT_data_member_location] = "data_member_location", 3370 [DW_AT_decl_column] = "decl_column", 3371 [DW_AT_decl_file] = "decl_file", 3372 [DW_AT_decl_line] = "decl_line", 3373 [DW_AT_declaration] = "declaration", 3374 [DW_AT_discr_list] = "discr_list", 3375 [DW_AT_encoding] = "encoding", 3376 [DW_AT_external] = "external", 3377 [DW_AT_frame_base] = "frame_base", 3378 [DW_AT_friend] = "friend", 3379 [DW_AT_identifier_case] = "identifier_case", 3380 [DW_AT_macro_info] = "macro_info", 3381 [DW_AT_namelist_item] = "namelist_item", 3382 [DW_AT_priority] = "priority", 3383 [DW_AT_segment] = "segment", 3384 [DW_AT_specification] = "specification", 3385 [DW_AT_static_link] = "static_link", 3386 [DW_AT_type] = "type", 3387 [DW_AT_use_location] = "use_location", 3388 [DW_AT_variable_parameter] = "variable_parameter", 3389 [DW_AT_virtuality] = "virtuality", 3390 [DW_AT_vtable_elem_location] = "vtable_elem_location", 3391 [DW_AT_allocated] = "allocated", 3392 [DW_AT_associated] = "associated", 3393 [DW_AT_data_location] = "data_location", 3394 [DW_AT_byte_stride] = "byte_stride", 3395 [DW_AT_entry_pc] = "entry_pc", 3396 [DW_AT_use_UTF8] = "use_UTF8", 3397 [DW_AT_extension] = "extension", 3398 [DW_AT_ranges] = "ranges", 3399 [DW_AT_trampoline] = "trampoline", 3400 [DW_AT_call_column] = "call_column", 3401 [DW_AT_call_file] = "call_file", 3402 [DW_AT_call_line] = "call_line", 3403 [DW_AT_description] = "description", 3404 [DW_AT_binary_scale] = "binary_scale", 3405 [DW_AT_decimal_scale] = "decimal_scale", 3406 [DW_AT_small] = "small", 3407 [DW_AT_decimal_sign] = "decimal_sign", 3408 [DW_AT_digit_count] = "digit_count", 3409 [DW_AT_picture_string] = "picture_string", 3410 [DW_AT_mutable] = "mutable", 3411 [DW_AT_threads_scaled] = "threads_scaled", 3412 [DW_AT_explicit] = "explicit", 3413 [DW_AT_object_pointer] = "object_pointer", 3414 [DW_AT_endianity] = "endianity", 3415 [DW_AT_elemental] = "elemental", 3416 [DW_AT_pure] = "pure", 3417 [DW_AT_recursive] = "recursive", 3418 [DW_AT_signature] = "signature", 3419 [DW_AT_main_subprogram] = "main_subprogram", 3420 [DW_AT_data_bit_offset] = "data_bit_offset", 3421 [DW_AT_const_expr] = "const_expr", 3422 [DW_AT_enum_class] = "enum_class", 3423 [DW_AT_linkage_name] = "linkage_name", 3424 }; 3425 const unsigned int nknown_attrs = (sizeof (known_attrs) 3426 / sizeof (known_attrs[0])); 3427 static char buf[40]; 3428 const char *result = NULL; 3429 3430 if (likely (attrnum < nknown_attrs)) 3431 result = known_attrs[attrnum]; 3432 3433 if (unlikely (result == NULL)) 3434 /* There are a few known extensions. */ 3435 switch (attrnum) 3436 { 3437 case DW_AT_MIPS_fde: 3438 result = "MIPS_fde"; 3439 break; 3440 3441 case DW_AT_MIPS_loop_begin: 3442 result = "MIPS_loop_begin"; 3443 break; 3444 3445 case DW_AT_MIPS_tail_loop_begin: 3446 result = "MIPS_tail_loop_begin"; 3447 break; 3448 3449 case DW_AT_MIPS_epilog_begin: 3450 result = "MIPS_epilog_begin"; 3451 break; 3452 3453 case DW_AT_MIPS_loop_unroll_factor: 3454 result = "MIPS_loop_unroll_factor"; 3455 break; 3456 3457 case DW_AT_MIPS_software_pipeline_depth: 3458 result = "MIPS_software_pipeline_depth"; 3459 break; 3460 3461 case DW_AT_MIPS_linkage_name: 3462 result = "MIPS_linkage_name"; 3463 break; 3464 3465 case DW_AT_MIPS_stride: 3466 result = "MIPS_stride"; 3467 break; 3468 3469 case DW_AT_MIPS_abstract_name: 3470 result = "MIPS_abstract_name"; 3471 break; 3472 3473 case DW_AT_MIPS_clone_origin: 3474 result = "MIPS_clone_origin"; 3475 break; 3476 3477 case DW_AT_MIPS_has_inlines: 3478 result = "MIPS_has_inlines"; 3479 break; 3480 3481 case DW_AT_MIPS_stride_byte: 3482 result = "MIPS_stride_byte"; 3483 break; 3484 3485 case DW_AT_MIPS_stride_elem: 3486 result = "MIPS_stride_elem"; 3487 break; 3488 3489 case DW_AT_MIPS_ptr_dopetype: 3490 result = "MIPS_ptr_dopetype"; 3491 break; 3492 3493 case DW_AT_MIPS_allocatable_dopetype: 3494 result = "MIPS_allocatable_dopetype"; 3495 break; 3496 3497 case DW_AT_MIPS_assumed_shape_dopetype: 3498 result = "MIPS_assumed_shape_dopetype"; 3499 break; 3500 3501 case DW_AT_MIPS_assumed_size: 3502 result = "MIPS_assumed_size"; 3503 break; 3504 3505 case DW_AT_sf_names: 3506 result = "sf_names"; 3507 break; 3508 3509 case DW_AT_src_info: 3510 result = "src_info"; 3511 break; 3512 3513 case DW_AT_mac_info: 3514 result = "mac_info"; 3515 break; 3516 3517 case DW_AT_src_coords: 3518 result = "src_coords"; 3519 break; 3520 3521 case DW_AT_body_begin: 3522 result = "body_begin"; 3523 break; 3524 3525 case DW_AT_body_end: 3526 result = "body_end"; 3527 break; 3528 3529 case DW_AT_GNU_vector: 3530 result = "GNU_vector"; 3531 break; 3532 3533 case DW_AT_GNU_guarded_by: 3534 result = "GNU_guarded_by"; 3535 break; 3536 3537 case DW_AT_GNU_pt_guarded_by: 3538 result = "GNU_pt_guarded_by"; 3539 break; 3540 3541 case DW_AT_GNU_guarded: 3542 result = "GNU_guarded"; 3543 break; 3544 3545 case DW_AT_GNU_pt_guarded: 3546 result = "GNU_pt_guarded"; 3547 break; 3548 3549 case DW_AT_GNU_locks_excluded: 3550 result = "GNU_locks_excluded"; 3551 break; 3552 3553 case DW_AT_GNU_exclusive_locks_required: 3554 result = "GNU_exclusive_locks_required"; 3555 break; 3556 3557 case DW_AT_GNU_shared_locks_required: 3558 result = "GNU_shared_locks_required"; 3559 break; 3560 3561 case DW_AT_GNU_odr_signature: 3562 result = "GNU_odr_signature"; 3563 break; 3564 3565 case DW_AT_GNU_template_name: 3566 result = "GNU_template_name"; 3567 break; 3568 3569 case DW_AT_GNU_call_site_value: 3570 result = "GNU_call_site_value"; 3571 break; 3572 3573 case DW_AT_GNU_call_site_data_value: 3574 result = "GNU_call_site_data_value"; 3575 break; 3576 3577 case DW_AT_GNU_call_site_target: 3578 result = "GNU_call_site_target"; 3579 break; 3580 3581 case DW_AT_GNU_call_site_target_clobbered: 3582 result = "GNU_call_site_target_clobbered"; 3583 break; 3584 3585 case DW_AT_GNU_tail_call: 3586 result = "GNU_tail_call"; 3587 break; 3588 3589 case DW_AT_GNU_all_tail_call_sites: 3590 result = "GNU_all_tail_call_sites"; 3591 break; 3592 3593 case DW_AT_GNU_all_call_sites: 3594 result = "GNU_all_call_sites"; 3595 break; 3596 3597 case DW_AT_GNU_all_source_call_sites: 3598 result = "GNU_all_source_call_sites"; 3599 break; 3600 3601 default: 3602 if (attrnum < DW_AT_lo_user) 3603 snprintf (buf, sizeof buf, gettext ("unknown attribute %hx"), 3604 attrnum); 3605 else 3606 snprintf (buf, sizeof buf, gettext ("unknown user attribute %hx"), 3607 attrnum); 3608 result = buf; 3609 break; 3610 } 3611 3612 return result; 3613 } 3614 3615 3616 static const char * 3617 dwarf_form_string (unsigned int form) 3618 { 3619 static const char *const known_forms[] = 3620 { 3621 [DW_FORM_addr] = "addr", 3622 [DW_FORM_block2] = "block2", 3623 [DW_FORM_block4] = "block4", 3624 [DW_FORM_data2] = "data2", 3625 [DW_FORM_data4] = "data4", 3626 [DW_FORM_data8] = "data8", 3627 [DW_FORM_string] = "string", 3628 [DW_FORM_block] = "block", 3629 [DW_FORM_block1] = "block1", 3630 [DW_FORM_data1] = "data1", 3631 [DW_FORM_flag] = "flag", 3632 [DW_FORM_sdata] = "sdata", 3633 [DW_FORM_strp] = "strp", 3634 [DW_FORM_udata] = "udata", 3635 [DW_FORM_ref_addr] = "ref_addr", 3636 [DW_FORM_ref1] = "ref1", 3637 [DW_FORM_ref2] = "ref2", 3638 [DW_FORM_ref4] = "ref4", 3639 [DW_FORM_ref8] = "ref8", 3640 [DW_FORM_ref_udata] = "ref_udata", 3641 [DW_FORM_indirect] = "indirect", 3642 [DW_FORM_sec_offset] = "sec_offset", 3643 [DW_FORM_exprloc] = "exprloc", 3644 [DW_FORM_flag_present] = "flag_present", 3645 [DW_FORM_ref_sig8] = "ref_sig8", 3646 }; 3647 const unsigned int nknown_forms = (sizeof (known_forms) 3648 / sizeof (known_forms[0])); 3649 static char buf[40]; 3650 const char *result = NULL; 3651 3652 if (likely (form < nknown_forms)) 3653 result = known_forms[form]; 3654 3655 if (unlikely (result == NULL)) 3656 { 3657 snprintf (buf, sizeof buf, gettext ("unknown form %#" PRIx64), 3658 (uint64_t) form); 3659 result = buf; 3660 } 3661 3662 return result; 3663 } 3664 3665 3666 static const char * 3667 dwarf_lang_string (unsigned int lang) 3668 { 3669 static const char *const known[] = 3670 { 3671 [DW_LANG_C89] = "ISO C89", 3672 [DW_LANG_C] = "C", 3673 [DW_LANG_Ada83] = "Ada83", 3674 [DW_LANG_C_plus_plus] = "C++", 3675 [DW_LANG_Cobol74] = "Cobol74", 3676 [DW_LANG_Cobol85] = "Cobol85", 3677 [DW_LANG_Fortran77] = "Fortran77", 3678 [DW_LANG_Fortran90] = "Fortran90", 3679 [DW_LANG_Pascal83] = "Pascal83", 3680 [DW_LANG_Modula2] = "Modula2", 3681 [DW_LANG_Java] = "Java", 3682 [DW_LANG_C99] = "ISO C99", 3683 [DW_LANG_Ada95] = "Ada95", 3684 [DW_LANG_Fortran95] = "Fortran95", 3685 [DW_LANG_PL1] = "PL1", 3686 [DW_LANG_Objc] = "Objective C", 3687 [DW_LANG_ObjC_plus_plus] = "Objective C++", 3688 [DW_LANG_UPC] = "UPC", 3689 [DW_LANG_D] = "D", 3690 }; 3691 3692 if (likely (lang < sizeof (known) / sizeof (known[0]))) 3693 return known[lang]; 3694 else if (lang == DW_LANG_Mips_Assembler) 3695 /* This language tag is used for assembler in general. */ 3696 return "Assembler"; 3697 3698 if (lang >= DW_LANG_lo_user && lang <= DW_LANG_hi_user) 3699 { 3700 static char buf[30]; 3701 snprintf (buf, sizeof (buf), "lo_user+%u", lang - DW_LANG_lo_user); 3702 return buf; 3703 } 3704 3705 return "???"; 3706 } 3707 3708 3709 static const char * 3710 dwarf_inline_string (unsigned int code) 3711 { 3712 static const char *const known[] = 3713 { 3714 [DW_INL_not_inlined] = "not_inlined", 3715 [DW_INL_inlined] = "inlined", 3716 [DW_INL_declared_not_inlined] = "declared_not_inlined", 3717 [DW_INL_declared_inlined] = "declared_inlined" 3718 }; 3719 3720 if (likely (code < sizeof (known) / sizeof (known[0]))) 3721 return known[code]; 3722 3723 return "???"; 3724 } 3725 3726 3727 static const char * 3728 dwarf_encoding_string (unsigned int code) 3729 { 3730 static const char *const known[] = 3731 { 3732 [DW_ATE_void] = "void", 3733 [DW_ATE_address] = "address", 3734 [DW_ATE_boolean] = "boolean", 3735 [DW_ATE_complex_float] = "complex_float", 3736 [DW_ATE_float] = "float", 3737 [DW_ATE_signed] = "signed", 3738 [DW_ATE_signed_char] = "signed_char", 3739 [DW_ATE_unsigned] = "unsigned", 3740 [DW_ATE_unsigned_char] = "unsigned_char", 3741 [DW_ATE_imaginary_float] = "imaginary_float", 3742 [DW_ATE_packed_decimal] = "packed_decimal", 3743 [DW_ATE_numeric_string] = "numeric_string", 3744 [DW_ATE_edited] = "edited", 3745 [DW_ATE_signed_fixed] = "signed_fixed", 3746 [DW_ATE_unsigned_fixed] = "unsigned_fixed", 3747 [DW_ATE_decimal_float] = "decimal_float", 3748 }; 3749 3750 if (likely (code < sizeof (known) / sizeof (known[0]))) 3751 return known[code]; 3752 3753 if (code >= DW_ATE_lo_user && code <= DW_ATE_hi_user) 3754 { 3755 static char buf[30]; 3756 snprintf (buf, sizeof (buf), "lo_user+%u", code - DW_ATE_lo_user); 3757 return buf; 3758 } 3759 3760 return "???"; 3761 } 3762 3763 3764 static const char * 3765 dwarf_access_string (unsigned int code) 3766 { 3767 static const char *const known[] = 3768 { 3769 [DW_ACCESS_public] = "public", 3770 [DW_ACCESS_protected] = "protected", 3771 [DW_ACCESS_private] = "private" 3772 }; 3773 3774 if (likely (code < sizeof (known) / sizeof (known[0]))) 3775 return known[code]; 3776 3777 return "???"; 3778 } 3779 3780 3781 static const char * 3782 dwarf_visibility_string (unsigned int code) 3783 { 3784 static const char *const known[] = 3785 { 3786 [DW_VIS_local] = "local", 3787 [DW_VIS_exported] = "exported", 3788 [DW_VIS_qualified] = "qualified" 3789 }; 3790 3791 if (likely (code < sizeof (known) / sizeof (known[0]))) 3792 return known[code]; 3793 3794 return "???"; 3795 } 3796 3797 3798 static const char * 3799 dwarf_virtuality_string (unsigned int code) 3800 { 3801 static const char *const known[] = 3802 { 3803 [DW_VIRTUALITY_none] = "none", 3804 [DW_VIRTUALITY_virtual] = "virtual", 3805 [DW_VIRTUALITY_pure_virtual] = "pure_virtual" 3806 }; 3807 3808 if (likely (code < sizeof (known) / sizeof (known[0]))) 3809 return known[code]; 3810 3811 return "???"; 3812 } 3813 3814 3815 static const char * 3816 dwarf_identifier_case_string (unsigned int code) 3817 { 3818 static const char *const known[] = 3819 { 3820 [DW_ID_case_sensitive] = "sensitive", 3821 [DW_ID_up_case] = "up_case", 3822 [DW_ID_down_case] = "down_case", 3823 [DW_ID_case_insensitive] = "insensitive" 3824 }; 3825 3826 if (likely (code < sizeof (known) / sizeof (known[0]))) 3827 return known[code]; 3828 3829 return "???"; 3830 } 3831 3832 3833 static const char * 3834 dwarf_calling_convention_string (unsigned int code) 3835 { 3836 static const char *const known[] = 3837 { 3838 [DW_CC_normal] = "normal", 3839 [DW_CC_program] = "program", 3840 [DW_CC_nocall] = "nocall", 3841 }; 3842 3843 if (likely (code < sizeof (known) / sizeof (known[0]))) 3844 return known[code]; 3845 3846 if (code >= DW_CC_lo_user && code <= DW_CC_hi_user) 3847 { 3848 static char buf[30]; 3849 snprintf (buf, sizeof (buf), "lo_user+%u", code - DW_CC_lo_user); 3850 return buf; 3851 } 3852 3853 return "???"; 3854 } 3855 3856 3857 static const char * 3858 dwarf_ordering_string (unsigned int code) 3859 { 3860 static const char *const known[] = 3861 { 3862 [DW_ORD_row_major] = "row_major", 3863 [DW_ORD_col_major] = "col_major" 3864 }; 3865 3866 if (likely (code < sizeof (known) / sizeof (known[0]))) 3867 return known[code]; 3868 3869 return "???"; 3870 } 3871 3872 3873 static const char * 3874 dwarf_discr_list_string (unsigned int code) 3875 { 3876 static const char *const known[] = 3877 { 3878 [DW_DSC_label] = "label", 3879 [DW_DSC_range] = "range" 3880 }; 3881 3882 if (likely (code < sizeof (known) / sizeof (known[0]))) 3883 return known[code]; 3884 3885 return "???"; 3886 } 3887 3888 3889 static void 3890 print_block (size_t n, const void *block) 3891 { 3892 if (n == 0) 3893 puts (_("empty block")); 3894 else 3895 { 3896 printf (_("%zu byte block:"), n); 3897 const unsigned char *data = block; 3898 do 3899 printf (" %02x", *data++); 3900 while (--n > 0); 3901 putchar ('\n'); 3902 } 3903 } 3904 3905 static void 3906 print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, 3907 unsigned int vers, unsigned int addrsize, unsigned int offset_size, 3908 Dwarf_Word len, const unsigned char *data) 3909 { 3910 const unsigned int ref_size = vers < 3 ? addrsize : offset_size; 3911 3912 static const char *const known[] = 3913 { 3914 [DW_OP_addr] = "addr", 3915 [DW_OP_deref] = "deref", 3916 [DW_OP_const1u] = "const1u", 3917 [DW_OP_const1s] = "const1s", 3918 [DW_OP_const2u] = "const2u", 3919 [DW_OP_const2s] = "const2s", 3920 [DW_OP_const4u] = "const4u", 3921 [DW_OP_const4s] = "const4s", 3922 [DW_OP_const8u] = "const8u", 3923 [DW_OP_const8s] = "const8s", 3924 [DW_OP_constu] = "constu", 3925 [DW_OP_consts] = "consts", 3926 [DW_OP_dup] = "dup", 3927 [DW_OP_drop] = "drop", 3928 [DW_OP_over] = "over", 3929 [DW_OP_pick] = "pick", 3930 [DW_OP_swap] = "swap", 3931 [DW_OP_rot] = "rot", 3932 [DW_OP_xderef] = "xderef", 3933 [DW_OP_abs] = "abs", 3934 [DW_OP_and] = "and", 3935 [DW_OP_div] = "div", 3936 [DW_OP_minus] = "minus", 3937 [DW_OP_mod] = "mod", 3938 [DW_OP_mul] = "mul", 3939 [DW_OP_neg] = "neg", 3940 [DW_OP_not] = "not", 3941 [DW_OP_or] = "or", 3942 [DW_OP_plus] = "plus", 3943 [DW_OP_plus_uconst] = "plus_uconst", 3944 [DW_OP_shl] = "shl", 3945 [DW_OP_shr] = "shr", 3946 [DW_OP_shra] = "shra", 3947 [DW_OP_xor] = "xor", 3948 [DW_OP_bra] = "bra", 3949 [DW_OP_eq] = "eq", 3950 [DW_OP_ge] = "ge", 3951 [DW_OP_gt] = "gt", 3952 [DW_OP_le] = "le", 3953 [DW_OP_lt] = "lt", 3954 [DW_OP_ne] = "ne", 3955 [DW_OP_skip] = "skip", 3956 [DW_OP_lit0] = "lit0", 3957 [DW_OP_lit1] = "lit1", 3958 [DW_OP_lit2] = "lit2", 3959 [DW_OP_lit3] = "lit3", 3960 [DW_OP_lit4] = "lit4", 3961 [DW_OP_lit5] = "lit5", 3962 [DW_OP_lit6] = "lit6", 3963 [DW_OP_lit7] = "lit7", 3964 [DW_OP_lit8] = "lit8", 3965 [DW_OP_lit9] = "lit9", 3966 [DW_OP_lit10] = "lit10", 3967 [DW_OP_lit11] = "lit11", 3968 [DW_OP_lit12] = "lit12", 3969 [DW_OP_lit13] = "lit13", 3970 [DW_OP_lit14] = "lit14", 3971 [DW_OP_lit15] = "lit15", 3972 [DW_OP_lit16] = "lit16", 3973 [DW_OP_lit17] = "lit17", 3974 [DW_OP_lit18] = "lit18", 3975 [DW_OP_lit19] = "lit19", 3976 [DW_OP_lit20] = "lit20", 3977 [DW_OP_lit21] = "lit21", 3978 [DW_OP_lit22] = "lit22", 3979 [DW_OP_lit23] = "lit23", 3980 [DW_OP_lit24] = "lit24", 3981 [DW_OP_lit25] = "lit25", 3982 [DW_OP_lit26] = "lit26", 3983 [DW_OP_lit27] = "lit27", 3984 [DW_OP_lit28] = "lit28", 3985 [DW_OP_lit29] = "lit29", 3986 [DW_OP_lit30] = "lit30", 3987 [DW_OP_lit31] = "lit31", 3988 [DW_OP_reg0] = "reg0", 3989 [DW_OP_reg1] = "reg1", 3990 [DW_OP_reg2] = "reg2", 3991 [DW_OP_reg3] = "reg3", 3992 [DW_OP_reg4] = "reg4", 3993 [DW_OP_reg5] = "reg5", 3994 [DW_OP_reg6] = "reg6", 3995 [DW_OP_reg7] = "reg7", 3996 [DW_OP_reg8] = "reg8", 3997 [DW_OP_reg9] = "reg9", 3998 [DW_OP_reg10] = "reg10", 3999 [DW_OP_reg11] = "reg11", 4000 [DW_OP_reg12] = "reg12", 4001 [DW_OP_reg13] = "reg13", 4002 [DW_OP_reg14] = "reg14", 4003 [DW_OP_reg15] = "reg15", 4004 [DW_OP_reg16] = "reg16", 4005 [DW_OP_reg17] = "reg17", 4006 [DW_OP_reg18] = "reg18", 4007 [DW_OP_reg19] = "reg19", 4008 [DW_OP_reg20] = "reg20", 4009 [DW_OP_reg21] = "reg21", 4010 [DW_OP_reg22] = "reg22", 4011 [DW_OP_reg23] = "reg23", 4012 [DW_OP_reg24] = "reg24", 4013 [DW_OP_reg25] = "reg25", 4014 [DW_OP_reg26] = "reg26", 4015 [DW_OP_reg27] = "reg27", 4016 [DW_OP_reg28] = "reg28", 4017 [DW_OP_reg29] = "reg29", 4018 [DW_OP_reg30] = "reg30", 4019 [DW_OP_reg31] = "reg31", 4020 [DW_OP_breg0] = "breg0", 4021 [DW_OP_breg1] = "breg1", 4022 [DW_OP_breg2] = "breg2", 4023 [DW_OP_breg3] = "breg3", 4024 [DW_OP_breg4] = "breg4", 4025 [DW_OP_breg5] = "breg5", 4026 [DW_OP_breg6] = "breg6", 4027 [DW_OP_breg7] = "breg7", 4028 [DW_OP_breg8] = "breg8", 4029 [DW_OP_breg9] = "breg9", 4030 [DW_OP_breg10] = "breg10", 4031 [DW_OP_breg11] = "breg11", 4032 [DW_OP_breg12] = "breg12", 4033 [DW_OP_breg13] = "breg13", 4034 [DW_OP_breg14] = "breg14", 4035 [DW_OP_breg15] = "breg15", 4036 [DW_OP_breg16] = "breg16", 4037 [DW_OP_breg17] = "breg17", 4038 [DW_OP_breg18] = "breg18", 4039 [DW_OP_breg19] = "breg19", 4040 [DW_OP_breg20] = "breg20", 4041 [DW_OP_breg21] = "breg21", 4042 [DW_OP_breg22] = "breg22", 4043 [DW_OP_breg23] = "breg23", 4044 [DW_OP_breg24] = "breg24", 4045 [DW_OP_breg25] = "breg25", 4046 [DW_OP_breg26] = "breg26", 4047 [DW_OP_breg27] = "breg27", 4048 [DW_OP_breg28] = "breg28", 4049 [DW_OP_breg29] = "breg29", 4050 [DW_OP_breg30] = "breg30", 4051 [DW_OP_breg31] = "breg31", 4052 [DW_OP_regx] = "regx", 4053 [DW_OP_fbreg] = "fbreg", 4054 [DW_OP_bregx] = "bregx", 4055 [DW_OP_piece] = "piece", 4056 [DW_OP_deref_size] = "deref_size", 4057 [DW_OP_xderef_size] = "xderef_size", 4058 [DW_OP_nop] = "nop", 4059 [DW_OP_push_object_address] = "push_object_address", 4060 [DW_OP_call2] = "call2", 4061 [DW_OP_call4] = "call4", 4062 [DW_OP_call_ref] = "call_ref", 4063 [DW_OP_form_tls_address] = "form_tls_address", 4064 [DW_OP_call_frame_cfa] = "call_frame_cfa", 4065 [DW_OP_bit_piece] = "bit_piece", 4066 [DW_OP_implicit_value] = "implicit_value", 4067 [DW_OP_stack_value] = "stack_value", 4068 [DW_OP_GNU_implicit_pointer] = "GNU_implicit_pointer", 4069 [DW_OP_GNU_entry_value] = "GNU_entry_value", 4070 [DW_OP_GNU_const_type] = "GNU_const_type", 4071 [DW_OP_GNU_regval_type] = "GNU_regval_type", 4072 [DW_OP_GNU_deref_type] = "GNU_deref_type", 4073 [DW_OP_GNU_convert] = "GNU_convert", 4074 [DW_OP_GNU_reinterpret] = "GNU_reinterpret", 4075 }; 4076 4077 if (len == 0) 4078 { 4079 printf ("%*s(empty)\n", indent, ""); 4080 return; 4081 } 4082 4083 #define NEED(n) if (len < (Dwarf_Word) (n)) goto invalid 4084 #define CONSUME(n) NEED (n); else len -= (n) 4085 4086 Dwarf_Word offset = 0; 4087 while (len-- > 0) 4088 { 4089 uint_fast8_t op = *data++; 4090 4091 switch (op) 4092 { 4093 case DW_OP_addr:; 4094 /* Address operand. */ 4095 Dwarf_Word addr; 4096 NEED (addrsize); 4097 if (addrsize == 4) 4098 addr = read_4ubyte_unaligned (dbg, data); 4099 else 4100 { 4101 assert (addrsize == 8); 4102 addr = read_8ubyte_unaligned (dbg, data); 4103 } 4104 data += addrsize; 4105 CONSUME (addrsize); 4106 4107 char *a = format_dwarf_addr (dwflmod, 0, addr); 4108 printf ("%*s[%4" PRIuMAX "] %s %s\n", 4109 indent, "", (uintmax_t) offset, known[op], a); 4110 free (a); 4111 4112 offset += 1 + addrsize; 4113 break; 4114 4115 case DW_OP_call_ref: 4116 /* Offset operand. */ 4117 NEED (ref_size); 4118 if (ref_size == 4) 4119 addr = read_4ubyte_unaligned (dbg, data); 4120 else 4121 { 4122 assert (ref_size == 8); 4123 addr = read_8ubyte_unaligned (dbg, data); 4124 } 4125 data += ref_size; 4126 CONSUME (ref_size); 4127 4128 printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n", 4129 indent, "", (uintmax_t) offset, 4130 known[op], (uintmax_t) addr); 4131 offset += 1 + ref_size; 4132 break; 4133 4134 case DW_OP_deref_size: 4135 case DW_OP_xderef_size: 4136 case DW_OP_pick: 4137 case DW_OP_const1u: 4138 // XXX value might be modified by relocation 4139 NEED (1); 4140 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n", 4141 indent, "", (uintmax_t) offset, 4142 known[op], *((uint8_t *) data)); 4143 ++data; 4144 --len; 4145 offset += 2; 4146 break; 4147 4148 case DW_OP_const2u: 4149 NEED (2); 4150 // XXX value might be modified by relocation 4151 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n", 4152 indent, "", (uintmax_t) offset, 4153 known[op], read_2ubyte_unaligned (dbg, data)); 4154 CONSUME (2); 4155 data += 2; 4156 offset += 3; 4157 break; 4158 4159 case DW_OP_const4u: 4160 NEED (4); 4161 // XXX value might be modified by relocation 4162 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n", 4163 indent, "", (uintmax_t) offset, 4164 known[op], read_4ubyte_unaligned (dbg, data)); 4165 CONSUME (4); 4166 data += 4; 4167 offset += 5; 4168 break; 4169 4170 case DW_OP_const8u: 4171 NEED (8); 4172 // XXX value might be modified by relocation 4173 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n", 4174 indent, "", (uintmax_t) offset, 4175 known[op], read_8ubyte_unaligned (dbg, data)); 4176 CONSUME (8); 4177 data += 8; 4178 offset += 9; 4179 break; 4180 4181 case DW_OP_const1s: 4182 NEED (1); 4183 // XXX value might be modified by relocation 4184 printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n", 4185 indent, "", (uintmax_t) offset, 4186 known[op], *((int8_t *) data)); 4187 ++data; 4188 --len; 4189 offset += 2; 4190 break; 4191 4192 case DW_OP_const2s: 4193 NEED (2); 4194 // XXX value might be modified by relocation 4195 printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n", 4196 indent, "", (uintmax_t) offset, 4197 known[op], read_2sbyte_unaligned (dbg, data)); 4198 CONSUME (2); 4199 data += 2; 4200 offset += 3; 4201 break; 4202 4203 case DW_OP_const4s: 4204 NEED (4); 4205 // XXX value might be modified by relocation 4206 printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n", 4207 indent, "", (uintmax_t) offset, 4208 known[op], read_4sbyte_unaligned (dbg, data)); 4209 CONSUME (4); 4210 data += 4; 4211 offset += 5; 4212 break; 4213 4214 case DW_OP_const8s: 4215 NEED (8); 4216 // XXX value might be modified by relocation 4217 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n", 4218 indent, "", (uintmax_t) offset, 4219 known[op], read_8sbyte_unaligned (dbg, data)); 4220 CONSUME (8); 4221 data += 8; 4222 offset += 9; 4223 break; 4224 4225 case DW_OP_piece: 4226 case DW_OP_regx: 4227 case DW_OP_plus_uconst: 4228 case DW_OP_constu:; 4229 const unsigned char *start = data; 4230 uint64_t uleb; 4231 NEED (1); 4232 get_uleb128 (uleb, data); /* XXX check overrun */ 4233 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n", 4234 indent, "", (uintmax_t) offset, known[op], uleb); 4235 CONSUME (data - start); 4236 offset += 1 + (data - start); 4237 break; 4238 4239 case DW_OP_bit_piece: 4240 start = data; 4241 uint64_t uleb2; 4242 NEED (2); 4243 get_uleb128 (uleb, data); /* XXX check overrun */ 4244 get_uleb128 (uleb2, data); /* XXX check overrun */ 4245 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n", 4246 indent, "", (uintmax_t) offset, known[op], uleb, uleb2); 4247 CONSUME (data - start); 4248 offset += 1 + (data - start); 4249 break; 4250 4251 case DW_OP_fbreg: 4252 case DW_OP_breg0 ... DW_OP_breg31: 4253 case DW_OP_consts: 4254 start = data; 4255 int64_t sleb; 4256 NEED (1); 4257 get_sleb128 (sleb, data); /* XXX check overrun */ 4258 printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n", 4259 indent, "", (uintmax_t) offset, known[op], sleb); 4260 CONSUME (data - start); 4261 offset += 1 + (data - start); 4262 break; 4263 4264 case DW_OP_bregx: 4265 start = data; 4266 NEED (2); 4267 get_uleb128 (uleb, data); /* XXX check overrun */ 4268 get_sleb128 (sleb, data); /* XXX check overrun */ 4269 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n", 4270 indent, "", (uintmax_t) offset, known[op], uleb, sleb); 4271 CONSUME (data - start); 4272 offset += 1 + (data - start); 4273 break; 4274 4275 case DW_OP_call2: 4276 NEED (2); 4277 printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n", 4278 indent, "", (uintmax_t) offset, known[op], 4279 read_2ubyte_unaligned (dbg, data)); 4280 CONSUME (2); 4281 offset += 3; 4282 break; 4283 4284 case DW_OP_call4: 4285 NEED (4); 4286 printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n", 4287 indent, "", (uintmax_t) offset, known[op], 4288 read_4ubyte_unaligned (dbg, data)); 4289 CONSUME (4); 4290 offset += 5; 4291 break; 4292 4293 case DW_OP_skip: 4294 case DW_OP_bra: 4295 NEED (2); 4296 printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n", 4297 indent, "", (uintmax_t) offset, known[op], 4298 (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data))); 4299 CONSUME (2); 4300 data += 2; 4301 offset += 3; 4302 break; 4303 4304 case DW_OP_implicit_value: 4305 start = data; 4306 NEED (1); 4307 get_uleb128 (uleb, data); /* XXX check overrun */ 4308 printf ("%*s[%4" PRIuMAX "] %s: ", 4309 indent, "", (uintmax_t) offset, known[op]); 4310 NEED (uleb); 4311 print_block (uleb, data); 4312 data += uleb; 4313 CONSUME (data - start); 4314 offset += 1 + (data - start); 4315 break; 4316 4317 case DW_OP_GNU_implicit_pointer: 4318 /* DIE offset operand. */ 4319 start = data; 4320 NEED (ref_size + 1); 4321 if (ref_size == 4) 4322 addr = read_4ubyte_unaligned (dbg, data); 4323 else 4324 { 4325 assert (ref_size == 8); 4326 addr = read_8ubyte_unaligned (dbg, data); 4327 } 4328 data += ref_size; 4329 /* Byte offset operand. */ 4330 get_sleb128 (sleb, data); /* XXX check overrun */ 4331 4332 printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX ", %+" PRId64 "\n", 4333 indent, "", (intmax_t) offset, 4334 known[op], (uintmax_t) addr, sleb); 4335 CONSUME (data - start); 4336 offset += 1 + (data - start); 4337 break; 4338 4339 case DW_OP_GNU_entry_value: 4340 /* Size plus expression block. */ 4341 start = data; 4342 NEED (1); 4343 get_uleb128 (uleb, data); /* XXX check overrun */ 4344 printf ("%*s[%4" PRIuMAX "] %s:\n", 4345 indent, "", (uintmax_t) offset, known[op]); 4346 NEED (uleb); 4347 print_ops (dwflmod, dbg, indent + 6, indent + 6, vers, 4348 addrsize, offset_size, uleb, data); 4349 data += uleb; 4350 CONSUME (data - start); 4351 offset += 1 + (data - start); 4352 break; 4353 4354 case DW_OP_GNU_const_type: 4355 /* DIE offset, size plus block. */ 4356 start = data; 4357 NEED (2); 4358 get_uleb128 (uleb, data); /* XXX check overrun */ 4359 uint8_t usize = *(uint8_t *) data++; 4360 NEED (usize); 4361 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ", 4362 indent, "", (uintmax_t) offset, known[op], uleb); 4363 print_block (usize, data); 4364 data += usize; 4365 CONSUME (data - start); 4366 offset += 1 + (data - start); 4367 break; 4368 4369 case DW_OP_GNU_regval_type: 4370 start = data; 4371 NEED (2); 4372 get_uleb128 (uleb, data); /* XXX check overrun */ 4373 get_uleb128 (uleb2, data); /* XXX check overrun */ 4374 printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %#" PRIx64 "\n", 4375 indent, "", (uintmax_t) offset, known[op], uleb, uleb2); 4376 CONSUME (data - start); 4377 offset += 1 + (data - start); 4378 break; 4379 4380 case DW_OP_GNU_deref_type: 4381 start = data; 4382 NEED (2); 4383 usize = *(uint8_t *) data++; 4384 get_uleb128 (uleb, data); /* XXX check overrun */ 4385 printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n", 4386 indent, "", (uintmax_t) offset, 4387 known[op], usize, uleb); 4388 CONSUME (data - start); 4389 offset += 1 + (data - start); 4390 break; 4391 4392 case DW_OP_GNU_convert: 4393 case DW_OP_GNU_reinterpret: 4394 start = data; 4395 NEED (1); 4396 get_uleb128 (uleb, data); /* XXX check overrun */ 4397 printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n", 4398 indent, "", (uintmax_t) offset, known[op], uleb); 4399 CONSUME (data - start); 4400 offset += 1 + (data - start); 4401 break; 4402 4403 default: 4404 /* No Operand. */ 4405 if (op < sizeof known / sizeof known[0] && known[op] != NULL) 4406 printf ("%*s[%4" PRIuMAX "] %s\n", 4407 indent, "", (uintmax_t) offset, known[op]); 4408 else 4409 printf ("%*s[%4" PRIuMAX "] %#x\n", 4410 indent, "", (uintmax_t) offset, op); 4411 ++offset; 4412 break; 4413 } 4414 4415 indent = indentrest; 4416 continue; 4417 4418 invalid: 4419 printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"), 4420 indent, "", (uintmax_t) offset, known[op]); 4421 break; 4422 } 4423 } 4424 4425 4426 struct listptr 4427 { 4428 Dwarf_Off offset:(64 - 3); 4429 bool addr64:1; 4430 bool dwarf64:1; 4431 bool warned:1; 4432 }; 4433 4434 #define listptr_offset_size(p) ((p)->dwarf64 ? 8 : 4) 4435 #define listptr_address_size(p) ((p)->addr64 ? 8 : 4) 4436 4437 static int 4438 compare_listptr (const void *a, const void *b, void *arg) 4439 { 4440 const char *name = arg; 4441 struct listptr *p1 = (void *) a; 4442 struct listptr *p2 = (void *) b; 4443 4444 if (p1->offset < p2->offset) 4445 return -1; 4446 if (p1->offset > p2->offset) 4447 return 1; 4448 4449 if (!p1->warned && !p2->warned) 4450 { 4451 if (p1->addr64 != p2->addr64) 4452 { 4453 p1->warned = p2->warned = true; 4454 error (0, 0, 4455 gettext ("%s %#" PRIx64 " used with different address sizes"), 4456 name, (uint64_t) p1->offset); 4457 } 4458 if (p1->dwarf64 != p2->dwarf64) 4459 { 4460 p1->warned = p2->warned = true; 4461 error (0, 0, 4462 gettext ("%s %#" PRIx64 " used with different offset sizes"), 4463 name, (uint64_t) p1->offset); 4464 } 4465 } 4466 4467 return 0; 4468 } 4469 4470 struct listptr_table 4471 { 4472 size_t n; 4473 size_t alloc; 4474 struct listptr *table; 4475 }; 4476 4477 static struct listptr_table known_loclistptr; 4478 static struct listptr_table known_rangelistptr; 4479 4480 static void 4481 reset_listptr (struct listptr_table *table) 4482 { 4483 free (table->table); 4484 table->table = NULL; 4485 table->n = table->alloc = 0; 4486 } 4487 4488 static void 4489 notice_listptr (enum section_e section, struct listptr_table *table, 4490 uint_fast8_t address_size, uint_fast8_t offset_size, 4491 Dwarf_Off offset) 4492 { 4493 if (print_debug_sections & section) 4494 { 4495 if (table->n == table->alloc) 4496 { 4497 if (table->alloc == 0) 4498 table->alloc = 128; 4499 else 4500 table->alloc *= 2; 4501 table->table = xrealloc (table->table, 4502 table->alloc * sizeof table->table[0]); 4503 } 4504 4505 struct listptr *p = &table->table[table->n++]; 4506 4507 *p = (struct listptr) 4508 { 4509 .addr64 = address_size == 8, 4510 .dwarf64 = offset_size == 8, 4511 .offset = offset 4512 }; 4513 assert (p->offset == offset); 4514 } 4515 } 4516 4517 static void 4518 sort_listptr (struct listptr_table *table, const char *name) 4519 { 4520 if (table->n > 0) 4521 qsort_r (table->table, table->n, sizeof table->table[0], 4522 &compare_listptr, (void *) name); 4523 } 4524 4525 static bool 4526 skip_listptr_hole (struct listptr_table *table, size_t *idxp, 4527 uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep, 4528 ptrdiff_t offset, unsigned char **readp, unsigned char *endp) 4529 { 4530 if (table->n == 0) 4531 return false; 4532 4533 while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset) 4534 ++*idxp; 4535 4536 struct listptr *p = &table->table[*idxp]; 4537 4538 if (*idxp == table->n 4539 || p->offset >= (Dwarf_Off) (endp - *readp + offset)) 4540 { 4541 *readp = endp; 4542 printf (gettext (" [%6tx] <UNUSED GARBAGE IN REST OF SECTION>\n"), 4543 offset); 4544 return true; 4545 } 4546 4547 if (p->offset != (Dwarf_Off) offset) 4548 { 4549 *readp += p->offset - offset; 4550 printf (gettext (" [%6tx] <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"), 4551 offset, (Dwarf_Off) p->offset - offset); 4552 return true; 4553 } 4554 4555 if (address_sizep != NULL) 4556 *address_sizep = listptr_address_size (p); 4557 if (offset_sizep != NULL) 4558 *offset_sizep = listptr_offset_size (p); 4559 4560 return false; 4561 } 4562 4563 4564 static void 4565 print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 4566 Ebl *ebl, GElf_Ehdr *ehdr, 4567 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 4568 { 4569 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n" 4570 " [ Code]\n"), 4571 elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 4572 (uint64_t) shdr->sh_offset); 4573 4574 Dwarf_Off offset = 0; 4575 while (offset < dbg->sectiondata[IDX_debug_abbrev]->d_size) 4576 { 4577 printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"), 4578 offset); 4579 4580 while (1) 4581 { 4582 size_t length; 4583 Dwarf_Abbrev abbrev; 4584 4585 int res = dwarf_offabbrev (dbg, offset, &length, &abbrev); 4586 if (res != 0) 4587 { 4588 if (unlikely (res < 0)) 4589 { 4590 printf (gettext ("\ 4591 *** error while reading abbreviation: %s\n"), 4592 dwarf_errmsg (-1)); 4593 return; 4594 } 4595 4596 /* This is the NUL byte at the end of the section. */ 4597 ++offset; 4598 break; 4599 } 4600 4601 /* We know these calls can never fail. */ 4602 unsigned int code = dwarf_getabbrevcode (&abbrev); 4603 unsigned int tag = dwarf_getabbrevtag (&abbrev); 4604 int has_children = dwarf_abbrevhaschildren (&abbrev); 4605 4606 printf (gettext (" [%5u] offset: %" PRId64 4607 ", children: %s, tag: %s\n"), 4608 code, (int64_t) offset, 4609 has_children ? gettext ("yes") : gettext ("no"), 4610 dwarf_tag_string (tag)); 4611 4612 size_t cnt = 0; 4613 unsigned int name; 4614 unsigned int form; 4615 Dwarf_Off enoffset; 4616 while (dwarf_getabbrevattr (&abbrev, cnt, 4617 &name, &form, &enoffset) == 0) 4618 { 4619 printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n", 4620 dwarf_attr_string (name), dwarf_form_string (form), 4621 (uint64_t) enoffset); 4622 4623 ++cnt; 4624 } 4625 4626 offset += length; 4627 } 4628 } 4629 } 4630 4631 4632 /* Print content of DWARF .debug_aranges section. We fortunately do 4633 not have to know a bit about the structure of the section, libdwarf 4634 takes care of it. */ 4635 static void 4636 print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 4637 Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, 4638 GElf_Shdr *shdr, Dwarf *dbg) 4639 { 4640 Dwarf_Aranges *aranges; 4641 size_t cnt; 4642 if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0)) 4643 { 4644 error (0, 0, gettext ("cannot get .debug_aranges content: %s"), 4645 dwarf_errmsg (-1)); 4646 return; 4647 } 4648 4649 printf (ngettext ("\ 4650 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n", 4651 "\ 4652 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n", 4653 cnt), 4654 elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 4655 (uint64_t) shdr->sh_offset, cnt); 4656 4657 /* Compute floor(log16(cnt)). */ 4658 size_t tmp = cnt; 4659 int digits = 1; 4660 while (tmp >= 16) 4661 { 4662 ++digits; 4663 tmp >>= 4; 4664 } 4665 4666 for (size_t n = 0; n < cnt; ++n) 4667 { 4668 Dwarf_Arange *runp = dwarf_onearange (aranges, n); 4669 if (unlikely (runp == NULL)) 4670 { 4671 printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1)); 4672 return; 4673 } 4674 4675 Dwarf_Addr start; 4676 Dwarf_Word length; 4677 Dwarf_Off offset; 4678 4679 if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0)) 4680 printf (gettext (" [%*zu] ???\n"), digits, n); 4681 else 4682 printf (gettext (" [%*zu] start: %0#*" PRIx64 4683 ", length: %5" PRIu64 ", CU DIE offset: %6" 4684 PRId64 "\n"), 4685 digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18, 4686 (uint64_t) start, (uint64_t) length, (int64_t) offset); 4687 } 4688 } 4689 4690 /* Print content of DWARF .debug_ranges section. */ 4691 static void 4692 print_debug_ranges_section (Dwfl_Module *dwflmod, 4693 Ebl *ebl, GElf_Ehdr *ehdr, 4694 Elf_Scn *scn, GElf_Shdr *shdr, 4695 Dwarf *dbg) 4696 { 4697 Elf_Data *data = elf_rawdata (scn, NULL); 4698 4699 if (unlikely (data == NULL)) 4700 { 4701 error (0, 0, gettext ("cannot get .debug_ranges content: %s"), 4702 elf_errmsg (-1)); 4703 return; 4704 } 4705 4706 printf (gettext ("\ 4707 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), 4708 elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 4709 (uint64_t) shdr->sh_offset); 4710 4711 sort_listptr (&known_rangelistptr, "rangelistptr"); 4712 size_t listptr_idx = 0; 4713 4714 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; 4715 4716 bool first = true; 4717 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size; 4718 unsigned char *readp = data->d_buf; 4719 while (readp < endp) 4720 { 4721 ptrdiff_t offset = readp - (unsigned char *) data->d_buf; 4722 4723 if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx, 4724 &address_size, NULL, 4725 offset, &readp, endp)) 4726 continue; 4727 4728 if (unlikely (data->d_size - offset < address_size * 2)) 4729 { 4730 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset); 4731 break; 4732 } 4733 4734 Dwarf_Addr begin; 4735 Dwarf_Addr end; 4736 if (address_size == 8) 4737 { 4738 begin = read_8ubyte_unaligned_inc (dbg, readp); 4739 end = read_8ubyte_unaligned_inc (dbg, readp); 4740 } 4741 else 4742 { 4743 begin = read_4ubyte_unaligned_inc (dbg, readp); 4744 end = read_4ubyte_unaligned_inc (dbg, readp); 4745 if (begin == (Dwarf_Addr) (uint32_t) -1) 4746 begin = (Dwarf_Addr) -1l; 4747 } 4748 4749 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */ 4750 { 4751 char *b = format_dwarf_addr (dwflmod, address_size, end); 4752 printf (gettext (" [%6tx] base address %s\n"), offset, b); 4753 free (b); 4754 } 4755 else if (begin == 0 && end == 0) /* End of list entry. */ 4756 { 4757 if (first) 4758 printf (gettext (" [%6tx] empty list\n"), offset); 4759 first = true; 4760 } 4761 else 4762 { 4763 char *b = format_dwarf_addr (dwflmod, address_size, begin); 4764 char *e = format_dwarf_addr (dwflmod, address_size, end); 4765 /* We have an address range entry. */ 4766 if (first) /* First address range entry in a list. */ 4767 printf (gettext (" [%6tx] %s..%s\n"), offset, b, e); 4768 else 4769 printf (gettext (" %s..%s\n"), b, e); 4770 free (b); 4771 free (e); 4772 4773 first = false; 4774 } 4775 } 4776 } 4777 4778 #define REGNAMESZ 16 4779 static const char * 4780 register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc, 4781 char name[REGNAMESZ], int *bits, int *type) 4782 { 4783 const char *set; 4784 const char *pfx; 4785 int ignore; 4786 ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set, 4787 bits ?: &ignore, type ?: &ignore); 4788 if (n <= 0) 4789 { 4790 snprintf (name, REGNAMESZ, "reg%u", loc->regno); 4791 if (bits != NULL) 4792 *bits = loc->bits; 4793 if (type != NULL) 4794 *type = DW_ATE_unsigned; 4795 set = "??? unrecognized"; 4796 } 4797 else 4798 { 4799 if (bits != NULL && *bits <= 0) 4800 *bits = loc->bits; 4801 if (type != NULL && *type == DW_ATE_void) 4802 *type = DW_ATE_unsigned; 4803 4804 } 4805 return set; 4806 } 4807 4808 static void 4809 print_cfa_program (const unsigned char *readp, const unsigned char *const endp, 4810 Dwarf_Word vma_base, unsigned int code_align, 4811 int data_align, 4812 unsigned int version, unsigned int ptr_size, 4813 Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg) 4814 { 4815 char regnamebuf[REGNAMESZ]; 4816 const char *regname (unsigned int regno) 4817 { 4818 register_info (ebl, regno, NULL, regnamebuf, NULL, NULL); 4819 return regnamebuf; 4820 } 4821 4822 puts ("\n Program:"); 4823 Dwarf_Word pc = vma_base; 4824 while (readp < endp) 4825 { 4826 unsigned int opcode = *readp++; 4827 4828 if (opcode < DW_CFA_advance_loc) 4829 /* Extended opcode. */ 4830 switch (opcode) 4831 { 4832 uint64_t op1; 4833 int64_t sop1; 4834 uint64_t op2; 4835 int64_t sop2; 4836 4837 case DW_CFA_nop: 4838 puts (" nop"); 4839 break; 4840 case DW_CFA_set_loc: 4841 // XXX overflow check 4842 get_uleb128 (op1, readp); 4843 op1 += vma_base; 4844 printf (" set_loc %" PRIu64 "\n", op1 * code_align); 4845 break; 4846 case DW_CFA_advance_loc1: 4847 printf (" advance_loc1 %u to %#" PRIx64 "\n", 4848 *readp, pc += *readp * code_align); 4849 ++readp; 4850 break; 4851 case DW_CFA_advance_loc2: 4852 op1 = read_2ubyte_unaligned_inc (dbg, readp); 4853 printf (" advance_loc2 %" PRIu64 " to %#" PRIx64 "\n", 4854 op1, pc += op1 * code_align); 4855 break; 4856 case DW_CFA_advance_loc4: 4857 op1 = read_4ubyte_unaligned_inc (dbg, readp); 4858 printf (" advance_loc4 %" PRIu64 " to %#" PRIx64 "\n", 4859 op1, pc += op1 * code_align); 4860 break; 4861 case DW_CFA_offset_extended: 4862 // XXX overflow check 4863 get_uleb128 (op1, readp); 4864 get_uleb128 (op2, readp); 4865 printf (" offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64 4866 "\n", 4867 op1, regname (op1), op2 * data_align); 4868 break; 4869 case DW_CFA_restore_extended: 4870 // XXX overflow check 4871 get_uleb128 (op1, readp); 4872 printf (" restore_extended r%" PRIu64 " (%s)\n", 4873 op1, regname (op1)); 4874 break; 4875 case DW_CFA_undefined: 4876 // XXX overflow check 4877 get_uleb128 (op1, readp); 4878 printf (" undefined r%" PRIu64 " (%s)\n", op1, regname (op1)); 4879 break; 4880 case DW_CFA_same_value: 4881 // XXX overflow check 4882 get_uleb128 (op1, readp); 4883 printf (" same_value r%" PRIu64 " (%s)\n", op1, regname (op1)); 4884 break; 4885 case DW_CFA_register: 4886 // XXX overflow check 4887 get_uleb128 (op1, readp); 4888 get_uleb128 (op2, readp); 4889 printf (" register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n", 4890 op1, regname (op1), op2, regname (op2)); 4891 break; 4892 case DW_CFA_remember_state: 4893 puts (" remember_state"); 4894 break; 4895 case DW_CFA_restore_state: 4896 puts (" restore_state"); 4897 break; 4898 case DW_CFA_def_cfa: 4899 // XXX overflow check 4900 get_uleb128 (op1, readp); 4901 get_uleb128 (op2, readp); 4902 printf (" def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n", 4903 op1, regname (op1), op2); 4904 break; 4905 case DW_CFA_def_cfa_register: 4906 // XXX overflow check 4907 get_uleb128 (op1, readp); 4908 printf (" def_cfa_register r%" PRIu64 " (%s)\n", 4909 op1, regname (op1)); 4910 break; 4911 case DW_CFA_def_cfa_offset: 4912 // XXX overflow check 4913 get_uleb128 (op1, readp); 4914 printf (" def_cfa_offset %" PRIu64 "\n", op1); 4915 break; 4916 case DW_CFA_def_cfa_expression: 4917 // XXX overflow check 4918 get_uleb128 (op1, readp); /* Length of DW_FORM_block. */ 4919 printf (" def_cfa_expression %" PRIu64 "\n", op1); 4920 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, op1, readp); 4921 readp += op1; 4922 break; 4923 case DW_CFA_expression: 4924 // XXX overflow check 4925 get_uleb128 (op1, readp); 4926 get_uleb128 (op2, readp); /* Length of DW_FORM_block. */ 4927 printf (" expression r%" PRIu64 " (%s) \n", 4928 op1, regname (op1)); 4929 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, op2, readp); 4930 readp += op2; 4931 break; 4932 case DW_CFA_offset_extended_sf: 4933 // XXX overflow check 4934 get_uleb128 (op1, readp); 4935 get_sleb128 (sop2, readp); 4936 printf (" offset_extended_sf r%" PRIu64 " (%s) at cfa%+" 4937 PRId64 "\n", 4938 op1, regname (op1), sop2 * data_align); 4939 break; 4940 case DW_CFA_def_cfa_sf: 4941 // XXX overflow check 4942 get_uleb128 (op1, readp); 4943 get_sleb128 (sop2, readp); 4944 printf (" def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n", 4945 op1, regname (op1), sop2 * data_align); 4946 break; 4947 case DW_CFA_def_cfa_offset_sf: 4948 // XXX overflow check 4949 get_sleb128 (sop1, readp); 4950 printf (" def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align); 4951 break; 4952 case DW_CFA_val_offset: 4953 // XXX overflow check 4954 get_uleb128 (op1, readp); 4955 get_uleb128 (op2, readp); 4956 printf (" val_offset %" PRIu64 " at offset %" PRIu64 "\n", 4957 op1, op2 * data_align); 4958 break; 4959 case DW_CFA_val_offset_sf: 4960 // XXX overflow check 4961 get_uleb128 (op1, readp); 4962 get_sleb128 (sop2, readp); 4963 printf (" val_offset_sf %" PRIu64 " at offset %" PRId64 "\n", 4964 op1, sop2 * data_align); 4965 break; 4966 case DW_CFA_val_expression: 4967 // XXX overflow check 4968 get_uleb128 (op1, readp); 4969 get_uleb128 (op2, readp); /* Length of DW_FORM_block. */ 4970 printf (" val_expression r%" PRIu64 " (%s)\n", 4971 op1, regname (op1)); 4972 print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, op2, readp); 4973 readp += op2; 4974 break; 4975 case DW_CFA_MIPS_advance_loc8: 4976 op1 = read_8ubyte_unaligned_inc (dbg, readp); 4977 printf (" MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n", 4978 op1, pc += op1 * code_align); 4979 break; 4980 case DW_CFA_GNU_window_save: 4981 puts (" GNU_window_save"); 4982 break; 4983 case DW_CFA_GNU_args_size: 4984 // XXX overflow check 4985 get_uleb128 (op1, readp); 4986 printf (" args_size %" PRIu64 "\n", op1); 4987 break; 4988 default: 4989 printf (" ??? (%u)\n", opcode); 4990 break; 4991 } 4992 else if (opcode < DW_CFA_offset) 4993 printf (" advance_loc %u to %#" PRIx64 "\n", 4994 opcode & 0x3f, pc += (opcode & 0x3f) * code_align); 4995 else if (opcode < DW_CFA_restore) 4996 { 4997 uint64_t offset; 4998 // XXX overflow check 4999 get_uleb128 (offset, readp); 5000 printf (" offset r%u (%s) at cfa%+" PRId64 "\n", 5001 opcode & 0x3f, regname (opcode & 0x3f), offset * data_align); 5002 } 5003 else 5004 printf (" restore r%u (%s)\n", 5005 opcode & 0x3f, regname (opcode & 0x3f)); 5006 } 5007 } 5008 5009 5010 static unsigned int 5011 encoded_ptr_size (int encoding, unsigned int ptr_size) 5012 { 5013 switch (encoding & 7) 5014 { 5015 case 2: 5016 return 2; 5017 case 3: 5018 return 4; 5019 case 4: 5020 return 8; 5021 default: 5022 return ptr_size; 5023 } 5024 } 5025 5026 5027 static unsigned int 5028 print_encoding (unsigned int val) 5029 { 5030 switch (val & 0xf) 5031 { 5032 case DW_EH_PE_absptr: 5033 fputs ("absptr", stdout); 5034 break; 5035 case DW_EH_PE_uleb128: 5036 fputs ("uleb128", stdout); 5037 break; 5038 case DW_EH_PE_udata2: 5039 fputs ("udata2", stdout); 5040 break; 5041 case DW_EH_PE_udata4: 5042 fputs ("udata4", stdout); 5043 break; 5044 case DW_EH_PE_udata8: 5045 fputs ("udata8", stdout); 5046 break; 5047 case DW_EH_PE_sleb128: 5048 fputs ("sleb128", stdout); 5049 break; 5050 case DW_EH_PE_sdata2: 5051 fputs ("sdata2", stdout); 5052 break; 5053 case DW_EH_PE_sdata4: 5054 fputs ("sdata4", stdout); 5055 break; 5056 case DW_EH_PE_sdata8: 5057 fputs ("sdata8", stdout); 5058 break; 5059 default: 5060 /* We did not use any of the bits after all. */ 5061 return val; 5062 } 5063 5064 return val & ~0xf; 5065 } 5066 5067 5068 static unsigned int 5069 print_relinfo (unsigned int val) 5070 { 5071 switch (val & 0x70) 5072 { 5073 case DW_EH_PE_pcrel: 5074 fputs ("pcrel", stdout); 5075 break; 5076 case DW_EH_PE_textrel: 5077 fputs ("textrel", stdout); 5078 break; 5079 case DW_EH_PE_datarel: 5080 fputs ("datarel", stdout); 5081 break; 5082 case DW_EH_PE_funcrel: 5083 fputs ("funcrel", stdout); 5084 break; 5085 case DW_EH_PE_aligned: 5086 fputs ("aligned", stdout); 5087 break; 5088 default: 5089 return val; 5090 } 5091 5092 return val & ~0x70; 5093 } 5094 5095 5096 static void 5097 print_encoding_base (const char *pfx, unsigned int fde_encoding) 5098 { 5099 printf ("(%s", pfx); 5100 5101 if (fde_encoding == DW_EH_PE_omit) 5102 puts ("omit)"); 5103 else 5104 { 5105 unsigned int w = fde_encoding; 5106 5107 w = print_encoding (w); 5108 5109 if (w & 0x70) 5110 { 5111 if (w != fde_encoding) 5112 fputc_unlocked (' ', stdout); 5113 5114 w = print_relinfo (w); 5115 } 5116 5117 if (w != 0) 5118 printf ("%s%x", w != fde_encoding ? " " : "", w); 5119 5120 puts (")"); 5121 } 5122 } 5123 5124 5125 static const unsigned char * 5126 read_encoded (unsigned int encoding, const unsigned char *readp, 5127 const unsigned char *const endp, uint64_t *res, Dwarf *dbg) 5128 { 5129 if ((encoding & 0xf) == DW_EH_PE_absptr) 5130 encoding = gelf_getclass (dbg->elf) == ELFCLASS32 5131 ? DW_EH_PE_udata4 : DW_EH_PE_udata8; 5132 5133 switch (encoding & 0xf) 5134 { 5135 case DW_EH_PE_uleb128: 5136 // XXX buffer overrun check 5137 get_uleb128 (*res, readp); 5138 break; 5139 case DW_EH_PE_sleb128: 5140 // XXX buffer overrun check 5141 get_sleb128 (*res, readp); 5142 break; 5143 case DW_EH_PE_udata2: 5144 if (readp + 2 > endp) 5145 goto invalid; 5146 *res = read_2ubyte_unaligned_inc (dbg, readp); 5147 break; 5148 case DW_EH_PE_udata4: 5149 if (readp + 4 > endp) 5150 goto invalid; 5151 *res = read_4ubyte_unaligned_inc (dbg, readp); 5152 break; 5153 case DW_EH_PE_udata8: 5154 if (readp + 8 > endp) 5155 goto invalid; 5156 *res = read_8ubyte_unaligned_inc (dbg, readp); 5157 break; 5158 case DW_EH_PE_sdata2: 5159 if (readp + 2 > endp) 5160 goto invalid; 5161 *res = read_2sbyte_unaligned_inc (dbg, readp); 5162 break; 5163 case DW_EH_PE_sdata4: 5164 if (readp + 4 > endp) 5165 goto invalid; 5166 *res = read_4sbyte_unaligned_inc (dbg, readp); 5167 break; 5168 case DW_EH_PE_sdata8: 5169 if (readp + 8 > endp) 5170 goto invalid; 5171 *res = read_8sbyte_unaligned_inc (dbg, readp); 5172 break; 5173 default: 5174 invalid: 5175 error (1, 0, 5176 gettext ("invalid encoding")); 5177 } 5178 5179 return readp; 5180 } 5181 5182 5183 static void 5184 print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, 5185 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 5186 { 5187 size_t shstrndx; 5188 /* We know this call will succeed since it did in the caller. */ 5189 (void) elf_getshdrstrndx (ebl->elf, &shstrndx); 5190 const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); 5191 5192 Elf_Data *data = elf_rawdata (scn, NULL); 5193 5194 if (unlikely (data == NULL)) 5195 { 5196 error (0, 0, gettext ("cannot get %s content: %s"), 5197 scnname, elf_errmsg (-1)); 5198 return; 5199 } 5200 bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0; 5201 5202 if (is_eh_frame) 5203 printf (gettext ("\ 5204 \nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"), 5205 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset); 5206 else 5207 printf (gettext ("\ 5208 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), 5209 elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset); 5210 5211 struct cieinfo 5212 { 5213 ptrdiff_t cie_offset; 5214 const char *augmentation; 5215 unsigned int code_alignment_factor; 5216 unsigned int data_alignment_factor; 5217 uint8_t address_size; 5218 uint8_t fde_encoding; 5219 uint8_t lsda_encoding; 5220 struct cieinfo *next; 5221 } *cies = NULL; 5222 5223 const unsigned char *readp = data->d_buf; 5224 const unsigned char *const dataend = ((unsigned char *) data->d_buf 5225 + data->d_size); 5226 while (readp < dataend) 5227 { 5228 if (unlikely (readp + 4 > dataend)) 5229 { 5230 invalid_data: 5231 error (0, 0, gettext ("invalid data in section [%zu] '%s'"), 5232 elf_ndxscn (scn), scnname); 5233 return; 5234 } 5235 5236 /* At the beginning there must be a CIE. There can be multiple, 5237 hence we test tis in a loop. */ 5238 ptrdiff_t offset = readp - (unsigned char *) data->d_buf; 5239 5240 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp); 5241 unsigned int length = 4; 5242 if (unlikely (unit_length == 0xffffffff)) 5243 { 5244 if (unlikely (readp + 8 > dataend)) 5245 goto invalid_data; 5246 5247 unit_length = read_8ubyte_unaligned_inc (dbg, readp); 5248 length = 8; 5249 } 5250 5251 if (unlikely (unit_length == 0)) 5252 { 5253 printf (gettext ("\n [%6tx] Zero terminator\n"), offset); 5254 continue; 5255 } 5256 5257 unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; 5258 5259 ptrdiff_t start = readp - (unsigned char *) data->d_buf; 5260 const unsigned char *const cieend = readp + unit_length; 5261 if (unlikely (cieend > dataend || readp + 8 > dataend)) 5262 goto invalid_data; 5263 5264 Dwarf_Off cie_id; 5265 if (length == 4) 5266 { 5267 cie_id = read_4ubyte_unaligned_inc (dbg, readp); 5268 if (!is_eh_frame && cie_id == DW_CIE_ID_32) 5269 cie_id = DW_CIE_ID_64; 5270 } 5271 else 5272 cie_id = read_8ubyte_unaligned_inc (dbg, readp); 5273 5274 uint_fast8_t version = 2; 5275 unsigned int code_alignment_factor; 5276 int data_alignment_factor; 5277 unsigned int fde_encoding = 0; 5278 unsigned int lsda_encoding = 0; 5279 Dwarf_Word initial_location = 0; 5280 Dwarf_Word vma_base = 0; 5281 5282 if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64)) 5283 { 5284 version = *readp++; 5285 const char *const augmentation = (const char *) readp; 5286 readp = memchr (readp, '\0', cieend - readp); 5287 if (unlikely (readp == NULL)) 5288 goto invalid_data; 5289 ++readp; 5290 5291 uint_fast8_t segment_size = 0; 5292 if (version >= 4) 5293 { 5294 if (cieend - readp < 5) 5295 goto invalid_data; 5296 ptr_size = *readp++; 5297 segment_size = *readp++; 5298 } 5299 5300 // XXX Check overflow 5301 get_uleb128 (code_alignment_factor, readp); 5302 // XXX Check overflow 5303 get_sleb128 (data_alignment_factor, readp); 5304 5305 /* In some variant for unwind data there is another field. */ 5306 if (strcmp (augmentation, "eh") == 0) 5307 readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; 5308 5309 unsigned int return_address_register; 5310 if (unlikely (version == 1)) 5311 return_address_register = *readp++; 5312 else 5313 // XXX Check overflow 5314 get_uleb128 (return_address_register, readp); 5315 5316 printf ("\n [%6tx] CIE length=%" PRIu64 "\n" 5317 " CIE_id: %" PRIu64 "\n" 5318 " version: %u\n" 5319 " augmentation: \"%s\"\n", 5320 offset, (uint64_t) unit_length, (uint64_t) cie_id, 5321 version, augmentation); 5322 if (version >= 4) 5323 printf (" address_size: %u\n" 5324 " segment_size: %u\n", 5325 ptr_size, segment_size); 5326 printf (" code_alignment_factor: %u\n" 5327 " data_alignment_factor: %d\n" 5328 " return_address_register: %u\n", 5329 code_alignment_factor, 5330 data_alignment_factor, return_address_register); 5331 5332 if (augmentation[0] == 'z') 5333 { 5334 unsigned int augmentationlen; 5335 get_uleb128 (augmentationlen, readp); 5336 5337 if (augmentationlen > (size_t) (dataend - readp)) 5338 error (1, 0, gettext ("invalid augmentation length")); 5339 5340 const char *hdr = "Augmentation data:"; 5341 const char *cp = augmentation + 1; 5342 while (*cp != '\0') 5343 { 5344 printf (" %-26s%#x ", hdr, *readp); 5345 hdr = ""; 5346 5347 if (*cp == 'R') 5348 { 5349 fde_encoding = *readp++; 5350 print_encoding_base (gettext ("FDE address encoding: "), 5351 fde_encoding); 5352 } 5353 else if (*cp == 'L') 5354 { 5355 lsda_encoding = *readp++; 5356 print_encoding_base (gettext ("LSDA pointer encoding: "), 5357 lsda_encoding); 5358 } 5359 else if (*cp == 'P') 5360 { 5361 /* Personality. This field usually has a relocation 5362 attached pointing to __gcc_personality_v0. */ 5363 const unsigned char *startp = readp; 5364 unsigned int encoding = *readp++; 5365 uint64_t val = 0; 5366 readp = read_encoded (encoding, readp, 5367 readp - 1 + augmentationlen, 5368 &val, dbg); 5369 5370 while (++startp < readp) 5371 printf ("%#x ", *startp); 5372 5373 putchar ('('); 5374 print_encoding (encoding); 5375 putchar (' '); 5376 switch (encoding & 0xf) 5377 { 5378 case DW_EH_PE_sleb128: 5379 case DW_EH_PE_sdata2: 5380 case DW_EH_PE_sdata4: 5381 printf ("%" PRId64 ")\n", val); 5382 break; 5383 default: 5384 printf ("%#" PRIx64 ")\n", val); 5385 break; 5386 } 5387 } 5388 else 5389 printf ("(%x)\n", *readp++); 5390 5391 ++cp; 5392 } 5393 } 5394 5395 if (likely (ptr_size == 4 || ptr_size == 8)) 5396 { 5397 struct cieinfo *newp = alloca (sizeof (*newp)); 5398 newp->cie_offset = offset; 5399 newp->augmentation = augmentation; 5400 newp->fde_encoding = fde_encoding; 5401 newp->lsda_encoding = lsda_encoding; 5402 newp->address_size = ptr_size; 5403 newp->code_alignment_factor = code_alignment_factor; 5404 newp->data_alignment_factor = data_alignment_factor; 5405 newp->next = cies; 5406 cies = newp; 5407 } 5408 } 5409 else 5410 { 5411 struct cieinfo *cie = cies; 5412 while (cie != NULL) 5413 if (is_eh_frame 5414 ? start - (ptrdiff_t) cie_id == cie->cie_offset 5415 : (ptrdiff_t) cie_id == cie->cie_offset) 5416 break; 5417 else 5418 cie = cie->next; 5419 if (unlikely (cie == NULL)) 5420 { 5421 puts ("invalid CIE reference in FDE"); 5422 return; 5423 } 5424 5425 /* Initialize from CIE data. */ 5426 fde_encoding = cie->fde_encoding; 5427 lsda_encoding = cie->lsda_encoding; 5428 ptr_size = encoded_ptr_size (fde_encoding, cie->address_size); 5429 code_alignment_factor = cie->code_alignment_factor; 5430 data_alignment_factor = cie->data_alignment_factor; 5431 5432 const unsigned char *base = readp; 5433 // XXX There are sometimes relocations for this value 5434 initial_location = read_ubyte_unaligned_inc (ptr_size, dbg, readp); 5435 Dwarf_Word address_range 5436 = read_ubyte_unaligned_inc (ptr_size, dbg, readp); 5437 5438 char *a = format_dwarf_addr (dwflmod, cie->address_size, 5439 initial_location); 5440 printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n" 5441 " CIE_pointer: %" PRIu64 "\n" 5442 " initial_location: %s", 5443 offset, (uint64_t) unit_length, 5444 cie->cie_offset, (uint64_t) cie_id, a); 5445 free (a); 5446 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel) 5447 { 5448 vma_base = (((uint64_t) shdr->sh_offset 5449 + (base - (const unsigned char *) data->d_buf) 5450 + (uint64_t) initial_location) 5451 & (ptr_size == 4 5452 ? UINT64_C (0xffffffff) 5453 : UINT64_C (0xffffffffffffffff))); 5454 printf (gettext (" (offset: %#" PRIx64 ")"), 5455 (uint64_t) vma_base); 5456 } 5457 5458 printf ("\n address_range: %#" PRIx64, 5459 (uint64_t) address_range); 5460 if ((fde_encoding & 0x70) == DW_EH_PE_pcrel) 5461 printf (gettext (" (end offset: %#" PRIx64 ")"), 5462 ((uint64_t) vma_base + (uint64_t) address_range) 5463 & (ptr_size == 4 5464 ? UINT64_C (0xffffffff) 5465 : UINT64_C (0xffffffffffffffff))); 5466 putchar ('\n'); 5467 5468 if (cie->augmentation[0] == 'z') 5469 { 5470 unsigned int augmentationlen; 5471 get_uleb128 (augmentationlen, readp); 5472 5473 if (augmentationlen > 0) 5474 { 5475 const char *hdr = "Augmentation data:"; 5476 const char *cp = cie->augmentation + 1; 5477 unsigned int u = 0; 5478 while (*cp != '\0') 5479 { 5480 if (*cp == 'L') 5481 { 5482 uint64_t lsda_pointer; 5483 const unsigned char *p 5484 = read_encoded (lsda_encoding, &readp[u], 5485 &readp[augmentationlen], 5486 &lsda_pointer, dbg); 5487 u = p - readp; 5488 printf (gettext ("\ 5489 %-26sLSDA pointer: %#" PRIx64 "\n"), 5490 hdr, lsda_pointer); 5491 hdr = ""; 5492 } 5493 ++cp; 5494 } 5495 5496 while (u < augmentationlen) 5497 { 5498 printf (" %-26s%#x\n", hdr, readp[u++]); 5499 hdr = ""; 5500 } 5501 } 5502 5503 readp += augmentationlen; 5504 } 5505 } 5506 5507 /* Handle the initialization instructions. */ 5508 print_cfa_program (readp, cieend, vma_base, code_alignment_factor, 5509 data_alignment_factor, version, ptr_size, 5510 dwflmod, ebl, dbg); 5511 readp = cieend; 5512 } 5513 } 5514 5515 5516 struct attrcb_args 5517 { 5518 Dwfl_Module *dwflmod; 5519 Dwarf *dbg; 5520 int level; 5521 bool silent; 5522 unsigned int version; 5523 unsigned int addrsize; 5524 unsigned int offset_size; 5525 Dwarf_Off cu_offset; 5526 }; 5527 5528 5529 static int 5530 attr_callback (Dwarf_Attribute *attrp, void *arg) 5531 { 5532 struct attrcb_args *cbargs = (struct attrcb_args *) arg; 5533 const int level = cbargs->level; 5534 5535 unsigned int attr = dwarf_whatattr (attrp); 5536 if (unlikely (attr == 0)) 5537 { 5538 if (!cbargs->silent) 5539 error (0, 0, gettext ("cannot get attribute code: %s"), 5540 dwarf_errmsg (-1)); 5541 return DWARF_CB_ABORT; 5542 } 5543 5544 unsigned int form = dwarf_whatform (attrp); 5545 if (unlikely (form == 0)) 5546 { 5547 if (!cbargs->silent) 5548 error (0, 0, gettext ("cannot get attribute form: %s"), 5549 dwarf_errmsg (-1)); 5550 return DWARF_CB_ABORT; 5551 } 5552 5553 switch (form) 5554 { 5555 case DW_FORM_addr: 5556 if (!cbargs->silent) 5557 { 5558 Dwarf_Addr addr; 5559 if (unlikely (dwarf_formaddr (attrp, &addr) != 0)) 5560 { 5561 attrval_out: 5562 if (!cbargs->silent) 5563 error (0, 0, gettext ("cannot get attribute value: %s"), 5564 dwarf_errmsg (-1)); 5565 return DWARF_CB_ABORT; 5566 } 5567 char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr); 5568 printf (" %*s%-20s (%s) %s\n", 5569 (int) (level * 2), "", dwarf_attr_string (attr), 5570 dwarf_form_string (form), a); 5571 free (a); 5572 } 5573 break; 5574 5575 case DW_FORM_indirect: 5576 case DW_FORM_strp: 5577 case DW_FORM_string: 5578 if (cbargs->silent) 5579 break; 5580 const char *str = dwarf_formstring (attrp); 5581 if (unlikely (str == NULL)) 5582 goto attrval_out; 5583 printf (" %*s%-20s (%s) \"%s\"\n", 5584 (int) (level * 2), "", dwarf_attr_string (attr), 5585 dwarf_form_string (form), str); 5586 break; 5587 5588 case DW_FORM_ref_addr: 5589 case DW_FORM_ref_udata: 5590 case DW_FORM_ref8: 5591 case DW_FORM_ref4: 5592 case DW_FORM_ref2: 5593 case DW_FORM_ref1:; 5594 if (cbargs->silent) 5595 break; 5596 Dwarf_Die ref; 5597 if (unlikely (dwarf_formref_die (attrp, &ref) == NULL)) 5598 goto attrval_out; 5599 5600 printf (" %*s%-20s (%s) [%6" PRIxMAX "]\n", 5601 (int) (level * 2), "", dwarf_attr_string (attr), 5602 dwarf_form_string (form), (uintmax_t) dwarf_dieoffset (&ref)); 5603 break; 5604 5605 case DW_FORM_ref_sig8: 5606 if (cbargs->silent) 5607 break; 5608 printf (" %*s%-20s (%s) {%6" PRIx64 "}\n", 5609 (int) (level * 2), "", dwarf_attr_string (attr), 5610 dwarf_form_string (form), 5611 read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp)); 5612 break; 5613 5614 case DW_FORM_sec_offset: 5615 case DW_FORM_udata: 5616 case DW_FORM_sdata: 5617 case DW_FORM_data8: 5618 case DW_FORM_data4: 5619 case DW_FORM_data2: 5620 case DW_FORM_data1:; 5621 Dwarf_Word num; 5622 if (unlikely (dwarf_formudata (attrp, &num) != 0)) 5623 goto attrval_out; 5624 5625 const char *valuestr = NULL; 5626 switch (attr) 5627 { 5628 /* This case can take either a constant or a loclistptr. */ 5629 case DW_AT_data_member_location: 5630 if (form != DW_FORM_sec_offset 5631 && (cbargs->version >= 4 5632 || (form != DW_FORM_data4 && form != DW_FORM_data8))) 5633 { 5634 if (!cbargs->silent) 5635 printf (" %*s%-20s (%s) %" PRIxMAX "\n", 5636 (int) (level * 2), "", dwarf_attr_string (attr), 5637 dwarf_form_string (form), (uintmax_t) num); 5638 return DWARF_CB_OK; 5639 } 5640 /* else fallthrough */ 5641 5642 /* These cases always take a loclistptr and no constant. */ 5643 case DW_AT_location: 5644 case DW_AT_data_location: 5645 case DW_AT_vtable_elem_location: 5646 case DW_AT_string_length: 5647 case DW_AT_use_location: 5648 case DW_AT_frame_base: 5649 case DW_AT_return_addr: 5650 case DW_AT_static_link: 5651 case DW_AT_GNU_call_site_value: 5652 case DW_AT_GNU_call_site_data_value: 5653 case DW_AT_GNU_call_site_target: 5654 case DW_AT_GNU_call_site_target_clobbered: 5655 notice_listptr (section_loc, &known_loclistptr, 5656 cbargs->addrsize, cbargs->offset_size, num); 5657 if (!cbargs->silent) 5658 printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]\n", 5659 (int) (level * 2), "", dwarf_attr_string (attr), 5660 dwarf_form_string (form), (uintmax_t) num); 5661 return DWARF_CB_OK; 5662 5663 case DW_AT_ranges: 5664 notice_listptr (section_ranges, &known_rangelistptr, 5665 cbargs->addrsize, cbargs->offset_size, num); 5666 if (!cbargs->silent) 5667 printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]\n", 5668 (int) (level * 2), "", dwarf_attr_string (attr), 5669 dwarf_form_string (form), (uintmax_t) num); 5670 return DWARF_CB_OK; 5671 5672 case DW_AT_language: 5673 valuestr = dwarf_lang_string (num); 5674 break; 5675 case DW_AT_encoding: 5676 valuestr = dwarf_encoding_string (num); 5677 break; 5678 case DW_AT_accessibility: 5679 valuestr = dwarf_access_string (num); 5680 break; 5681 case DW_AT_visibility: 5682 valuestr = dwarf_visibility_string (num); 5683 break; 5684 case DW_AT_virtuality: 5685 valuestr = dwarf_virtuality_string (num); 5686 break; 5687 case DW_AT_identifier_case: 5688 valuestr = dwarf_identifier_case_string (num); 5689 break; 5690 case DW_AT_calling_convention: 5691 valuestr = dwarf_calling_convention_string (num); 5692 break; 5693 case DW_AT_inline: 5694 valuestr = dwarf_inline_string (num); 5695 break; 5696 case DW_AT_ordering: 5697 valuestr = dwarf_ordering_string (num); 5698 break; 5699 case DW_AT_discr_list: 5700 valuestr = dwarf_discr_list_string (num); 5701 break; 5702 default: 5703 /* Nothing. */ 5704 break; 5705 } 5706 5707 if (cbargs->silent) 5708 break; 5709 5710 if (valuestr == NULL) 5711 printf (" %*s%-20s (%s) %" PRIuMAX "\n", 5712 (int) (level * 2), "", dwarf_attr_string (attr), 5713 dwarf_form_string (form), (uintmax_t) num); 5714 else 5715 printf (" %*s%-20s (%s) %s (%" PRIuMAX ")\n", 5716 (int) (level * 2), "", dwarf_attr_string (attr), 5717 dwarf_form_string (form), valuestr, (uintmax_t) num); 5718 break; 5719 5720 case DW_FORM_flag: 5721 if (cbargs->silent) 5722 break; 5723 bool flag; 5724 if (unlikely (dwarf_formflag (attrp, &flag) != 0)) 5725 goto attrval_out; 5726 5727 printf (" %*s%-20s (%s) %s\n", 5728 (int) (level * 2), "", dwarf_attr_string (attr), 5729 dwarf_form_string (form), nl_langinfo (flag ? YESSTR : NOSTR)); 5730 break; 5731 5732 case DW_FORM_flag_present: 5733 if (cbargs->silent) 5734 break; 5735 printf (" %*s%-20s (%s) %s\n", 5736 (int) (level * 2), "", dwarf_attr_string (attr), 5737 dwarf_form_string (form), nl_langinfo (YESSTR)); 5738 break; 5739 5740 case DW_FORM_exprloc: 5741 case DW_FORM_block4: 5742 case DW_FORM_block2: 5743 case DW_FORM_block1: 5744 case DW_FORM_block: 5745 if (cbargs->silent) 5746 break; 5747 Dwarf_Block block; 5748 if (unlikely (dwarf_formblock (attrp, &block) != 0)) 5749 goto attrval_out; 5750 5751 printf (" %*s%-20s (%s) ", 5752 (int) (level * 2), "", dwarf_attr_string (attr), 5753 dwarf_form_string (form)); 5754 5755 switch (attr) 5756 { 5757 default: 5758 if (form != DW_FORM_exprloc) 5759 { 5760 print_block (block.length, block.data); 5761 break; 5762 } 5763 /* Fall through. */ 5764 5765 case DW_AT_location: 5766 case DW_AT_data_location: 5767 case DW_AT_data_member_location: 5768 case DW_AT_vtable_elem_location: 5769 case DW_AT_string_length: 5770 case DW_AT_use_location: 5771 case DW_AT_frame_base: 5772 case DW_AT_return_addr: 5773 case DW_AT_static_link: 5774 case DW_AT_allocated: 5775 case DW_AT_associated: 5776 case DW_AT_bit_size: 5777 case DW_AT_bit_offset: 5778 case DW_AT_bit_stride: 5779 case DW_AT_byte_size: 5780 case DW_AT_byte_stride: 5781 case DW_AT_count: 5782 case DW_AT_lower_bound: 5783 case DW_AT_upper_bound: 5784 case DW_AT_GNU_call_site_value: 5785 case DW_AT_GNU_call_site_data_value: 5786 case DW_AT_GNU_call_site_target: 5787 case DW_AT_GNU_call_site_target_clobbered: 5788 putchar ('\n'); 5789 print_ops (cbargs->dwflmod, cbargs->dbg, 5790 12 + level * 2, 12 + level * 2, 5791 cbargs->version, cbargs->addrsize, cbargs->offset_size, 5792 block.length, block.data); 5793 break; 5794 } 5795 break; 5796 5797 default: 5798 if (cbargs->silent) 5799 break; 5800 printf (" %*s%-20s (form: %#x) ???\n", 5801 (int) (level * 2), "", dwarf_attr_string (attr), 5802 (int) form); 5803 break; 5804 } 5805 5806 return DWARF_CB_OK; 5807 } 5808 5809 static void 5810 print_debug_units (Dwfl_Module *dwflmod, 5811 Ebl *ebl, GElf_Ehdr *ehdr, 5812 Elf_Scn *scn, GElf_Shdr *shdr, 5813 Dwarf *dbg, bool debug_types) 5814 { 5815 const bool silent = !(print_debug_sections & section_info); 5816 const char *secname = section_name (ebl, ehdr, shdr); 5817 5818 if (!silent) 5819 printf (gettext ("\ 5820 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"), 5821 elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset); 5822 5823 /* If the section is empty we don't have to do anything. */ 5824 if (!silent && shdr->sh_size == 0) 5825 return; 5826 5827 int maxdies = 20; 5828 Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die)); 5829 5830 Dwarf_Off offset = 0; 5831 5832 /* New compilation unit. */ 5833 size_t cuhl; 5834 Dwarf_Half version; 5835 Dwarf_Off abbroffset; 5836 uint8_t addrsize; 5837 uint8_t offsize; 5838 Dwarf_Off nextcu; 5839 uint64_t typesig; 5840 Dwarf_Off typeoff; 5841 next_cu: 5842 if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version, 5843 &abbroffset, &addrsize, &offsize, 5844 debug_types ? &typesig : NULL, 5845 debug_types ? &typeoff : NULL) != 0) 5846 goto do_return; 5847 5848 if (!silent) 5849 { 5850 if (debug_types) 5851 printf (gettext (" Type unit at offset %" PRIu64 ":\n" 5852 " Version: %" PRIu16 ", Abbreviation section offset: %" 5853 PRIu64 ", Address size: %" PRIu8 5854 ", Offset size: %" PRIu8 5855 "\n Type signature: %#" PRIx64 5856 ", Type offset: %#" PRIx64 "\n"), 5857 (uint64_t) offset, version, abbroffset, addrsize, offsize, 5858 typesig, (uint64_t) typeoff); 5859 else 5860 printf (gettext (" Compilation unit at offset %" PRIu64 ":\n" 5861 " Version: %" PRIu16 ", Abbreviation section offset: %" 5862 PRIu64 ", Address size: %" PRIu8 5863 ", Offset size: %" PRIu8 "\n"), 5864 (uint64_t) offset, version, abbroffset, addrsize, offsize); 5865 } 5866 5867 struct attrcb_args args = 5868 { 5869 .dwflmod = dwflmod, 5870 .dbg = dbg, 5871 .silent = silent, 5872 .version = version, 5873 .addrsize = addrsize, 5874 .offset_size = offsize, 5875 .cu_offset = offset 5876 }; 5877 5878 offset += cuhl; 5879 5880 int level = 0; 5881 5882 if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie) 5883 (dbg, offset, &dies[level]) == NULL)) 5884 { 5885 if (!silent) 5886 error (0, 0, gettext ("cannot get DIE at offset %" PRIu64 5887 " in section '%s': %s"), 5888 (uint64_t) offset, secname, dwarf_errmsg (-1)); 5889 goto do_return; 5890 } 5891 5892 do 5893 { 5894 offset = dwarf_dieoffset (&dies[level]); 5895 if (unlikely (offset == ~0ul)) 5896 { 5897 if (!silent) 5898 error (0, 0, gettext ("cannot get DIE offset: %s"), 5899 dwarf_errmsg (-1)); 5900 goto do_return; 5901 } 5902 5903 int tag = dwarf_tag (&dies[level]); 5904 if (unlikely (tag == DW_TAG_invalid)) 5905 { 5906 if (!silent) 5907 error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64 5908 " in section '%s': %s"), 5909 (uint64_t) offset, secname, dwarf_errmsg (-1)); 5910 goto do_return; 5911 } 5912 5913 if (!silent) 5914 printf (" [%6" PRIx64 "] %*s%s\n", 5915 (uint64_t) offset, (int) (level * 2), "", 5916 dwarf_tag_string (tag)); 5917 5918 /* Print the attribute values. */ 5919 args.level = level; 5920 (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0); 5921 5922 /* Make room for the next level's DIE. */ 5923 if (level + 1 == maxdies) 5924 dies = (Dwarf_Die *) xrealloc (dies, 5925 (maxdies += 10) 5926 * sizeof (Dwarf_Die)); 5927 5928 int res = dwarf_child (&dies[level], &dies[level + 1]); 5929 if (res > 0) 5930 { 5931 while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1) 5932 if (level-- == 0) 5933 break; 5934 5935 if (unlikely (res == -1)) 5936 { 5937 if (!silent) 5938 error (0, 0, gettext ("cannot get next DIE: %s\n"), 5939 dwarf_errmsg (-1)); 5940 goto do_return; 5941 } 5942 } 5943 else if (unlikely (res < 0)) 5944 { 5945 if (!silent) 5946 error (0, 0, gettext ("cannot get next DIE: %s"), 5947 dwarf_errmsg (-1)); 5948 goto do_return; 5949 } 5950 else 5951 ++level; 5952 } 5953 while (level >= 0); 5954 5955 offset = nextcu; 5956 if (offset != 0) 5957 goto next_cu; 5958 5959 do_return: 5960 free (dies); 5961 } 5962 5963 static void 5964 print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, 5965 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 5966 { 5967 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false); 5968 } 5969 5970 static void 5971 print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, 5972 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 5973 { 5974 print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true); 5975 } 5976 5977 5978 static void 5979 print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, 5980 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 5981 { 5982 printf (gettext ("\ 5983 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), 5984 elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 5985 (uint64_t) shdr->sh_offset); 5986 5987 if (shdr->sh_size == 0) 5988 return; 5989 5990 /* There is no functionality in libdw to read the information in the 5991 way it is represented here. Hardcode the decoder. */ 5992 Elf_Data *data = elf_getdata (scn, NULL); 5993 if (unlikely (data == NULL || data->d_buf == NULL)) 5994 { 5995 error (0, 0, gettext ("cannot get line data section data: %s"), 5996 elf_errmsg (-1)); 5997 return; 5998 } 5999 6000 const unsigned char *linep = (const unsigned char *) data->d_buf; 6001 const unsigned char *lineendp; 6002 6003 while (linep 6004 < (lineendp = (const unsigned char *) data->d_buf + data->d_size)) 6005 { 6006 size_t start_offset = linep - (const unsigned char *) data->d_buf; 6007 6008 printf (gettext ("\nTable at offset %Zu:\n"), start_offset); 6009 6010 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep); 6011 unsigned int length = 4; 6012 if (unlikely (unit_length == 0xffffffff)) 6013 { 6014 if (unlikely (linep + 8 > lineendp)) 6015 { 6016 invalid_data: 6017 error (0, 0, gettext ("invalid data in section [%zu] '%s'"), 6018 elf_ndxscn (scn), section_name (ebl, ehdr, shdr)); 6019 return; 6020 } 6021 unit_length = read_8ubyte_unaligned_inc (dbg, linep); 6022 length = 8; 6023 } 6024 6025 /* Check whether we have enough room in the section. */ 6026 if (unit_length < 2 + length + 5 * 1 6027 || unlikely (linep + unit_length > lineendp)) 6028 goto invalid_data; 6029 lineendp = linep + unit_length; 6030 6031 /* The next element of the header is the version identifier. */ 6032 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep); 6033 6034 /* Next comes the header length. */ 6035 Dwarf_Word header_length; 6036 if (length == 4) 6037 header_length = read_4ubyte_unaligned_inc (dbg, linep); 6038 else 6039 header_length = read_8ubyte_unaligned_inc (dbg, linep); 6040 //const unsigned char *header_start = linep; 6041 6042 /* Next the minimum instruction length. */ 6043 uint_fast8_t minimum_instr_len = *linep++; 6044 6045 /* Next the maximum operations per instruction, in version 4 format. */ 6046 uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++; 6047 6048 /* Then the flag determining the default value of the is_stmt 6049 register. */ 6050 uint_fast8_t default_is_stmt = *linep++; 6051 6052 /* Now the line base. */ 6053 int_fast8_t line_base = *((const int_fast8_t *) linep); 6054 ++linep; 6055 6056 /* And the line range. */ 6057 uint_fast8_t line_range = *linep++; 6058 6059 /* The opcode base. */ 6060 uint_fast8_t opcode_base = *linep++; 6061 6062 /* Print what we got so far. */ 6063 printf (gettext ("\n" 6064 " Length: %" PRIu64 "\n" 6065 " DWARF version: %" PRIuFAST16 "\n" 6066 " Prologue length: %" PRIu64 "\n" 6067 " Minimum instruction length: %" PRIuFAST8 "\n" 6068 " Maximum operations per instruction: %" PRIuFAST8 "\n" 6069 " Initial value if '%s': %" PRIuFAST8 "\n" 6070 " Line base: %" PRIdFAST8 "\n" 6071 " Line range: %" PRIuFAST8 "\n" 6072 " Opcode base: %" PRIuFAST8 "\n" 6073 "\n" 6074 "Opcodes:\n"), 6075 (uint64_t) unit_length, version, (uint64_t) header_length, 6076 minimum_instr_len, max_ops_per_instr, 6077 "is_stmt", default_is_stmt, line_base, 6078 line_range, opcode_base); 6079 6080 if (unlikely (linep + opcode_base - 1 >= lineendp)) 6081 { 6082 invalid_unit: 6083 error (0, 0, 6084 gettext ("invalid data at offset %tu in section [%zu] '%s'"), 6085 linep - (const unsigned char *) data->d_buf, 6086 elf_ndxscn (scn), section_name (ebl, ehdr, shdr)); 6087 linep = lineendp; 6088 continue; 6089 } 6090 int opcode_base_l10 = 1; 6091 unsigned int tmp = opcode_base; 6092 while (tmp > 10) 6093 { 6094 tmp /= 10; 6095 ++opcode_base_l10; 6096 } 6097 const uint8_t *standard_opcode_lengths = linep - 1; 6098 for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt) 6099 printf (ngettext (" [%*" PRIuFAST8 "] %hhu argument\n", 6100 " [%*" PRIuFAST8 "] %hhu arguments\n", 6101 (int) linep[cnt - 1]), 6102 opcode_base_l10, cnt, linep[cnt - 1]); 6103 linep += opcode_base - 1; 6104 if (unlikely (linep >= lineendp)) 6105 goto invalid_unit; 6106 6107 puts (gettext ("\nDirectory table:")); 6108 while (*linep != 0) 6109 { 6110 unsigned char *endp = memchr (linep, '\0', lineendp - linep); 6111 if (unlikely (endp == NULL)) 6112 goto invalid_unit; 6113 6114 printf (" %s\n", (char *) linep); 6115 6116 linep = endp + 1; 6117 } 6118 /* Skip the final NUL byte. */ 6119 ++linep; 6120 6121 if (unlikely (linep >= lineendp)) 6122 goto invalid_unit; 6123 puts (gettext ("\nFile name table:\n" 6124 " Entry Dir Time Size Name")); 6125 for (unsigned int cnt = 1; *linep != 0; ++cnt) 6126 { 6127 /* First comes the file name. */ 6128 char *fname = (char *) linep; 6129 unsigned char *endp = memchr (fname, '\0', lineendp - linep); 6130 if (unlikely (endp == NULL)) 6131 goto invalid_unit; 6132 linep = endp + 1; 6133 6134 /* Then the index. */ 6135 unsigned int diridx; 6136 get_uleb128 (diridx, linep); 6137 6138 /* Next comes the modification time. */ 6139 unsigned int mtime; 6140 get_uleb128 (mtime, linep); 6141 6142 /* Finally the length of the file. */ 6143 unsigned int fsize; 6144 get_uleb128 (fsize, linep); 6145 6146 printf (" %-5u %-5u %-9u %-9u %s\n", 6147 cnt, diridx, mtime, fsize, fname); 6148 } 6149 /* Skip the final NUL byte. */ 6150 ++linep; 6151 6152 puts (gettext ("\nLine number statements:")); 6153 Dwarf_Word address = 0; 6154 unsigned int op_index = 0; 6155 size_t line = 1; 6156 uint_fast8_t is_stmt = default_is_stmt; 6157 6158 /* Default address value, in case we do not find the CU. */ 6159 size_t address_size 6160 = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8; 6161 6162 /* Determine the CU this block is for. */ 6163 Dwarf_Off cuoffset; 6164 Dwarf_Off ncuoffset = 0; 6165 size_t hsize; 6166 while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize, 6167 NULL, NULL, NULL) == 0) 6168 { 6169 Dwarf_Die cudie; 6170 if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL) 6171 continue; 6172 Dwarf_Attribute stmt_list; 6173 if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL) 6174 continue; 6175 Dwarf_Word lineoff; 6176 if (dwarf_formudata (&stmt_list, &lineoff) != 0) 6177 continue; 6178 if (lineoff == start_offset) 6179 { 6180 /* Found the CU. */ 6181 address_size = cudie.cu->address_size; 6182 break; 6183 } 6184 } 6185 6186 /* Apply the "operation advance" from a special opcode 6187 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */ 6188 unsigned int op_addr_advance; 6189 bool show_op_index; 6190 inline void advance_pc (unsigned int op_advance) 6191 { 6192 op_addr_advance = minimum_instr_len * ((op_index + op_advance) 6193 / max_ops_per_instr); 6194 address += op_advance; 6195 show_op_index = (op_index > 0 || 6196 (op_index + op_advance) % max_ops_per_instr > 0); 6197 op_index = (op_index + op_advance) % max_ops_per_instr; 6198 } 6199 6200 while (linep < lineendp) 6201 { 6202 size_t offset = linep - (const unsigned char *) data->d_buf; 6203 unsigned int u128; 6204 int s128; 6205 6206 /* Read the opcode. */ 6207 unsigned int opcode = *linep++; 6208 6209 printf (" [%6" PRIx64 "]", (uint64_t)offset); 6210 /* Is this a special opcode? */ 6211 if (likely (opcode >= opcode_base)) 6212 { 6213 /* Yes. Handling this is quite easy since the opcode value 6214 is computed with 6215 6216 opcode = (desired line increment - line_base) 6217 + (line_range * address advance) + opcode_base 6218 */ 6219 int line_increment = (line_base 6220 + (opcode - opcode_base) % line_range); 6221 6222 /* Perform the increments. */ 6223 line += line_increment; 6224 advance_pc ((opcode - opcode_base) / line_range); 6225 6226 char *a = format_dwarf_addr (dwflmod, 0, address); 6227 if (show_op_index) 6228 printf (gettext ("\ 6229 special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"), 6230 opcode, op_addr_advance, a, op_index, 6231 line_increment, line); 6232 else 6233 printf (gettext ("\ 6234 special opcode %u: address+%u = %s, line%+d = %zu\n"), 6235 opcode, op_addr_advance, a, line_increment, line); 6236 free (a); 6237 } 6238 else if (opcode == 0) 6239 { 6240 /* This an extended opcode. */ 6241 if (unlikely (linep + 2 > lineendp)) 6242 goto invalid_unit; 6243 6244 /* The length. */ 6245 unsigned int len = *linep++; 6246 6247 if (unlikely (linep + len > lineendp)) 6248 goto invalid_unit; 6249 6250 /* The sub-opcode. */ 6251 opcode = *linep++; 6252 6253 printf (gettext (" extended opcode %u: "), opcode); 6254 6255 switch (opcode) 6256 { 6257 case DW_LNE_end_sequence: 6258 puts (gettext (" end of sequence")); 6259 6260 /* Reset the registers we care about. */ 6261 address = 0; 6262 op_index = 0; 6263 line = 1; 6264 is_stmt = default_is_stmt; 6265 break; 6266 6267 case DW_LNE_set_address: 6268 op_index = 0; 6269 if (address_size == 4) 6270 address = read_4ubyte_unaligned_inc (dbg, linep); 6271 else 6272 address = read_8ubyte_unaligned_inc (dbg, linep); 6273 { 6274 char *a = format_dwarf_addr (dwflmod, 0, address); 6275 printf (gettext (" set address to %s\n"), a); 6276 free (a); 6277 } 6278 break; 6279 6280 case DW_LNE_define_file: 6281 { 6282 char *fname = (char *) linep; 6283 unsigned char *endp = memchr (linep, '\0', 6284 lineendp - linep); 6285 if (unlikely (endp == NULL)) 6286 goto invalid_unit; 6287 linep = endp + 1; 6288 6289 unsigned int diridx; 6290 get_uleb128 (diridx, linep); 6291 Dwarf_Word mtime; 6292 get_uleb128 (mtime, linep); 6293 Dwarf_Word filelength; 6294 get_uleb128 (filelength, linep); 6295 6296 printf (gettext ("\ 6297 define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"), 6298 diridx, (uint64_t) mtime, (uint64_t) filelength, 6299 fname); 6300 } 6301 break; 6302 6303 case DW_LNE_set_discriminator: 6304 /* Takes one ULEB128 parameter, the discriminator. */ 6305 if (unlikely (standard_opcode_lengths[opcode] != 1)) 6306 goto invalid_unit; 6307 6308 get_uleb128 (u128, linep); 6309 printf (gettext (" set discriminator to %u\n"), u128); 6310 break; 6311 6312 default: 6313 /* Unknown, ignore it. */ 6314 puts (gettext (" unknown opcode")); 6315 linep += len - 1; 6316 break; 6317 } 6318 } 6319 else if (opcode <= DW_LNS_set_isa) 6320 { 6321 /* This is a known standard opcode. */ 6322 switch (opcode) 6323 { 6324 case DW_LNS_copy: 6325 /* Takes no argument. */ 6326 puts (gettext (" copy")); 6327 break; 6328 6329 case DW_LNS_advance_pc: 6330 /* Takes one uleb128 parameter which is added to the 6331 address. */ 6332 get_uleb128 (u128, linep); 6333 advance_pc (u128); 6334 { 6335 char *a = format_dwarf_addr (dwflmod, 0, address); 6336 if (show_op_index) 6337 printf (gettext ("\ 6338 advance address by %u to %s, op_index to %u\n"), 6339 op_addr_advance, a, op_index); 6340 else 6341 printf (gettext (" advance address by %u to %s\n"), 6342 op_addr_advance, a); 6343 free (a); 6344 } 6345 break; 6346 6347 case DW_LNS_advance_line: 6348 /* Takes one sleb128 parameter which is added to the 6349 line. */ 6350 get_sleb128 (s128, linep); 6351 line += s128; 6352 printf (gettext ("\ 6353 advance line by constant %d to %" PRId64 "\n"), 6354 s128, (int64_t) line); 6355 break; 6356 6357 case DW_LNS_set_file: 6358 /* Takes one uleb128 parameter which is stored in file. */ 6359 get_uleb128 (u128, linep); 6360 printf (gettext (" set file to %" PRIu64 "\n"), 6361 (uint64_t) u128); 6362 break; 6363 6364 case DW_LNS_set_column: 6365 /* Takes one uleb128 parameter which is stored in column. */ 6366 if (unlikely (standard_opcode_lengths[opcode] != 1)) 6367 goto invalid_unit; 6368 6369 get_uleb128 (u128, linep); 6370 printf (gettext (" set column to %" PRIu64 "\n"), 6371 (uint64_t) u128); 6372 break; 6373 6374 case DW_LNS_negate_stmt: 6375 /* Takes no argument. */ 6376 is_stmt = 1 - is_stmt; 6377 printf (gettext (" set '%s' to %" PRIuFAST8 "\n"), 6378 "is_stmt", is_stmt); 6379 break; 6380 6381 case DW_LNS_set_basic_block: 6382 /* Takes no argument. */ 6383 puts (gettext (" set basic block flag")); 6384 break; 6385 6386 case DW_LNS_const_add_pc: 6387 /* Takes no argument. */ 6388 advance_pc ((255 - opcode_base) / line_range); 6389 { 6390 char *a = format_dwarf_addr (dwflmod, 0, address); 6391 if (show_op_index) 6392 printf (gettext ("\ 6393 advance address by constant %u to %s, op_index to %u\n"), 6394 op_addr_advance, a, op_index); 6395 else 6396 printf (gettext ("\ 6397 advance address by constant %u to %s\n"), 6398 op_addr_advance, a); 6399 free (a); 6400 } 6401 break; 6402 6403 case DW_LNS_fixed_advance_pc: 6404 /* Takes one 16 bit parameter which is added to the 6405 address. */ 6406 if (unlikely (standard_opcode_lengths[opcode] != 1)) 6407 goto invalid_unit; 6408 6409 u128 = read_2ubyte_unaligned_inc (dbg, linep); 6410 address += u128; 6411 op_index = 0; 6412 { 6413 char *a = format_dwarf_addr (dwflmod, 0, address); 6414 printf (gettext ("\ 6415 advance address by fixed value %u to %s\n"), 6416 u128, a); 6417 free (a); 6418 } 6419 break; 6420 6421 case DW_LNS_set_prologue_end: 6422 /* Takes no argument. */ 6423 puts (gettext (" set prologue end flag")); 6424 break; 6425 6426 case DW_LNS_set_epilogue_begin: 6427 /* Takes no argument. */ 6428 puts (gettext (" set epilogue begin flag")); 6429 break; 6430 6431 case DW_LNS_set_isa: 6432 /* Takes one uleb128 parameter which is stored in isa. */ 6433 if (unlikely (standard_opcode_lengths[opcode] != 1)) 6434 goto invalid_unit; 6435 6436 get_uleb128 (u128, linep); 6437 printf (gettext (" set isa to %u\n"), u128); 6438 break; 6439 } 6440 } 6441 else 6442 { 6443 /* This is a new opcode the generator but not we know about. 6444 Read the parameters associated with it but then discard 6445 everything. Read all the parameters for this opcode. */ 6446 printf (ngettext (" unknown opcode with %" PRIu8 " parameter:", 6447 " unknown opcode with %" PRIu8 " parameters:", 6448 standard_opcode_lengths[opcode]), 6449 standard_opcode_lengths[opcode]); 6450 for (int n = standard_opcode_lengths[opcode]; n > 0; --n) 6451 { 6452 get_uleb128 (u128, linep); 6453 if (n != standard_opcode_lengths[opcode]) 6454 putc_unlocked (',', stdout); 6455 printf (" %u", u128); 6456 } 6457 6458 /* Next round, ignore this opcode. */ 6459 continue; 6460 } 6461 } 6462 } 6463 6464 /* There must only be one data block. */ 6465 assert (elf_getdata (scn, data) == NULL); 6466 } 6467 6468 6469 static void 6470 print_debug_loc_section (Dwfl_Module *dwflmod, 6471 Ebl *ebl, GElf_Ehdr *ehdr, 6472 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 6473 { 6474 Elf_Data *data = elf_rawdata (scn, NULL); 6475 6476 if (unlikely (data == NULL)) 6477 { 6478 error (0, 0, gettext ("cannot get .debug_loc content: %s"), 6479 elf_errmsg (-1)); 6480 return; 6481 } 6482 6483 printf (gettext ("\ 6484 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), 6485 elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 6486 (uint64_t) shdr->sh_offset); 6487 6488 sort_listptr (&known_loclistptr, "loclistptr"); 6489 size_t listptr_idx = 0; 6490 6491 uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; 6492 uint_fast8_t offset_size = 4; 6493 6494 bool first = true; 6495 unsigned char *readp = data->d_buf; 6496 unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size; 6497 while (readp < endp) 6498 { 6499 ptrdiff_t offset = readp - (unsigned char *) data->d_buf; 6500 6501 if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx, 6502 &address_size, &offset_size, 6503 offset, &readp, endp)) 6504 continue; 6505 6506 if (unlikely (data->d_size - offset < address_size * 2)) 6507 { 6508 printf (gettext (" [%6tx] <INVALID DATA>\n"), offset); 6509 break; 6510 } 6511 6512 Dwarf_Addr begin; 6513 Dwarf_Addr end; 6514 if (address_size == 8) 6515 { 6516 begin = read_8ubyte_unaligned_inc (dbg, readp); 6517 end = read_8ubyte_unaligned_inc (dbg, readp); 6518 } 6519 else 6520 { 6521 begin = read_4ubyte_unaligned_inc (dbg, readp); 6522 end = read_4ubyte_unaligned_inc (dbg, readp); 6523 if (begin == (Dwarf_Addr) (uint32_t) -1) 6524 begin = (Dwarf_Addr) -1l; 6525 } 6526 6527 if (begin == (Dwarf_Addr) -1l) /* Base address entry. */ 6528 { 6529 char *b = format_dwarf_addr (dwflmod, address_size, end); 6530 printf (gettext (" [%6tx] base address %s\n"), offset, b); 6531 free (b); 6532 } 6533 else if (begin == 0 && end == 0) /* End of list entry. */ 6534 { 6535 if (first) 6536 printf (gettext (" [%6tx] empty list\n"), offset); 6537 first = true; 6538 } 6539 else 6540 { 6541 /* We have a location expression entry. */ 6542 uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp); 6543 6544 char *b = format_dwarf_addr (dwflmod, address_size, begin); 6545 char *e = format_dwarf_addr (dwflmod, address_size, end); 6546 6547 if (first) /* First entry in a list. */ 6548 printf (gettext (" [%6tx] %s..%s"), offset, b, e); 6549 else 6550 printf (gettext (" %s..%s"), b, e); 6551 6552 free (b); 6553 free (e); 6554 6555 if (endp - readp <= (ptrdiff_t) len) 6556 { 6557 fputs (gettext (" <INVALID DATA>\n"), stdout); 6558 break; 6559 } 6560 6561 print_ops (dwflmod, dbg, 1, 18 + (address_size * 4), 6562 3 /*XXX*/, address_size, offset_size, len, readp); 6563 6564 first = false; 6565 readp += len; 6566 } 6567 } 6568 } 6569 6570 struct mac_culist 6571 { 6572 Dwarf_Die die; 6573 Dwarf_Off offset; 6574 Dwarf_Files *files; 6575 struct mac_culist *next; 6576 }; 6577 6578 6579 static int 6580 mac_compare (const void *p1, const void *p2) 6581 { 6582 struct mac_culist *m1 = (struct mac_culist *) p1; 6583 struct mac_culist *m2 = (struct mac_culist *) p2; 6584 6585 if (m1->offset < m2->offset) 6586 return -1; 6587 if (m1->offset > m2->offset) 6588 return 1; 6589 return 0; 6590 } 6591 6592 6593 static void 6594 print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 6595 Ebl *ebl, GElf_Ehdr *ehdr, 6596 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 6597 { 6598 printf (gettext ("\ 6599 \nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), 6600 elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 6601 (uint64_t) shdr->sh_offset); 6602 putc_unlocked ('\n', stdout); 6603 6604 /* There is no function in libdw to iterate over the raw content of 6605 the section but it is easy enough to do. */ 6606 Elf_Data *data = elf_getdata (scn, NULL); 6607 if (unlikely (data == NULL || data->d_buf == NULL)) 6608 { 6609 error (0, 0, gettext ("cannot get macro information section data: %s"), 6610 elf_errmsg (-1)); 6611 return; 6612 } 6613 6614 /* Get the source file information for all CUs. */ 6615 Dwarf_Off offset; 6616 Dwarf_Off ncu = 0; 6617 size_t hsize; 6618 struct mac_culist *culist = NULL; 6619 size_t nculist = 0; 6620 while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0) 6621 { 6622 Dwarf_Die cudie; 6623 if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL) 6624 continue; 6625 6626 Dwarf_Attribute attr; 6627 if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL) 6628 continue; 6629 6630 Dwarf_Word macoff; 6631 if (dwarf_formudata (&attr, &macoff) != 0) 6632 continue; 6633 6634 struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp)); 6635 newp->die = cudie; 6636 newp->offset = macoff; 6637 newp->files = NULL; 6638 newp->next = culist; 6639 culist = newp; 6640 ++nculist; 6641 } 6642 6643 /* Convert the list into an array for easier consumption. */ 6644 struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1) 6645 * sizeof (*cus)); 6646 /* Add sentinel. */ 6647 cus[nculist].offset = data->d_size; 6648 if (nculist > 0) 6649 { 6650 for (size_t cnt = nculist - 1; culist != NULL; --cnt) 6651 { 6652 assert (cnt < nculist); 6653 cus[cnt] = *culist; 6654 culist = culist->next; 6655 } 6656 6657 /* Sort the array according to the offset in the .debug_macinfo 6658 section. Note we keep the sentinel at the end. */ 6659 qsort (cus, nculist, sizeof (*cus), mac_compare); 6660 } 6661 6662 const unsigned char *readp = (const unsigned char *) data->d_buf; 6663 const unsigned char *readendp = readp + data->d_size; 6664 int level = 1; 6665 6666 while (readp < readendp) 6667 { 6668 unsigned int opcode = *readp++; 6669 unsigned int u128; 6670 unsigned int u128_2; 6671 const unsigned char *endp; 6672 6673 switch (opcode) 6674 { 6675 case DW_MACINFO_define: 6676 case DW_MACINFO_undef: 6677 case DW_MACINFO_vendor_ext: 6678 /* For the first two opcodes the parameters are 6679 line, string 6680 For the latter 6681 number, string. 6682 We can treat these cases together. */ 6683 get_uleb128 (u128, readp); 6684 6685 endp = memchr (readp, '\0', readendp - readp); 6686 if (unlikely (endp == NULL)) 6687 { 6688 printf (gettext ("\ 6689 %*s*** non-terminated string at end of section"), 6690 level, ""); 6691 return; 6692 } 6693 6694 if (opcode == DW_MACINFO_define) 6695 printf ("%*s#define %s, line %u\n", 6696 level, "", (char *) readp, u128); 6697 else if (opcode == DW_MACINFO_undef) 6698 printf ("%*s#undef %s, line %u\n", 6699 level, "", (char *) readp, u128); 6700 else 6701 printf (" #vendor-ext %s, number %u\n", (char *) readp, u128); 6702 6703 readp = endp + 1; 6704 break; 6705 6706 case DW_MACINFO_start_file: 6707 /* The two parameters are line and file index, in this order. */ 6708 get_uleb128 (u128, readp); 6709 get_uleb128 (u128_2, readp); 6710 6711 /* Find the CU DIE for this file. */ 6712 size_t macoff = readp - (const unsigned char *) data->d_buf; 6713 const char *fname = "???"; 6714 if (macoff >= cus[0].offset) 6715 { 6716 while (macoff >= cus[1].offset) 6717 ++cus; 6718 6719 if (cus[0].files == NULL 6720 && dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0) 6721 cus[0].files = (Dwarf_Files *) -1l; 6722 6723 if (cus[0].files != (Dwarf_Files *) -1l) 6724 fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL) 6725 ?: "???"); 6726 } 6727 6728 printf ("%*sstart_file %u, [%u] %s\n", 6729 level, "", u128, u128_2, fname); 6730 ++level; 6731 break; 6732 6733 case DW_MACINFO_end_file: 6734 --level; 6735 printf ("%*send_file\n", level, ""); 6736 /* Nothing more to do. */ 6737 break; 6738 6739 default: 6740 // XXX gcc seems to generate files with a trailing zero. 6741 if (unlikely (opcode != 0 || readp != readendp)) 6742 printf ("%*s*** invalid opcode %u\n", level, "", opcode); 6743 break; 6744 } 6745 } 6746 } 6747 6748 6749 /* Callback for printing global names. */ 6750 static int 6751 print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global, 6752 void *arg) 6753 { 6754 int *np = (int *) arg; 6755 6756 printf (gettext (" [%5d] DIE offset: %6" PRId64 6757 ", CU DIE offset: %6" PRId64 ", name: %s\n"), 6758 (*np)++, global->die_offset, global->cu_offset, global->name); 6759 6760 return 0; 6761 } 6762 6763 6764 /* Print the known exported symbols in the DWARF section '.debug_pubnames'. */ 6765 static void 6766 print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 6767 Ebl *ebl, GElf_Ehdr *ehdr, 6768 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 6769 { 6770 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"), 6771 elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 6772 (uint64_t) shdr->sh_offset); 6773 6774 int n = 0; 6775 (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0); 6776 } 6777 6778 /* Print the content of the DWARF string section '.debug_str'. */ 6779 static void 6780 print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 6781 Ebl *ebl, GElf_Ehdr *ehdr, 6782 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 6783 { 6784 const size_t sh_size = dbg->sectiondata[IDX_debug_str]->d_size; 6785 6786 /* Compute floor(log16(shdr->sh_size)). */ 6787 GElf_Addr tmp = sh_size; 6788 int digits = 1; 6789 while (tmp >= 16) 6790 { 6791 ++digits; 6792 tmp >>= 4; 6793 } 6794 digits = MAX (4, digits); 6795 6796 printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n" 6797 " %*s String\n"), 6798 elf_ndxscn (scn), 6799 section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset, 6800 /* TRANS: the debugstr| prefix makes the string unique. */ 6801 digits + 2, sgettext ("debugstr|Offset")); 6802 6803 Dwarf_Off offset = 0; 6804 while (offset < sh_size) 6805 { 6806 size_t len; 6807 const char *str = dwarf_getstring (dbg, offset, &len); 6808 if (unlikely (str == NULL)) 6809 { 6810 printf (gettext (" *** error while reading strings: %s\n"), 6811 dwarf_errmsg (-1)); 6812 break; 6813 } 6814 6815 printf (" [%*" PRIx64 "] \"%s\"\n", digits, (uint64_t) offset, str); 6816 6817 offset += len + 1; 6818 } 6819 } 6820 6821 6822 /* Print the content of the call frame search table section 6823 '.eh_frame_hdr'. */ 6824 static void 6825 print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)), 6826 Ebl *ebl __attribute__ ((unused)), 6827 GElf_Ehdr *ehdr __attribute__ ((unused)), 6828 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 6829 { 6830 printf (gettext ("\ 6831 \nCall frame search table section [%2zu] '.eh_frame_hdr':\n"), 6832 elf_ndxscn (scn)); 6833 6834 Elf_Data *data = elf_rawdata (scn, NULL); 6835 6836 if (unlikely (data == NULL)) 6837 { 6838 error (0, 0, gettext ("cannot get %s content: %s"), 6839 ".eh_frame_hdr", elf_errmsg (-1)); 6840 return; 6841 } 6842 6843 const unsigned char *readp = data->d_buf; 6844 const unsigned char *const dataend = ((unsigned char *) data->d_buf 6845 + data->d_size); 6846 6847 if (unlikely (readp + 4 > dataend)) 6848 { 6849 invalid_data: 6850 error (0, 0, gettext ("invalid data")); 6851 return; 6852 } 6853 6854 unsigned int version = *readp++; 6855 unsigned int eh_frame_ptr_enc = *readp++; 6856 unsigned int fde_count_enc = *readp++; 6857 unsigned int table_enc = *readp++; 6858 6859 printf (" version: %u\n" 6860 " eh_frame_ptr_enc: %#x ", 6861 version, eh_frame_ptr_enc); 6862 print_encoding_base ("", eh_frame_ptr_enc); 6863 printf (" fde_count_enc: %#x ", fde_count_enc); 6864 print_encoding_base ("", fde_count_enc); 6865 printf (" table_enc: %#x ", table_enc); 6866 print_encoding_base ("", table_enc); 6867 6868 uint64_t eh_frame_ptr = 0; 6869 if (eh_frame_ptr_enc != DW_EH_PE_omit) 6870 { 6871 readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr, 6872 dbg); 6873 if (unlikely (readp == NULL)) 6874 goto invalid_data; 6875 6876 printf (" eh_frame_ptr: %#" PRIx64, eh_frame_ptr); 6877 if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel) 6878 printf (" (offset: %#" PRIx64 ")", 6879 /* +4 because of the 4 byte header of the section. */ 6880 (uint64_t) shdr->sh_offset + 4 + eh_frame_ptr); 6881 6882 putchar_unlocked ('\n'); 6883 } 6884 6885 uint64_t fde_count = 0; 6886 if (fde_count_enc != DW_EH_PE_omit) 6887 { 6888 readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg); 6889 if (unlikely (readp == NULL)) 6890 goto invalid_data; 6891 6892 printf (" fde_count: %" PRIu64 "\n", fde_count); 6893 } 6894 6895 if (fde_count == 0 || table_enc == DW_EH_PE_omit) 6896 return; 6897 6898 puts (" Table:"); 6899 6900 /* Optimize for the most common case. */ 6901 if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4)) 6902 while (fde_count > 0 && readp + 8 <= dataend) 6903 { 6904 int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp); 6905 uint64_t initial_offset = ((uint64_t) shdr->sh_offset 6906 + (int64_t) initial_location); 6907 int32_t address = read_4sbyte_unaligned_inc (dbg, readp); 6908 // XXX Possibly print symbol name or section offset for initial_offset 6909 printf (" %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32 6910 " fde=[%6" PRIx64 "]\n", 6911 initial_location, initial_offset, 6912 address, address - (eh_frame_ptr + 4)); 6913 } 6914 else 6915 while (0 && readp < dataend) 6916 { 6917 6918 } 6919 } 6920 6921 6922 /* Print the content of the exception handling table section 6923 '.eh_frame_hdr'. */ 6924 static void 6925 print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)), 6926 Ebl *ebl __attribute__ ((unused)), 6927 GElf_Ehdr *ehdr __attribute__ ((unused)), 6928 Elf_Scn *scn, 6929 GElf_Shdr *shdr __attribute__ ((unused)), 6930 Dwarf *dbg __attribute__ ((unused))) 6931 { 6932 printf (gettext ("\ 6933 \nException handling table section [%2zu] '.gcc_except_table':\n"), 6934 elf_ndxscn (scn)); 6935 6936 Elf_Data *data = elf_rawdata (scn, NULL); 6937 6938 if (unlikely (data == NULL)) 6939 { 6940 error (0, 0, gettext ("cannot get %s content: %s"), 6941 ".gcc_except_table", elf_errmsg (-1)); 6942 return; 6943 } 6944 6945 const unsigned char *readp = data->d_buf; 6946 const unsigned char *const dataend = readp + data->d_size; 6947 6948 if (unlikely (readp + 1 > dataend)) 6949 { 6950 invalid_data: 6951 error (0, 0, gettext ("invalid data")); 6952 return; 6953 } 6954 unsigned int lpstart_encoding = *readp++; 6955 printf (gettext (" LPStart encoding: %#x "), lpstart_encoding); 6956 print_encoding_base ("", lpstart_encoding); 6957 if (lpstart_encoding != DW_EH_PE_omit) 6958 { 6959 uint64_t lpstart; 6960 readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg); 6961 printf (" LPStart: %#" PRIx64 "\n", lpstart); 6962 } 6963 6964 if (unlikely (readp + 1 > dataend)) 6965 goto invalid_data; 6966 unsigned int ttype_encoding = *readp++; 6967 printf (gettext (" TType encoding: %#x "), ttype_encoding); 6968 print_encoding_base ("", ttype_encoding); 6969 const unsigned char *ttype_base = NULL; 6970 if (ttype_encoding != DW_EH_PE_omit) 6971 { 6972 unsigned int ttype_base_offset; 6973 get_uleb128 (ttype_base_offset, readp); 6974 printf (" TType base offset: %#x\n", ttype_base_offset); 6975 ttype_base = readp + ttype_base_offset; 6976 } 6977 6978 if (unlikely (readp + 1 > dataend)) 6979 goto invalid_data; 6980 unsigned int call_site_encoding = *readp++; 6981 printf (gettext (" Call site encoding: %#x "), call_site_encoding); 6982 print_encoding_base ("", call_site_encoding); 6983 unsigned int call_site_table_len; 6984 get_uleb128 (call_site_table_len, readp); 6985 6986 const unsigned char *const action_table = readp + call_site_table_len; 6987 if (unlikely (action_table > dataend)) 6988 goto invalid_data; 6989 unsigned int u = 0; 6990 unsigned int max_action = 0; 6991 while (readp < action_table) 6992 { 6993 if (u == 0) 6994 puts (gettext ("\n Call site table:")); 6995 6996 uint64_t call_site_start; 6997 readp = read_encoded (call_site_encoding, readp, dataend, 6998 &call_site_start, dbg); 6999 uint64_t call_site_length; 7000 readp = read_encoded (call_site_encoding, readp, dataend, 7001 &call_site_length, dbg); 7002 uint64_t landing_pad; 7003 readp = read_encoded (call_site_encoding, readp, dataend, 7004 &landing_pad, dbg); 7005 unsigned int action; 7006 get_uleb128 (action, readp); 7007 max_action = MAX (action, max_action); 7008 printf (gettext (" [%4u] Call site start: %#" PRIx64 "\n" 7009 " Call site length: %" PRIu64 "\n" 7010 " Landing pad: %#" PRIx64 "\n" 7011 " Action: %u\n"), 7012 u++, call_site_start, call_site_length, landing_pad, action); 7013 } 7014 assert (readp == action_table); 7015 7016 unsigned int max_ar_filter = 0; 7017 if (max_action > 0) 7018 { 7019 puts ("\n Action table:"); 7020 7021 const unsigned char *const action_table_end 7022 = action_table + max_action + 1; 7023 7024 u = 0; 7025 do 7026 { 7027 int ar_filter; 7028 get_sleb128 (ar_filter, readp); 7029 if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter) 7030 max_ar_filter = ar_filter; 7031 int ar_disp; 7032 get_sleb128 (ar_disp, readp); 7033 7034 printf (" [%4u] ar_filter: % d\n" 7035 " ar_disp: % -5d", 7036 u, ar_filter, ar_disp); 7037 if (abs (ar_disp) & 1) 7038 printf (" -> [%4u]\n", u + (ar_disp + 1) / 2); 7039 else if (ar_disp != 0) 7040 puts (" -> ???"); 7041 else 7042 putchar_unlocked ('\n'); 7043 ++u; 7044 } 7045 while (readp < action_table_end); 7046 } 7047 7048 if (max_ar_filter > 0) 7049 { 7050 puts ("\n TType table:"); 7051 7052 // XXX Not *4, size of encoding; 7053 switch (ttype_encoding & 7) 7054 { 7055 case DW_EH_PE_udata2: 7056 case DW_EH_PE_sdata2: 7057 readp = ttype_base - max_ar_filter * 2; 7058 break; 7059 case DW_EH_PE_udata4: 7060 case DW_EH_PE_sdata4: 7061 readp = ttype_base - max_ar_filter * 4; 7062 break; 7063 case DW_EH_PE_udata8: 7064 case DW_EH_PE_sdata8: 7065 readp = ttype_base - max_ar_filter * 8; 7066 break; 7067 default: 7068 error (1, 0, gettext ("invalid TType encoding")); 7069 } 7070 7071 do 7072 { 7073 uint64_t ttype; 7074 readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype, 7075 dbg); 7076 printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype); 7077 } 7078 while (readp < ttype_base); 7079 } 7080 } 7081 7082 /* Print the content of the '.gdb_index' section. 7083 http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html 7084 */ 7085 static void 7086 print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, 7087 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg) 7088 { 7089 printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64 7090 " contains %" PRId64 " bytes :\n"), 7091 elf_ndxscn (scn), section_name (ebl, ehdr, shdr), 7092 (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size); 7093 7094 Elf_Data *data = elf_rawdata (scn, NULL); 7095 7096 if (unlikely (data == NULL)) 7097 { 7098 error (0, 0, gettext ("cannot get %s content: %s"), 7099 ".gdb_index", elf_errmsg (-1)); 7100 return; 7101 } 7102 7103 // .gdb_index is always in little endian. 7104 Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB }; 7105 dbg = &dummy_dbg; 7106 7107 const unsigned char *readp = data->d_buf; 7108 const unsigned char *const dataend = readp + data->d_size; 7109 7110 if (unlikely (readp + 4 > dataend)) 7111 { 7112 invalid_data: 7113 error (0, 0, gettext ("invalid data")); 7114 return; 7115 } 7116 7117 int32_t vers = read_4ubyte_unaligned (dbg, readp); 7118 printf (gettext (" Version: %" PRId32 "\n"), vers); 7119 7120 // The only difference between version 4 and version 5 is the 7121 // hash used for generating the table. 7122 if (vers < 4 || vers > 5) 7123 { 7124 printf (gettext (" unknown version, cannot parse section\n")); 7125 return; 7126 } 7127 7128 readp += 4; 7129 if (unlikely (readp + 4 > dataend)) 7130 goto invalid_data; 7131 7132 uint32_t cu_off = read_4ubyte_unaligned (dbg, readp); 7133 printf (gettext (" CU offset: %#" PRIx32 "\n"), cu_off); 7134 7135 readp += 4; 7136 if (unlikely (readp + 4 > dataend)) 7137 goto invalid_data; 7138 7139 uint32_t tu_off = read_4ubyte_unaligned (dbg, readp); 7140 printf (gettext (" TU offset: %#" PRIx32 "\n"), tu_off); 7141 7142 readp += 4; 7143 if (unlikely (readp + 4 > dataend)) 7144 goto invalid_data; 7145 7146 uint32_t addr_off = read_4ubyte_unaligned (dbg, readp); 7147 printf (gettext (" address offset: %#" PRIx32 "\n"), addr_off); 7148 7149 readp += 4; 7150 if (unlikely (readp + 4 > dataend)) 7151 goto invalid_data; 7152 7153 uint32_t sym_off = read_4ubyte_unaligned (dbg, readp); 7154 printf (gettext (" symbol offset: %#" PRIx32 "\n"), sym_off); 7155 7156 readp += 4; 7157 if (unlikely (readp + 4 > dataend)) 7158 goto invalid_data; 7159 7160 uint32_t const_off = read_4ubyte_unaligned (dbg, readp); 7161 printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off); 7162 7163 readp = data->d_buf + cu_off; 7164 7165 const unsigned char *nextp = data->d_buf + tu_off; 7166 size_t nr = (nextp - readp) / 16; 7167 7168 printf (gettext ("\n CU list at offset %#" PRIx32 7169 " contains %zu entries:\n"), 7170 cu_off, nr); 7171 7172 size_t n = 0; 7173 while (readp + 16 <= dataend && n < nr) 7174 { 7175 uint64_t off = read_8ubyte_unaligned (dbg, readp); 7176 readp += 8; 7177 7178 uint64_t len = read_8ubyte_unaligned (dbg, readp); 7179 readp += 8; 7180 7181 printf (" [%4zu] start: %0#8" PRIx64 7182 ", length: %5" PRIu64 "\n", n, off, len); 7183 n++; 7184 } 7185 7186 readp = data->d_buf + tu_off; 7187 nextp = data->d_buf + addr_off; 7188 nr = (nextp - readp) / 24; 7189 7190 printf (gettext ("\n TU list at offset %#" PRIx32 7191 " contains %zu entries:\n"), 7192 tu_off, nr); 7193 7194 n = 0; 7195 while (readp + 24 <= dataend && n < nr) 7196 { 7197 uint64_t off = read_8ubyte_unaligned (dbg, readp); 7198 readp += 8; 7199 7200 uint64_t type = read_8ubyte_unaligned (dbg, readp); 7201 readp += 8; 7202 7203 uint64_t sig = read_8ubyte_unaligned (dbg, readp); 7204 readp += 8; 7205 7206 printf (" [%4zu] CU offset: %5" PRId64 7207 ", type offset: %5" PRId64 7208 ", signature: %0#8" PRIx64 "\n", n, off, type, sig); 7209 n++; 7210 } 7211 7212 readp = data->d_buf + addr_off; 7213 nextp = data->d_buf + sym_off; 7214 nr = (nextp - readp) / 20; 7215 7216 printf (gettext ("\n Address list at offset %#" PRIx32 7217 " contains %zu entries:\n"), 7218 addr_off, nr); 7219 7220 n = 0; 7221 while (readp + 20 <= dataend && n < nr) 7222 { 7223 uint64_t low = read_8ubyte_unaligned (dbg, readp); 7224 readp += 8; 7225 7226 uint64_t high = read_8ubyte_unaligned (dbg, readp); 7227 readp += 8; 7228 7229 uint32_t idx = read_4ubyte_unaligned (dbg, readp); 7230 readp += 4; 7231 7232 char *l = format_dwarf_addr (dwflmod, 8, low); 7233 char *h = format_dwarf_addr (dwflmod, 8, high - 1); 7234 printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n", 7235 n, l, h, idx); 7236 n++; 7237 } 7238 7239 readp = data->d_buf + sym_off; 7240 nextp = data->d_buf + const_off; 7241 nr = (nextp - readp) / 8; 7242 7243 printf (gettext ("\n Symbol table at offset %#" PRIx32 7244 " contains %zu slots:\n"), 7245 addr_off, nr); 7246 7247 n = 0; 7248 while (readp + 8 <= dataend && n < nr) 7249 { 7250 uint32_t name = read_4ubyte_unaligned (dbg, readp); 7251 readp += 4; 7252 7253 uint32_t vector = read_4ubyte_unaligned (dbg, readp); 7254 readp += 4; 7255 7256 if (name != 0 || vector != 0) 7257 { 7258 const unsigned char *sym = data->d_buf + const_off + name; 7259 if (unlikely (sym > dataend)) 7260 goto invalid_data; 7261 7262 printf (" [%4zu] symbol: %s, CUs: ", n, sym); 7263 7264 const unsigned char *readcus = data->d_buf + const_off + vector; 7265 if (unlikely (readcus + 8 > dataend)) 7266 goto invalid_data; 7267 7268 uint32_t cus = read_4ubyte_unaligned (dbg, readcus); 7269 while (cus--) 7270 { 7271 uint32_t cu; 7272 readcus += 4; 7273 cu = read_4ubyte_unaligned (dbg, readcus); 7274 printf ("%" PRId32 "%s", cu, ((cus > 0) ? ", " : "")); 7275 } 7276 printf ("\n"); 7277 } 7278 n++; 7279 } 7280 } 7281 7282 static void 7283 print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr) 7284 { 7285 /* Before we start the real work get a debug context descriptor. */ 7286 Dwarf_Addr dwbias; 7287 Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias); 7288 Dwarf dummy_dbg = 7289 { 7290 .elf = ebl->elf, 7291 .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA] 7292 }; 7293 if (dbg == NULL) 7294 { 7295 if ((print_debug_sections & ~section_exception) != 0) 7296 error (0, 0, gettext ("cannot get debug context descriptor: %s"), 7297 dwfl_errmsg (-1)); 7298 if ((print_debug_sections & section_exception) == 0) 7299 return; 7300 dbg = &dummy_dbg; 7301 } 7302 7303 /* Get the section header string table index. */ 7304 size_t shstrndx; 7305 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 7306 error (EXIT_FAILURE, 0, 7307 gettext ("cannot get section header string table index")); 7308 7309 /* Look through all the sections for the debugging sections to print. */ 7310 Elf_Scn *scn = NULL; 7311 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 7312 { 7313 GElf_Shdr shdr_mem; 7314 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 7315 7316 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS) 7317 { 7318 static const struct 7319 { 7320 const char *name; 7321 enum section_e bitmask; 7322 void (*fp) (Dwfl_Module *, Ebl *, 7323 GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *); 7324 } debug_sections[] = 7325 { 7326 #define NEW_SECTION(name) \ 7327 { ".debug_" #name, section_##name, print_debug_##name##_section } 7328 NEW_SECTION (abbrev), 7329 NEW_SECTION (aranges), 7330 NEW_SECTION (frame), 7331 NEW_SECTION (info), 7332 NEW_SECTION (types), 7333 NEW_SECTION (line), 7334 NEW_SECTION (loc), 7335 NEW_SECTION (pubnames), 7336 NEW_SECTION (str), 7337 NEW_SECTION (macinfo), 7338 NEW_SECTION (ranges), 7339 { ".eh_frame", section_frame | section_exception, 7340 print_debug_frame_section }, 7341 { ".eh_frame_hdr", section_frame | section_exception, 7342 print_debug_frame_hdr_section }, 7343 { ".gcc_except_table", section_frame | section_exception, 7344 print_debug_exception_table }, 7345 { ".gdb_index", section_gdb_index, print_gdb_index_section } 7346 }; 7347 const int ndebug_sections = (sizeof (debug_sections) 7348 / sizeof (debug_sections[0])); 7349 const char *name = elf_strptr (ebl->elf, shstrndx, 7350 shdr->sh_name); 7351 int n; 7352 7353 for (n = 0; n < ndebug_sections; ++n) 7354 if (strcmp (name, debug_sections[n].name) == 0 7355 #if USE_ZLIB 7356 || (name[0] == '.' && name[1] == 'z' 7357 && debug_sections[n].name[1] == 'd' 7358 && strcmp (&name[2], &debug_sections[n].name[1]) == 0) 7359 #endif 7360 ) 7361 { 7362 if ((print_debug_sections | implicit_debug_sections) 7363 & debug_sections[n].bitmask) 7364 debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg); 7365 break; 7366 } 7367 } 7368 } 7369 7370 reset_listptr (&known_loclistptr); 7371 reset_listptr (&known_rangelistptr); 7372 } 7373 7374 7375 #define ITEM_INDENT 4 7376 #define ITEM_WRAP_COLUMN 150 7377 #define REGISTER_WRAP_COLUMN 75 7378 7379 /* Print "NAME: FORMAT", wrapping when FORMAT_MAX chars of FORMAT would 7380 make the line exceed ITEM_WRAP_COLUMN. Unpadded numbers look better 7381 for the core items. But we do not want the line breaks to depend on 7382 the particular values. */ 7383 static unsigned int 7384 __attribute__ ((format (printf, 7, 8))) 7385 print_core_item (unsigned int colno, char sep, unsigned int wrap, 7386 size_t name_width, const char *name, 7387 size_t format_max, const char *format, ...)