1 /* Print the strings of printable characters in files. 2 Copyright (C) 2005-2010, 2012, 2014 Red Hat, Inc. 3 This file is part of elfutils. 4 Written by Ulrich Drepper <drepper (at) redhat.com>, 2005. 5 6 This file is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 elfutils is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 19 #ifdef HAVE_CONFIG_H 20 # include <config.h> 21 #endif 22 23 #include <argp.h> 24 #include <assert.h> 25 #include <ctype.h> 26 #include <endian.h> 27 #include <errno.h> 28 #include <error.h> 29 #include <fcntl.h> 30 #include <gelf.h> 31 #include <inttypes.h> 32 #include <libintl.h> 33 #include <locale.h> 34 #include <stdbool.h> 35 #include <stdio.h> 36 #include <stdio_ext.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <unistd.h> 40 #include <sys/mman.h> 41 #include <sys/param.h> 42 #include <sys/stat.h> 43 44 #include <system.h> 45 46 #ifndef MAP_POPULATE 47 # define MAP_POPULATE 0 48 #endif 49 50 51 /* Prototypes of local functions. */ 52 static int read_fd (int fd, const char *fname, off_t fdlen); 53 static int read_elf (Elf *elf, int fd, const char *fname, off_t fdlen); 54 55 56 /* Name and version of program. */ 57 static void print_version (FILE *stream, struct argp_state *state); 58 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; 59 60 /* Bug report address. */ 61 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; 62 63 /* Definitions of arguments for argp functions. */ 64 static const struct argp_option options[] = 65 { 66 { NULL, 0, NULL, 0, N_("Output Selection:"), 0 }, 67 { "all", 'a', NULL, 0, N_("Scan entire file, not only loaded sections"), 0 }, 68 { "bytes", 'n', "MIN-LEN", 0, 69 N_("Only NUL-terminated sequences of MIN-LEN characters or more are printed"), 0 }, 70 { "encoding", 'e', "SELECTOR", 0, N_("\ 71 Select character size and endianess: s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit"), 72 0}, 73 { "print-file-name", 'f', NULL, 0, 74 N_("Print name of the file before each string."), 0 }, 75 { "radix", 't', "{o,d,x}", 0, 76 N_("Print location of the string in base 8, 10, or 16 respectively."), 0 }, 77 { NULL, 'o', NULL, 0, N_("Alias for --radix=o"), 0 }, 78 79 { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 }, 80 { NULL, 0, NULL, 0, NULL, 0 } 81 }; 82 83 /* Short description of program. */ 84 static const char doc[] = N_("\ 85 Print the strings of printable characters in files."); 86 87 /* Strings for arguments in help texts. */ 88 static const char args_doc[] = N_("[FILE...]"); 89 90 /* Prototype for option handler. */ 91 static error_t parse_opt (int key, char *arg, struct argp_state *state); 92 93 /* Data structure to communicate with argp functions. */ 94 static struct argp argp = 95 { 96 options, parse_opt, args_doc, doc, NULL, NULL, NULL 97 }; 98 99 100 /* Global variables. */ 101 102 /* True if whole file and not only loaded sections are looked at. */ 103 static bool entire_file; 104 105 /* Minimum length of any sequence reported. */ 106 static size_t min_len = 4; 107 108 /* Number of bytes per character. */ 109 static size_t bytes_per_char = 1; 110 111 /* Minimum length of any sequence reported in bytes. */ 112 static size_t min_len_bytes; 113 114 /* True if multibyte characters are in big-endian order. */ 115 static bool big_endian; 116 117 /* True unless 7-bit ASCII are expected. */ 118 static bool char_7bit; 119 120 /* True if file names should be printed before strings. */ 121 static bool print_file_name; 122 123 /* Radix for printed numbers. */ 124 static enum 125 { 126 radix_none = 0, 127 radix_decimal, 128 radix_hex, 129 radix_octal 130 } radix = radix_none; 131 132 133 /* Page size in use. */ 134 static size_t ps; 135 136 137 /* Mapped parts of the ELF file. */ 138 static unsigned char *elfmap; 139 static unsigned char *elfmap_base; 140 static size_t elfmap_size; 141 static off_t elfmap_off; 142 143 144 int 145 main (int argc, char *argv[]) 146 { 147 /* We use no threads. */ 148 __fsetlocking (stdin, FSETLOCKING_BYCALLER); 149 __fsetlocking (stdout, FSETLOCKING_BYCALLER); 150 151 /* Set locale. */ 152 (void) setlocale (LC_ALL, ""); 153 154 /* Make sure the message catalog can be found. */ 155 (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); 156 157 /* Initialize the message catalog. */ 158 (void) textdomain (PACKAGE_TARNAME); 159 160 /* Parse and process arguments. */ 161 int remaining; 162 (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL); 163 164 /* Tell the library which version we are expecting. */ 165 elf_version (EV_CURRENT); 166 167 /* Determine the page size. We will likely need it a couple of times. */ 168 ps = sysconf (_SC_PAGESIZE); 169 170 struct stat st; 171 int result = 0; 172 if (remaining == argc) 173 /* We read from standard input. This we cannot do for a 174 structured file. */ 175 result = read_fd (STDIN_FILENO, 176 print_file_name ? "{standard input}" : NULL, 177 (fstat (STDIN_FILENO, &st) == 0 && S_ISREG (st.st_mode)) 178 ? st.st_size : INT64_C (0x7fffffffffffffff)); 179 else 180 do 181 { 182 int fd = (strcmp (argv[remaining], "-") == 0 183 ? STDIN_FILENO : open (argv[remaining], O_RDONLY)); 184 if (unlikely (fd == -1)) 185 { 186 error (0, errno, gettext ("cannot open '%s'"), argv[remaining]); 187 result = 1; 188 } 189 else 190 { 191 const char *fname = print_file_name ? argv[remaining] : NULL; 192 int fstat_fail = fstat (fd, &st); 193 off_t fdlen = (fstat_fail 194 ? INT64_C (0x7fffffffffffffff) : st.st_size); 195 if (fdlen > (off_t) min_len_bytes) 196 { 197 Elf *elf = NULL; 198 if (entire_file 199 || fstat_fail 200 || !S_ISREG (st.st_mode) 201 || (elf = elf_begin (fd, ELF_C_READ, NULL)) == NULL 202 || elf_kind (elf) != ELF_K_ELF) 203 result |= read_fd (fd, fname, fdlen); 204 else 205 result |= read_elf (elf, fd, fname, fdlen); 206 207 /* This call will succeed even if ELF is NULL. */ 208 elf_end (elf); 209 } 210 211 if (strcmp (argv[remaining], "-") != 0) 212 close (fd); 213 } 214 215 if (elfmap != NULL && elfmap != MAP_FAILED) 216 munmap (elfmap, elfmap_size); 217 elfmap = NULL; 218 } 219 while (++remaining < argc); 220 221 return result; 222 } 223 224 225 /* Print the version information. */ 226 static void 227 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 228 { 229 fprintf (stream, "strings (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 230 fprintf (stream, gettext ("\ 231 Copyright (C) %s Red Hat, Inc.\n\ 232 This is free software; see the source for copying conditions. There is NO\n\ 233 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 234 "), "2012"); 235 fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 236 } 237 238 239 /* Handle program arguments. */ 240 static error_t 241 parse_opt (int key, char *arg, 242 struct argp_state *state __attribute__ ((unused))) 243 { 244 switch (key) 245 { 246 case 'a': 247 entire_file = true; 248 break; 249 250 case 'e': 251 /* We expect a string of one character. */ 252 switch (arg[1] != '\0' ? '\0' : arg[0]) 253 { 254 case 's': 255 case 'S': 256 char_7bit = arg[0] == 's'; 257 bytes_per_char = 1; 258 break; 259 260 case 'b': 261 case 'B': 262 big_endian = true; 263 /* FALLTHROUGH */ 264 265 case 'l': 266 case 'L': 267 bytes_per_char = isupper (arg[0]) ? 4 : 2; 268 break; 269 270 default: 271 error (0, 0, gettext ("invalid value '%s' for %s parameter"), 272 arg, "-e"); 273 argp_help (&argp, stderr, ARGP_HELP_SEE, "strings"); 274 return ARGP_ERR_UNKNOWN; 275 } 276 break; 277 278 case 'f': 279 print_file_name = true; 280 break; 281 282 case 'n': 283 min_len = atoi (arg); 284 break; 285 286 case 'o': 287 goto octfmt; 288 289 case 't': 290 switch (arg[0]) 291 { 292 case 'd': 293 radix = radix_decimal; 294 break; 295 296 case 'o': 297 octfmt: 298 radix = radix_octal; 299 break; 300 301 case 'x': 302 radix = radix_hex; 303 break; 304 305 default: 306 error (0, 0, gettext ("invalid value '%s' for %s parameter"), 307 arg, "-t"); 308 argp_help (&argp, stderr, ARGP_HELP_SEE, "strings"); 309 return ARGP_ERR_UNKNOWN; 310 } 311 break; 312 313 case ARGP_KEY_FINI: 314 /* Compute the length in bytes of any match. */ 315 if (min_len <= 0 || min_len > INT_MAX / bytes_per_char) 316 error (EXIT_FAILURE, 0, 317 gettext ("invalid minimum length of matched string size")); 318 min_len_bytes = min_len * bytes_per_char; 319 break; 320 321 default: 322 return ARGP_ERR_UNKNOWN; 323 } 324 return 0; 325 } 326 327 328 static void 329 process_chunk_mb (const char *fname, const unsigned char *buf, off_t to, 330 size_t len, char **unprinted) 331 { 332 size_t curlen = *unprinted == NULL ? 0 : strlen (*unprinted); 333 const unsigned char *start = buf; 334 while (len >= bytes_per_char) 335 { 336 uint32_t ch; 337 338 if (bytes_per_char == 2) 339 { 340 if (big_endian) 341 ch = buf[0] << 8 | buf[1]; 342 else 343 ch = buf[1] << 8 | buf[0]; 344 } 345 else 346 { 347 if (big_endian) 348 ch = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]; 349 else 350 ch = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]; 351 } 352 353 if (ch <= 255 && (isprint (ch) || ch == '\t')) 354 { 355 ++buf; 356 ++curlen; 357 } 358 else 359 { 360 if (curlen >= min_len) 361 { 362 /* We found a match. */ 363 if (unlikely (fname != NULL)) 364 { 365 fputs_unlocked (fname, stdout); 366 fputs_unlocked (": ", stdout); 367 } 368 369 if (unlikely (radix != radix_none)) 370 printf ((radix == radix_octal ? "%7" PRIo64 " " 371 : (radix == radix_decimal ? "%7" PRId64 " " 372 : "%7" PRIx64 " ")), 373 (int64_t) to - len - (buf - start)); 374 375 if (unlikely (*unprinted != NULL)) 376 { 377 fputs_unlocked (*unprinted, stdout); 378 free (*unprinted); 379 *unprinted = NULL; 380 } 381 382 /* There is no sane way of printing the string. If we 383 assume the file data is encoded in UCS-2/UTF-16 or 384 UCS-4/UTF-32 respectively we could covert the string. 385 But there is no such guarantee. */ 386 fwrite_unlocked (start, 1, buf - start, stdout); 387 putc_unlocked ('\n', stdout); 388 } 389 390 start = ++buf; 391 curlen = 0; 392 393 if (len <= min_len) 394 break; 395 } 396 397 --len; 398 } 399 400 if (curlen != 0) 401 *unprinted = xstrndup ((const char *) start, curlen); 402 } 403 404 405 static void 406 process_chunk (const char *fname, const unsigned char *buf, off_t to, 407 size_t len, char **unprinted) 408 { 409 /* We are not going to slow the check down for the 2- and 4-byte 410 encodings. Handle them special. */ 411 if (unlikely (bytes_per_char != 1)) 412 { 413 process_chunk_mb (fname, buf, to, len, unprinted); 414 return; 415 } 416 417 size_t curlen = *unprinted == NULL ? 0 : strlen (*unprinted); 418 const unsigned char *start = buf; 419 while (len > 0) 420 { 421 if ((isprint (*buf) || *buf == '\t') && (! char_7bit || *buf <= 127)) 422 { 423 ++buf; 424 ++curlen; 425 } 426 else 427 { 428 if (curlen >= min_len) 429 { 430 /* We found a match. */ 431 if (likely (fname != NULL)) 432 { 433 fputs_unlocked (fname, stdout); 434 fputs_unlocked (": ", stdout); 435 } 436 437 if (likely (radix != radix_none)) 438 printf ((radix == radix_octal ? "%7" PRIo64 " " 439 : (radix == radix_decimal ? "%7" PRId64 " " 440 : "%7" PRIx64 " ")), 441 (int64_t) to - len - (buf - start)); 442 443 if (unlikely (*unprinted != NULL)) 444 { 445 fputs_unlocked (*unprinted, stdout); 446 free (*unprinted); 447 *unprinted = NULL; 448 } 449 fwrite_unlocked (start, 1, buf - start, stdout); 450 putc_unlocked ('\n', stdout); 451 } 452 453 start = ++buf; 454 curlen = 0; 455 456 if (len <= min_len) 457 break; 458 } 459 460 --len; 461 } 462 463 if (curlen != 0) 464 *unprinted = xstrndup ((const char *) start, curlen); 465 } 466 467 468 /* Map a file in as large chunks as possible. */ 469 static void * 470 map_file (int fd, off_t start_off, off_t fdlen, size_t *map_sizep) 471 { 472 /* Maximum size we mmap. We use an #ifdef to avoid overflows on 473 32-bit machines. 64-bit machines these days do not have usable 474 address spaces larger than about 43 bits. Not that any file 475 should be that large. */ 476 # if SIZE_MAX > 0xffffffff 477 const size_t mmap_max = 0x4000000000lu; 478 # else 479 const size_t mmap_max = 0x40000000lu; 480 # endif 481 482 /* Try to mmap the file. */ 483 size_t map_size = MIN ((off_t) mmap_max, fdlen); 484 const size_t map_size_min = MAX (MAX (SIZE_MAX / 16, 2 * ps), 485 roundup (2 * min_len_bytes + 1, ps)); 486 void *mem; 487 while (1) 488 { 489 /* We map the memory for reading only here. Since we will 490 always look at every byte of the file it makes sense to 491 use MAP_POPULATE. */ 492 mem = mmap (NULL, map_size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, 493 fd, start_off); 494 if (mem != MAP_FAILED) 495 { 496 /* We will go through the mapping sequentially. */ 497 (void) posix_madvise (mem, map_size, POSIX_MADV_SEQUENTIAL); 498 break; 499 } 500 if (errno != EINVAL && errno != ENOMEM) 501 /* This is an error other than the lack of address space. */ 502 break; 503 504 /* Maybe the size of the mapping is too big. Try again. */ 505 map_size /= 2; 506 if (map_size < map_size_min) 507 /* That size should have fit. */ 508 break; 509 } 510 511 *map_sizep = map_size; 512 return mem; 513 } 514 515 516 /* Read the file without mapping. */ 517 static int 518 read_block_no_mmap (int fd, const char *fname, off_t from, off_t fdlen) 519 { 520 char *unprinted = NULL; 521 #define CHUNKSIZE 65536 522 unsigned char *buf = xmalloc (CHUNKSIZE + min_len_bytes 523 + bytes_per_char - 1); 524 size_t ntrailer = 0; 525 int result = 0; 526 while (fdlen > 0) 527 { 528 ssize_t n = TEMP_FAILURE_RETRY (read (fd, buf + ntrailer, 529 MIN (fdlen, CHUNKSIZE))); 530 if (n == 0) 531 { 532 /* There are less than MIN_LEN+1 bytes left so there cannot be 533 another match. */ 534 assert (unprinted == NULL || ntrailer == 0); 535 break; 536 } 537 if (unlikely (n < 0)) 538 { 539 /* Something went wrong. */ 540 result = 1; 541 break; 542 } 543 544 /* Account for the number of bytes read in this round. */ 545 fdlen -= n; 546 547 /* Do not use the signed N value. Note that the addition cannot 548 overflow. */ 549 size_t nb = (size_t) n + ntrailer; 550 if (nb >= min_len_bytes) 551 { 552 /* We only use complete characters. */ 553 nb &= ~(bytes_per_char - 1); 554 555 process_chunk (fname, buf, from + nb, nb, &unprinted); 556 557 /* If the last bytes of the buffer (modulo the character 558 size) have been printed we are not copying them. */ 559 size_t to_keep = unprinted != NULL ? 0 : min_len_bytes; 560 561 memmove (buf, buf + nb - to_keep, to_keep); 562 ntrailer = to_keep; 563 from += nb; 564 } 565 else 566 ntrailer = nb; 567 } 568 569 free (buf); 570 571 /* Don't print anything we collected so far. There is no 572 terminating NUL byte. */ 573 free (unprinted); 574 575 return result; 576 } 577 578 579 static int 580 read_block (int fd, const char *fname, off_t fdlen, off_t from, off_t to) 581 { 582 if (elfmap == NULL) 583 { 584 /* We need a completely new mapping. */ 585 elfmap_off = from & ~(ps - 1); 586 elfmap_base = elfmap = map_file (fd, elfmap_off, fdlen, &elfmap_size); 587 588 if (unlikely (elfmap == MAP_FAILED)) 589 /* Let the kernel know we are going to read everything in sequence. */ 590 (void) posix_fadvise (fd, 0, 0, POSIX_FADV_SEQUENTIAL); 591 } 592 593 if (unlikely (elfmap == MAP_FAILED)) 594 { 595 /* Read from the file descriptor. For this we must position the 596 read pointer. */ 597 // XXX Eventually add flag which avoids this if the position 598 // XXX is known to match. 599 if (from != 0 && lseek (fd, from, SEEK_SET) != from) 600 error (EXIT_FAILURE, errno, gettext ("lseek failed")); 601 602 return read_block_no_mmap (fd, fname, from, to - from); 603 } 604 605 assert ((off_t) min_len_bytes < fdlen); 606 607 if (to < (off_t) elfmap_off || from > (off_t) (elfmap_off + elfmap_size)) 608 { 609 /* The existing mapping cannot fit at all. Map the new area. 610 We always map the full range of ELFMAP_SIZE bytes even if 611 this extend beyond the end of the file. The Linux kernel 612 handles this OK if the access pages are not touched. */ 613 elfmap_off = from & ~(ps - 1); 614 if (mmap (elfmap, elfmap_size, PROT_READ, 615 MAP_PRIVATE | MAP_POPULATE | MAP_FIXED, fd, from) 616 == MAP_FAILED) 617 error (EXIT_FAILURE, errno, gettext ("re-mmap failed")); 618 elfmap_base = elfmap; 619 } 620 621 char *unprinted = NULL; 622 623 /* Use the existing mapping as much as possible. If necessary, map 624 new pages. */ 625 if (from >= (off_t) elfmap_off 626 && from < (off_t) (elfmap_off + elfmap_size)) 627 /* There are at least a few bytes in this mapping which we can 628 use. */ 629 process_chunk (fname, elfmap_base + (from - elfmap_off), 630 MIN (to, (off_t) (elfmap_off + elfmap_size)), 631 MIN (to, (off_t) (elfmap_off + elfmap_size)) - from, 632 &unprinted); 633 634 if (to > (off_t) (elfmap_off + elfmap_size)) 635 { 636 unsigned char *remap_base = elfmap_base; 637 size_t read_now = elfmap_size - (elfmap_base - elfmap); 638 639 assert (from >= (off_t) elfmap_off 640 && from < (off_t) (elfmap_off + elfmap_size)); 641 off_t handled_to = elfmap_off + elfmap_size; 642 assert (elfmap == elfmap_base 643 || (elfmap_base - elfmap 644 == (ptrdiff_t) ((min_len_bytes + ps - 1) & ~(ps - 1)))); 645 if (elfmap == elfmap_base) 646 { 647 size_t keep_area = (min_len_bytes + ps - 1) & ~(ps - 1); 648 assert (elfmap_size >= keep_area + ps); 649 /* The keep area is used for the content of the previous 650 buffer we have to keep. This means copying those bytes 651 and for this we have to make the data writable. */ 652 if (unlikely (mprotect (elfmap, keep_area, PROT_READ | PROT_WRITE) 653 != 0)) 654 error (EXIT_FAILURE, errno, gettext ("mprotect failed")); 655 656 elfmap_base = elfmap + keep_area; 657 } 658 659 while (1) 660 { 661 /* Map the rest of the file, eventually again in pieces. 662 We speed things up with a nice Linux feature. Note 663 that we have at least two pages mapped. */ 664 size_t to_keep = unprinted != NULL ? 0 : min_len_bytes; 665 666 assert (read_now >= to_keep); 667 memmove (elfmap_base - to_keep, 668 remap_base + read_now - to_keep, to_keep); 669 remap_base = elfmap_base; 670 671 assert ((elfmap_size - (elfmap_base - elfmap)) % bytes_per_char 672 == 0); 673 read_now = MIN (to - handled_to, 674 (ptrdiff_t) elfmap_size - (elfmap_base - elfmap)); 675 676 assert (handled_to % ps == 0); 677 assert (handled_to % bytes_per_char == 0); 678 if (mmap (remap_base, read_now, PROT_READ, 679 MAP_PRIVATE | MAP_POPULATE | MAP_FIXED, fd, handled_to) 680 == MAP_FAILED) 681 error (EXIT_FAILURE, errno, gettext ("re-mmap failed")); 682 elfmap_off = handled_to; 683 684 process_chunk (fname, remap_base - to_keep, 685 elfmap_off + (read_now & ~(bytes_per_char - 1)), 686 to_keep + (read_now & ~(bytes_per_char - 1)), 687 &unprinted); 688 handled_to += read_now; 689 if (handled_to >= to) 690 break; 691 } 692 } 693 694 /* Don't print anything we collected so far. There is no 695 terminating NUL byte. */ 696 free (unprinted); 697 698 return 0; 699 } 700 701 702 static int 703 read_fd (int fd, const char *fname, off_t fdlen) 704 { 705 return read_block (fd, fname, fdlen, 0, fdlen); 706 } 707 708 709 static int 710 read_elf (Elf *elf, int fd, const char *fname, off_t fdlen) 711 { 712 assert (fdlen >= 0); 713 714 /* We will look at each section separately. The ELF file is not 715 mmapped. The libelf implementation will load the needed parts on 716 demand. Since we only interate over the section header table the 717 memory consumption at this stage is kept minimal. */ 718 Elf_Scn *scn = elf_nextscn (elf, NULL); 719 if (scn == NULL) 720 return read_fd (fd, fname, fdlen); 721 722 int result = 0; 723 do 724 { 725 GElf_Shdr shdr_mem; 726 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 727 728 /* Only look in sections which are loaded at runtime and 729 actually have content. */ 730 if (shdr != NULL && shdr->sh_type != SHT_NOBITS 731 && (shdr->sh_flags & SHF_ALLOC) != 0) 732 { 733 if (shdr->sh_offset > (Elf64_Off) fdlen 734 || fdlen - shdr->sh_offset < shdr->sh_size) 735 { 736 size_t strndx = 0; 737 const char *sname; 738 if (unlikely (elf_getshdrstrndx (elf, &strndx) < 0)) 739 sname = "<unknown>"; 740 else 741 sname = elf_strptr (elf, strndx, shdr->sh_name) ?: "<unknown>"; 742 error (0, 0, 743 gettext ("Skipping section %zd '%s' data outside file"), 744 elf_ndxscn (scn), sname); 745 result = 1; 746 } 747 else 748 result |= read_block (fd, fname, fdlen, shdr->sh_offset, 749 shdr->sh_offset + shdr->sh_size); 750 } 751 } 752 while ((scn = elf_nextscn (elf, scn)) != NULL); 753 754 if (elfmap != NULL && elfmap != MAP_FAILED) 755 munmap (elfmap, elfmap_size); 756 elfmap = NULL; 757 758 return result; 759 } 760 761 762 #include "debugpred.h" 763