* configure, config.in: Rebuild.
[platform/upstream/binutils.git] / bfd / bfdio.c
1 /* Low-level I/O routines for BFDs.
2
3    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
4    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
5    Free Software Foundation, Inc.
6
7    Written by Cygnus Support.
8
9    This file is part of BFD, the Binary File Descriptor library.
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
24    MA 02110-1301, USA.  */
25
26 #include "sysdep.h"
27 #include <limits.h>
28 #include "bfd.h"
29 #include "libbfd.h"
30
31 #ifndef S_IXUSR
32 #define S_IXUSR 0100    /* Execute by owner.  */
33 #endif
34 #ifndef S_IXGRP
35 #define S_IXGRP 0010    /* Execute by group.  */
36 #endif
37 #ifndef S_IXOTH
38 #define S_IXOTH 0001    /* Execute by others.  */
39 #endif
40
41 #ifndef FD_CLOEXEC
42 #define FD_CLOEXEC 1
43 #endif
44
45 file_ptr
46 real_ftell (FILE *file)
47 {
48 #if defined (HAVE_FTELLO64)
49   return ftello64 (file);
50 #elif defined (HAVE_FTELLO)
51   return ftello (file);
52 #else
53   return ftell (file);
54 #endif
55 }
56
57 int
58 real_fseek (FILE *file, file_ptr offset, int whence)
59 {
60 #if defined (HAVE_FSEEKO64)
61   return fseeko64 (file, offset, whence);
62 #elif defined (HAVE_FSEEKO)
63   return fseeko (file, offset, whence);
64 #else
65   return fseek (file, offset, whence);
66 #endif
67 }
68
69 /* Mark FILE as close-on-exec.  Return FILE.  FILE may be NULL, in
70    which case nothing is done.  */
71 static FILE *
72 close_on_exec (FILE *file)
73 {
74 #if defined (HAVE_FILENO) && defined (F_GETFD)
75   if (file)
76     {
77       int fd = fileno (file);
78       int old = fcntl (fd, F_GETFD, 0);
79       if (old >= 0)
80         fcntl (fd, F_SETFD, old | FD_CLOEXEC);
81     }
82 #endif
83   return file;
84 }
85
86 FILE *
87 real_fopen (const char *filename, const char *modes)
88 {
89 #if defined (HAVE_FOPEN64)
90   return close_on_exec (fopen64 (filename, modes));
91 #else
92   return close_on_exec (fopen (filename, modes));
93 #endif
94 }
95
96 /*
97 INTERNAL_DEFINITION
98         struct bfd_iovec
99
100 DESCRIPTION
101
102         The <<struct bfd_iovec>> contains the internal file I/O class.
103         Each <<BFD>> has an instance of this class and all file I/O is
104         routed through it (it is assumed that the instance implements
105         all methods listed below).
106
107 .struct bfd_iovec
108 .{
109 .  {* To avoid problems with macros, a "b" rather than "f"
110 .     prefix is prepended to each method name.  *}
111 .  {* Attempt to read/write NBYTES on ABFD's IOSTREAM storing/fetching
112 .     bytes starting at PTR.  Return the number of bytes actually
113 .     transfered (a read past end-of-file returns less than NBYTES),
114 .     or -1 (setting <<bfd_error>>) if an error occurs.  *}
115 .  file_ptr (*bread) (struct bfd *abfd, void *ptr, file_ptr nbytes);
116 .  file_ptr (*bwrite) (struct bfd *abfd, const void *ptr,
117 .                      file_ptr nbytes);
118 .  {* Return the current IOSTREAM file offset, or -1 (setting <<bfd_error>>
119 .     if an error occurs.  *}
120 .  file_ptr (*btell) (struct bfd *abfd);
121 .  {* For the following, on successful completion a value of 0 is returned.
122 .     Otherwise, a value of -1 is returned (and  <<bfd_error>> is set).  *}
123 .  int (*bseek) (struct bfd *abfd, file_ptr offset, int whence);
124 .  int (*bclose) (struct bfd *abfd);
125 .  int (*bflush) (struct bfd *abfd);
126 .  int (*bstat) (struct bfd *abfd, struct stat *sb);
127 .};
128
129 */
130
131
132 /* Return value is amount read.  */
133
134 bfd_size_type
135 bfd_bread (void *ptr, bfd_size_type size, bfd *abfd)
136 {
137   size_t nread;
138
139   /* If this is an archive element, don't read past the end of
140      this element.  */
141   if (abfd->arelt_data != NULL)
142     {
143       size_t maxbytes = ((struct areltdata *) abfd->arelt_data)->parsed_size;
144       if (size > maxbytes)
145         size = maxbytes;
146     }
147
148   if ((abfd->flags & BFD_IN_MEMORY) != 0)
149     {
150       struct bfd_in_memory *bim;
151       bfd_size_type get;
152
153       bim = abfd->iostream;
154       get = size;
155       if (abfd->where + get > bim->size)
156         {
157           if (bim->size < (bfd_size_type) abfd->where)
158             get = 0;
159           else
160             get = bim->size - abfd->where;
161           bfd_set_error (bfd_error_file_truncated);
162         }
163       memcpy (ptr, bim->buffer + abfd->where, (size_t) get);
164       abfd->where += get;
165       return get;
166     }
167
168   if (abfd->iovec)
169     nread = abfd->iovec->bread (abfd, ptr, size);
170   else
171     nread = 0;
172   if (nread != (size_t) -1)
173     abfd->where += nread;
174
175   return nread;
176 }
177
178 bfd_size_type
179 bfd_bwrite (const void *ptr, bfd_size_type size, bfd *abfd)
180 {
181   size_t nwrote;
182
183   if ((abfd->flags & BFD_IN_MEMORY) != 0)
184     {
185       struct bfd_in_memory *bim = abfd->iostream;
186
187       size = (size_t) size;
188       if (abfd->where + size > bim->size)
189         {
190           bfd_size_type newsize, oldsize;
191
192           oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
193           bim->size = abfd->where + size;
194           /* Round up to cut down on memory fragmentation */
195           newsize = (bim->size + 127) & ~(bfd_size_type) 127;
196           if (newsize > oldsize)
197             {
198               bim->buffer = bfd_realloc_or_free (bim->buffer, newsize);
199               if (bim->buffer == NULL)
200                 {
201                   bim->size = 0;
202                   return 0;
203                 }
204             }
205         }
206       memcpy (bim->buffer + abfd->where, ptr, (size_t) size);
207       abfd->where += size;
208       return size;
209     }
210
211   if (abfd->iovec)
212     nwrote = abfd->iovec->bwrite (abfd, ptr, size);
213   else
214     nwrote = 0;
215
216   if (nwrote != (size_t) -1)
217     abfd->where += nwrote;
218   if (nwrote != size)
219     {
220 #ifdef ENOSPC
221       errno = ENOSPC;
222 #endif
223       bfd_set_error (bfd_error_system_call);
224     }
225   return nwrote;
226 }
227
228 file_ptr
229 bfd_tell (bfd *abfd)
230 {
231   file_ptr ptr;
232
233   if ((abfd->flags & BFD_IN_MEMORY) != 0)
234     return abfd->where;
235
236   if (abfd->iovec)
237     {
238       ptr = abfd->iovec->btell (abfd);
239
240       if (abfd->my_archive)
241         ptr -= abfd->origin;
242     }
243   else
244     ptr = 0;
245
246   abfd->where = ptr;
247   return ptr;
248 }
249
250 int
251 bfd_flush (bfd *abfd)
252 {
253   if ((abfd->flags & BFD_IN_MEMORY) != 0)
254     return 0;
255
256   if (abfd->iovec)
257     return abfd->iovec->bflush (abfd);
258   return 0;
259 }
260
261 /* Returns 0 for success, negative value for failure (in which case
262    bfd_get_error can retrieve the error code).  */
263 int
264 bfd_stat (bfd *abfd, struct stat *statbuf)
265 {
266   int result;
267
268   if ((abfd->flags & BFD_IN_MEMORY) != 0)
269     abort ();
270
271   if (abfd->iovec)
272     result = abfd->iovec->bstat (abfd, statbuf);
273   else
274     result = -1;
275
276   if (result < 0)
277     bfd_set_error (bfd_error_system_call);
278   return result;
279 }
280
281 /* Returns 0 for success, nonzero for failure (in which case bfd_get_error
282    can retrieve the error code).  */
283
284 int
285 bfd_seek (bfd *abfd, file_ptr position, int direction)
286 {
287   int result;
288   file_ptr file_position;
289   /* For the time being, a BFD may not seek to it's end.  The problem
290      is that we don't easily have a way to recognize the end of an
291      element in an archive.  */
292
293   BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);
294
295   if (direction == SEEK_CUR && position == 0)
296     return 0;
297
298   if ((abfd->flags & BFD_IN_MEMORY) != 0)
299     {
300       struct bfd_in_memory *bim;
301
302       bim = abfd->iostream;
303
304       if (direction == SEEK_SET)
305         abfd->where = position;
306       else
307         abfd->where += position;
308
309       if (abfd->where > bim->size)
310         {
311           if ((abfd->direction == write_direction) ||
312               (abfd->direction == both_direction))
313             {
314               bfd_size_type newsize, oldsize;
315
316               oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
317               bim->size = abfd->where;
318               /* Round up to cut down on memory fragmentation */
319               newsize = (bim->size + 127) & ~(bfd_size_type) 127;
320               if (newsize > oldsize)
321                 {
322                   bim->buffer = bfd_realloc_or_free (bim->buffer, newsize);
323                   if (bim->buffer == NULL)
324                     {
325                       bim->size = 0;
326                       return -1;
327                     }
328                 }
329             }
330           else
331             {
332               abfd->where = bim->size;
333               bfd_set_error (bfd_error_file_truncated);
334               return -1;
335             }
336         }
337       return 0;
338     }
339
340   if (abfd->format != bfd_archive && abfd->my_archive == 0)
341     {
342       if (direction == SEEK_SET && (bfd_vma) position == abfd->where)
343         return 0;
344     }
345   else
346     {
347       /* We need something smarter to optimize access to archives.
348          Currently, anything inside an archive is read via the file
349          handle for the archive.  Which means that a bfd_seek on one
350          component affects the `current position' in the archive, as
351          well as in any other component.
352
353          It might be sufficient to put a spike through the cache
354          abstraction, and look to the archive for the file position,
355          but I think we should try for something cleaner.
356
357          In the meantime, no optimization for archives.  */
358     }
359
360   file_position = position;
361   if (direction == SEEK_SET && abfd->my_archive != NULL)
362     file_position += abfd->origin;
363
364   if (abfd->iovec)
365     result = abfd->iovec->bseek (abfd, file_position, direction);
366   else
367     result = -1;
368
369   if (result != 0)
370     {
371       int hold_errno = errno;
372
373       /* Force redetermination of `where' field.  */
374       bfd_tell (abfd);
375
376       /* An EINVAL error probably means that the file offset was
377          absurd.  */
378       if (hold_errno == EINVAL)
379         bfd_set_error (bfd_error_file_truncated);
380       else
381         {
382           bfd_set_error (bfd_error_system_call);
383           errno = hold_errno;
384         }
385     }
386   else
387     {
388       /* Adjust `where' field.  */
389       if (direction == SEEK_SET)
390         abfd->where = position;
391       else
392         abfd->where += position;
393     }
394   return result;
395 }
396
397 /*
398 FUNCTION
399         bfd_get_mtime
400
401 SYNOPSIS
402         long bfd_get_mtime (bfd *abfd);
403
404 DESCRIPTION
405         Return the file modification time (as read from the file system, or
406         from the archive header for archive members).
407
408 */
409
410 long
411 bfd_get_mtime (bfd *abfd)
412 {
413   struct stat buf;
414
415   if (abfd->mtime_set)
416     return abfd->mtime;
417
418   if (abfd->iovec == NULL)
419     return 0;
420
421   if (abfd->iovec->bstat (abfd, &buf) != 0)
422     return 0;
423
424   abfd->mtime = buf.st_mtime;           /* Save value in case anyone wants it */
425   return buf.st_mtime;
426 }
427
428 /*
429 FUNCTION
430         bfd_get_size
431
432 SYNOPSIS
433         file_ptr bfd_get_size (bfd *abfd);
434
435 DESCRIPTION
436         Return the file size (as read from file system) for the file
437         associated with BFD @var{abfd}.
438
439         The initial motivation for, and use of, this routine is not
440         so we can get the exact size of the object the BFD applies to, since
441         that might not be generally possible (archive members for example).
442         It would be ideal if someone could eventually modify
443         it so that such results were guaranteed.
444
445         Instead, we want to ask questions like "is this NNN byte sized
446         object I'm about to try read from file offset YYY reasonable?"
447         As as example of where we might do this, some object formats
448         use string tables for which the first <<sizeof (long)>> bytes of the
449         table contain the size of the table itself, including the size bytes.
450         If an application tries to read what it thinks is one of these
451         string tables, without some way to validate the size, and for
452         some reason the size is wrong (byte swapping error, wrong location
453         for the string table, etc.), the only clue is likely to be a read
454         error when it tries to read the table, or a "virtual memory
455         exhausted" error when it tries to allocate 15 bazillon bytes
456         of space for the 15 bazillon byte table it is about to read.
457         This function at least allows us to answer the question, "is the
458         size reasonable?".
459 */
460
461 file_ptr
462 bfd_get_size (bfd *abfd)
463 {
464   struct stat buf;
465
466   if ((abfd->flags & BFD_IN_MEMORY) != 0)
467     return ((struct bfd_in_memory *) abfd->iostream)->size;
468
469   if (abfd->iovec == NULL)
470     return 0;
471
472   if (abfd->iovec->bstat (abfd, &buf) != 0)
473     return 0;
474
475   return buf.st_size;
476 }