1 /* Print the strings of printable characters in files.
2 Copyright (C) 2005-2010, 2012, 2014 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2005.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 elfutils is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
36 #include <stdio_ext.h>
41 #include <sys/param.h>
47 /* Prototypes of local functions. */
48 static int read_fd (int fd, const char *fname, off64_t fdlen);
49 static int read_elf (Elf *elf, int fd, const char *fname, off64_t fdlen);
52 /* Name and version of program. */
53 static void print_version (FILE *stream, struct argp_state *state);
54 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
56 /* Bug report address. */
57 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
59 /* Definitions of arguments for argp functions. */
60 static const struct argp_option options[] =
62 { NULL, 0, NULL, 0, N_("Output Selection:"), 0 },
63 { "all", 'a', NULL, 0, N_("Scan entire file, not only loaded sections"), 0 },
64 { "bytes", 'n', "MIN-LEN", 0,
65 N_("Only NUL-terminated sequences of MIN-LEN characters or more are printed"), 0 },
66 { "encoding", 'e', "SELECTOR", 0, N_("\
67 Select character size and endianess: s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit"),
69 { "print-file-name", 'f', NULL, 0,
70 N_("Print name of the file before each string."), 0 },
71 { "radix", 't', "{o,d,x}", 0,
72 N_("Print location of the string in base 8, 10, or 16 respectively."), 0 },
73 { NULL, 'o', NULL, 0, N_("Alias for --radix=o"), 0 },
75 { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 },
76 { NULL, 0, NULL, 0, NULL, 0 }
79 /* Short description of program. */
80 static const char doc[] = N_("\
81 Print the strings of printable characters in files.");
83 /* Strings for arguments in help texts. */
84 static const char args_doc[] = N_("[FILE...]");
86 /* Prototype for option handler. */
87 static error_t parse_opt (int key, char *arg, struct argp_state *state);
89 /* Data structure to communicate with argp functions. */
90 static struct argp argp =
92 options, parse_opt, args_doc, doc, NULL, NULL, NULL
96 /* Global variables. */
98 /* True if whole file and not only loaded sections are looked at. */
99 static bool entire_file;
101 /* Minimum length of any sequence reported. */
102 static size_t min_len = 4;
104 /* Number of bytes per character. */
105 static size_t bytes_per_char = 1;
107 /* Minimum length of any sequence reported in bytes. */
108 static size_t min_len_bytes;
110 /* True if multibyte characters are in big-endian order. */
111 static bool big_endian;
113 /* True unless 7-bit ASCII are expected. */
114 static bool char_7bit;
116 /* True if file names should be printed before strings. */
117 static bool print_file_name;
119 /* Radix for printed numbers. */
126 } radix = radix_none;
129 /* Page size in use. */
133 /* Mapped parts of the ELF file. */
134 static unsigned char *elfmap;
135 static unsigned char *elfmap_base;
136 static size_t elfmap_size;
137 static off64_t elfmap_off;
141 main (int argc, char *argv[])
143 /* We use no threads. */
144 __fsetlocking (stdin, FSETLOCKING_BYCALLER);
145 __fsetlocking (stdout, FSETLOCKING_BYCALLER);
148 (void) setlocale (LC_ALL, "");
150 /* Make sure the message catalog can be found. */
151 (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
153 /* Initialize the message catalog. */
154 (void) textdomain (PACKAGE_TARNAME);
156 /* Parse and process arguments. */
158 (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL);
160 /* Tell the library which version we are expecting. */
161 elf_version (EV_CURRENT);
163 /* Determine the page size. We will likely need it a couple of times. */
164 ps = sysconf (_SC_PAGESIZE);
168 if (remaining == argc)
169 /* We read from standard input. This we cannot do for a
171 result = read_fd (STDIN_FILENO,
172 print_file_name ? "{standard input}" : NULL,
173 (fstat64 (STDIN_FILENO, &st) == 0 && S_ISREG (st.st_mode))
174 ? st.st_size : INT64_C (0x7fffffffffffffff));
178 int fd = (strcmp (argv[remaining], "-") == 0
179 ? STDIN_FILENO : open (argv[remaining], O_RDONLY));
180 if (unlikely (fd == -1))
182 error (0, errno, gettext ("cannot open '%s'"), argv[remaining]);
187 const char *fname = print_file_name ? argv[remaining] : NULL;
188 int fstat_fail = fstat64 (fd, &st);
189 off64_t fdlen = (fstat_fail
190 ? INT64_C (0x7fffffffffffffff) : st.st_size);
191 if (fdlen > (off64_t) min_len_bytes)
196 || !S_ISREG (st.st_mode)
197 || (elf = elf_begin (fd, ELF_C_READ, NULL)) == NULL
198 || elf_kind (elf) != ELF_K_ELF)
199 result |= read_fd (fd, fname, fdlen);
201 result |= read_elf (elf, fd, fname, fdlen);
203 /* This call will succeed even if ELF is NULL. */
207 if (strcmp (argv[remaining], "-") != 0)
211 if (elfmap != NULL && elfmap != MAP_FAILED)
212 munmap (elfmap, elfmap_size);
215 while (++remaining < argc);
221 /* Print the version information. */
223 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
225 fprintf (stream, "strings (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
226 fprintf (stream, gettext ("\
227 Copyright (C) %s Red Hat, Inc.\n\
228 This is free software; see the source for copying conditions. There is NO\n\
229 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
231 fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
235 /* Handle program arguments. */
237 parse_opt (int key, char *arg,
238 struct argp_state *state __attribute__ ((unused)))
247 /* We expect a string of one character. */
248 switch (arg[1] != '\0' ? '\0' : arg[0])
252 char_7bit = arg[0] == 's';
263 bytes_per_char = isupper (arg[0]) ? 4 : 2;
267 error (0, 0, gettext ("invalid value '%s' for %s parameter"),
269 argp_help (&argp, stderr, ARGP_HELP_SEE, "strings");
270 return ARGP_ERR_UNKNOWN;
275 print_file_name = true;
279 min_len = atoi (arg);
289 radix = radix_decimal;
302 error (0, 0, gettext ("invalid value '%s' for %s parameter"),
304 argp_help (&argp, stderr, ARGP_HELP_SEE, "strings");
305 return ARGP_ERR_UNKNOWN;
310 /* Compute the length in bytes of any match. */
311 if (min_len <= 0 || min_len > INT_MAX / bytes_per_char)
312 error (EXIT_FAILURE, 0,
313 gettext ("invalid minimum length of matched string size"));
314 min_len_bytes = min_len * bytes_per_char;
318 return ARGP_ERR_UNKNOWN;
325 process_chunk_mb (const char *fname, const unsigned char *buf, off64_t to,
326 size_t len, char **unprinted)
328 size_t curlen = *unprinted == NULL ? 0 : strlen (*unprinted);
329 const unsigned char *start = buf;
330 while (len >= bytes_per_char)
334 if (bytes_per_char == 2)
337 ch = buf[0] << 8 | buf[1];
339 ch = buf[1] << 8 | buf[0];
344 ch = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
346 ch = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
349 if (ch <= 255 && (isprint (ch) || ch == '\t'))
356 if (curlen >= min_len)
358 /* We found a match. */
359 if (unlikely (fname != NULL))
361 fputs_unlocked (fname, stdout);
362 fputs_unlocked (": ", stdout);
365 if (unlikely (radix != radix_none))
366 printf ((radix == radix_octal ? "%7" PRIo64 " "
367 : (radix == radix_decimal ? "%7" PRId64 " "
369 (int64_t) to - len - (buf - start));
371 if (unlikely (*unprinted != NULL))
373 fputs_unlocked (*unprinted, stdout);
378 /* There is no sane way of printing the string. If we
379 assume the file data is encoded in UCS-2/UTF-16 or
380 UCS-4/UTF-32 respectively we could covert the string.
381 But there is no such guarantee. */
382 fwrite_unlocked (start, 1, buf - start, stdout);
383 putc_unlocked ('\n', stdout);
397 *unprinted = xstrndup ((const char *) start, curlen);
402 process_chunk (const char *fname, const unsigned char *buf, off64_t to,
403 size_t len, char **unprinted)
405 /* We are not going to slow the check down for the 2- and 4-byte
406 encodings. Handle them special. */
407 if (unlikely (bytes_per_char != 1))
409 process_chunk_mb (fname, buf, to, len, unprinted);
413 size_t curlen = *unprinted == NULL ? 0 : strlen (*unprinted);
414 const unsigned char *start = buf;
417 if ((isprint (*buf) || *buf == '\t') && (! char_7bit || *buf <= 127))
424 if (curlen >= min_len)
426 /* We found a match. */
427 if (likely (fname != NULL))
429 fputs_unlocked (fname, stdout);
430 fputs_unlocked (": ", stdout);
433 if (likely (radix != radix_none))
434 printf ((radix == radix_octal ? "%7" PRIo64 " "
435 : (radix == radix_decimal ? "%7" PRId64 " "
437 (int64_t) to - len - (buf - start));
439 if (unlikely (*unprinted != NULL))
441 fputs_unlocked (*unprinted, stdout);
445 fwrite_unlocked (start, 1, buf - start, stdout);
446 putc_unlocked ('\n', stdout);
460 *unprinted = xstrndup ((const char *) start, curlen);
464 /* Map a file in as large chunks as possible. */
466 map_file (int fd, off64_t start_off, off64_t fdlen, size_t *map_sizep)
468 /* Maximum size we mmap. We use an #ifdef to avoid overflows on
469 32-bit machines. 64-bit machines these days do not have usable
470 address spaces larger than about 43 bits. Not that any file
471 should be that large. */
472 # if SIZE_MAX > 0xffffffff
473 const size_t mmap_max = 0x4000000000lu;
475 const size_t mmap_max = 0x40000000lu;
478 /* Try to mmap the file. */
479 size_t map_size = MIN ((off64_t) mmap_max, fdlen);
480 const size_t map_size_min = MAX (MAX (SIZE_MAX / 16, 2 * ps),
481 roundup (2 * min_len_bytes + 1, ps));
485 /* We map the memory for reading only here. Since we will
486 always look at every byte of the file it makes sense to
488 mem = mmap64 (NULL, map_size, PROT_READ, MAP_PRIVATE | MAP_POPULATE,
490 if (mem != MAP_FAILED)
492 /* We will go through the mapping sequentially. */
493 (void) posix_madvise (mem, map_size, POSIX_MADV_SEQUENTIAL);
496 if (errno != EINVAL && errno != ENOMEM)
497 /* This is an error other than the lack of address space. */
500 /* Maybe the size of the mapping is too big. Try again. */
502 if (map_size < map_size_min)
503 /* That size should have fit. */
507 *map_sizep = map_size;
512 /* Read the file without mapping. */
514 read_block_no_mmap (int fd, const char *fname, off64_t from, off64_t fdlen)
516 char *unprinted = NULL;
517 #define CHUNKSIZE 65536
518 unsigned char *buf = xmalloc (CHUNKSIZE + min_len_bytes
519 + bytes_per_char - 1);
524 ssize_t n = TEMP_FAILURE_RETRY (read (fd, buf + ntrailer,
525 MIN (fdlen, CHUNKSIZE)));
528 /* There are less than MIN_LEN+1 bytes left so there cannot be
530 assert (unprinted == NULL || ntrailer == 0);
533 if (unlikely (n < 0))
535 /* Something went wrong. */
540 /* Account for the number of bytes read in this round. */
543 /* Do not use the signed N value. Note that the addition cannot
545 size_t nb = (size_t) n + ntrailer;
546 if (nb >= min_len_bytes)
548 /* We only use complete characters. */
549 nb &= ~(bytes_per_char - 1);
551 process_chunk (fname, buf, from + nb, nb, &unprinted);
553 /* If the last bytes of the buffer (modulo the character
554 size) have been printed we are not copying them. */
555 size_t to_keep = unprinted != NULL ? 0 : min_len_bytes;
557 memmove (buf, buf + nb - to_keep, to_keep);
567 /* Don't print anything we collected so far. There is no
568 terminating NUL byte. */
576 read_block (int fd, const char *fname, off64_t fdlen, off64_t from, off64_t to)
580 /* We need a completely new mapping. */
581 elfmap_off = from & ~(ps - 1);
582 elfmap_base = elfmap = map_file (fd, elfmap_off, fdlen, &elfmap_size);
584 if (unlikely (elfmap == MAP_FAILED))
585 /* Let the kernel know we are going to read everything in sequence. */
586 (void) posix_fadvise (fd, 0, 0, POSIX_FADV_SEQUENTIAL);
589 if (unlikely (elfmap == MAP_FAILED))
591 /* Read from the file descriptor. For this we must position the
593 // XXX Eventually add flag which avoids this if the position
594 // XXX is known to match.
595 if (from != 0 && lseek64 (fd, from, SEEK_SET) != from)
596 error (EXIT_FAILURE, errno, gettext ("lseek64 failed"));
598 return read_block_no_mmap (fd, fname, from, to - from);
601 assert ((off64_t) min_len_bytes < fdlen);
603 if (to < (off64_t) elfmap_off || from > (off64_t) (elfmap_off + elfmap_size))
605 /* The existing mapping cannot fit at all. Map the new area.
606 We always map the full range of ELFMAP_SIZE bytes even if
607 this extend beyond the end of the file. The Linux kernel
608 handles this OK if the access pages are not touched. */
609 elfmap_off = from & ~(ps - 1);
610 if (mmap64 (elfmap, elfmap_size, PROT_READ,
611 MAP_PRIVATE | MAP_POPULATE | MAP_FIXED, fd, from)
613 error (EXIT_FAILURE, errno, gettext ("re-mmap failed"));
614 elfmap_base = elfmap;
617 char *unprinted = NULL;
619 /* Use the existing mapping as much as possible. If necessary, map
621 if (from >= (off64_t) elfmap_off
622 && from < (off64_t) (elfmap_off + elfmap_size))
623 /* There are at least a few bytes in this mapping which we can
625 process_chunk (fname, elfmap_base + (from - elfmap_off),
626 MIN (to, (off64_t) (elfmap_off + elfmap_size)),
627 MIN (to, (off64_t) (elfmap_off + elfmap_size)) - from,
630 if (to > (off64_t) (elfmap_off + elfmap_size))
632 unsigned char *remap_base = elfmap_base;
633 size_t read_now = elfmap_size - (elfmap_base - elfmap);
635 assert (from >= (off64_t) elfmap_off
636 && from < (off64_t) (elfmap_off + elfmap_size));
637 off64_t handled_to = elfmap_off + elfmap_size;
638 assert (elfmap == elfmap_base
639 || (elfmap_base - elfmap
640 == (ptrdiff_t) ((min_len_bytes + ps - 1) & ~(ps - 1))));
641 if (elfmap == elfmap_base)
643 size_t keep_area = (min_len_bytes + ps - 1) & ~(ps - 1);
644 assert (elfmap_size >= keep_area + ps);
645 /* The keep area is used for the content of the previous
646 buffer we have to keep. This means copying those bytes
647 and for this we have to make the data writable. */
648 if (unlikely (mprotect (elfmap, keep_area, PROT_READ | PROT_WRITE)
650 error (EXIT_FAILURE, errno, gettext ("mprotect failed"));
652 elfmap_base = elfmap + keep_area;
657 /* Map the rest of the file, eventually again in pieces.
658 We speed things up with a nice Linux feature. Note
659 that we have at least two pages mapped. */
660 size_t to_keep = unprinted != NULL ? 0 : min_len_bytes;
662 assert (read_now >= to_keep);
663 memmove (elfmap_base - to_keep,
664 remap_base + read_now - to_keep, to_keep);
665 remap_base = elfmap_base;
667 assert ((elfmap_size - (elfmap_base - elfmap)) % bytes_per_char
669 read_now = MIN (to - handled_to,
670 (ptrdiff_t) elfmap_size - (elfmap_base - elfmap));
672 assert (handled_to % ps == 0);
673 assert (handled_to % bytes_per_char == 0);
674 if (mmap64 (remap_base, read_now, PROT_READ,
675 MAP_PRIVATE | MAP_POPULATE | MAP_FIXED, fd, handled_to)
677 error (EXIT_FAILURE, errno, gettext ("re-mmap failed"));
678 elfmap_off = handled_to;
680 process_chunk (fname, remap_base - to_keep,
681 elfmap_off + (read_now & ~(bytes_per_char - 1)),
682 to_keep + (read_now & ~(bytes_per_char - 1)),
684 handled_to += read_now;
685 if (handled_to >= to)
690 /* Don't print anything we collected so far. There is no
691 terminating NUL byte. */
699 read_fd (int fd, const char *fname, off64_t fdlen)
701 return read_block (fd, fname, fdlen, 0, fdlen);
706 read_elf (Elf *elf, int fd, const char *fname, off64_t fdlen)
710 /* We will look at each section separately. The ELF file is not
711 mmapped. The libelf implementation will load the needed parts on
712 demand. Since we only interate over the section header table the
713 memory consumption at this stage is kept minimal. */
714 Elf_Scn *scn = elf_nextscn (elf, NULL);
716 return read_fd (fd, fname, fdlen);
722 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
724 /* Only look in sections which are loaded at runtime and
725 actually have content. */
726 if (shdr != NULL && shdr->sh_type != SHT_NOBITS
727 && (shdr->sh_flags & SHF_ALLOC) != 0)
728 result |= read_block (fd, fname, fdlen, shdr->sh_offset,
729 shdr->sh_offset + shdr->sh_size);
731 while ((scn = elf_nextscn (elf, scn)) != NULL);
733 if (elfmap != NULL && elfmap != MAP_FAILED)
734 munmap (elfmap, elfmap_size);
741 #include "debugpred.h"