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