1 /* Print information from ELF file in human-readable form. 2 Copyright (C) 1999-2018 Red Hat, Inc. 3 This file is part of elfutils. 4 5 This file is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 elfutils is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18 #ifdef HAVE_CONFIG_H 19 # include <config.h> 20 #endif 21 22 #include <argp.h> 23 #include <assert.h> 24 #include <ctype.h> 25 #include <dwarf.h> 26 #include <errno.h> 27 #include <fcntl.h> 28 #include <gelf.h> 29 #include <inttypes.h> 30 #include <langinfo.h> 31 #include <libdw.h> 32 #include <libdwfl.h> 33 #include <libintl.h> 34 #include <locale.h> 35 #include <stdarg.h> 36 #include <stdbool.h> 37 #include <stdio.h> 38 #include <stdio_ext.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <strings.h> 42 #include <time.h> 43 #include <unistd.h> 44 #include <sys/stat.h> 45 #include <signal.h> 46 47 #include <libeu.h> 48 #include <system.h> 49 #include <printversion.h> 50 #include "../libelf/libelfP.h" 51 #include "../libelf/common.h" 52 #include "../libebl/libeblP.h" 53 #include "../libdwelf/libdwelf.h" 54 #include "../libdw/libdwP.h" 55 #include "../libdwfl/libdwflP.h" 56 #include "../libdw/memory-access.h" 57 58 #include "../libdw/known-dwarf.h" 59 60 #ifdef __linux__ 61 #define CORE_SIGILL SIGILL 62 #define CORE_SIGBUS SIGBUS 63 #define CORE_SIGFPE SIGFPE 64 #define CORE_SIGSEGV SIGSEGV 65 #define CORE_SI_USER SI_USER 66 #else 67 /* We want the linux version of those as that is what shows up in the core files. */ 68 #define CORE_SIGILL 4 /* Illegal instruction (ANSI). */ 69 #define CORE_SIGBUS 7 /* BUS error (4.2 BSD). */ 70 #define CORE_SIGFPE 8 /* Floating-point exception (ANSI). */ 71 #define CORE_SIGSEGV 11 /* Segmentation violation (ANSI). */ 72 #define CORE_SI_USER 0 /* Sent by kill, sigsend. */ 73 #endif 74 75 /* Name and version of program. */ 76 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; 77 78 /* Bug report address. */ 79 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; 80 81 /* argp key value for --elf-section, non-ascii. */ 82 #define ELF_INPUT_SECTION 256 83 84 /* argp key value for --dwarf-skeleton, non-ascii. */ 85 #define DWARF_SKELETON 257 86 87 /* Terrible hack for hooking unrelated skeleton/split compile units, 88 see __libdw_link_skel_split in print_debug. */ 89 static bool do_not_close_dwfl = false; 90 91 /* Definitions of arguments for argp functions. */ 92 static const struct argp_option options[] = 93 { 94 { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 }, 95 { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL, 96 N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF " 97 "input data"), 0 }, 98 { "dwarf-skeleton", DWARF_SKELETON, "FILE", 0, 99 N_("Used with -w to find the skeleton Compile Units in FILE associated " 100 "with the Split Compile units in a .dwo input file"), 0 }, 101 { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 }, 102 { "all", 'a', NULL, 0, 103 N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 }, 104 { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 }, 105 { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 }, 106 { "histogram", 'I', NULL, 0, 107 N_("Display histogram of bucket list lengths"), 0 }, 108 { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 }, 109 { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, 110 { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 }, 111 { "section-groups", 'g', NULL, 0, N_("Display the section groups"), 0 }, 112 { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 }, 113 { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, 114 { "symbols", 's', "SECTION", OPTION_ARG_OPTIONAL, 115 N_("Display the symbol table sections"), 0 }, 116 { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 }, 117 { "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 }, 118 { "arch-specific", 'A', NULL, 0, 119 N_("Display architecture specific information, if any"), 0 }, 120 { "exception", 'e', NULL, 0, 121 N_("Display sections for exception handling"), 0 }, 122 123 { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 }, 124 { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL, 125 N_("Display DWARF section content. SECTION can be one of abbrev, addr, " 126 "aranges, decodedaranges, frame, gdb_index, info, info+, loc, line, " 127 "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 }, 128 { "hex-dump", 'x', "SECTION", 0, 129 N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 }, 130 { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL, 131 N_("Print string contents of sections"), 0 }, 132 { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 }, 133 { "archive-index", 'c', NULL, 0, 134 N_("Display the symbol index of an archive"), 0 }, 135 136 { NULL, 0, NULL, 0, N_("Output control:"), 0 }, 137 { "numeric-addresses", 'N', NULL, 0, 138 N_("Do not find symbol names for addresses in DWARF data"), 0 }, 139 { "unresolved-address-offsets", 'U', NULL, 0, 140 N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 }, 141 { "wide", 'W', NULL, 0, 142 N_("Ignored for compatibility (lines always wide)"), 0 }, 143 { "decompress", 'z', NULL, 0, 144 N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 }, 145 { NULL, 0, NULL, 0, NULL, 0 } 146 }; 147 148 /* Short description of program. */ 149 static const char doc[] = N_("\ 150 Print information from ELF file in human-readable form."); 151 152 /* Strings for arguments in help texts. */ 153 static const char args_doc[] = N_("FILE..."); 154 155 /* Prototype for option handler. */ 156 static error_t parse_opt (int key, char *arg, struct argp_state *state); 157 158 /* Data structure to communicate with argp functions. */ 159 static struct argp argp = 160 { 161 options, parse_opt, args_doc, doc, NULL, NULL, NULL 162 }; 163 164 /* If non-null, the section from which we should read to (compressed) ELF. */ 165 static const char *elf_input_section = NULL; 166 167 /* If non-null, the file that contains the skeleton CUs. */ 168 static const char *dwarf_skeleton = NULL; 169 170 /* Flags set by the option controlling the output. */ 171 172 /* True if dynamic segment should be printed. */ 173 static bool print_dynamic_table; 174 175 /* True if the file header should be printed. */ 176 static bool print_file_header; 177 178 /* True if the program headers should be printed. */ 179 static bool print_program_header; 180 181 /* True if relocations should be printed. */ 182 static bool print_relocations; 183 184 /* True if the section headers should be printed. */ 185 static bool print_section_header; 186 187 /* True if the symbol table should be printed. */ 188 static bool print_symbol_table; 189 190 /* A specific section name, or NULL to print all symbol tables. */ 191 static char *symbol_table_section; 192 193 /* True if the version information should be printed. */ 194 static bool print_version_info; 195 196 /* True if section groups should be printed. */ 197 static bool print_section_groups; 198 199 /* True if bucket list length histogram should be printed. */ 200 static bool print_histogram; 201 202 /* True if the architecture specific data should be printed. */ 203 static bool print_arch; 204 205 /* True if note section content should be printed. */ 206 static bool print_notes; 207 208 /* True if SHF_STRINGS section content should be printed. */ 209 static bool print_string_sections; 210 211 /* True if archive index should be printed. */ 212 static bool print_archive_index; 213 214 /* True if any of the control options except print_archive_index is set. */ 215 static bool any_control_option; 216 217 /* True if we should print addresses from DWARF in symbolic form. */ 218 static bool print_address_names = true; 219 220 /* True if we should print raw values instead of relativized addresses. */ 221 static bool print_unresolved_addresses = false; 222 223 /* True if we should print the .debug_aranges section using libdw. */ 224 static bool decodedaranges = false; 225 226 /* True if we should print the .debug_aranges section using libdw. */ 227 static bool decodedline = false; 228 229 /* True if we want to show more information about compressed sections. */ 230 static bool print_decompress = false; 231 232 /* True if we want to show split compile units for debug_info skeletons. */ 233 static bool show_split_units = false; 234 235 /* Select printing of debugging sections. */ 236 static enum section_e 237 { 238 section_abbrev = 1, /* .debug_abbrev */ 239 section_aranges = 2, /* .debug_aranges */ 240 section_frame = 4, /* .debug_frame or .eh_frame & al. */ 241 section_info = 8, /* .debug_info, (implies .debug_types) */ 242 section_line = 16, /* .debug_line */ 243 section_loc = 32, /* .debug_loc */ 244 section_pubnames = 64, /* .debug_pubnames */ 245 section_str = 128, /* .debug_str */ 246 section_macinfo = 256, /* .debug_macinfo */ 247 section_ranges = 512, /* .debug_ranges */ 248 section_exception = 1024, /* .eh_frame & al. */ 249 section_gdb_index = 2048, /* .gdb_index */ 250 section_macro = 4096, /* .debug_macro */ 251 section_addr = 8192, /* .debug_addr */ 252 section_types = 16384, /* .debug_types (implied by .debug_info) */ 253 section_all = (section_abbrev | section_aranges | section_frame 254 | section_info | section_line | section_loc 255 | section_pubnames | section_str | section_macinfo 256 | section_ranges | section_exception | section_gdb_index 257 | section_macro | section_addr | section_types) 258 } print_debug_sections, implicit_debug_sections; 259 260 /* Select hex dumping of sections. */ 261 static struct section_argument *dump_data_sections; 262 static struct section_argument **dump_data_sections_tail = &dump_data_sections; 263 264 /* Select string dumping of sections. */ 265 static struct section_argument *string_sections; 266 static struct section_argument **string_sections_tail = &string_sections; 267 268 struct section_argument 269 { 270 struct section_argument *next; 271 const char *arg; 272 bool implicit; 273 }; 274 275 /* Numbers of sections and program headers in the file. */ 276 static size_t shnum; 277 static size_t phnum; 278 279 280 /* Declarations of local functions. */ 281 static void process_file (int fd, const char *fname, bool only_one); 282 static void process_elf_file (Dwfl_Module *dwflmod, int fd); 283 static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr); 284 static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr); 285 static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr); 286 static void print_scngrp (Ebl *ebl); 287 static void print_dynamic (Ebl *ebl); 288 static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr); 289 static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, 290 GElf_Shdr *shdr); 291 static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, 292 GElf_Shdr *shdr); 293 static void print_symtab (Ebl *ebl, int type); 294 static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 295 static void print_verinfo (Ebl *ebl); 296 static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 297 static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr); 298 static void handle_versym (Ebl *ebl, Elf_Scn *scn, 299 GElf_Shdr *shdr); 300 static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr); 301 static void handle_hash (Ebl *ebl); 302 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr); 303 static void print_liblist (Ebl *ebl); 304 static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr); 305 static void dump_data (Ebl *ebl); 306 static void dump_strings (Ebl *ebl); 307 static void print_strings (Ebl *ebl); 308 static void dump_archive_index (Elf *, const char *); 309 310 311 /* Looked up once with gettext in main. */ 312 static char *yes_str; 313 static char *no_str; 314 315 int 316 main (int argc, char *argv[]) 317 { 318 /* We use no threads here which can interfere with handling a stream. */ 319 (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER); 320 321 /* Set locale. */ 322 setlocale (LC_ALL, ""); 323 324 /* Initialize the message catalog. */ 325 textdomain (PACKAGE_TARNAME); 326 327 /* Look up once. */ 328 yes_str = gettext ("yes"); 329 no_str = gettext ("no"); 330 331 /* Parse and process arguments. */ 332 int remaining; 333 argp_parse (&argp, argc, argv, 0, &remaining, NULL); 334 335 /* Before we start tell the ELF library which version we are using. */ 336 elf_version (EV_CURRENT); 337 338 /* Now process all the files given at the command line. */ 339 bool only_one = remaining + 1 == argc; 340 do 341 { 342 /* Open the file. */ 343 int fd = open (argv[remaining], O_RDONLY); 344 if (fd == -1) 345 { 346 error (0, errno, gettext ("cannot open input file")); 347 continue; 348 } 349 350 process_file (fd, argv[remaining], only_one); 351 352 close (fd); 353 } 354 while (++remaining < argc); 355 356 return error_message_count != 0; 357 } 358 359 360 /* Handle program arguments. */ 361 static error_t 362 parse_opt (int key, char *arg, 363 struct argp_state *state __attribute__ ((unused))) 364 { 365 void add_dump_section (const char *name, bool implicit) 366 { 367 struct section_argument *a = xmalloc (sizeof *a); 368 a->arg = name; 369 a->next = NULL; 370 a->implicit = implicit; 371 struct section_argument ***tailp 372 = key == 'x' ? &dump_data_sections_tail : &string_sections_tail; 373 **tailp = a; 374 *tailp = &a->next; 375 } 376 377 switch (key) 378 { 379 case 'a': 380 print_file_header = true; 381 print_program_header = true; 382 print_relocations = true; 383 print_section_header = true; 384 print_symbol_table = true; 385 print_version_info = true; 386 print_dynamic_table = true; 387 print_section_groups = true; 388 print_histogram = true; 389 print_arch = true; 390 print_notes = true; 391 implicit_debug_sections |= section_exception; 392 add_dump_section (".strtab", true); 393 add_dump_section (".dynstr", true); 394 add_dump_section (".comment", true); 395 any_control_option = true; 396 break; 397 case 'A': 398 print_arch = true; 399 any_control_option = true; 400 break; 401 case 'd': 402 print_dynamic_table = true; 403 any_control_option = true; 404 break; 405 case 'e': 406 print_debug_sections |= section_exception; 407 any_control_option = true; 408 break; 409 case 'g': 410 print_section_groups = true; 411 any_control_option = true; 412 break; 413 case 'h': 414 print_file_header = true; 415 any_control_option = true; 416 break; 417 case 'I': 418 print_histogram = true; 419 any_control_option = true; 420 break; 421 case 'l': 422 print_program_header = true; 423 any_control_option = true; 424 break; 425 case 'n': 426 print_notes = true; 427 any_control_option = true; 428 break; 429 case 'r': 430 print_relocations = true; 431 any_control_option = true; 432 break; 433 case 'S': 434 print_section_header = true; 435 any_control_option = true; 436 break; 437 case 's': 438 print_symbol_table = true; 439 any_control_option = true; 440 symbol_table_section = arg; 441 break; 442 case 'V': 443 print_version_info = true; 444 any_control_option = true; 445 break; 446 case 'c': 447 print_archive_index = true; 448 break; 449 case 'w': 450 if (arg == NULL) 451 { 452 print_debug_sections = section_all; 453 implicit_debug_sections = section_info; 454 show_split_units = true; 455 } 456 else if (strcmp (arg, "abbrev") == 0) 457 print_debug_sections |= section_abbrev; 458 else if (strcmp (arg, "addr") == 0) 459 { 460 print_debug_sections |= section_addr; 461 implicit_debug_sections |= section_info; 462 } 463 else if (strcmp (arg, "aranges") == 0) 464 print_debug_sections |= section_aranges; 465 else if (strcmp (arg, "decodedaranges") == 0) 466 { 467 print_debug_sections |= section_aranges; 468 decodedaranges = true; 469 } 470 else if (strcmp (arg, "ranges") == 0) 471 { 472 print_debug_sections |= section_ranges; 473 implicit_debug_sections |= section_info; 474 } 475 else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0) 476 print_debug_sections |= section_frame; 477 else if (strcmp (arg, "info") == 0) 478 { 479 print_debug_sections |= section_info; 480 print_debug_sections |= section_types; 481 } 482 else if (strcmp (arg, "info+") == 0) 483 { 484 print_debug_sections |= section_info; 485 print_debug_sections |= section_types; 486 show_split_units = true; 487 } 488 else if (strcmp (arg, "loc") == 0) 489 { 490 print_debug_sections |= section_loc; 491 implicit_debug_sections |= section_info; 492 } 493 else if (strcmp (arg, "line") == 0) 494 print_debug_sections |= section_line; 495 else if (strcmp (arg, "decodedline") == 0) 496 { 497 print_debug_sections |= section_line; 498 decodedline = true; 499 } 500 else if (strcmp (arg, "pubnames") == 0) 501 print_debug_sections |= section_pubnames; 502 else if (strcmp (arg, "str") == 0) 503 { 504 print_debug_sections |= section_str; 505 /* For mapping string offset tables to CUs. */ 506 implicit_debug_sections |= section_info; 507 } 508 else if (strcmp (arg, "macinfo") == 0) 509 print_debug_sections |= section_macinfo; 510 else if (strcmp (arg, "macro") == 0) 511 print_debug_sections |= section_macro; 512 else if (strcmp (arg, "exception") == 0) 513 print_debug_sections |= section_exception; 514 else if (strcmp (arg, "gdb_index") == 0) 515 print_debug_sections |= section_gdb_index; 516 else 517 { 518 fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"), 519 arg); 520 argp_help (&argp, stderr, ARGP_HELP_SEE, 521 program_invocation_short_name); 522 exit (1); 523 } 524 any_control_option = true; 525 break; 526 case 'p': 527 any_control_option = true; 528 if (arg == NULL) 529 { 530 print_string_sections = true; 531 break; 532 } 533 FALLTHROUGH; 534 case 'x': 535 add_dump_section (arg, false); 536 any_control_option = true; 537 break; 538 case 'N': 539 print_address_names = false; 540 break; 541 case 'U': 542 print_unresolved_addresses = true; 543 break; 544 case ARGP_KEY_NO_ARGS: 545 fputs (gettext ("Missing file name.\n"), stderr); 546 goto do_argp_help; 547 case ARGP_KEY_FINI: 548 if (! any_control_option && ! print_archive_index) 549 { 550 fputs (gettext ("No operation specified.\n"), stderr); 551 do_argp_help: 552 argp_help (&argp, stderr, ARGP_HELP_SEE, 553 program_invocation_short_name); 554 exit (EXIT_FAILURE); 555 } 556 break; 557 case 'W': /* Ignored. */ 558 break; 559 case 'z': 560 print_decompress = true; 561 break; 562 case ELF_INPUT_SECTION: 563 if (arg == NULL) 564 elf_input_section = ".gnu_debugdata"; 565 else 566 elf_input_section = arg; 567 break; 568 case DWARF_SKELETON: 569 dwarf_skeleton = arg; 570 break; 571 default: 572 return ARGP_ERR_UNKNOWN; 573 } 574 return 0; 575 } 576 577 578 /* Create a file descriptor to read the data from the 579 elf_input_section given a file descriptor to an ELF file. */ 580 static int 581 open_input_section (int fd) 582 { 583 size_t shnums; 584 size_t cnt; 585 size_t shstrndx; 586 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 587 if (elf == NULL) 588 { 589 error (0, 0, gettext ("cannot generate Elf descriptor: %s"), 590 elf_errmsg (-1)); 591 return -1; 592 } 593 594 if (elf_getshdrnum (elf, &shnums) < 0) 595 { 596 error (0, 0, gettext ("cannot determine number of sections: %s"), 597 elf_errmsg (-1)); 598 open_error: 599 elf_end (elf); 600 return -1; 601 } 602 603 if (elf_getshdrstrndx (elf, &shstrndx) < 0) 604 { 605 error (0, 0, gettext ("cannot get section header string table index")); 606 goto open_error; 607 } 608 609 for (cnt = 0; cnt < shnums; ++cnt) 610 { 611 Elf_Scn *scn = elf_getscn (elf, cnt); 612 if (scn == NULL) 613 { 614 error (0, 0, gettext ("cannot get section: %s"), 615 elf_errmsg (-1)); 616 goto open_error; 617 } 618 619 GElf_Shdr shdr_mem; 620 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 621 if (unlikely (shdr == NULL)) 622 { 623 error (0, 0, gettext ("cannot get section header: %s"), 624 elf_errmsg (-1)); 625 goto open_error; 626 } 627 628 const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name); 629 if (sname == NULL) 630 { 631 error (0, 0, gettext ("cannot get section name")); 632 goto open_error; 633 } 634 635 if (strcmp (sname, elf_input_section) == 0) 636 { 637 Elf_Data *data = elf_rawdata (scn, NULL); 638 if (data == NULL) 639 { 640 error (0, 0, gettext ("cannot get %s content: %s"), 641 sname, elf_errmsg (-1)); 642 goto open_error; 643 } 644 645 /* Create (and immediately unlink) a temporary file to store 646 section data in to create a file descriptor for it. */ 647 const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir; 648 static const char suffix[] = "/readelfXXXXXX"; 649 int tmplen = strlen (tmpdir) + sizeof (suffix); 650 char *tempname = alloca (tmplen); 651 sprintf (tempname, "%s%s", tmpdir, suffix); 652 653 int sfd = mkstemp (tempname); 654 if (sfd == -1) 655 { 656 error (0, 0, gettext ("cannot create temp file '%s'"), 657 tempname); 658 goto open_error; 659 } 660 unlink (tempname); 661 662 ssize_t size = data->d_size; 663 if (write_retry (sfd, data->d_buf, size) != size) 664 { 665 error (0, 0, gettext ("cannot write section data")); 666 goto open_error; 667 } 668 669 if (elf_end (elf) != 0) 670 { 671 error (0, 0, gettext ("error while closing Elf descriptor: %s"), 672 elf_errmsg (-1)); 673 return -1; 674 } 675 676 if (lseek (sfd, 0, SEEK_SET) == -1) 677 { 678 error (0, 0, gettext ("error while rewinding file descriptor")); 679 return -1; 680 } 681 682 return sfd; 683 } 684 } 685 686 /* Named section not found. */ 687 if (elf_end (elf) != 0) 688 error (0, 0, gettext ("error while closing Elf descriptor: %s"), 689 elf_errmsg (-1)); 690 return -1; 691 } 692 693 /* Check if the file is an archive, and if so dump its index. */ 694 static void 695 check_archive_index (int fd, const char *fname, bool only_one) 696 { 697 /* Create an `Elf' descriptor. */ 698 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 699 if (elf == NULL) 700 error (0, 0, gettext ("cannot generate Elf descriptor: %s"), 701 elf_errmsg (-1)); 702 else 703 { 704 if (elf_kind (elf) == ELF_K_AR) 705 { 706 if (!only_one) 707 printf ("\n%s:\n\n", fname); 708 dump_archive_index (elf, fname); 709 } 710 else 711 error (0, 0, 712 gettext ("'%s' is not an archive, cannot print archive index"), 713 fname); 714 715 /* Now we can close the descriptor. */ 716 if (elf_end (elf) != 0) 717 error (0, 0, gettext ("error while closing Elf descriptor: %s"), 718 elf_errmsg (-1)); 719 } 720 } 721 722 /* Trivial callback used for checking if we opened an archive. */ 723 static int 724 count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)), 725 void **userdata __attribute__ ((unused)), 726 const char *name __attribute__ ((unused)), 727 Dwarf_Addr base __attribute__ ((unused)), 728 void *arg) 729 { 730 if (*(bool *) arg) 731 return DWARF_CB_ABORT; 732 *(bool *) arg = true; 733 return DWARF_CB_OK; 734 } 735 736 struct process_dwflmod_args 737 { 738 int fd; 739 bool only_one; 740 }; 741 742 static int 743 process_dwflmod (Dwfl_Module *dwflmod, 744 void **userdata __attribute__ ((unused)), 745 const char *name __attribute__ ((unused)), 746 Dwarf_Addr base __attribute__ ((unused)), 747 void *arg) 748 { 749 const struct process_dwflmod_args *a = arg; 750 751 /* Print the file name. */ 752 if (!a->only_one) 753 { 754 const char *fname; 755 dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL); 756 757 printf ("\n%s:\n\n", fname); 758 } 759 760 process_elf_file (dwflmod, a->fd); 761 762 return DWARF_CB_OK; 763 } 764 765 /* Stub libdwfl callback, only the ELF handle already open is ever used. 766 Only used for finding the alternate debug file if the Dwarf comes from 767 the main file. We are not interested in separate debuginfo. */ 768 static int 769 find_no_debuginfo (Dwfl_Module *mod, 770 void **userdata, 771 const char *modname, 772 Dwarf_Addr base, 773 const char *file_name, 774 const char *debuglink_file, 775 GElf_Word debuglink_crc, 776 char **debuginfo_file_name) 777 { 778 Dwarf_Addr dwbias; 779 dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL); 780 781 /* We are only interested if the Dwarf has been setup on the main 782 elf file but is only missing the alternate debug link. If dwbias 783 hasn't even been setup, this is searching for separate debuginfo 784 for the main elf. We don't care in that case. */ 785 if (dwbias == (Dwarf_Addr) -1) 786 return -1; 787 788 return dwfl_standard_find_debuginfo (mod, userdata, modname, base, 789 file_name, debuglink_file, 790 debuglink_crc, debuginfo_file_name); 791 } 792 793 static Dwfl * 794 create_dwfl (int fd, const char *fname) 795 { 796 /* Duplicate an fd for dwfl_report_offline to swallow. */ 797 int dwfl_fd = dup (fd); 798 if (unlikely (dwfl_fd < 0)) 799 error (EXIT_FAILURE, errno, "dup"); 800 801 /* Use libdwfl in a trivial way to open the libdw handle for us. 802 This takes care of applying relocations to DWARF data in ET_REL files. */ 803 static const Dwfl_Callbacks callbacks = 804 { 805 .section_address = dwfl_offline_section_address, 806 .find_debuginfo = find_no_debuginfo 807 }; 808 Dwfl *dwfl = dwfl_begin (&callbacks); 809 if (likely (dwfl != NULL)) 810 /* Let 0 be the logical address of the file (or first in archive). */ 811 dwfl->offline_next_address = 0; 812 if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL) 813 { 814 struct stat st; 815 if (fstat (dwfl_fd, &st) != 0) 816 error (0, errno, gettext ("cannot stat input file")); 817 else if (unlikely (st.st_size == 0)) 818 error (0, 0, gettext ("input file is empty")); 819 else 820 error (0, 0, gettext ("failed reading '%s': %s"), 821 fname, dwfl_errmsg (-1)); 822 close (dwfl_fd); /* Consumed on success, not on failure. */ 823 dwfl = NULL; 824 } 825 else 826 dwfl_report_end (dwfl, NULL, NULL); 827 828 return dwfl; 829 } 830 831 /* Process one input file. */ 832 static void 833 process_file (int fd, const char *fname, bool only_one) 834 { 835 if (print_archive_index) 836 check_archive_index (fd, fname, only_one); 837 838 if (!any_control_option) 839 return; 840 841 if (elf_input_section != NULL) 842 { 843 /* Replace fname and fd with section content. */ 844 char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2); 845 sprintf (fnname, "%s:%s", fname, elf_input_section); 846 fd = open_input_section (fd); 847 if (fd == -1) 848 { 849 error (0, 0, gettext ("No such section '%s' in '%s'"), 850 elf_input_section, fname); 851 return; 852 } 853 fname = fnname; 854 } 855 856 Dwfl *dwfl = create_dwfl (fd, fname); 857 if (dwfl != NULL) 858 { 859 if (only_one) 860 { 861 /* Clear ONLY_ONE if we have multiple modules, from an archive. */ 862 bool seen = false; 863 only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0; 864 } 865 866 /* Process the one or more modules gleaned from this file. */ 867 struct process_dwflmod_args a = { .fd = fd, .only_one = only_one }; 868 dwfl_getmodules (dwfl, &process_dwflmod, &a, 0); 869 } 870 /* Terrible hack for hooking unrelated skeleton/split compile units, 871 see __libdw_link_skel_split in print_debug. */ 872 if (! do_not_close_dwfl) 873 dwfl_end (dwfl); 874 875 /* Need to close the replaced fd if we created it. Caller takes 876 care of original. */ 877 if (elf_input_section != NULL) 878 close (fd); 879 } 880 881 /* Check whether there are any compressed sections in the ELF file. */ 882 static bool 883 elf_contains_chdrs (Elf *elf) 884 { 885 Elf_Scn *scn = NULL; 886 while ((scn = elf_nextscn (elf, scn)) != NULL) 887 { 888 GElf_Shdr shdr_mem; 889 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 890 if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0) 891 return true; 892 } 893 return false; 894 } 895 896 /* Process one ELF file. */ 897 static void 898 process_elf_file (Dwfl_Module *dwflmod, int fd) 899 { 900 GElf_Addr dwflbias; 901 Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias); 902 903 GElf_Ehdr ehdr_mem; 904 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 905 906 if (ehdr == NULL) 907 { 908 error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1)); 909 return; 910 } 911 912 Ebl *ebl = ebl_openbackend (elf); 913 if (unlikely (ebl == NULL)) 914 { 915 ebl_error: 916 error (0, errno, gettext ("cannot create EBL handle")); 917 return; 918 } 919 920 /* Determine the number of sections. */ 921 if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0)) 922 error (EXIT_FAILURE, 0, 923 gettext ("cannot determine number of sections: %s"), 924 elf_errmsg (-1)); 925 926 /* Determine the number of phdrs. */ 927 if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0)) 928 error (EXIT_FAILURE, 0, 929 gettext ("cannot determine number of program headers: %s"), 930 elf_errmsg (-1)); 931 932 /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and 933 may have applied relocation to some sections. If there are any 934 compressed sections, any pass (or libdw/libdwfl) might have 935 uncompressed them. So we need to get a fresh Elf handle on the 936 file to display those. */ 937 bool print_unchanged = ((print_section_header 938 || print_relocations 939 || dump_data_sections != NULL 940 || print_notes) 941 && (ehdr->e_type == ET_REL 942 || elf_contains_chdrs (ebl->elf))); 943 944 Elf *pure_elf = NULL; 945 Ebl *pure_ebl = ebl; 946 if (print_unchanged) 947 { 948 /* Read the file afresh. */ 949 off_t aroff = elf_getaroff (elf); 950 pure_elf = dwelf_elf_begin (fd); 951 if (aroff > 0) 952 { 953 /* Archive member. */ 954 (void) elf_rand (pure_elf, aroff); 955 Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf); 956 elf_end (pure_elf); 957 pure_elf = armem; 958 } 959 if (pure_elf == NULL) 960 { 961 error (0, 0, gettext ("cannot read ELF: %s"), elf_errmsg (-1)); 962 return; 963 } 964 pure_ebl = ebl_openbackend (pure_elf); 965 if (pure_ebl == NULL) 966 goto ebl_error; 967 } 968 969 if (print_file_header) 970 print_ehdr (ebl, ehdr); 971 if (print_section_header) 972 print_shdr (pure_ebl, ehdr); 973 if (print_program_header) 974 print_phdr (ebl, ehdr); 975 if (print_section_groups) 976 print_scngrp (ebl); 977 if (print_dynamic_table) 978 print_dynamic (ebl); 979 if (print_relocations) 980 print_relocs (pure_ebl, ehdr); 981 if (print_histogram) 982 handle_hash (ebl); 983 if (print_symbol_table) 984 print_symtab (ebl, SHT_DYNSYM); 985 if (print_version_info) 986 print_verinfo (ebl); 987 if (print_symbol_table) 988 print_symtab (ebl, SHT_SYMTAB); 989 if (print_arch) 990 print_liblist (ebl); 991 if (print_arch) 992 print_attributes (ebl, ehdr); 993 if (dump_data_sections != NULL) 994 dump_data (pure_ebl); 995 if (string_sections != NULL) 996 dump_strings (ebl); 997 if ((print_debug_sections | implicit_debug_sections) != 0) 998 print_debug (dwflmod, ebl, ehdr); 999 if (print_notes) 1000 handle_notes (pure_ebl, ehdr); 1001 if (print_string_sections) 1002 print_strings (ebl); 1003 1004 ebl_closebackend (ebl); 1005 1006 if (pure_ebl != ebl) 1007 { 1008 ebl_closebackend (pure_ebl); 1009 elf_end (pure_elf); 1010 } 1011 } 1012 1013 1014 /* Print file type. */ 1015 static void 1016 print_file_type (unsigned short int e_type) 1017 { 1018 if (likely (e_type <= ET_CORE)) 1019 { 1020 static const char *const knowntypes[] = 1021 { 1022 N_("NONE (None)"), 1023 N_("REL (Relocatable file)"), 1024 N_("EXEC (Executable file)"), 1025 N_("DYN (Shared object file)"), 1026 N_("CORE (Core file)") 1027 }; 1028 puts (gettext (knowntypes[e_type])); 1029 } 1030 else if (e_type >= ET_LOOS && e_type <= ET_HIOS) 1031 printf (gettext ("OS Specific: (%x)\n"), e_type); 1032 else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */) 1033 printf (gettext ("Processor Specific: (%x)\n"), e_type); 1034 else 1035 puts ("???"); 1036 } 1037 1038 1039 /* Print ELF header. */ 1040 static void 1041 print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr) 1042 { 1043 fputs_unlocked (gettext ("ELF Header:\n Magic: "), stdout); 1044 for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt) 1045 printf (" %02hhx", ehdr->e_ident[cnt]); 1046 1047 printf (gettext ("\n Class: %s\n"), 1048 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32" 1049 : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64" 1050 : "\?\?\?"); 1051 1052 printf (gettext (" Data: %s\n"), 1053 ehdr->e_ident[EI_DATA] == ELFDATA2LSB 1054 ? "2's complement, little endian" 1055 : ehdr->e_ident[EI_DATA] == ELFDATA2MSB 1056 ? "2's complement, big endian" : "\?\?\?"); 1057 1058 printf (gettext (" Ident Version: %hhd %s\n"), 1059 ehdr->e_ident[EI_VERSION], 1060 ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)") 1061 : "(\?\?\?)"); 1062 1063 char buf[512]; 1064 printf (gettext (" OS/ABI: %s\n"), 1065 ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf))); 1066 1067 printf (gettext (" ABI Version: %hhd\n"), 1068 ehdr->e_ident[EI_ABIVERSION]); 1069 1070 fputs_unlocked (gettext (" Type: "), stdout); 1071 print_file_type (ehdr->e_type); 1072 1073 printf (gettext (" Machine: %s\n"), ebl->name); 1074 1075 printf (gettext (" Version: %d %s\n"), 1076 ehdr->e_version, 1077 ehdr->e_version == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)"); 1078 1079 printf (gettext (" Entry point address: %#" PRIx64 "\n"), 1080 ehdr->e_entry); 1081 1082 printf (gettext (" Start of program headers: %" PRId64 " %s\n"), 1083 ehdr->e_phoff, gettext ("(bytes into file)")); 1084 1085 printf (gettext (" Start of section headers: %" PRId64 " %s\n"), 1086 ehdr->e_shoff, gettext ("(bytes into file)")); 1087 1088 printf (gettext (" Flags: %s\n"), 1089 ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf))); 1090 1091 printf (gettext (" Size of this header: %" PRId16 " %s\n"), 1092 ehdr->e_ehsize, gettext ("(bytes)")); 1093 1094 printf (gettext (" Size of program header entries: %" PRId16 " %s\n"), 1095 ehdr->e_phentsize, gettext ("(bytes)")); 1096 1097 printf (gettext (" Number of program headers entries: %" PRId16), 1098 ehdr->e_phnum); 1099 if (ehdr->e_phnum == PN_XNUM) 1100 { 1101 GElf_Shdr shdr_mem; 1102 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 1103 if (shdr != NULL) 1104 printf (gettext (" (%" PRIu32 " in [0].sh_info)"), 1105 (uint32_t) shdr->sh_info); 1106 else 1107 fputs_unlocked (gettext (" ([0] not available)"), stdout); 1108 } 1109 fputc_unlocked ('\n', stdout); 1110 1111 printf (gettext (" Size of section header entries: %" PRId16 " %s\n"), 1112 ehdr->e_shentsize, gettext ("(bytes)")); 1113 1114 printf (gettext (" Number of section headers entries: %" PRId16), 1115 ehdr->e_shnum); 1116 if (ehdr->e_shnum == 0) 1117 { 1118 GElf_Shdr shdr_mem; 1119 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 1120 if (shdr != NULL) 1121 printf (gettext (" (%" PRIu32 " in [0].sh_size)"), 1122 (uint32_t) shdr->sh_size); 1123 else 1124 fputs_unlocked (gettext (" ([0] not available)"), stdout); 1125 } 1126 fputc_unlocked ('\n', stdout); 1127 1128 if (unlikely (ehdr->e_shstrndx == SHN_XINDEX)) 1129 { 1130 GElf_Shdr shdr_mem; 1131 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem); 1132 if (shdr != NULL) 1133 /* We managed to get the zeroth section. */ 1134 snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"), 1135 (uint32_t) shdr->sh_link); 1136 else 1137 { 1138 strncpy (buf, gettext (" ([0] not available)"), sizeof (buf)); 1139 buf[sizeof (buf) - 1] = '\0'; 1140 } 1141 1142 printf (gettext (" Section header string table index: XINDEX%s\n\n"), 1143 buf); 1144 } 1145 else 1146 printf (gettext (" Section header string table index: %" PRId16 "\n\n"), 1147 ehdr->e_shstrndx); 1148 } 1149 1150 1151 static const char * 1152 get_visibility_type (int value) 1153 { 1154 switch (value) 1155 { 1156 case STV_DEFAULT: 1157 return "DEFAULT"; 1158 case STV_INTERNAL: 1159 return "INTERNAL"; 1160 case STV_HIDDEN: 1161 return "HIDDEN"; 1162 case STV_PROTECTED: 1163 return "PROTECTED"; 1164 default: 1165 return "???"; 1166 } 1167 } 1168 1169 static const char * 1170 elf_ch_type_name (unsigned int code) 1171 { 1172 if (code == 0) 1173 return "NONE"; 1174 1175 if (code == ELFCOMPRESS_ZLIB) 1176 return "ZLIB"; 1177 1178 return "UNKNOWN"; 1179 } 1180 1181 /* Print the section headers. */ 1182 static void 1183 print_shdr (Ebl *ebl, GElf_Ehdr *ehdr) 1184 { 1185 size_t cnt; 1186 size_t shstrndx; 1187 1188 if (! print_file_header) 1189 { 1190 size_t sections; 1191 if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0)) 1192 error (EXIT_FAILURE, 0, 1193 gettext ("cannot get number of sections: %s"), 1194 elf_errmsg (-1)); 1195 1196 printf (gettext ("\ 1197 There are %zd section headers, starting at offset %#" PRIx64 ":\n\ 1198 \n"), 1199 sections, ehdr->e_shoff); 1200 } 1201 1202 /* Get the section header string table index. */ 1203 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 1204 error (EXIT_FAILURE, 0, 1205 gettext ("cannot get section header string table index: %s"), 1206 elf_errmsg (-1)); 1207 1208 puts (gettext ("Section Headers:")); 1209 1210 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32) 1211 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al")); 1212 else 1213 puts (gettext ("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al")); 1214 1215 if (print_decompress) 1216 { 1217 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32) 1218 puts (gettext (" [Compression Size Al]")); 1219 else 1220 puts (gettext (" [Compression Size Al]")); 1221 } 1222 1223 for (cnt = 0; cnt < shnum; ++cnt) 1224 { 1225 Elf_Scn *scn = elf_getscn (ebl->elf, cnt); 1226 1227 if (unlikely (scn == NULL)) 1228 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"), 1229 elf_errmsg (-1)); 1230 1231 /* Get the section header. */ 1232 GElf_Shdr shdr_mem; 1233 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1234 if (unlikely (shdr == NULL)) 1235 error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"), 1236 elf_errmsg (-1)); 1237 1238 char flagbuf[20]; 1239 char *cp = flagbuf; 1240 if (shdr->sh_flags & SHF_WRITE) 1241 *cp++ = 'W'; 1242 if (shdr->sh_flags & SHF_ALLOC) 1243 *cp++ = 'A'; 1244 if (shdr->sh_flags & SHF_EXECINSTR) 1245 *cp++ = 'X'; 1246 if (shdr->sh_flags & SHF_MERGE) 1247 *cp++ = 'M'; 1248 if (shdr->sh_flags & SHF_STRINGS) 1249 *cp++ = 'S'; 1250 if (shdr->sh_flags & SHF_INFO_LINK) 1251 *cp++ = 'I'; 1252 if (shdr->sh_flags & SHF_LINK_ORDER) 1253 *cp++ = 'L'; 1254 if (shdr->sh_flags & SHF_OS_NONCONFORMING) 1255 *cp++ = 'N'; 1256 if (shdr->sh_flags & SHF_GROUP) 1257 *cp++ = 'G'; 1258 if (shdr->sh_flags & SHF_TLS) 1259 *cp++ = 'T'; 1260 if (shdr->sh_flags & SHF_COMPRESSED) 1261 *cp++ = 'C'; 1262 if (shdr->sh_flags & SHF_ORDERED) 1263 *cp++ = 'O'; 1264 if (shdr->sh_flags & SHF_EXCLUDE) 1265 *cp++ = 'E'; 1266 *cp = '\0'; 1267 1268 const char *sname; 1269 char buf[128]; 1270 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>"; 1271 printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64 1272 " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32 1273 " %2" PRId64 "\n", 1274 cnt, sname, 1275 ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)), 1276 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr, 1277 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset, 1278 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size, 1279 shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info, 1280 shdr->sh_addralign); 1281 1282 if (print_decompress) 1283 { 1284 if ((shdr->sh_flags & SHF_COMPRESSED) != 0) 1285 { 1286 GElf_Chdr chdr; 1287 if (gelf_getchdr (scn, &chdr) != NULL) 1288 printf (" [ELF %s (%" PRId32 ") %0*" PRIx64 1289 " %2" PRId64 "]\n", 1290 elf_ch_type_name (chdr.ch_type), 1291 chdr.ch_type, 1292 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, 1293 chdr.ch_size, chdr.ch_addralign); 1294 else 1295 error (0, 0, 1296 gettext ("bad compression header for section %zd: %s"), 1297 elf_ndxscn (scn), elf_errmsg (-1)); 1298 } 1299 else if (strncmp(".zdebug", sname, strlen (".zdebug")) == 0) 1300 { 1301 ssize_t size; 1302 if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0) 1303 printf (" [GNU ZLIB %0*zx ]\n", 1304 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size); 1305 else 1306 error (0, 0, 1307 gettext ("bad gnu compressed size for section %zd: %s"), 1308 elf_ndxscn (scn), elf_errmsg (-1)); 1309 } 1310 } 1311 } 1312 1313 fputc_unlocked ('\n', stdout); 1314 } 1315 1316 1317 /* Print the program header. */ 1318 static void 1319 print_phdr (Ebl *ebl, GElf_Ehdr *ehdr) 1320 { 1321 if (phnum == 0) 1322 /* No program header, this is OK in relocatable objects. */ 1323 return; 1324 1325 puts (gettext ("Program Headers:")); 1326 if (ehdr->e_ident[EI_CLASS] == ELFCLASS32) 1327 puts (gettext ("\ 1328 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align")); 1329 else 1330 puts (gettext ("\ 1331 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align")); 1332 1333 /* Process all program headers. */ 1334 bool has_relro = false; 1335 GElf_Addr relro_from = 0; 1336 GElf_Addr relro_to = 0; 1337 for (size_t cnt = 0; cnt < phnum; ++cnt) 1338 { 1339 char buf[128]; 1340 GElf_Phdr mem; 1341 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem); 1342 1343 /* If for some reason the header cannot be returned show this. */ 1344 if (unlikely (phdr == NULL)) 1345 { 1346 puts (" ???"); 1347 continue; 1348 } 1349 1350 printf (" %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64 1351 " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n", 1352 ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)), 1353 phdr->p_offset, 1354 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr, 1355 ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr, 1356 phdr->p_filesz, 1357 phdr->p_memsz, 1358 phdr->p_flags & PF_R ? 'R' : ' ', 1359 phdr->p_flags & PF_W ? 'W' : ' ', 1360 phdr->p_flags & PF_X ? 'E' : ' ', 1361 phdr->p_align); 1362 1363 if (phdr->p_type == PT_INTERP) 1364 { 1365 /* If we are sure the file offset is valid then we can show 1366 the user the name of the interpreter. We check whether 1367 there is a section at the file offset. Normally there 1368 would be a section called ".interp". But in separate 1369 .debug files it is a NOBITS section (and so doesn't match 1370 with gelf_offscn). Which probably means the offset is 1371 not valid another reason could be because the ELF file 1372 just doesn't contain any section headers, in that case 1373 just play it safe and don't display anything. */ 1374 1375 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset); 1376 GElf_Shdr shdr_mem; 1377 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1378 1379 size_t maxsize; 1380 char *filedata = elf_rawfile (ebl->elf, &maxsize); 1381 1382 if (shdr != NULL && shdr->sh_type == SHT_PROGBITS 1383 && filedata != NULL && phdr->p_offset < maxsize 1384 && phdr->p_filesz <= maxsize - phdr->p_offset 1385 && memchr (filedata + phdr->p_offset, '\0', 1386 phdr->p_filesz) != NULL) 1387 printf (gettext ("\t[Requesting program interpreter: %s]\n"), 1388 filedata + phdr->p_offset); 1389 } 1390 else if (phdr->p_type == PT_GNU_RELRO) 1391 { 1392 has_relro = true; 1393 relro_from = phdr->p_vaddr; 1394 relro_to = relro_from + phdr->p_memsz; 1395 } 1396 } 1397 1398 size_t sections; 1399 if (unlikely (elf_getshdrnum (ebl->elf, §ions) < 0)) 1400 error (EXIT_FAILURE, 0, 1401 gettext ("cannot get number of sections: %s"), 1402 elf_errmsg (-1)); 1403 1404 if (sections == 0) 1405 /* No sections in the file. Punt. */ 1406 return; 1407 1408 /* Get the section header string table index. */ 1409 size_t shstrndx; 1410 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 1411 error (EXIT_FAILURE, 0, 1412 gettext ("cannot get section header string table index")); 1413 1414 puts (gettext ("\n Section to Segment mapping:\n Segment Sections...")); 1415 1416 for (size_t cnt = 0; cnt < phnum; ++cnt) 1417 { 1418 /* Print the segment number. */ 1419 printf (" %2.2zu ", cnt); 1420 1421 GElf_Phdr phdr_mem; 1422 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem); 1423 /* This must not happen. */ 1424 if (unlikely (phdr == NULL)) 1425 error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"), 1426 elf_errmsg (-1)); 1427 1428 /* Iterate over the sections. */ 1429 bool in_relro = false; 1430 bool in_ro = false; 1431 for (size_t inner = 1; inner < shnum; ++inner) 1432 { 1433 Elf_Scn *scn = elf_getscn (ebl->elf, inner); 1434 /* This should not happen. */ 1435 if (unlikely (scn == NULL)) 1436 error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"), 1437 elf_errmsg (-1)); 1438 1439 /* Get the section header. */ 1440 GElf_Shdr shdr_mem; 1441 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1442 if (unlikely (shdr == NULL)) 1443 error (EXIT_FAILURE, 0, 1444 gettext ("cannot get section header: %s"), 1445 elf_errmsg (-1)); 1446 1447 if (shdr->sh_size > 0 1448 /* Compare allocated sections by VMA, unallocated 1449 sections by file offset. */ 1450 && (shdr->sh_flags & SHF_ALLOC 1451 ? (shdr->sh_addr >= phdr->p_vaddr 1452 && (shdr->sh_addr + shdr->sh_size 1453 <= phdr->p_vaddr + phdr->p_memsz)) 1454 : (shdr->sh_offset >= phdr->p_offset 1455 && (shdr->sh_offset + shdr->sh_size 1456 <= phdr->p_offset + phdr->p_filesz)))) 1457 { 1458 if (has_relro && !in_relro 1459 && shdr->sh_addr >= relro_from 1460 && shdr->sh_addr + shdr->sh_size <= relro_to) 1461 { 1462 fputs_unlocked (" [RELRO:", stdout); 1463 in_relro = true; 1464 } 1465 else if (has_relro && in_relro && shdr->sh_addr >= relro_to) 1466 { 1467 fputs_unlocked ("]", stdout); 1468 in_relro = false; 1469 } 1470 else if (has_relro && in_relro 1471 && shdr->sh_addr + shdr->sh_size > relro_to) 1472 fputs_unlocked ("] <RELRO:", stdout); 1473 else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0) 1474 { 1475 if (!in_ro) 1476 { 1477 fputs_unlocked (" [RO:", stdout); 1478 in_ro = true; 1479 } 1480 } 1481 else 1482 { 1483 /* Determine the segment this section is part of. */ 1484 size_t cnt2; 1485 GElf_Phdr phdr2_mem; 1486 GElf_Phdr *phdr2 = NULL; 1487 for (cnt2 = 0; cnt2 < phnum; ++cnt2) 1488 { 1489 phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem); 1490 1491 if (phdr2 != NULL && phdr2->p_type == PT_LOAD 1492 && shdr->sh_addr >= phdr2->p_vaddr 1493 && (shdr->sh_addr + shdr->sh_size 1494 <= phdr2->p_vaddr + phdr2->p_memsz)) 1495 break; 1496 } 1497 1498 if (cnt2 < phnum) 1499 { 1500 if ((phdr2->p_flags & PF_W) == 0 && !in_ro) 1501 { 1502 fputs_unlocked (" [RO:", stdout); 1503 in_ro = true; 1504 } 1505 else if ((phdr2->p_flags & PF_W) != 0 && in_ro) 1506 { 1507 fputs_unlocked ("]", stdout); 1508 in_ro = false; 1509 } 1510 } 1511 } 1512 1513 printf (" %s", 1514 elf_strptr (ebl->elf, shstrndx, shdr->sh_name)); 1515 1516 /* Signal that this sectin is only partially covered. */ 1517 if (has_relro && in_relro 1518 && shdr->sh_addr + shdr->sh_size > relro_to) 1519 { 1520 fputs_unlocked (">", stdout); 1521 in_relro = false; 1522 } 1523 } 1524 } 1525 if (in_relro || in_ro) 1526 fputs_unlocked ("]", stdout); 1527 1528 /* Finish the line. */ 1529 fputc_unlocked ('\n', stdout); 1530 } 1531 } 1532 1533 1534 static const char * 1535 section_name (Ebl *ebl, GElf_Shdr *shdr) 1536 { 1537 size_t shstrndx; 1538 if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0) 1539 return "???"; 1540 return elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "???"; 1541 } 1542 1543 1544 static void 1545 handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 1546 { 1547 /* Get the data of the section. */ 1548 Elf_Data *data = elf_getdata (scn, NULL); 1549 1550 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1551 GElf_Shdr symshdr_mem; 1552 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1553 Elf_Data *symdata = elf_getdata (symscn, NULL); 1554 1555 if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL 1556 || symdata == NULL) 1557 return; 1558 1559 /* Get the section header string table index. */ 1560 size_t shstrndx; 1561 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 1562 error (EXIT_FAILURE, 0, 1563 gettext ("cannot get section header string table index")); 1564 1565 Elf32_Word *grpref = (Elf32_Word *) data->d_buf; 1566 1567 GElf_Sym sym_mem; 1568 GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem); 1569 1570 printf ((grpref[0] & GRP_COMDAT) 1571 ? ngettext ("\ 1572 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n", 1573 "\ 1574 \nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n", 1575 data->d_size / sizeof (Elf32_Word) - 1) 1576 : ngettext ("\ 1577 \nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\ 1578 \nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n", 1579 data->d_size / sizeof (Elf32_Word) - 1), 1580 elf_ndxscn (scn), 1581 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 1582 (sym == NULL ? NULL 1583 : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)) 1584 ?: gettext ("<INVALID SYMBOL>"), 1585 data->d_size / sizeof (Elf32_Word) - 1); 1586 1587 for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt) 1588 { 1589 GElf_Shdr grpshdr_mem; 1590 GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]), 1591 &grpshdr_mem); 1592 1593 const char *str; 1594 printf (" [%2u] %s\n", 1595 grpref[cnt], 1596 grpshdr != NULL 1597 && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name)) 1598 ? str : gettext ("<INVALID SECTION>")); 1599 } 1600 } 1601 1602 1603 static void 1604 print_scngrp (Ebl *ebl) 1605 { 1606 /* Find all relocation sections and handle them. */ 1607 Elf_Scn *scn = NULL; 1608 1609 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 1610 { 1611 /* Handle the section if it is a symbol table. */ 1612 GElf_Shdr shdr_mem; 1613 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1614 1615 if (shdr != NULL && shdr->sh_type == SHT_GROUP) 1616 { 1617 if ((shdr->sh_flags & SHF_COMPRESSED) != 0) 1618 { 1619 if (elf_compress (scn, 0, 0) < 0) 1620 printf ("WARNING: %s [%zd]\n", 1621 gettext ("Couldn't uncompress section"), 1622 elf_ndxscn (scn)); 1623 shdr = gelf_getshdr (scn, &shdr_mem); 1624 if (unlikely (shdr == NULL)) 1625 error (EXIT_FAILURE, 0, 1626 gettext ("cannot get section [%zd] header: %s"), 1627 elf_ndxscn (scn), 1628 elf_errmsg (-1)); 1629 } 1630 handle_scngrp (ebl, scn, shdr); 1631 } 1632 } 1633 } 1634 1635 1636 static const struct flags 1637 { 1638 int mask; 1639 const char *str; 1640 } dt_flags[] = 1641 { 1642 { DF_ORIGIN, "ORIGIN" }, 1643 { DF_SYMBOLIC, "SYMBOLIC" }, 1644 { DF_TEXTREL, "TEXTREL" }, 1645 { DF_BIND_NOW, "BIND_NOW" }, 1646 { DF_STATIC_TLS, "STATIC_TLS" } 1647 }; 1648 static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]); 1649 1650 static const struct flags dt_flags_1[] = 1651 { 1652 { DF_1_NOW, "NOW" }, 1653 { DF_1_GLOBAL, "GLOBAL" }, 1654 { DF_1_GROUP, "GROUP" }, 1655 { DF_1_NODELETE, "NODELETE" }, 1656 { DF_1_LOADFLTR, "LOADFLTR" }, 1657 { DF_1_INITFIRST, "INITFIRST" }, 1658 { DF_1_NOOPEN, "NOOPEN" }, 1659 { DF_1_ORIGIN, "ORIGIN" }, 1660 { DF_1_DIRECT, "DIRECT" }, 1661 { DF_1_TRANS, "TRANS" }, 1662 { DF_1_INTERPOSE, "INTERPOSE" }, 1663 { DF_1_NODEFLIB, "NODEFLIB" }, 1664 { DF_1_NODUMP, "NODUMP" }, 1665 { DF_1_CONFALT, "CONFALT" }, 1666 { DF_1_ENDFILTEE, "ENDFILTEE" }, 1667 { DF_1_DISPRELDNE, "DISPRELDNE" }, 1668 { DF_1_DISPRELPND, "DISPRELPND" }, 1669 }; 1670 static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]); 1671 1672 static const struct flags dt_feature_1[] = 1673 { 1674 { DTF_1_PARINIT, "PARINIT" }, 1675 { DTF_1_CONFEXP, "CONFEXP" } 1676 }; 1677 static const int ndt_feature_1 = (sizeof (dt_feature_1) 1678 / sizeof (dt_feature_1[0])); 1679 1680 static const struct flags dt_posflag_1[] = 1681 { 1682 { DF_P1_LAZYLOAD, "LAZYLOAD" }, 1683 { DF_P1_GROUPPERM, "GROUPPERM" } 1684 }; 1685 static const int ndt_posflag_1 = (sizeof (dt_posflag_1) 1686 / sizeof (dt_posflag_1[0])); 1687 1688 1689 static void 1690 print_flags (int class, GElf_Xword d_val, const struct flags *flags, 1691 int nflags) 1692 { 1693 bool first = true; 1694 int cnt; 1695 1696 for (cnt = 0; cnt < nflags; ++cnt) 1697 if (d_val & flags[cnt].mask) 1698 { 1699 if (!first) 1700 putchar_unlocked (' '); 1701 fputs_unlocked (flags[cnt].str, stdout); 1702 d_val &= ~flags[cnt].mask; 1703 first = false; 1704 } 1705 1706 if (d_val != 0) 1707 { 1708 if (!first) 1709 putchar_unlocked (' '); 1710 printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val); 1711 } 1712 1713 putchar_unlocked ('\n'); 1714 } 1715 1716 1717 static void 1718 print_dt_flags (int class, GElf_Xword d_val) 1719 { 1720 print_flags (class, d_val, dt_flags, ndt_flags); 1721 } 1722 1723 1724 static void 1725 print_dt_flags_1 (int class, GElf_Xword d_val) 1726 { 1727 print_flags (class, d_val, dt_flags_1, ndt_flags_1); 1728 } 1729 1730 1731 static void 1732 print_dt_feature_1 (int class, GElf_Xword d_val) 1733 { 1734 print_flags (class, d_val, dt_feature_1, ndt_feature_1); 1735 } 1736 1737 1738 static void 1739 print_dt_posflag_1 (int class, GElf_Xword d_val) 1740 { 1741 print_flags (class, d_val, dt_posflag_1, ndt_posflag_1); 1742 } 1743 1744 1745 static void 1746 handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 1747 { 1748 int class = gelf_getclass (ebl->elf); 1749 GElf_Shdr glink_mem; 1750 GElf_Shdr *glink; 1751 Elf_Data *data; 1752 size_t cnt; 1753 size_t shstrndx; 1754 size_t sh_entsize; 1755 1756 /* Get the data of the section. */ 1757 data = elf_getdata (scn, NULL); 1758 if (data == NULL) 1759 return; 1760 1761 /* Get the section header string table index. */ 1762 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 1763 error (EXIT_FAILURE, 0, 1764 gettext ("cannot get section header string table index")); 1765 1766 sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT); 1767 1768 glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem); 1769 if (glink == NULL) 1770 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"), 1771 elf_ndxscn (scn)); 1772 1773 printf (ngettext ("\ 1774 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 1775 "\ 1776 \nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 1777 shdr->sh_size / sh_entsize), 1778 (unsigned long int) (shdr->sh_size / sh_entsize), 1779 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 1780 shdr->sh_offset, 1781 (int) shdr->sh_link, 1782 elf_strptr (ebl->elf, shstrndx, glink->sh_name)); 1783 fputs_unlocked (gettext (" Type Value\n"), stdout); 1784 1785 for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) 1786 { 1787 GElf_Dyn dynmem; 1788 GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem); 1789 if (dyn == NULL) 1790 break; 1791 1792 char buf[64]; 1793 printf (" %-17s ", 1794 ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf))); 1795 1796 switch (dyn->d_tag) 1797 { 1798 case DT_NULL: 1799 case DT_DEBUG: 1800 case DT_BIND_NOW: 1801 case DT_TEXTREL: 1802 /* No further output. */ 1803 fputc_unlocked ('\n', stdout); 1804 break; 1805 1806 case DT_NEEDED: 1807 printf (gettext ("Shared library: [%s]\n"), 1808 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 1809 break; 1810 1811 case DT_SONAME: 1812 printf (gettext ("Library soname: [%s]\n"), 1813 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 1814 break; 1815 1816 case DT_RPATH: 1817 printf (gettext ("Library rpath: [%s]\n"), 1818 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 1819 break; 1820 1821 case DT_RUNPATH: 1822 printf (gettext ("Library runpath: [%s]\n"), 1823 elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val)); 1824 break; 1825 1826 case DT_PLTRELSZ: 1827 case DT_RELASZ: 1828 case DT_STRSZ: 1829 case DT_RELSZ: 1830 case DT_RELAENT: 1831 case DT_SYMENT: 1832 case DT_RELENT: 1833 case DT_PLTPADSZ: 1834 case DT_MOVEENT: 1835 case DT_MOVESZ: 1836 case DT_INIT_ARRAYSZ: 1837 case DT_FINI_ARRAYSZ: 1838 case DT_SYMINSZ: 1839 case DT_SYMINENT: 1840 case DT_GNU_CONFLICTSZ: 1841 case DT_GNU_LIBLISTSZ: 1842 printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val); 1843 break; 1844 1845 case DT_VERDEFNUM: 1846 case DT_VERNEEDNUM: 1847 case DT_RELACOUNT: 1848 case DT_RELCOUNT: 1849 printf ("%" PRId64 "\n", dyn->d_un.d_val); 1850 break; 1851 1852 case DT_PLTREL:; 1853 const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val, 1854 NULL, 0); 1855 puts (tagname ?: "???"); 1856 break; 1857 1858 case DT_FLAGS: 1859 print_dt_flags (class, dyn->d_un.d_val); 1860 break; 1861 1862 case DT_FLAGS_1: 1863 print_dt_flags_1 (class, dyn->d_un.d_val); 1864 break; 1865 1866 case DT_FEATURE_1: 1867 print_dt_feature_1 (class, dyn->d_un.d_val); 1868 break; 1869 1870 case DT_POSFLAG_1: 1871 print_dt_posflag_1 (class, dyn->d_un.d_val); 1872 break; 1873 1874 default: 1875 printf ("%#0*" PRIx64 "\n", 1876 class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val); 1877 break; 1878 } 1879 } 1880 } 1881 1882 1883 /* Print the dynamic segment. */ 1884 static void 1885 print_dynamic (Ebl *ebl) 1886 { 1887 for (size_t i = 0; i < phnum; ++i) 1888 { 1889 GElf_Phdr phdr_mem; 1890 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem); 1891 1892 if (phdr != NULL && phdr->p_type == PT_DYNAMIC) 1893 { 1894 Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset); 1895 GElf_Shdr shdr_mem; 1896 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1897 if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC) 1898 handle_dynamic (ebl, scn, shdr); 1899 break; 1900 } 1901 } 1902 } 1903 1904 1905 /* Print relocations. */ 1906 static void 1907 print_relocs (Ebl *ebl, GElf_Ehdr *ehdr) 1908 { 1909 /* Find all relocation sections and handle them. */ 1910 Elf_Scn *scn = NULL; 1911 1912 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 1913 { 1914 /* Handle the section if it is a symbol table. */ 1915 GElf_Shdr shdr_mem; 1916 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1917 1918 if (likely (shdr != NULL)) 1919 { 1920 if (shdr->sh_type == SHT_REL) 1921 handle_relocs_rel (ebl, ehdr, scn, shdr); 1922 else if (shdr->sh_type == SHT_RELA) 1923 handle_relocs_rela (ebl, ehdr, scn, shdr); 1924 } 1925 } 1926 } 1927 1928 1929 /* Handle a relocation section. */ 1930 static void 1931 handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr) 1932 { 1933 int class = gelf_getclass (ebl->elf); 1934 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT); 1935 int nentries = shdr->sh_size / sh_entsize; 1936 1937 /* Get the data of the section. */ 1938 Elf_Data *data = elf_getdata (scn, NULL); 1939 if (data == NULL) 1940 return; 1941 1942 /* Get the symbol table information. */ 1943 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 1944 GElf_Shdr symshdr_mem; 1945 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 1946 Elf_Data *symdata = elf_getdata (symscn, NULL); 1947 1948 /* Get the section header of the section the relocations are for. */ 1949 GElf_Shdr destshdr_mem; 1950 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), 1951 &destshdr_mem); 1952 1953 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL)) 1954 { 1955 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"), 1956 shdr->sh_offset); 1957 return; 1958 } 1959 1960 /* Search for the optional extended section index table. */ 1961 Elf_Data *xndxdata = NULL; 1962 int xndxscnidx = elf_scnshndx (scn); 1963 if (unlikely (xndxscnidx > 0)) 1964 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL); 1965 1966 /* Get the section header string table index. */ 1967 size_t shstrndx; 1968 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 1969 error (EXIT_FAILURE, 0, 1970 gettext ("cannot get section header string table index")); 1971 1972 if (shdr->sh_info != 0) 1973 printf (ngettext ("\ 1974 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 1975 "\ 1976 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 1977 nentries), 1978 elf_ndxscn (scn), 1979 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 1980 (unsigned int) shdr->sh_info, 1981 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name), 1982 shdr->sh_offset, 1983 nentries); 1984 else 1985 /* The .rel.dyn section does not refer to a specific section but 1986 instead of section index zero. Do not try to print a section 1987 name. */ 1988 printf (ngettext ("\ 1989 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 1990 "\ 1991 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 1992 nentries), 1993 (unsigned int) elf_ndxscn (scn), 1994 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 1995 shdr->sh_offset, 1996 nentries); 1997 fputs_unlocked (class == ELFCLASS32 1998 ? gettext ("\ 1999 Offset Type Value Name\n") 2000 : gettext ("\ 2001 Offset Type Value Name\n"), 2002 stdout); 2003 2004 int is_statically_linked = 0; 2005 for (int cnt = 0; cnt < nentries; ++cnt) 2006 { 2007 GElf_Rel relmem; 2008 GElf_Rel *rel = gelf_getrel (data, cnt, &relmem); 2009 if (likely (rel != NULL)) 2010 { 2011 char buf[128]; 2012 GElf_Sym symmem; 2013 Elf32_Word xndx; 2014 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, 2015 GELF_R_SYM (rel->r_info), 2016 &symmem, &xndx); 2017 if (unlikely (sym == NULL)) 2018 { 2019 /* As a special case we have to handle relocations in static 2020 executables. This only happens for IRELATIVE relocations 2021 (so far). There is no symbol table. */ 2022 if (is_statically_linked == 0) 2023 { 2024 /* Find the program header and look for a PT_INTERP entry. */ 2025 is_statically_linked = -1; 2026 if (ehdr->e_type == ET_EXEC) 2027 { 2028 is_statically_linked = 1; 2029 2030 for (size_t inner = 0; inner < phnum; ++inner) 2031 { 2032 GElf_Phdr phdr_mem; 2033 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner, 2034 &phdr_mem); 2035 if (phdr != NULL && phdr->p_type == PT_INTERP) 2036 { 2037 is_statically_linked = -1; 2038 break; 2039 } 2040 } 2041 } 2042 } 2043 2044 if (is_statically_linked > 0 && shdr->sh_link == 0) 2045 printf ("\ 2046 %#0*" PRIx64 " %-20s %*s %s\n", 2047 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 2048 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 2049 /* Avoid the leading R_ which isn't carrying any 2050 information. */ 2051 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 2052 buf, sizeof (buf)) + 2 2053 : gettext ("<INVALID RELOC>"), 2054 class == ELFCLASS32 ? 10 : 18, "", 2055 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name)); 2056 else 2057 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n", 2058 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 2059 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 2060 /* Avoid the leading R_ which isn't carrying any 2061 information. */ 2062 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 2063 buf, sizeof (buf)) + 2 2064 : gettext ("<INVALID RELOC>"), 2065 gettext ("INVALID SYMBOL"), 2066 (long int) GELF_R_SYM (rel->r_info)); 2067 } 2068 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION) 2069 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n", 2070 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 2071 likely (ebl_reloc_type_check (ebl, 2072 GELF_R_TYPE (rel->r_info))) 2073 /* Avoid the leading R_ which isn't carrying any 2074 information. */ 2075 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 2076 buf, sizeof (buf)) + 2 2077 : gettext ("<INVALID RELOC>"), 2078 class == ELFCLASS32 ? 10 : 18, sym->st_value, 2079 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)); 2080 else 2081 { 2082 /* This is a relocation against a STT_SECTION symbol. */ 2083 GElf_Shdr secshdr_mem; 2084 GElf_Shdr *secshdr; 2085 secshdr = gelf_getshdr (elf_getscn (ebl->elf, 2086 sym->st_shndx == SHN_XINDEX 2087 ? xndx : sym->st_shndx), 2088 &secshdr_mem); 2089 2090 if (unlikely (secshdr == NULL)) 2091 printf (" %#0*" PRIx64 " %-20s <%s %ld>\n", 2092 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 2093 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 2094 /* Avoid the leading R_ which isn't carrying any 2095 information. */ 2096 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 2097 buf, sizeof (buf)) + 2 2098 : gettext ("<INVALID RELOC>"), 2099 gettext ("INVALID SECTION"), 2100 (long int) (sym->st_shndx == SHN_XINDEX 2101 ? xndx : sym->st_shndx)); 2102 else 2103 printf (" %#0*" PRIx64 " %-20s %#0*" PRIx64 " %s\n", 2104 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 2105 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 2106 /* Avoid the leading R_ which isn't carrying any 2107 information. */ 2108 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 2109 buf, sizeof (buf)) + 2 2110 : gettext ("<INVALID RELOC>"), 2111 class == ELFCLASS32 ? 10 : 18, sym->st_value, 2112 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name)); 2113 } 2114 } 2115 } 2116 } 2117 2118 2119 /* Handle a relocation section. */ 2120 static void 2121 handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr) 2122 { 2123 int class = gelf_getclass (ebl->elf); 2124 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT); 2125 int nentries = shdr->sh_size / sh_entsize; 2126 2127 /* Get the data of the section. */ 2128 Elf_Data *data = elf_getdata (scn, NULL); 2129 if (data == NULL) 2130 return; 2131 2132 /* Get the symbol table information. */ 2133 Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link); 2134 GElf_Shdr symshdr_mem; 2135 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem); 2136 Elf_Data *symdata = elf_getdata (symscn, NULL); 2137 2138 /* Get the section header of the section the relocations are for. */ 2139 GElf_Shdr destshdr_mem; 2140 GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info), 2141 &destshdr_mem); 2142 2143 if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL)) 2144 { 2145 printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"), 2146 shdr->sh_offset); 2147 return; 2148 } 2149 2150 /* Search for the optional extended section index table. */ 2151 Elf_Data *xndxdata = NULL; 2152 int xndxscnidx = elf_scnshndx (scn); 2153 if (unlikely (xndxscnidx > 0)) 2154 xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL); 2155 2156 /* Get the section header string table index. */ 2157 size_t shstrndx; 2158 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 2159 error (EXIT_FAILURE, 0, 2160 gettext ("cannot get section header string table index")); 2161 2162 if (shdr->sh_info != 0) 2163 printf (ngettext ("\ 2164 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 2165 "\ 2166 \nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 2167 nentries), 2168 elf_ndxscn (scn), 2169 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 2170 (unsigned int) shdr->sh_info, 2171 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name), 2172 shdr->sh_offset, 2173 nentries); 2174 else 2175 /* The .rela.dyn section does not refer to a specific section but 2176 instead of section index zero. Do not try to print a section 2177 name. */ 2178 printf (ngettext ("\ 2179 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 2180 "\ 2181 \nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 2182 nentries), 2183 (unsigned int) elf_ndxscn (scn), 2184 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 2185 shdr->sh_offset, 2186 nentries); 2187 fputs_unlocked (class == ELFCLASS32 2188 ? gettext ("\ 2189 Offset Type Value Addend Name\n") 2190 : gettext ("\ 2191 Offset Type Value Addend Name\n"), 2192 stdout); 2193 2194 int is_statically_linked = 0; 2195 for (int cnt = 0; cnt < nentries; ++cnt) 2196 { 2197 GElf_Rela relmem; 2198 GElf_Rela *rel = gelf_getrela (data, cnt, &relmem); 2199 if (likely (rel != NULL)) 2200 { 2201 char buf[64]; 2202 GElf_Sym symmem; 2203 Elf32_Word xndx; 2204 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, 2205 GELF_R_SYM (rel->r_info), 2206 &symmem, &xndx); 2207 2208 if (unlikely (sym == NULL)) 2209 { 2210 /* As a special case we have to handle relocations in static 2211 executables. This only happens for IRELATIVE relocations 2212 (so far). There is no symbol table. */ 2213 if (is_statically_linked == 0) 2214 { 2215 /* Find the program header and look for a PT_INTERP entry. */ 2216 is_statically_linked = -1; 2217 if (ehdr->e_type == ET_EXEC) 2218 { 2219 is_statically_linked = 1; 2220 2221 for (size_t inner = 0; inner < phnum; ++inner) 2222 { 2223 GElf_Phdr phdr_mem; 2224 GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner, 2225 &phdr_mem); 2226 if (phdr != NULL && phdr->p_type == PT_INTERP) 2227 { 2228 is_statically_linked = -1; 2229 break; 2230 } 2231 } 2232 } 2233 } 2234 2235 if (is_statically_linked > 0 && shdr->sh_link == 0) 2236 printf ("\ 2237 %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n", 2238 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 2239 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 2240 /* Avoid the leading R_ which isn't carrying any 2241 information. */ 2242 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 2243 buf, sizeof (buf)) + 2 2244 : gettext ("<INVALID RELOC>"), 2245 class == ELFCLASS32 ? 10 : 18, "", 2246 rel->r_addend, 2247 elf_strptr (ebl->elf, shstrndx, destshdr->sh_name)); 2248 else 2249 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n", 2250 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 2251 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 2252 /* Avoid the leading R_ which isn't carrying any 2253 information. */ 2254 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 2255 buf, sizeof (buf)) + 2 2256 : gettext ("<INVALID RELOC>"), 2257 gettext ("INVALID SYMBOL"), 2258 (long int) GELF_R_SYM (rel->r_info)); 2259 } 2260 else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION) 2261 printf ("\ 2262 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n", 2263 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 2264 likely (ebl_reloc_type_check (ebl, 2265 GELF_R_TYPE (rel->r_info))) 2266 /* Avoid the leading R_ which isn't carrying any 2267 information. */ 2268 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 2269 buf, sizeof (buf)) + 2 2270 : gettext ("<INVALID RELOC>"), 2271 class == ELFCLASS32 ? 10 : 18, sym->st_value, 2272 rel->r_addend, 2273 elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name)); 2274 else 2275 { 2276 /* This is a relocation against a STT_SECTION symbol. */ 2277 GElf_Shdr secshdr_mem; 2278 GElf_Shdr *secshdr; 2279 secshdr = gelf_getshdr (elf_getscn (ebl->elf, 2280 sym->st_shndx == SHN_XINDEX 2281 ? xndx : sym->st_shndx), 2282 &secshdr_mem); 2283 2284 if (unlikely (secshdr == NULL)) 2285 printf (" %#0*" PRIx64 " %-15s <%s %ld>\n", 2286 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 2287 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 2288 /* Avoid the leading R_ which isn't carrying any 2289 information. */ 2290 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 2291 buf, sizeof (buf)) + 2 2292 : gettext ("<INVALID RELOC>"), 2293 gettext ("INVALID SECTION"), 2294 (long int) (sym->st_shndx == SHN_XINDEX 2295 ? xndx : sym->st_shndx)); 2296 else 2297 printf ("\ 2298 %#0*" PRIx64 " %-15s %#0*" PRIx64 " %+6" PRId64 " %s\n", 2299 class == ELFCLASS32 ? 10 : 18, rel->r_offset, 2300 ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info)) 2301 /* Avoid the leading R_ which isn't carrying any 2302 information. */ 2303 ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info), 2304 buf, sizeof (buf)) + 2 2305 : gettext ("<INVALID RELOC>"), 2306 class == ELFCLASS32 ? 10 : 18, sym->st_value, 2307 rel->r_addend, 2308 elf_strptr (ebl->elf, shstrndx, secshdr->sh_name)); 2309 } 2310 } 2311 } 2312 } 2313 2314 2315 /* Print the program header. */ 2316 static void 2317 print_symtab (Ebl *ebl, int type) 2318 { 2319 /* Find the symbol table(s). For this we have to search through the 2320 section table. */ 2321 Elf_Scn *scn = NULL; 2322 2323 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 2324 { 2325 /* Handle the section if it is a symbol table. */ 2326 GElf_Shdr shdr_mem; 2327 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2328 2329 if (shdr != NULL && shdr->sh_type == (GElf_Word) type) 2330 { 2331 if (symbol_table_section != NULL) 2332 { 2333 /* Get the section header string table index. */ 2334 size_t shstrndx; 2335 const char *sname; 2336 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 2337 error (EXIT_FAILURE, 0, 2338 gettext ("cannot get section header string table index")); 2339 sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name); 2340 if (sname == NULL || strcmp (sname, symbol_table_section) != 0) 2341 continue; 2342 } 2343 2344 if ((shdr->sh_flags & SHF_COMPRESSED) != 0) 2345 { 2346 if (elf_compress (scn, 0, 0) < 0) 2347 printf ("WARNING: %s [%zd]\n", 2348 gettext ("Couldn't uncompress section"), 2349 elf_ndxscn (scn)); 2350 shdr = gelf_getshdr (scn, &shdr_mem); 2351 if (unlikely (shdr == NULL)) 2352 error (EXIT_FAILURE, 0, 2353 gettext ("cannot get section [%zd] header: %s"), 2354 elf_ndxscn (scn), elf_errmsg (-1)); 2355 } 2356 handle_symtab (ebl, scn, shdr); 2357 } 2358 } 2359 } 2360 2361 2362 static void 2363 handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 2364 { 2365 Elf_Data *versym_data = NULL; 2366 Elf_Data *verneed_data = NULL; 2367 Elf_Data *verdef_data = NULL; 2368 Elf_Data *xndx_data = NULL; 2369 int class = gelf_getclass (ebl->elf); 2370 Elf32_Word verneed_stridx = 0; 2371 Elf32_Word verdef_stridx = 0; 2372 2373 /* Get the data of the section. */ 2374 Elf_Data *data = elf_getdata (scn, NULL); 2375 if (data == NULL) 2376 return; 2377 2378 /* Find out whether we have other sections we might need. */ 2379 Elf_Scn *runscn = NULL; 2380 while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL) 2381 { 2382 GElf_Shdr runshdr_mem; 2383 GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem); 2384 2385 if (likely (runshdr != NULL)) 2386 { 2387 if (runshdr->sh_type == SHT_GNU_versym 2388 && runshdr->sh_link == elf_ndxscn (scn)) 2389 /* Bingo, found the version information. Now get the data. */ 2390 versym_data = elf_getdata (runscn, NULL); 2391 else if (runshdr->sh_type == SHT_GNU_verneed) 2392 { 2393 /* This is the information about the needed versions. */ 2394 verneed_data = elf_getdata (runscn, NULL); 2395 verneed_stridx = runshdr->sh_link; 2396 } 2397 else if (runshdr->sh_type == SHT_GNU_verdef) 2398 { 2399 /* This is the information about the defined versions. */ 2400 verdef_data = elf_getdata (runscn, NULL); 2401 verdef_stridx = runshdr->sh_link; 2402 } 2403 else if (runshdr->sh_type == SHT_SYMTAB_SHNDX 2404 && runshdr->sh_link == elf_ndxscn (scn)) 2405 /* Extended section index. */ 2406 xndx_data = elf_getdata (runscn, NULL); 2407 } 2408 } 2409 2410 /* Get the section header string table index. */ 2411 size_t shstrndx; 2412 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 2413 error (EXIT_FAILURE, 0, 2414 gettext ("cannot get section header string table index")); 2415 2416 GElf_Shdr glink_mem; 2417 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2418 &glink_mem); 2419 if (glink == NULL) 2420 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"), 2421 elf_ndxscn (scn)); 2422 2423 /* Now we can compute the number of entries in the section. */ 2424 unsigned int nsyms = data->d_size / (class == ELFCLASS32 2425 ? sizeof (Elf32_Sym) 2426 : sizeof (Elf64_Sym)); 2427 2428 printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n", 2429 "\nSymbol table [%2u] '%s' contains %u entries:\n", 2430 nsyms), 2431 (unsigned int) elf_ndxscn (scn), 2432 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms); 2433 printf (ngettext (" %lu local symbol String table: [%2u] '%s'\n", 2434 " %lu local symbols String table: [%2u] '%s'\n", 2435 shdr->sh_info), 2436 (unsigned long int) shdr->sh_info, 2437 (unsigned int) shdr->sh_link, 2438 elf_strptr (ebl->elf, shstrndx, glink->sh_name)); 2439 2440 fputs_unlocked (class == ELFCLASS32 2441 ? gettext ("\ 2442 Num: Value Size Type Bind Vis Ndx Name\n") 2443 : gettext ("\ 2444 Num: Value Size Type Bind Vis Ndx Name\n"), 2445 stdout); 2446 2447 for (unsigned int cnt = 0; cnt < nsyms; ++cnt) 2448 { 2449 char typebuf[64]; 2450 char bindbuf[64]; 2451 char scnbuf[64]; 2452 Elf32_Word xndx; 2453 GElf_Sym sym_mem; 2454 GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx); 2455 2456 if (unlikely (sym == NULL)) 2457 continue; 2458 2459 /* Determine the real section index. */ 2460 if (likely (sym->st_shndx != SHN_XINDEX)) 2461 xndx = sym->st_shndx; 2462 2463 printf (gettext ("\ 2464 %5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"), 2465 cnt, 2466 class == ELFCLASS32 ? 8 : 16, 2467 sym->st_value, 2468 sym->st_size, 2469 ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), 2470 typebuf, sizeof (typebuf)), 2471 ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info), 2472 bindbuf, sizeof (bindbuf)), 2473 get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)), 2474 ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf, 2475 sizeof (scnbuf), NULL, shnum), 2476 elf_strptr (ebl->elf, shdr->sh_link, sym->st_name)); 2477 2478 if (versym_data != NULL) 2479 { 2480 /* Get the version information. */ 2481 GElf_Versym versym_mem; 2482 GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem); 2483 2484 if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1)) 2485 { 2486 bool is_nobits = false; 2487 bool check_def = xndx != SHN_UNDEF; 2488 2489 if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX) 2490 { 2491 GElf_Shdr symshdr_mem; 2492 GElf_Shdr *symshdr = 2493 gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem); 2494 2495 is_nobits = (symshdr != NULL 2496 && symshdr->sh_type == SHT_NOBITS); 2497 } 2498 2499 if (is_nobits || ! check_def) 2500 { 2501 /* We must test both. */ 2502 GElf_Vernaux vernaux_mem; 2503 GElf_Vernaux *vernaux = NULL; 2504 size_t vn_offset = 0; 2505 2506 GElf_Verneed verneed_mem; 2507 GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0, 2508 &verneed_mem); 2509 while (verneed != NULL) 2510 { 2511 size_t vna_offset = vn_offset; 2512 2513 vernaux = gelf_getvernaux (verneed_data, 2514 vna_offset += verneed->vn_aux, 2515 &vernaux_mem); 2516 while (vernaux != NULL 2517 && vernaux->vna_other != *versym 2518 && vernaux->vna_next != 0) 2519 { 2520 /* Update the offset. */ 2521 vna_offset += vernaux->vna_next; 2522 2523 vernaux = (vernaux->vna_next == 0 2524 ? NULL 2525 : gelf_getvernaux (verneed_data, 2526 vna_offset, 2527 &vernaux_mem)); 2528 } 2529 2530 /* Check whether we found the version. */ 2531 if (vernaux != NULL && vernaux->vna_other == *versym) 2532 /* Found it. */ 2533 break; 2534 2535 vn_offset += verneed->vn_next; 2536 verneed = (verneed->vn_next == 0 2537 ? NULL 2538 : gelf_getverneed (verneed_data, vn_offset, 2539 &verneed_mem)); 2540 } 2541 2542 if (vernaux != NULL && vernaux->vna_other == *versym) 2543 { 2544 printf ("@%s (%u)", 2545 elf_strptr (ebl->elf, verneed_stridx, 2546 vernaux->vna_name), 2547 (unsigned int) vernaux->vna_other); 2548 check_def = 0; 2549 } 2550 else if (unlikely (! is_nobits)) 2551 error (0, 0, gettext ("bad dynamic symbol")); 2552 else 2553 check_def = 1; 2554 } 2555 2556 if (check_def && *versym != 0x8001) 2557 { 2558 /* We must test both. */ 2559 size_t vd_offset = 0; 2560 2561 GElf_Verdef verdef_mem; 2562 GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0, 2563 &verdef_mem); 2564 while (verdef != NULL) 2565 { 2566 if (verdef->vd_ndx == (*versym & 0x7fff)) 2567 /* Found the definition. */ 2568 break; 2569 2570 vd_offset += verdef->vd_next; 2571 verdef = (verdef->vd_next == 0 2572 ? NULL 2573 : gelf_getverdef (verdef_data, vd_offset, 2574 &verdef_mem)); 2575 } 2576 2577 if (verdef != NULL) 2578 { 2579 GElf_Verdaux verdaux_mem; 2580 GElf_Verdaux *verdaux 2581 = gelf_getverdaux (verdef_data, 2582 vd_offset + verdef->vd_aux, 2583 &verdaux_mem); 2584 2585 if (verdaux != NULL) 2586 printf ((*versym & 0x8000) ? "@%s" : "@@%s", 2587 elf_strptr (ebl->elf, verdef_stridx, 2588 verdaux->vda_name)); 2589 } 2590 } 2591 } 2592 } 2593 2594 putchar_unlocked ('\n'); 2595 } 2596 } 2597 2598 2599 /* Print version information. */ 2600 static void 2601 print_verinfo (Ebl *ebl) 2602 { 2603 /* Find the version information sections. For this we have to 2604 search through the section table. */ 2605 Elf_Scn *scn = NULL; 2606 2607 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 2608 { 2609 /* Handle the section if it is part of the versioning handling. */ 2610 GElf_Shdr shdr_mem; 2611 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 2612 2613 if (likely (shdr != NULL)) 2614 { 2615 if (shdr->sh_type == SHT_GNU_verneed) 2616 handle_verneed (ebl, scn, shdr); 2617 else if (shdr->sh_type == SHT_GNU_verdef) 2618 handle_verdef (ebl, scn, shdr); 2619 else if (shdr->sh_type == SHT_GNU_versym) 2620 handle_versym (ebl, scn, shdr); 2621 } 2622 } 2623 } 2624 2625 2626 static const char * 2627 get_ver_flags (unsigned int flags) 2628 { 2629 static char buf[32]; 2630 char *endp; 2631 2632 if (flags == 0) 2633 return gettext ("none"); 2634 2635 if (flags & VER_FLG_BASE) 2636 endp = stpcpy (buf, "BASE "); 2637 else 2638 endp = buf; 2639 2640 if (flags & VER_FLG_WEAK) 2641 { 2642 if (endp != buf) 2643 endp = stpcpy (endp, "| "); 2644 2645 endp = stpcpy (endp, "WEAK "); 2646 } 2647 2648 if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))) 2649 { 2650 strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp); 2651 buf[sizeof (buf) - 1] = '\0'; 2652 } 2653 2654 return buf; 2655 } 2656 2657 2658 static void 2659 handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 2660 { 2661 int class = gelf_getclass (ebl->elf); 2662 2663 /* Get the data of the section. */ 2664 Elf_Data *data = elf_getdata (scn, NULL); 2665 if (data == NULL) 2666 return; 2667 2668 /* Get the section header string table index. */ 2669 size_t shstrndx; 2670 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 2671 error (EXIT_FAILURE, 0, 2672 gettext ("cannot get section header string table index")); 2673 2674 GElf_Shdr glink_mem; 2675 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2676 &glink_mem); 2677 if (glink == NULL) 2678 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"), 2679 elf_ndxscn (scn)); 2680 2681 printf (ngettext ("\ 2682 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 2683 "\ 2684 \nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 2685 shdr->sh_info), 2686 (unsigned int) elf_ndxscn (scn), 2687 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info, 2688 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 2689 shdr->sh_offset, 2690 (unsigned int) shdr->sh_link, 2691 elf_strptr (ebl->elf, shstrndx, glink->sh_name)); 2692 2693 unsigned int offset = 0; 2694 for (int cnt = shdr->sh_info; --cnt >= 0; ) 2695 { 2696 /* Get the data at the next offset. */ 2697 GElf_Verneed needmem; 2698 GElf_Verneed *need = gelf_getverneed (data, offset, &needmem); 2699 if (unlikely (need == NULL)) 2700 break; 2701 2702 printf (gettext (" %#06x: Version: %hu File: %s Cnt: %hu\n"), 2703 offset, (unsigned short int) need->vn_version, 2704 elf_strptr (ebl->elf, shdr->sh_link, need->vn_file), 2705 (unsigned short int) need->vn_cnt); 2706 2707 unsigned int auxoffset = offset + need->vn_aux; 2708 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) 2709 { 2710 GElf_Vernaux auxmem; 2711 GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem); 2712 if (unlikely (aux == NULL)) 2713 break; 2714 2715 printf (gettext (" %#06x: Name: %s Flags: %s Version: %hu\n"), 2716 auxoffset, 2717 elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name), 2718 get_ver_flags (aux->vna_flags), 2719 (unsigned short int) aux->vna_other); 2720 2721 if (aux->vna_next == 0) 2722 break; 2723 2724 auxoffset += aux->vna_next; 2725 } 2726 2727 /* Find the next offset. */ 2728 if (need->vn_next == 0) 2729 break; 2730 2731 offset += need->vn_next; 2732 } 2733 } 2734 2735 2736 static void 2737 handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 2738 { 2739 /* Get the data of the section. */ 2740 Elf_Data *data = elf_getdata (scn, NULL); 2741 if (data == NULL) 2742 return; 2743 2744 /* Get the section header string table index. */ 2745 size_t shstrndx; 2746 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 2747 error (EXIT_FAILURE, 0, 2748 gettext ("cannot get section header string table index")); 2749 2750 GElf_Shdr glink_mem; 2751 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 2752 &glink_mem); 2753 if (glink == NULL) 2754 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"), 2755 elf_ndxscn (scn)); 2756 2757 int class = gelf_getclass (ebl->elf); 2758 printf (ngettext ("\ 2759 \nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 2760 "\ 2761 \nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 2762 shdr->sh_info), 2763 (unsigned int) elf_ndxscn (scn), 2764 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 2765 shdr->sh_info, 2766 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 2767 shdr->sh_offset, 2768 (unsigned int) shdr->sh_link, 2769 elf_strptr (ebl->elf, shstrndx, glink->sh_name)); 2770 2771 unsigned int offset = 0; 2772 for (int cnt = shdr->sh_info; --cnt >= 0; ) 2773 { 2774 /* Get the data at the next offset. */ 2775 GElf_Verdef defmem; 2776 GElf_Verdef *def = gelf_getverdef (data, offset, &defmem); 2777 if (unlikely (def == NULL)) 2778 break; 2779 2780 unsigned int auxoffset = offset + def->vd_aux; 2781 GElf_Verdaux auxmem; 2782 GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem); 2783 if (unlikely (aux == NULL)) 2784 break; 2785 2786 printf (gettext ("\ 2787 %#06x: Version: %hd Flags: %s Index: %hd Cnt: %hd Name: %s\n"), 2788 offset, def->vd_version, 2789 get_ver_flags (def->vd_flags), 2790 def->vd_ndx, 2791 def->vd_cnt, 2792 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name)); 2793 2794 auxoffset += aux->vda_next; 2795 for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2) 2796 { 2797 aux = gelf_getverdaux (data, auxoffset, &auxmem); 2798 if (unlikely (aux == NULL)) 2799 break; 2800 2801 printf (gettext (" %#06x: Parent %d: %s\n"), 2802 auxoffset, cnt2, 2803 elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name)); 2804 2805 if (aux->vda_next == 0) 2806 break; 2807 2808 auxoffset += aux->vda_next; 2809 } 2810 2811 /* Find the next offset. */ 2812 if (def->vd_next == 0) 2813 break; 2814 offset += def->vd_next; 2815 } 2816 } 2817 2818 2819 static void 2820 handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr) 2821 { 2822 int class = gelf_getclass (ebl->elf); 2823 const char **vername; 2824 const char **filename; 2825 2826 /* Get the data of the section. */ 2827 Elf_Data *data = elf_getdata (scn, NULL); 2828 if (data == NULL) 2829 return; 2830 2831 /* Get the section header string table index. */ 2832 size_t shstrndx; 2833 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 2834 error (EXIT_FAILURE, 0, 2835 gettext ("cannot get section header string table index")); 2836 2837 /* We have to find the version definition section and extract the 2838 version names. */ 2839 Elf_Scn *defscn = NULL; 2840 Elf_Scn *needscn = NULL; 2841 2842 Elf_Scn *verscn = NULL; 2843 while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL) 2844 { 2845 GElf_Shdr vershdr_mem; 2846 GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem); 2847 2848 if (likely (vershdr != NULL)) 2849 { 2850 if (vershdr->sh_type == SHT_GNU_verdef) 2851 defscn = verscn; 2852 else if (vershdr->sh_type == SHT_GNU_verneed) 2853 needscn = verscn; 2854 } 2855 } 2856 2857 size_t nvername; 2858 if (defscn != NULL || needscn != NULL) 2859 { 2860 /* We have a version information (better should have). Now get 2861 the version names. First find the maximum version number. */ 2862 nvername = 0; 2863 if (defscn != NULL) 2864 { 2865 /* Run through the version definitions and find the highest 2866 index. */ 2867 unsigned int offset = 0; 2868 Elf_Data *defdata; 2869 GElf_Shdr defshdrmem; 2870 GElf_Shdr *defshdr; 2871 2872 defdata = elf_getdata (defscn, NULL); 2873 if (unlikely (defdata == NULL)) 2874 return; 2875 2876 defshdr = gelf_getshdr (defscn, &defshdrmem); 2877 if (unlikely (defshdr == NULL)) 2878 return; 2879 2880 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt) 2881 { 2882 GElf_Verdef defmem; 2883 GElf_Verdef *def; 2884 2885 /* Get the data at the next offset. */ 2886 def = gelf_getverdef (defdata, offset, &defmem); 2887 if (unlikely (def == NULL)) 2888 break; 2889 2890 nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff)); 2891 2892 if (def->vd_next == 0) 2893 break; 2894 offset += def->vd_next; 2895 } 2896 } 2897 if (needscn != NULL) 2898 { 2899 unsigned int offset = 0; 2900 Elf_Data *needdata; 2901 GElf_Shdr needshdrmem; 2902 GElf_Shdr *needshdr; 2903 2904 needdata = elf_getdata (needscn, NULL); 2905 if (unlikely (needdata == NULL)) 2906 return; 2907 2908 needshdr = gelf_getshdr (needscn, &needshdrmem); 2909 if (unlikely (needshdr == NULL)) 2910 return; 2911 2912 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt) 2913 { 2914 GElf_Verneed needmem; 2915 GElf_Verneed *need; 2916 unsigned int auxoffset; 2917 int cnt2; 2918 2919 /* Get the data at the next offset. */ 2920 need = gelf_getverneed (needdata, offset, &needmem); 2921 if (unlikely (need == NULL)) 2922 break; 2923 2924 /* Run through the auxiliary entries. */ 2925 auxoffset = offset + need->vn_aux; 2926 for (cnt2 = need->vn_cnt; --cnt2 >= 0; ) 2927 { 2928 GElf_Vernaux auxmem; 2929 GElf_Vernaux *aux; 2930 2931 aux = gelf_getvernaux (needdata, auxoffset, &auxmem); 2932 if (unlikely (aux == NULL)) 2933 break; 2934 2935 nvername = MAX (nvername, 2936 (size_t) (aux->vna_other & 0x7fff)); 2937 2938 if (aux->vna_next == 0) 2939 break; 2940 auxoffset += aux->vna_next; 2941 } 2942 2943 if (need->vn_next == 0) 2944 break; 2945 offset += need->vn_next; 2946 } 2947 } 2948 2949 /* This is the number of versions we know about. */ 2950 ++nvername; 2951 2952 /* Allocate the array. */ 2953 vername = (const char **) alloca (nvername * sizeof (const char *)); 2954 memset(vername, 0, nvername * sizeof (const char *)); 2955 filename = (const char **) alloca (nvername * sizeof (const char *)); 2956 memset(filename, 0, nvername * sizeof (const char *)); 2957 2958 /* Run through the data structures again and collect the strings. */ 2959 if (defscn != NULL) 2960 { 2961 /* Run through the version definitions and find the highest 2962 index. */ 2963 unsigned int offset = 0; 2964 Elf_Data *defdata; 2965 GElf_Shdr defshdrmem; 2966 GElf_Shdr *defshdr; 2967 2968 defdata = elf_getdata (defscn, NULL); 2969 if (unlikely (defdata == NULL)) 2970 return; 2971 2972 defshdr = gelf_getshdr (defscn, &defshdrmem); 2973 if (unlikely (defshdr == NULL)) 2974 return; 2975 2976 for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt) 2977 { 2978 2979 /* Get the data at the next offset. */ 2980 GElf_Verdef defmem; 2981 GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem); 2982 if (unlikely (def == NULL)) 2983 break; 2984 2985 GElf_Verdaux auxmem; 2986 GElf_Verdaux *aux = gelf_getverdaux (defdata, 2987 offset + def->vd_aux, 2988 &auxmem); 2989 if (unlikely (aux == NULL)) 2990 break; 2991 2992 vername[def->vd_ndx & 0x7fff] 2993 = elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name); 2994 filename[def->vd_ndx & 0x7fff] = NULL; 2995 2996 if (def->vd_next == 0) 2997 break; 2998 offset += def->vd_next; 2999 } 3000 } 3001 if (needscn != NULL) 3002 { 3003 unsigned int offset = 0; 3004 3005 Elf_Data *needdata = elf_getdata (needscn, NULL); 3006 GElf_Shdr needshdrmem; 3007 GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem); 3008 if (unlikely (needdata == NULL || needshdr == NULL)) 3009 return; 3010 3011 for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt) 3012 { 3013 /* Get the data at the next offset. */ 3014 GElf_Verneed needmem; 3015 GElf_Verneed *need = gelf_getverneed (needdata, offset, 3016 &needmem); 3017 if (unlikely (need == NULL)) 3018 break; 3019 3020 /* Run through the auxiliary entries. */ 3021 unsigned int auxoffset = offset + need->vn_aux; 3022 for (int cnt2 = need->vn_cnt; --cnt2 >= 0; ) 3023 { 3024 GElf_Vernaux auxmem; 3025 GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset, 3026 &auxmem); 3027 if (unlikely (aux == NULL)) 3028 break; 3029 3030 vername[aux->vna_other & 0x7fff] 3031 = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name); 3032 filename[aux->vna_other & 0x7fff] 3033 = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file); 3034 3035 if (aux->vna_next == 0) 3036 break; 3037 auxoffset += aux->vna_next; 3038 } 3039 3040 if (need->vn_next == 0) 3041 break; 3042 offset += need->vn_next; 3043 } 3044 } 3045 } 3046 else 3047 { 3048 vername = NULL; 3049 nvername = 1; 3050 filename = NULL; 3051 } 3052 3053 GElf_Shdr glink_mem; 3054 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), 3055 &glink_mem); 3056 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT); 3057 if (glink == NULL) 3058 error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"), 3059 elf_ndxscn (scn)); 3060 3061 /* Print the header. */ 3062 printf (ngettext ("\ 3063 \nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'", 3064 "\ 3065 \nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'", 3066 shdr->sh_size / sh_entsize), 3067 (unsigned int) elf_ndxscn (scn), 3068 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 3069 (int) (shdr->sh_size / sh_entsize), 3070 class == ELFCLASS32 ? 10 : 18, shdr->sh_addr, 3071 shdr->sh_offset, 3072 (unsigned int) shdr->sh_link, 3073 elf_strptr (ebl->elf, shstrndx, glink->sh_name)); 3074 3075 /* Now we can finally look at the actual contents of this section. */ 3076 for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt) 3077 { 3078 if (cnt % 2 == 0) 3079 printf ("\n %4d:", cnt); 3080 3081 GElf_Versym symmem; 3082 GElf_Versym *sym = gelf_getversym (data, cnt, &symmem); 3083 if (sym == NULL) 3084 break; 3085 3086 switch (*sym) 3087 { 3088 ssize_t n; 3089 case 0: 3090 fputs_unlocked (gettext (" 0 *local* "), 3091 stdout); 3092 break; 3093 3094 case 1: 3095 fputs_unlocked (gettext (" 1 *global* "), 3096 stdout); 3097 break; 3098 3099 default: 3100 n = printf ("%4d%c%s", 3101 *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ', 3102 (vername != NULL 3103 && (unsigned int) (*sym & 0x7fff) < nvername) 3104 ? vername[*sym & 0x7fff] : "???"); 3105 if ((unsigned int) (*sym & 0x7fff) < nvername 3106 && filename != NULL && filename[*sym & 0x7fff] != NULL) 3107 n += printf ("(%s)", filename[*sym & 0x7fff]); 3108 printf ("%*s", MAX (0, 33 - (int) n), " "); 3109 break; 3110 } 3111 } 3112 putchar_unlocked ('\n'); 3113 } 3114 3115 3116 static void 3117 print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx, 3118 uint_fast32_t maxlength, Elf32_Word nbucket, 3119 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr) 3120 { 3121 uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t)); 3122 3123 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) 3124 ++counts[lengths[cnt]]; 3125 3126 GElf_Shdr glink_mem; 3127 GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, 3128 shdr->sh_link), 3129 &glink_mem); 3130 if (glink == NULL) 3131 { 3132 error (0, 0, gettext ("invalid sh_link value in section %zu"), 3133 elf_ndxscn (scn)); 3134 return; 3135 } 3136 3137 printf (ngettext ("\ 3138 \nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 3139 "\ 3140 \nHistogram for bucket list length in section [%2u] '%s' (total of %d buckets):\n Addr: %#0*" PRIx64 " Offset: %#08" PRIx64 " Link to section: [%2u] '%s'\n", 3141 nbucket), 3142 (unsigned int) elf_ndxscn (scn), 3143 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 3144 (int) nbucket, 3145 gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18, 3146 shdr->sh_addr, 3147 shdr->sh_offset, 3148 (unsigned int) shdr->sh_link, 3149 elf_strptr (ebl->elf, shstrndx, glink->sh_name)); 3150 3151 if (extrastr != NULL) 3152 fputs (extrastr, stdout); 3153 3154 if (likely (nbucket > 0)) 3155 { 3156 uint64_t success = 0; 3157 3158 /* xgettext:no-c-format */ 3159 fputs_unlocked (gettext ("\ 3160 Length Number % of total Coverage\n"), stdout); 3161 printf (gettext (" 0 %6" PRIu32 " %5.1f%%\n"), 3162 counts[0], (counts[0] * 100.0) / nbucket); 3163 3164 uint64_t nzero_counts = 0; 3165 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt) 3166 { 3167 nzero_counts += counts[cnt] * cnt; 3168 printf (gettext ("\ 3169 %7d %6" PRIu32 " %5.1f%% %5.1f%%\n"), 3170 (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket, 3171 (nzero_counts * 100.0) / nsyms); 3172 } 3173 3174 Elf32_Word acc = 0; 3175 for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt) 3176 { 3177 acc += cnt; 3178 success += counts[cnt] * acc; 3179 } 3180 3181 printf (gettext ("\ 3182 Average number of tests: successful lookup: %f\n\ 3183 unsuccessful lookup: %f\n"), 3184 (double) success / (double) nzero_counts, 3185 (double) nzero_counts / (double) nbucket); 3186 } 3187 3188 free (counts); 3189 } 3190 3191 3192 /* This function handles the traditional System V-style hash table format. */ 3193 static void 3194 handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx) 3195 { 3196 Elf_Data *data = elf_getdata (scn, NULL); 3197 if (unlikely (data == NULL)) 3198 { 3199 error (0, 0, gettext ("cannot get data for section %d: %s"), 3200 (int) elf_ndxscn (scn), elf_errmsg (-1)); 3201 return; 3202 } 3203 3204 if (unlikely (data->d_size < 2 * sizeof (Elf32_Word))) 3205 { 3206 invalid_data: 3207 error (0, 0, gettext ("invalid data in sysv.hash section %d"), 3208 (int) elf_ndxscn (scn)); 3209 return; 3210 } 3211 3212 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; 3213 Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1]; 3214 3215 uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word); 3216 if (used_buf > data->d_size) 3217 goto invalid_data; 3218 3219 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2]; 3220 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket]; 3221 3222 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); 3223 3224 uint_fast32_t maxlength = 0; 3225 uint_fast32_t nsyms = 0; 3226 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) 3227 { 3228 Elf32_Word inner = bucket[cnt]; 3229 Elf32_Word chain_len = 0; 3230 while (inner > 0 && inner < nchain) 3231 { 3232 ++nsyms; 3233 ++chain_len; 3234 if (chain_len > nchain) 3235 { 3236 error (0, 0, gettext ("invalid chain in sysv.hash section %d"), 3237 (int) elf_ndxscn (scn)); 3238 free (lengths); 3239 return; 3240 } 3241 if (maxlength < ++lengths[cnt]) 3242 ++maxlength; 3243 3244 inner = chain[inner]; 3245 } 3246 } 3247 3248 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms, 3249 lengths, NULL); 3250 3251 free (lengths); 3252 } 3253 3254 3255 /* This function handles the incorrect, System V-style hash table 3256 format some 64-bit architectures use. */ 3257 static void 3258 handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx) 3259 { 3260 Elf_Data *data = elf_getdata (scn, NULL); 3261 if (unlikely (data == NULL)) 3262 { 3263 error (0, 0, gettext ("cannot get data for section %d: %s"), 3264 (int) elf_ndxscn (scn), elf_errmsg (-1)); 3265 return; 3266 } 3267 3268 if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword))) 3269 { 3270 invalid_data: 3271 error (0, 0, gettext ("invalid data in sysv.hash64 section %d"), 3272 (int) elf_ndxscn (scn)); 3273 return; 3274 } 3275 3276 Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0]; 3277 Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1]; 3278 3279 uint64_t maxwords = data->d_size / sizeof (Elf64_Xword); 3280 if (maxwords < 2 3281 || maxwords - 2 < nbucket 3282 || maxwords - 2 - nbucket < nchain) 3283 goto invalid_data; 3284 3285 Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2]; 3286 Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket]; 3287 3288 uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); 3289 3290 uint_fast32_t maxlength = 0; 3291 uint_fast32_t nsyms = 0; 3292 for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt) 3293 { 3294 Elf64_Xword inner = bucket[cnt]; 3295 Elf64_Xword chain_len = 0; 3296 while (inner > 0 && inner < nchain) 3297 { 3298 ++nsyms; 3299 ++chain_len; 3300 if (chain_len > nchain) 3301 { 3302 error (0, 0, gettext ("invalid chain in sysv.hash64 section %d"), 3303 (int) elf_ndxscn (scn)); 3304 free (lengths); 3305 return; 3306 } 3307 if (maxlength < ++lengths[cnt]) 3308 ++maxlength; 3309 3310 inner = chain[inner]; 3311 } 3312 } 3313 3314 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms, 3315 lengths, NULL); 3316 3317 free (lengths); 3318 } 3319 3320 3321 /* This function handles the GNU-style hash table format. */ 3322 static void 3323 handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx) 3324 { 3325 uint32_t *lengths = NULL; 3326 Elf_Data *data = elf_getdata (scn, NULL); 3327 if (unlikely (data == NULL)) 3328 { 3329 error (0, 0, gettext ("cannot get data for section %d: %s"), 3330 (int) elf_ndxscn (scn), elf_errmsg (-1)); 3331 return; 3332 } 3333 3334 if (unlikely (data->d_size < 4 * sizeof (Elf32_Word))) 3335 { 3336 invalid_data: 3337 free (lengths); 3338 error (0, 0, gettext ("invalid data in gnu.hash section %d"), 3339 (int) elf_ndxscn (scn)); 3340 return; 3341 } 3342 3343 Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0]; 3344 Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1]; 3345 3346 /* Next comes the size of the bitmap. It's measured in words for 3347 the architecture. It's 32 bits for 32 bit archs, and 64 bits for 3348 64 bit archs. There is always a bloom filter present, so zero is 3349 an invalid value. */ 3350 Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2]; 3351 if (gelf_getclass (ebl->elf) == ELFCLASS64) 3352 bitmask_words *= 2; 3353 3354 if (bitmask_words == 0) 3355 goto invalid_data; 3356 3357 Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3]; 3358 3359 /* Is there still room for the sym chain? 3360 Use uint64_t calculation to prevent 32bit overlow. */ 3361 uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word); 3362 uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word); 3363 if (used_buf > data->d_size) 3364 goto invalid_data; 3365 3366 lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t)); 3367 3368 Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4]; 3369 Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words]; 3370 Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words 3371 + nbucket]; 3372 3373 /* Compute distribution of chain lengths. */ 3374 uint_fast32_t maxlength = 0; 3375 uint_fast32_t nsyms = 0; 3376 for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt) 3377 if (bucket[cnt] != 0) 3378 { 3379 Elf32_Word inner = bucket[cnt] - symbias; 3380 do 3381 { 3382 ++nsyms; 3383 if (maxlength < ++lengths[cnt]) 3384 ++maxlength; 3385 if (inner >= max_nsyms) 3386 goto invalid_data; 3387 } 3388 while ((chain[inner++] & 1) == 0); 3389 } 3390 3391 /* Count bits in bitmask. */ 3392 uint_fast32_t nbits = 0; 3393 for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt) 3394 { 3395 uint_fast32_t word = bitmask[cnt]; 3396 3397 word = (word & 0x55555555) + ((word >> 1) & 0x55555555); 3398 word = (word & 0x33333333) + ((word >> 2) & 0x33333333); 3399 word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f); 3400 word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff); 3401 nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff); 3402 } 3403 3404 char *str; 3405 if (unlikely (asprintf (&str, gettext ("\ 3406 Symbol Bias: %u\n\ 3407 Bitmask Size: %zu bytes %" PRIuFAST32 "%% bits set 2nd hash shift: %u\n"), 3408 (unsigned int) symbias, 3409 bitmask_words * sizeof (Elf32_Word), 3410 ((nbits * 100 + 50) 3411 / (uint_fast32_t) (bitmask_words 3412 * sizeof (Elf32_Word) * 8)), 3413 (unsigned int) shift) == -1)) 3414 error (EXIT_FAILURE, 0, gettext ("memory exhausted")); 3415 3416 print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms, 3417 lengths, str); 3418 3419 free (str); 3420 free (lengths); 3421 } 3422 3423 3424 /* Find the symbol table(s). For this we have to search through the 3425 section table. */ 3426 static void 3427 handle_hash (Ebl *ebl) 3428 { 3429 /* Get the section header string table index. */ 3430 size_t shstrndx; 3431 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 3432 error (EXIT_FAILURE, 0, 3433 gettext ("cannot get section header string table index")); 3434 3435 Elf_Scn *scn = NULL; 3436 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 3437 { 3438 /* Handle the section if it is a symbol table. */ 3439 GElf_Shdr shdr_mem; 3440 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 3441 3442 if (likely (shdr != NULL)) 3443 { 3444 if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH) 3445 && (shdr->sh_flags & SHF_COMPRESSED) != 0) 3446 { 3447 if (elf_compress (scn, 0, 0) < 0) 3448 printf ("WARNING: %s [%zd]\n", 3449 gettext ("Couldn't uncompress section"), 3450 elf_ndxscn (scn)); 3451 shdr = gelf_getshdr (scn, &shdr_mem); 3452 if (unlikely (shdr == NULL)) 3453 error (EXIT_FAILURE, 0, 3454 gettext ("cannot get section [%zd] header: %s"), 3455 elf_ndxscn (scn), elf_errmsg (-1)); 3456 } 3457 3458 if (shdr->sh_type == SHT_HASH) 3459 { 3460 if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword)) 3461 handle_sysv_hash64 (ebl, scn, shdr, shstrndx); 3462 else 3463 handle_sysv_hash (ebl, scn, shdr, shstrndx); 3464 } 3465 else if (shdr->sh_type == SHT_GNU_HASH) 3466 handle_gnu_hash (ebl, scn, shdr, shstrndx); 3467 } 3468 } 3469 } 3470 3471 3472 static void 3473 print_liblist (Ebl *ebl) 3474 { 3475 /* Find the library list sections. For this we have to search 3476 through the section table. */ 3477 Elf_Scn *scn = NULL; 3478 3479 /* Get the section header string table index. */ 3480 size_t shstrndx; 3481 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 3482 error (EXIT_FAILURE, 0, 3483 gettext ("cannot get section header string table index")); 3484 3485 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 3486 { 3487 GElf_Shdr shdr_mem; 3488 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 3489 3490 if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST) 3491 { 3492 size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT); 3493 int nentries = shdr->sh_size / sh_entsize; 3494 printf (ngettext ("\ 3495 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n", 3496 "\ 3497 \nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n", 3498 nentries), 3499 elf_ndxscn (scn), 3500 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 3501 shdr->sh_offset, 3502 nentries); 3503 3504 Elf_Data *data = elf_getdata (scn, NULL); 3505 if (data == NULL) 3506 return; 3507 3508 puts (gettext ("\ 3509 Library Time Stamp Checksum Version Flags")); 3510 3511 for (int cnt = 0; cnt < nentries; ++cnt) 3512 { 3513 GElf_Lib lib_mem; 3514 GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem); 3515 if (unlikely (lib == NULL)) 3516 continue; 3517 3518 time_t t = (time_t) lib->l_time_stamp; 3519 struct tm *tm = gmtime (&t); 3520 if (unlikely (tm == NULL)) 3521 continue; 3522 3523 printf (" [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n", 3524 cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name), 3525 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 3526 tm->tm_hour, tm->tm_min, tm->tm_sec, 3527 (unsigned int) lib->l_checksum, 3528 (unsigned int) lib->l_version, 3529 (unsigned int) lib->l_flags); 3530 } 3531 } 3532 } 3533 } 3534 3535 static void 3536 print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr) 3537 { 3538 /* Find the object attributes sections. For this we have to search 3539 through the section table. */ 3540 Elf_Scn *scn = NULL; 3541 3542 /* Get the section header string table index. */ 3543 size_t shstrndx; 3544 if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)) 3545 error (EXIT_FAILURE, 0, 3546 gettext ("cannot get section header string table index")); 3547 3548 while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 3549 { 3550 GElf_Shdr shdr_mem; 3551 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 3552 3553 if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES 3554 && (shdr->sh_type != SHT_ARM_ATTRIBUTES 3555 || ehdr->e_machine != EM_ARM))) 3556 continue; 3557 3558 printf (gettext ("\ 3559 \nObject attributes section [%2zu] '%s' of %" PRIu64 3560 " bytes at offset %#0" PRIx64 ":\n"), 3561 elf_ndxscn (scn), 3562 elf_strptr (ebl->elf, shstrndx, shdr->sh_name), 3563 shdr->sh_size, shdr->sh_offset); 3564 3565 Elf_Data *data = elf_rawdata (scn, NULL); 3566 if (unlikely (data == NULL || data->d_size == 0)) 3567 return; 3568 3569 const unsigned char *p = data->d_buf; 3570 3571 /* There is only one 'version', A. */ 3572 if (unlikely (*p++ != 'A')) 3573 return; 3574 3575 fputs_unlocked (gettext (" Owner Size\n"), stdout); 3576 3577 inline size_t left (void) 3578 { 3579 return (const unsigned char *) data->d_buf + data->d_size - p; 3580 } 3581 3582 /* Loop over the sections. */ 3583 while (left () >= 4) 3584 { 3585 /* Section length. */ 3586 uint32_t len; 3587 memcpy (&len, p, sizeof len); 3588 3589 if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) 3590 CONVERT (len); 3591 3592 if (unlikely (len > left ())) 3593 break; 3594 3595 /* Section vendor name. */ 3596 const unsigned char *name = p + sizeof len; 3597 p += len; 3598 3599 unsigned const char *q = memchr (name, '\0', len); 3600 if (unlikely (q == NULL)) 3601 break; 3602 ++q; 3603 3604 printf (gettext (" %-13s %4" PRIu32 "\n"), name, len); 3605 3606 bool gnu_vendor = (q - name == sizeof "gnu" 3607 && !memcmp (name, "gnu", sizeof "gnu")); 3608 3609 /* Loop over subsections. */ 3610 if (shdr->sh_type != SHT_GNU_ATTRIBUTES 3611 || gnu_vendor) 3612 while (q < p) 3613 { 3614 const unsigned char *const sub = q; 3615 3616 unsigned int subsection_tag; 3617 get_uleb128 (subsection_tag, q, p); 3618 if (unlikely (q >= p)) 3619 break; 3620 3621 uint32_t subsection_len; 3622 if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len)) 3623 break; 3624 3625 memcpy (&subsection_len, q, sizeof subsection_len); 3626 3627 if (MY_ELFDATA != ehdr->e_ident[EI_DATA]) 3628 CONVERT (subsection_len); 3629 3630 /* Don't overflow, ptrdiff_t might be 32bits, but signed. */ 3631 if (unlikely (subsection_len == 0 3632 || subsection_len >= (uint32_t) PTRDIFF_MAX 3633 || p - sub < (ptrdiff_t) subsection_len)) 3634 break; 3635 3636 const unsigned char *r = q + sizeof subsection_len; 3637 q = sub + subsection_len; 3638 3639 switch (subsection_tag) 3640 { 3641 default: 3642 /* Unknown subsection, print and skip. */ 3643 printf (gettext (" %-4u %12" PRIu32 "\n"), 3644 subsection_tag, subsection_len); 3645 break; 3646 3647 case 1: /* Tag_File */ 3648 printf (gettext (" File: %11" PRIu32 "\n"), 3649 subsection_len); 3650 3651 while (r < q) 3652 { 3653 unsigned int tag; 3654 get_uleb128 (tag, r, q); 3655 if (unlikely (r >= q)) 3656 break; 3657 3658 /* GNU style tags have either a uleb128 value, 3659 when lowest bit is not set, or a string 3660 when the lowest bit is set. 3661 "compatibility" (32) is special. It has 3662 both a string and a uleb128 value. For 3663 non-gnu we assume 6 till 31 only take ints. 3664 XXX see arm backend, do we need a separate 3665 hook? */ 3666 uint64_t value = 0; 3667 const char *string = NULL; 3668 if (tag == 32 || (tag & 1) == 0 3669 || (! gnu_vendor && (tag > 5 && tag < 32))) 3670 { 3671 get_uleb128 (value, r, q); 3672 if (r > q) 3673 break; 3674 } 3675 if (tag == 32 3676 || ((tag & 1) != 0 3677 && (