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