125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print the strings of printable characters in files. 203333823c75a1c1887e923828113a1b0fd12020cElliott Hughes Copyright (C) 2005-2010, 2012, 2014 Red Hat, Inc. 303333823c75a1c1887e923828113a1b0fd12020cElliott Hughes This file is part of elfutils. 425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Written by Ulrich Drepper <drepper@redhat.com>, 2005. 525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 603333823c75a1c1887e923828113a1b0fd12020cElliott Hughes This file is free software; you can redistribute it and/or modify 703333823c75a1c1887e923828113a1b0fd12020cElliott Hughes it under the terms of the GNU General Public License as published by 803333823c75a1c1887e923828113a1b0fd12020cElliott Hughes the Free Software Foundation; either version 3 of the License, or 903333823c75a1c1887e923828113a1b0fd12020cElliott Hughes (at your option) any later version. 1025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1103333823c75a1c1887e923828113a1b0fd12020cElliott Hughes elfutils is distributed in the hope that it will be useful, but 1225b3c049e70834cf33790a28643ab058b507b35cBen Cheng WITHOUT ANY WARRANTY; without even the implied warranty of 1303333823c75a1c1887e923828113a1b0fd12020cElliott Hughes MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1403333823c75a1c1887e923828113a1b0fd12020cElliott Hughes GNU General Public License for more details. 1525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1603333823c75a1c1887e923828113a1b0fd12020cElliott Hughes You should have received a copy of the GNU General Public License 1703333823c75a1c1887e923828113a1b0fd12020cElliott Hughes along with this program. If not, see <http://www.gnu.org/licenses/>. */ 1825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifdef HAVE_CONFIG_H 2025b3c049e70834cf33790a28643ab058b507b35cBen Cheng# include <config.h> 2125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 2225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 2325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <argp.h> 2425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <assert.h> 2525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <ctype.h> 2625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <endian.h> 2725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <errno.h> 2825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <error.h> 2925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <fcntl.h> 3025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <gelf.h> 3125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <inttypes.h> 3225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <libintl.h> 3325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <locale.h> 3425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdbool.h> 3525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdio.h> 3625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdio_ext.h> 3725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdlib.h> 3825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <string.h> 3925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <unistd.h> 4025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <sys/mman.h> 4125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <sys/param.h> 4225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <sys/stat.h> 4325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <system.h> 4525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4725b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Prototypes of local functions. */ 4825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int read_fd (int fd, const char *fname, off64_t fdlen); 4925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int read_elf (Elf *elf, int fd, const char *fname, off64_t fdlen); 5025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 5125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 5225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Name and version of program. */ 5325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_version (FILE *stream, struct argp_state *state); 5425b3c049e70834cf33790a28643ab058b507b35cBen ChengARGP_PROGRAM_VERSION_HOOK_DEF = print_version; 5525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 5625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Bug report address. */ 5725b3c049e70834cf33790a28643ab058b507b35cBen ChengARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; 5825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 5925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Definitions of arguments for argp functions. */ 6025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const struct argp_option options[] = 6125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 6225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { NULL, 0, NULL, 0, N_("Output Selection:"), 0 }, 6325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "all", 'a', NULL, 0, N_("Scan entire file, not only loaded sections"), 0 }, 6425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "bytes", 'n', "MIN-LEN", 0, 6525b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("Only NUL-terminated sequences of MIN-LEN characters or more are printed"), 0 }, 6625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "encoding", 'e', "SELECTOR", 0, N_("\ 6725b3c049e70834cf33790a28643ab058b507b35cBen ChengSelect character size and endianess: s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit"), 6825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 0}, 6925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "print-file-name", 'f', NULL, 0, 7025b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("Print name of the file before each string."), 0 }, 7125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "radix", 't', "{o,d,x}", 0, 7225b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("Print location of the string in base 8, 10, or 16 respectively."), 0 }, 7325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { NULL, 'o', NULL, 0, N_("Alias for --radix=o"), 0 }, 7425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 7525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 }, 7625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { NULL, 0, NULL, 0, NULL, 0 } 7725b3c049e70834cf33790a28643ab058b507b35cBen Cheng}; 7825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 7925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Short description of program. */ 8025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char doc[] = N_("\ 8125b3c049e70834cf33790a28643ab058b507b35cBen ChengPrint the strings of printable characters in files."); 8225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 8325b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Strings for arguments in help texts. */ 8425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char args_doc[] = N_("[FILE...]"); 8525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 8625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Prototype for option handler. */ 8725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic error_t parse_opt (int key, char *arg, struct argp_state *state); 8825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 8925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Data structure to communicate with argp functions. */ 9025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic struct argp argp = 9125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 9225b3c049e70834cf33790a28643ab058b507b35cBen Cheng options, parse_opt, args_doc, doc, NULL, NULL, NULL 9325b3c049e70834cf33790a28643ab058b507b35cBen Cheng}; 9425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 9525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 9625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Global variables. */ 9725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 9825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if whole file and not only loaded sections are looked at. */ 9925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool entire_file; 10025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 10125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Minimum length of any sequence reported. */ 10225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic size_t min_len = 4; 10325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 10425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Number of bytes per character. */ 10525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic size_t bytes_per_char = 1; 10625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 10725b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Minimum length of any sequence reported in bytes. */ 10825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic size_t min_len_bytes; 10925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11025b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if multibyte characters are in big-endian order. */ 11125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool big_endian; 11225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11325b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True unless 7-bit ASCII are expected. */ 11425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool char_7bit; 11525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if file names should be printed before strings. */ 11725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_file_name; 11825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11903333823c75a1c1887e923828113a1b0fd12020cElliott Hughes/* Radix for printed numbers. */ 12003333823c75a1c1887e923828113a1b0fd12020cElliott Hughesstatic enum 12103333823c75a1c1887e923828113a1b0fd12020cElliott Hughes{ 12203333823c75a1c1887e923828113a1b0fd12020cElliott Hughes radix_none = 0, 12303333823c75a1c1887e923828113a1b0fd12020cElliott Hughes radix_decimal, 12403333823c75a1c1887e923828113a1b0fd12020cElliott Hughes radix_hex, 12503333823c75a1c1887e923828113a1b0fd12020cElliott Hughes radix_octal 12603333823c75a1c1887e923828113a1b0fd12020cElliott Hughes} radix = radix_none; 12703333823c75a1c1887e923828113a1b0fd12020cElliott Hughes 12825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 12925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Page size in use. */ 13025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic size_t ps; 13125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13325b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Mapped parts of the ELF file. */ 13425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic unsigned char *elfmap; 13525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic unsigned char *elfmap_base; 13625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic size_t elfmap_size; 13725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic off64_t elfmap_off; 13825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 14025b3c049e70834cf33790a28643ab058b507b35cBen Chengint 14125b3c049e70834cf33790a28643ab058b507b35cBen Chengmain (int argc, char *argv[]) 14225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 14325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We use no threads. */ 14425b3c049e70834cf33790a28643ab058b507b35cBen Cheng __fsetlocking (stdin, FSETLOCKING_BYCALLER); 14525b3c049e70834cf33790a28643ab058b507b35cBen Cheng __fsetlocking (stdout, FSETLOCKING_BYCALLER); 14625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 14725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Set locale. */ 14825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) setlocale (LC_ALL, ""); 14925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 15025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Make sure the message catalog can be found. */ 15125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); 15225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 15325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Initialize the message catalog. */ 15425b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) textdomain (PACKAGE_TARNAME); 15525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 15625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Parse and process arguments. */ 15725b3c049e70834cf33790a28643ab058b507b35cBen Cheng int remaining; 15825b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL); 15925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Tell the library which version we are expecting. */ 16125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_version (EV_CURRENT); 16225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine the page size. We will likely need it a couple of times. */ 16425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ps = sysconf (_SC_PAGESIZE); 16525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16625b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct stat64 st; 16725b3c049e70834cf33790a28643ab058b507b35cBen Cheng int result = 0; 16825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (remaining == argc) 16925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We read from standard input. This we cannot do for a 17025b3c049e70834cf33790a28643ab058b507b35cBen Cheng structured file. */ 17125b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = read_fd (STDIN_FILENO, 17225b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_file_name ? "{standard input}" : NULL, 17325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (fstat64 (STDIN_FILENO, &st) == 0 && S_ISREG (st.st_mode)) 17425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? st.st_size : INT64_C (0x7fffffffffffffff)); 17525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 17625b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 17725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 17825b3c049e70834cf33790a28643ab058b507b35cBen Cheng int fd = (strcmp (argv[remaining], "-") == 0 17925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? STDIN_FILENO : open (argv[remaining], O_RDONLY)); 18025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (fd == -1)) 18125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 18225b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, errno, gettext ("cannot open '%s'"), argv[remaining]); 18325b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = 1; 18425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 18525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 18625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 18725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *fname = print_file_name ? argv[remaining] : NULL; 18825b3c049e70834cf33790a28643ab058b507b35cBen Cheng int fstat_fail = fstat64 (fd, &st); 18925b3c049e70834cf33790a28643ab058b507b35cBen Cheng off64_t fdlen = (fstat_fail 19025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ? INT64_C (0x7fffffffffffffff) : st.st_size); 19125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (fdlen > (off64_t) min_len_bytes) 19225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 19325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf *elf = NULL; 19425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (entire_file 19525b3c049e70834cf33790a28643ab058b507b35cBen Cheng || fstat_fail 19625b3c049e70834cf33790a28643ab058b507b35cBen Cheng || !S_ISREG (st.st_mode) 19725b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (elf = elf_begin (fd, ELF_C_READ, NULL)) == NULL 19825b3c049e70834cf33790a28643ab058b507b35cBen Cheng || elf_kind (elf) != ELF_K_ELF) 19925b3c049e70834cf33790a28643ab058b507b35cBen Cheng result |= read_fd (fd, fname, fdlen); 20025b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 20125b3c049e70834cf33790a28643ab058b507b35cBen Cheng result |= read_elf (elf, fd, fname, fdlen); 20225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 20325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This call will succeed even if ELF is NULL. */ 20425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elf_end (elf); 20525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 20625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 20725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (strcmp (argv[remaining], "-") != 0) 20825b3c049e70834cf33790a28643ab058b507b35cBen Cheng close (fd); 20925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 21025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 21125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elfmap != NULL && elfmap != MAP_FAILED) 21225b3c049e70834cf33790a28643ab058b507b35cBen Cheng munmap (elfmap, elfmap_size); 21325b3c049e70834cf33790a28643ab058b507b35cBen Cheng elfmap = NULL; 21425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 21525b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (++remaining < argc); 21625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 21725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return result; 21825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 21925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 22025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 22125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print the version information. */ 22225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 22325b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 22425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 22525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stream, "strings (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 22625b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stream, gettext ("\ 22725b3c049e70834cf33790a28643ab058b507b35cBen ChengCopyright (C) %s Red Hat, Inc.\n\ 22825b3c049e70834cf33790a28643ab058b507b35cBen ChengThis is free software; see the source for copying conditions. There is NO\n\ 22925b3c049e70834cf33790a28643ab058b507b35cBen Chengwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 23025b3c049e70834cf33790a28643ab058b507b35cBen Cheng"), "2012"); 23125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 23225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 23325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 23425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 23525b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Handle program arguments. */ 23625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic error_t 23725b3c049e70834cf33790a28643ab058b507b35cBen Chengparse_opt (int key, char *arg, 23825b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct argp_state *state __attribute__ ((unused))) 23925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 24025b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (key) 24125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 24225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'a': 24325b3c049e70834cf33790a28643ab058b507b35cBen Cheng entire_file = true; 24425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 24525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 24625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'e': 24725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We expect a string of one character. */ 24825b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (arg[1] != '\0' ? '\0' : arg[0]) 24925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 25025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 's': 25125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'S': 25225b3c049e70834cf33790a28643ab058b507b35cBen Cheng char_7bit = arg[0] == 's'; 25325b3c049e70834cf33790a28643ab058b507b35cBen Cheng bytes_per_char = 1; 25425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 25525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 25625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'b': 25725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'B': 25825b3c049e70834cf33790a28643ab058b507b35cBen Cheng big_endian = true; 25925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* FALLTHROUGH */ 26025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 26125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'l': 26225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'L': 26325b3c049e70834cf33790a28643ab058b507b35cBen Cheng bytes_per_char = isupper (arg[0]) ? 4 : 2; 26425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 26525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 26625b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 26725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("invalid value '%s' for %s parameter"), 26825b3c049e70834cf33790a28643ab058b507b35cBen Cheng arg, "-e"); 26925b3c049e70834cf33790a28643ab058b507b35cBen Cheng argp_help (&argp, stderr, ARGP_HELP_SEE, "strings"); 27025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return ARGP_ERR_UNKNOWN; 27125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 27225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 27325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 27425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'f': 27525b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_file_name = true; 27625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 27725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 27825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'n': 27925b3c049e70834cf33790a28643ab058b507b35cBen Cheng min_len = atoi (arg); 28025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 28125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 28225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'o': 28325b3c049e70834cf33790a28643ab058b507b35cBen Cheng goto octfmt; 28425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 28525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 't': 28625b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (arg[0]) 28725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 28825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'd': 28903333823c75a1c1887e923828113a1b0fd12020cElliott Hughes radix = radix_decimal; 29025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 29125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 29225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'o': 29325b3c049e70834cf33790a28643ab058b507b35cBen Cheng octfmt: 29403333823c75a1c1887e923828113a1b0fd12020cElliott Hughes radix = radix_octal; 29525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 29625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 29725b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'x': 29803333823c75a1c1887e923828113a1b0fd12020cElliott Hughes radix = radix_hex; 29925b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 30025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 30125b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 30225b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("invalid value '%s' for %s parameter"), 30325b3c049e70834cf33790a28643ab058b507b35cBen Cheng arg, "-t"); 30425b3c049e70834cf33790a28643ab058b507b35cBen Cheng argp_help (&argp, stderr, ARGP_HELP_SEE, "strings"); 30525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return ARGP_ERR_UNKNOWN; 30625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 30725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 30825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 30925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case ARGP_KEY_FINI: 31025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Compute the length in bytes of any match. */ 31125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (min_len <= 0 || min_len > INT_MAX / bytes_per_char) 31225b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, 31325b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("invalid minimum length of matched string size")); 31425b3c049e70834cf33790a28643ab058b507b35cBen Cheng min_len_bytes = min_len * bytes_per_char; 31525b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 31625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 31725b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 31825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return ARGP_ERR_UNKNOWN; 31925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 32025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 32125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 32225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 32325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 32425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 32525b3c049e70834cf33790a28643ab058b507b35cBen Chengprocess_chunk_mb (const char *fname, const unsigned char *buf, off64_t to, 32625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t len, char **unprinted) 32725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 32825b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t curlen = *unprinted == NULL ? 0 : strlen (*unprinted); 32925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *start = buf; 33025b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (len >= bytes_per_char) 33125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 33225b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t ch; 33325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 33425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (bytes_per_char == 2) 33525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 33625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (big_endian) 33725b3c049e70834cf33790a28643ab058b507b35cBen Cheng ch = buf[0] << 8 | buf[1]; 33825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 33925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ch = buf[1] << 8 | buf[0]; 34025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 34125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 34225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 34325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (big_endian) 34425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ch = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]; 34525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 34625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ch = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]; 34725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 34825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 34925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ch <= 255 && (isprint (ch) || ch == '\t')) 35025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 35125b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++buf; 35225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++curlen; 35325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 35425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 35525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 35625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (curlen >= min_len) 35725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 35825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We found a match. */ 35925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (fname != NULL)) 36025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 36125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (fname, stdout); 36225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (": ", stdout); 36325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 36425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 36503333823c75a1c1887e923828113a1b0fd12020cElliott Hughes if (unlikely (radix != radix_none)) 36603333823c75a1c1887e923828113a1b0fd12020cElliott Hughes printf ((radix == radix_octal ? "%7" PRIo64 " " 36703333823c75a1c1887e923828113a1b0fd12020cElliott Hughes : (radix == radix_decimal ? "%7" PRId64 " " 36803333823c75a1c1887e923828113a1b0fd12020cElliott Hughes : "%7" PRIx64 " ")), 36903333823c75a1c1887e923828113a1b0fd12020cElliott Hughes (int64_t) to - len - (buf - start)); 37025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 37125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (*unprinted != NULL)) 37225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 37325b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (*unprinted, stdout); 37425b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (*unprinted); 37525b3c049e70834cf33790a28643ab058b507b35cBen Cheng *unprinted = NULL; 37625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 37725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 37825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* There is no sane way of printing the string. If we 37925b3c049e70834cf33790a28643ab058b507b35cBen Cheng assume the file data is encoded in UCS-2/UTF-16 or 38025b3c049e70834cf33790a28643ab058b507b35cBen Cheng UCS-4/UTF-32 respectively we could covert the string. 38125b3c049e70834cf33790a28643ab058b507b35cBen Cheng But there is no such guarantee. */ 38225b3c049e70834cf33790a28643ab058b507b35cBen Cheng fwrite_unlocked (start, 1, buf - start, stdout); 38325b3c049e70834cf33790a28643ab058b507b35cBen Cheng putc_unlocked ('\n', stdout); 38425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 38525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 38625b3c049e70834cf33790a28643ab058b507b35cBen Cheng start = ++buf; 38725b3c049e70834cf33790a28643ab058b507b35cBen Cheng curlen = 0; 38825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 38925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (len <= min_len) 39025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 39125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 39225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 39325b3c049e70834cf33790a28643ab058b507b35cBen Cheng --len; 39425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 39525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 39625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (curlen != 0) 39725b3c049e70834cf33790a28643ab058b507b35cBen Cheng *unprinted = xstrndup ((const char *) start, curlen); 39825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 39925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 40025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 40125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 40225b3c049e70834cf33790a28643ab058b507b35cBen Chengprocess_chunk (const char *fname, const unsigned char *buf, off64_t to, 40325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t len, char **unprinted) 40425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 40525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We are not going to slow the check down for the 2- and 4-byte 40625b3c049e70834cf33790a28643ab058b507b35cBen Cheng encodings. Handle them special. */ 40725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (bytes_per_char != 1)) 40825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 40925b3c049e70834cf33790a28643ab058b507b35cBen Cheng process_chunk_mb (fname, buf, to, len, unprinted); 41025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 41125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 41225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 41325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t curlen = *unprinted == NULL ? 0 : strlen (*unprinted); 41425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const unsigned char *start = buf; 41525b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (len > 0) 41625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 41725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((isprint (*buf) || *buf == '\t') && (! char_7bit || *buf <= 127)) 41825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 41925b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++buf; 42025b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++curlen; 42125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 42225b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 42325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 42425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (curlen >= min_len) 42525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 42625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We found a match. */ 42725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (likely (fname != NULL)) 42825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 42925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (fname, stdout); 43025b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (": ", stdout); 43125b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 43225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 43303333823c75a1c1887e923828113a1b0fd12020cElliott Hughes if (likely (radix != radix_none)) 43403333823c75a1c1887e923828113a1b0fd12020cElliott Hughes printf ((radix == radix_octal ? "%7" PRIo64 " " 43503333823c75a1c1887e923828113a1b0fd12020cElliott Hughes : (radix == radix_decimal ? "%7" PRId64 " " 43603333823c75a1c1887e923828113a1b0fd12020cElliott Hughes : "%7" PRIx64 " ")), 43703333823c75a1c1887e923828113a1b0fd12020cElliott Hughes (int64_t) to - len - (buf - start)); 43825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 43925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (*unprinted != NULL)) 44025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 44125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs_unlocked (*unprinted, stdout); 44225b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (*unprinted); 44325b3c049e70834cf33790a28643ab058b507b35cBen Cheng *unprinted = NULL; 44425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 44525b3c049e70834cf33790a28643ab058b507b35cBen Cheng fwrite_unlocked (start, 1, buf - start, stdout); 44625b3c049e70834cf33790a28643ab058b507b35cBen Cheng putc_unlocked ('\n', stdout); 44725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 44825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 44925b3c049e70834cf33790a28643ab058b507b35cBen Cheng start = ++buf; 45025b3c049e70834cf33790a28643ab058b507b35cBen Cheng curlen = 0; 45125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 45225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (len <= min_len) 45325b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 45425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 45525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 45625b3c049e70834cf33790a28643ab058b507b35cBen Cheng --len; 45725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 45825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 45925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (curlen != 0) 46025b3c049e70834cf33790a28643ab058b507b35cBen Cheng *unprinted = xstrndup ((const char *) start, curlen); 46125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 46225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 46325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 46425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Map a file in as large chunks as possible. */ 46525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void * 46625b3c049e70834cf33790a28643ab058b507b35cBen Chengmap_file (int fd, off64_t start_off, off64_t fdlen, size_t *map_sizep) 46725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 46825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Maximum size we mmap. We use an #ifdef to avoid overflows on 46925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 32-bit machines. 64-bit machines these days do not have usable 47025b3c049e70834cf33790a28643ab058b507b35cBen Cheng address spaces larger than about 43 bits. Not that any file 47125b3c049e70834cf33790a28643ab058b507b35cBen Cheng should be that large. */ 47225b3c049e70834cf33790a28643ab058b507b35cBen Cheng# if SIZE_MAX > 0xffffffff 47325b3c049e70834cf33790a28643ab058b507b35cBen Cheng const size_t mmap_max = 0x4000000000lu; 47425b3c049e70834cf33790a28643ab058b507b35cBen Cheng# else 47525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const size_t mmap_max = 0x40000000lu; 47625b3c049e70834cf33790a28643ab058b507b35cBen Cheng# endif 47725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 47825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Try to mmap the file. */ 47925b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t map_size = MIN ((off64_t) mmap_max, fdlen); 48025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const size_t map_size_min = MAX (MAX (SIZE_MAX / 16, 2 * ps), 48125b3c049e70834cf33790a28643ab058b507b35cBen Cheng roundup (2 * min_len_bytes + 1, ps)); 48225b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *mem; 48325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (1) 48425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 48525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We map the memory for reading only here. Since we will 48625b3c049e70834cf33790a28643ab058b507b35cBen Cheng always look at every byte of the file it makes sense to 48725b3c049e70834cf33790a28643ab058b507b35cBen Cheng use MAP_POPULATE. */ 48825b3c049e70834cf33790a28643ab058b507b35cBen Cheng mem = mmap64 (NULL, map_size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, 48925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fd, start_off); 49025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (mem != MAP_FAILED) 49125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 49225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We will go through the mapping sequentially. */ 49325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) posix_madvise (mem, map_size, POSIX_MADV_SEQUENTIAL); 49425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 49525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 49625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (errno != EINVAL && errno != ENOMEM) 49725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* This is an error other than the lack of address space. */ 49825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 49925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 50025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Maybe the size of the mapping is too big. Try again. */ 50125b3c049e70834cf33790a28643ab058b507b35cBen Cheng map_size /= 2; 50225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (map_size < map_size_min) 50325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* That size should have fit. */ 50425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 50525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 50625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 50725b3c049e70834cf33790a28643ab058b507b35cBen Cheng *map_sizep = map_size; 50825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return mem; 50925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 51025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 51125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 51225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Read the file without mapping. */ 51325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 51425b3c049e70834cf33790a28643ab058b507b35cBen Chengread_block_no_mmap (int fd, const char *fname, off64_t from, off64_t fdlen) 51525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 51625b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *unprinted = NULL; 51725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define CHUNKSIZE 65536 51825b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned char *buf = xmalloc (CHUNKSIZE + min_len_bytes 51925b3c049e70834cf33790a28643ab058b507b35cBen Cheng + bytes_per_char - 1); 52025b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t ntrailer = 0; 52125b3c049e70834cf33790a28643ab058b507b35cBen Cheng int result = 0; 52225b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (fdlen > 0) 52325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 52425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ssize_t n = TEMP_FAILURE_RETRY (read (fd, buf + ntrailer, 52525b3c049e70834cf33790a28643ab058b507b35cBen Cheng MIN (fdlen, CHUNKSIZE))); 52625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (n == 0) 52725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 52825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* There are less than MIN_LEN+1 bytes left so there cannot be 52925b3c049e70834cf33790a28643ab058b507b35cBen Cheng another match. */ 53025b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (unprinted == NULL || ntrailer == 0); 53125b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 53225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 53325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (n < 0)) 53425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 53525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Something went wrong. */ 53625b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = 1; 53725b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 53825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 53925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 54025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Account for the number of bytes read in this round. */ 54125b3c049e70834cf33790a28643ab058b507b35cBen Cheng fdlen -= n; 54225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 54325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Do not use the signed N value. Note that the addition cannot 54425b3c049e70834cf33790a28643ab058b507b35cBen Cheng overflow. */ 54525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t nb = (size_t) n + ntrailer; 54625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (nb >= min_len_bytes) 54725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 54825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We only use complete characters. */ 54925b3c049e70834cf33790a28643ab058b507b35cBen Cheng nb &= ~(bytes_per_char - 1); 55025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 55125b3c049e70834cf33790a28643ab058b507b35cBen Cheng process_chunk (fname, buf, from + nb, nb, &unprinted); 55225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 55325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* If the last bytes of the buffer (modulo the character 55425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size) have been printed we are not copying them. */ 55525b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t to_keep = unprinted != NULL ? 0 : min_len_bytes; 55625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 55725b3c049e70834cf33790a28643ab058b507b35cBen Cheng memmove (buf, buf + nb - to_keep, to_keep); 55825b3c049e70834cf33790a28643ab058b507b35cBen Cheng ntrailer = to_keep; 55925b3c049e70834cf33790a28643ab058b507b35cBen Cheng from += nb; 56025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 56125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 56225b3c049e70834cf33790a28643ab058b507b35cBen Cheng ntrailer = nb; 56325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 56425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 56525b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (buf); 56625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 56725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Don't print anything we collected so far. There is no 56825b3c049e70834cf33790a28643ab058b507b35cBen Cheng terminating NUL byte. */ 56925b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (unprinted); 57025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 57125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return result; 57225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 57325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 57425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 57525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 57625b3c049e70834cf33790a28643ab058b507b35cBen Chengread_block (int fd, const char *fname, off64_t fdlen, off64_t from, off64_t to) 57725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 57825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elfmap == NULL) 57925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 58025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We need a completely new mapping. */ 58125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elfmap_off = from & ~(ps - 1); 58225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elfmap_base = elfmap = map_file (fd, elfmap_off, fdlen, &elfmap_size); 58325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 58425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elfmap == MAP_FAILED)) 58525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Let the kernel know we are going to read everything in sequence. */ 58625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) posix_fadvise (fd, 0, 0, POSIX_FADV_SEQUENTIAL); 58725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 58825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 58925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (elfmap == MAP_FAILED)) 59025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 59125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Read from the file descriptor. For this we must position the 59225b3c049e70834cf33790a28643ab058b507b35cBen Cheng read pointer. */ 59325b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX Eventually add flag which avoids this if the position 59425b3c049e70834cf33790a28643ab058b507b35cBen Cheng // XXX is known to match. 59525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (from != 0 && lseek64 (fd, from, SEEK_SET) != from) 59625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, errno, gettext ("lseek64 failed")); 59725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 59825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return read_block_no_mmap (fd, fname, from, to - from); 59925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 60025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 60125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert ((off64_t) min_len_bytes < fdlen); 60225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 60325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (to < (off64_t) elfmap_off || from > (off64_t) (elfmap_off + elfmap_size)) 60425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 60525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The existing mapping cannot fit at all. Map the new area. 60625b3c049e70834cf33790a28643ab058b507b35cBen Cheng We always map the full range of ELFMAP_SIZE bytes even if 60725b3c049e70834cf33790a28643ab058b507b35cBen Cheng this extend beyond the end of the file. The Linux kernel 60825b3c049e70834cf33790a28643ab058b507b35cBen Cheng handles this OK if the access pages are not touched. */ 60925b3c049e70834cf33790a28643ab058b507b35cBen Cheng elfmap_off = from & ~(ps - 1); 61025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (mmap64 (elfmap, elfmap_size, PROT_READ, 61125b3c049e70834cf33790a28643ab058b507b35cBen Cheng MAP_PRIVATE | MAP_POPULATE | MAP_FIXED, fd, from) 61225b3c049e70834cf33790a28643ab058b507b35cBen Cheng == MAP_FAILED) 61325b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, errno, gettext ("re-mmap failed")); 61425b3c049e70834cf33790a28643ab058b507b35cBen Cheng elfmap_base = elfmap; 61525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 61625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 61725b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *unprinted = NULL; 61825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 61925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Use the existing mapping as much as possible. If necessary, map 62025b3c049e70834cf33790a28643ab058b507b35cBen Cheng new pages. */ 62125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (from >= (off64_t) elfmap_off 62225b3c049e70834cf33790a28643ab058b507b35cBen Cheng && from < (off64_t) (elfmap_off + elfmap_size)) 62325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* There are at least a few bytes in this mapping which we can 62425b3c049e70834cf33790a28643ab058b507b35cBen Cheng use. */ 62525b3c049e70834cf33790a28643ab058b507b35cBen Cheng process_chunk (fname, elfmap_base + (from - elfmap_off), 62625b3c049e70834cf33790a28643ab058b507b35cBen Cheng MIN (to, (off64_t) (elfmap_off + elfmap_size)), 62725b3c049e70834cf33790a28643ab058b507b35cBen Cheng MIN (to, (off64_t) (elfmap_off + elfmap_size)) - from, 62825b3c049e70834cf33790a28643ab058b507b35cBen Cheng &unprinted); 62925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 63025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (to > (off64_t) (elfmap_off + elfmap_size)) 63125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 63225b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned char *remap_base = elfmap_base; 63325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t read_now = elfmap_size - (elfmap_base - elfmap); 63425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 63525b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (from >= (off64_t) elfmap_off 63625b3c049e70834cf33790a28643ab058b507b35cBen Cheng && from < (off64_t) (elfmap_off + elfmap_size)); 63725b3c049e70834cf33790a28643ab058b507b35cBen Cheng off64_t handled_to = elfmap_off + elfmap_size; 63825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (elfmap == elfmap_base 63925b3c049e70834cf33790a28643ab058b507b35cBen Cheng || (elfmap_base - elfmap 64025b3c049e70834cf33790a28643ab058b507b35cBen Cheng == (ptrdiff_t) ((min_len_bytes + ps - 1) & ~(ps - 1)))); 64125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elfmap == elfmap_base) 64225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 64325b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t keep_area = (min_len_bytes + ps - 1) & ~(ps - 1); 64425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (elfmap_size >= keep_area + ps); 64525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The keep area is used for the content of the previous 64625b3c049e70834cf33790a28643ab058b507b35cBen Cheng buffer we have to keep. This means copying those bytes 64725b3c049e70834cf33790a28643ab058b507b35cBen Cheng and for this we have to make the data writable. */ 64825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (mprotect (elfmap, keep_area, PROT_READ | PROT_WRITE) 64925b3c049e70834cf33790a28643ab058b507b35cBen Cheng != 0)) 65025b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, errno, gettext ("mprotect failed")); 65125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 65225b3c049e70834cf33790a28643ab058b507b35cBen Cheng elfmap_base = elfmap + keep_area; 65325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 65425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 65525b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (1) 65625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 65725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Map the rest of the file, eventually again in pieces. 65825b3c049e70834cf33790a28643ab058b507b35cBen Cheng We speed things up with a nice Linux feature. Note 65925b3c049e70834cf33790a28643ab058b507b35cBen Cheng that we have at least two pages mapped. */ 66025b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t to_keep = unprinted != NULL ? 0 : min_len_bytes; 66125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 66225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (read_now >= to_keep); 66325b3c049e70834cf33790a28643ab058b507b35cBen Cheng memmove (elfmap_base - to_keep, 66425b3c049e70834cf33790a28643ab058b507b35cBen Cheng remap_base + read_now - to_keep, to_keep); 66525b3c049e70834cf33790a28643ab058b507b35cBen Cheng remap_base = elfmap_base; 66625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 66725b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert ((elfmap_size - (elfmap_base - elfmap)) % bytes_per_char 66825b3c049e70834cf33790a28643ab058b507b35cBen Cheng == 0); 66925b3c049e70834cf33790a28643ab058b507b35cBen Cheng read_now = MIN (to - handled_to, 67025b3c049e70834cf33790a28643ab058b507b35cBen Cheng (ptrdiff_t) elfmap_size - (elfmap_base - elfmap)); 67125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 67225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (handled_to % ps == 0); 67325b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (handled_to % bytes_per_char == 0); 67425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (mmap64 (remap_base, read_now, PROT_READ, 67525b3c049e70834cf33790a28643ab058b507b35cBen Cheng MAP_PRIVATE | MAP_POPULATE | MAP_FIXED, fd, handled_to) 67625b3c049e70834cf33790a28643ab058b507b35cBen Cheng == MAP_FAILED) 67725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, errno, gettext ("re-mmap failed")); 67825b3c049e70834cf33790a28643ab058b507b35cBen Cheng elfmap_off = handled_to; 67925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 68025b3c049e70834cf33790a28643ab058b507b35cBen Cheng process_chunk (fname, remap_base - to_keep, 68125b3c049e70834cf33790a28643ab058b507b35cBen Cheng elfmap_off + (read_now & ~(bytes_per_char - 1)), 68225b3c049e70834cf33790a28643ab058b507b35cBen Cheng to_keep + (read_now & ~(bytes_per_char - 1)), 68325b3c049e70834cf33790a28643ab058b507b35cBen Cheng &unprinted); 68425b3c049e70834cf33790a28643ab058b507b35cBen Cheng handled_to += read_now; 68525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (handled_to >= to) 68625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 68725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 68825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 68925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 69025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Don't print anything we collected so far. There is no 69125b3c049e70834cf33790a28643ab058b507b35cBen Cheng terminating NUL byte. */ 69225b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (unprinted); 69325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 69425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 69525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 69625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 69725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 69825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 69925b3c049e70834cf33790a28643ab058b507b35cBen Chengread_fd (int fd, const char *fname, off64_t fdlen) 70025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 70125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return read_block (fd, fname, fdlen, 0, fdlen); 70225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 70325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 70425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 70525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 70625b3c049e70834cf33790a28643ab058b507b35cBen Chengread_elf (Elf *elf, int fd, const char *fname, off64_t fdlen) 70725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 70825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (fdlen >= 0); 70925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 71025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We will look at each section separately. The ELF file is not 71125b3c049e70834cf33790a28643ab058b507b35cBen Cheng mmapped. The libelf implementation will load the needed parts on 71225b3c049e70834cf33790a28643ab058b507b35cBen Cheng demand. Since we only interate over the section header table the 71325b3c049e70834cf33790a28643ab058b507b35cBen Cheng memory consumption at this stage is kept minimal. */ 71425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = elf_nextscn (elf, NULL); 71525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (scn == NULL) 71625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return read_fd (fd, fname, fdlen); 71725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 71825b3c049e70834cf33790a28643ab058b507b35cBen Cheng int result = 0; 71925b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 72025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 72125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 72225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 72325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 72425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Only look in sections which are loaded at runtime and 72525b3c049e70834cf33790a28643ab058b507b35cBen Cheng actually have content. */ 72625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr != NULL && shdr->sh_type != SHT_NOBITS 72725b3c049e70834cf33790a28643ab058b507b35cBen Cheng && (shdr->sh_flags & SHF_ALLOC) != 0) 72825b3c049e70834cf33790a28643ab058b507b35cBen Cheng result |= read_block (fd, fname, fdlen, shdr->sh_offset, 72925b3c049e70834cf33790a28643ab058b507b35cBen Cheng shdr->sh_offset + shdr->sh_size); 73025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 73125b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((scn = elf_nextscn (elf, scn)) != NULL); 73225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 73325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elfmap != NULL && elfmap != MAP_FAILED) 73425b3c049e70834cf33790a28643ab058b507b35cBen Cheng munmap (elfmap, elfmap_size); 73525b3c049e70834cf33790a28643ab058b507b35cBen Cheng elfmap = NULL; 73625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 73725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return result; 73825b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 73925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 74025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 74125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "debugpred.h" 742