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