* bfdio.c (bfd_seek): Formatting. Ensure newly allocated memory
[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 #ifdef VMS
90   char vms_modes[4];
91   char *vms_attr;
92
93   /* On VMS, fopen allows file attributes as optionnal arguments.
94      We need to use them but we'd better to use the common prototype.
95      In fopen-vms.h, they are separated from the mode with a comma.
96      Split here.  */
97   vms_attr = strchr (modes, ',');
98   if (vms_attr == NULL)
99     {
100       /* No attributes.  */
101       return close_on_exec (fopen (filename, modes));
102     }
103   else
104     {
105       /* Attributes found.  Split.  */
106       size_t modes_len = strlen (modes) + 1;
107       char attrs[modes_len + 1];
108       char *at[3];
109       int i;
110
111       memcpy (attrs, modes, modes_len);
112       at[0] = attrs;
113       for (i = 0; i < 2; i++)
114         {
115           at[i + 1] = strchr (at[i], ',');
116           BFD_ASSERT (at[i + 1] != NULL);
117           *(at[i + 1]++) = 0; /* Replace ',' with a nul, and skip it.  */
118         }
119       return close_on_exec (fopen (filename, at[0], at[1], at[2]));
120     }
121 #else /* !VMS */
122 #if defined (HAVE_FOPEN64)
123   return close_on_exec (fopen64 (filename, modes));
124 #else
125   return close_on_exec (fopen (filename, modes));
126 #endif
127 #endif /* !VMS */
128 }
129
130 /*
131 INTERNAL_DEFINITION
132         struct bfd_iovec
133
134 DESCRIPTION
135
136         The <<struct bfd_iovec>> contains the internal file I/O class.
137         Each <<BFD>> has an instance of this class and all file I/O is
138         routed through it (it is assumed that the instance implements
139         all methods listed below).
140
141 .struct bfd_iovec
142 .{
143 .  {* To avoid problems with macros, a "b" rather than "f"
144 .     prefix is prepended to each method name.  *}
145 .  {* Attempt to read/write NBYTES on ABFD's IOSTREAM storing/fetching
146 .     bytes starting at PTR.  Return the number of bytes actually
147 .     transfered (a read past end-of-file returns less than NBYTES),
148 .     or -1 (setting <<bfd_error>>) if an error occurs.  *}
149 .  file_ptr (*bread) (struct bfd *abfd, void *ptr, file_ptr nbytes);
150 .  file_ptr (*bwrite) (struct bfd *abfd, const void *ptr,
151 .                      file_ptr nbytes);
152 .  {* Return the current IOSTREAM file offset, or -1 (setting <<bfd_error>>
153 .     if an error occurs.  *}
154 .  file_ptr (*btell) (struct bfd *abfd);
155 .  {* For the following, on successful completion a value of 0 is returned.
156 .     Otherwise, a value of -1 is returned (and  <<bfd_error>> is set).  *}
157 .  int (*bseek) (struct bfd *abfd, file_ptr offset, int whence);
158 .  int (*bclose) (struct bfd *abfd);
159 .  int (*bflush) (struct bfd *abfd);
160 .  int (*bstat) (struct bfd *abfd, struct stat *sb);
161 .};
162
163 */
164
165
166 /* Return value is amount read.  */
167
168 bfd_size_type
169 bfd_bread (void *ptr, bfd_size_type size, bfd *abfd)
170 {
171   size_t nread;
172
173   /* If this is an archive element, don't read past the end of
174      this element.  */
175   if (abfd->arelt_data != NULL)
176     {
177       size_t maxbytes = ((struct areltdata *) abfd->arelt_data)->parsed_size;
178       if (size > maxbytes)
179         size = maxbytes;
180     }
181
182   if ((abfd->flags & BFD_IN_MEMORY) != 0)
183     {
184       struct bfd_in_memory *bim;
185       bfd_size_type get;
186
187       bim = abfd->iostream;
188       get = size;
189       if (abfd->where + get > bim->size)
190         {
191           if (bim->size < (bfd_size_type) abfd->where)
192             get = 0;
193           else
194             get = bim->size - abfd->where;
195           bfd_set_error (bfd_error_file_truncated);
196         }
197       memcpy (ptr, bim->buffer + abfd->where, (size_t) get);
198       abfd->where += get;
199       return get;
200     }
201
202   if (abfd->iovec)
203     nread = abfd->iovec->bread (abfd, ptr, size);
204   else
205     nread = 0;
206   if (nread != (size_t) -1)
207     abfd->where += nread;
208
209   return nread;
210 }
211
212 bfd_size_type
213 bfd_bwrite (const void *ptr, bfd_size_type size, bfd *abfd)
214 {
215   size_t nwrote;
216
217   if ((abfd->flags & BFD_IN_MEMORY) != 0)
218     {
219       struct bfd_in_memory *bim = abfd->iostream;
220
221       size = (size_t) size;
222       if (abfd->where + size > bim->size)
223         {
224           bfd_size_type newsize, oldsize;
225
226           oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
227           bim->size = abfd->where + size;
228           /* Round up to cut down on memory fragmentation */
229           newsize = (bim->size + 127) & ~(bfd_size_type) 127;
230           if (newsize > oldsize)
231             {
232               bim->buffer = bfd_realloc_or_free (bim->buffer, newsize);
233               if (bim->buffer == NULL)
234                 {
235                   bim->size = 0;
236                   return 0;
237                 }
238               if (newsize > bim->size)
239                 memset (bim->buffer + bim->size, 0, newsize - bim->size);
240             }
241         }
242       memcpy (bim->buffer + abfd->where, ptr, (size_t) size);
243       abfd->where += size;
244       return size;
245     }
246
247   if (abfd->iovec)
248     nwrote = abfd->iovec->bwrite (abfd, ptr, size);
249   else
250     nwrote = 0;
251
252   if (nwrote != (size_t) -1)
253     abfd->where += nwrote;
254   if (nwrote != size)
255     {
256 #ifdef ENOSPC
257       errno = ENOSPC;
258 #endif
259       bfd_set_error (bfd_error_system_call);
260     }
261   return nwrote;
262 }
263
264 file_ptr
265 bfd_tell (bfd *abfd)
266 {
267   file_ptr ptr;
268
269   if ((abfd->flags & BFD_IN_MEMORY) != 0)
270     return abfd->where;
271
272   if (abfd->iovec)
273     {
274       ptr = abfd->iovec->btell (abfd);
275
276       if (abfd->my_archive)
277         ptr -= abfd->origin;
278     }
279   else
280     ptr = 0;
281
282   abfd->where = ptr;
283   return ptr;
284 }
285
286 int
287 bfd_flush (bfd *abfd)
288 {
289   if ((abfd->flags & BFD_IN_MEMORY) != 0)
290     return 0;
291
292   if (abfd->iovec)
293     return abfd->iovec->bflush (abfd);
294   return 0;
295 }
296
297 /* Returns 0 for success, negative value for failure (in which case
298    bfd_get_error can retrieve the error code).  */
299 int
300 bfd_stat (bfd *abfd, struct stat *statbuf)
301 {
302   int result;
303
304   if ((abfd->flags & BFD_IN_MEMORY) != 0)
305     abort ();
306
307   if (abfd->iovec)
308     result = abfd->iovec->bstat (abfd, statbuf);
309   else
310     result = -1;
311
312   if (result < 0)
313     bfd_set_error (bfd_error_system_call);
314   return result;
315 }
316
317 /* Returns 0 for success, nonzero for failure (in which case bfd_get_error
318    can retrieve the error code).  */
319
320 int
321 bfd_seek (bfd *abfd, file_ptr position, int direction)
322 {
323   int result;
324   file_ptr file_position;
325   /* For the time being, a BFD may not seek to it's end.  The problem
326      is that we don't easily have a way to recognize the end of an
327      element in an archive.  */
328
329   BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);
330
331   if (direction == SEEK_CUR && position == 0)
332     return 0;
333
334   if ((abfd->flags & BFD_IN_MEMORY) != 0)
335     {
336       struct bfd_in_memory *bim;
337
338       bim = abfd->iostream;
339
340       if (direction == SEEK_SET)
341         abfd->where = position;
342       else
343         abfd->where += position;
344
345       if (abfd->where > bim->size)
346         {
347           if (abfd->direction == write_direction
348               || abfd->direction == both_direction)
349             {
350               bfd_size_type newsize, oldsize;
351
352               oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
353               bim->size = abfd->where;
354               /* Round up to cut down on memory fragmentation */
355               newsize = (bim->size + 127) & ~(bfd_size_type) 127;
356               if (newsize > oldsize)
357                 {
358                   bim->buffer = bfd_realloc_or_free (bim->buffer, newsize);
359                   if (bim->buffer == NULL)
360                     {
361                       bim->size = 0;
362                       return -1;
363                     }
364                   memset (bim->buffer + oldsize, 0, newsize - oldsize);
365                 }
366             }
367           else
368             {
369               abfd->where = bim->size;
370               bfd_set_error (bfd_error_file_truncated);
371               return -1;
372             }
373         }
374       return 0;
375     }
376
377   if (abfd->format != bfd_archive && abfd->my_archive == 0)
378     {
379       if (direction == SEEK_SET && (bfd_vma) position == abfd->where)
380         return 0;
381     }
382   else
383     {
384       /* We need something smarter to optimize access to archives.
385          Currently, anything inside an archive is read via the file
386          handle for the archive.  Which means that a bfd_seek on one
387          component affects the `current position' in the archive, as
388          well as in any other component.
389
390          It might be sufficient to put a spike through the cache
391          abstraction, and look to the archive for the file position,
392          but I think we should try for something cleaner.
393
394          In the meantime, no optimization for archives.  */
395     }
396
397   file_position = position;
398   if (direction == SEEK_SET && abfd->my_archive != NULL)
399     file_position += abfd->origin;
400
401   if (abfd->iovec)
402     result = abfd->iovec->bseek (abfd, file_position, direction);
403   else
404     result = -1;
405
406   if (result != 0)
407     {
408       int hold_errno = errno;
409
410       /* Force redetermination of `where' field.  */
411       bfd_tell (abfd);
412
413       /* An EINVAL error probably means that the file offset was
414          absurd.  */
415       if (hold_errno == EINVAL)
416         bfd_set_error (bfd_error_file_truncated);
417       else
418         {
419           bfd_set_error (bfd_error_system_call);
420           errno = hold_errno;
421         }
422     }
423   else
424     {
425       /* Adjust `where' field.  */
426       if (direction == SEEK_SET)
427         abfd->where = position;
428       else
429         abfd->where += position;
430     }
431   return result;
432 }
433
434 /*
435 FUNCTION
436         bfd_get_mtime
437
438 SYNOPSIS
439         long bfd_get_mtime (bfd *abfd);
440
441 DESCRIPTION
442         Return the file modification time (as read from the file system, or
443         from the archive header for archive members).
444
445 */
446
447 long
448 bfd_get_mtime (bfd *abfd)
449 {
450   struct stat buf;
451
452   if (abfd->mtime_set)
453     return abfd->mtime;
454
455   if (abfd->iovec == NULL)
456     return 0;
457
458   if (abfd->iovec->bstat (abfd, &buf) != 0)
459     return 0;
460
461   abfd->mtime = buf.st_mtime;           /* Save value in case anyone wants it */
462   return buf.st_mtime;
463 }
464
465 /*
466 FUNCTION
467         bfd_get_size
468
469 SYNOPSIS
470         file_ptr bfd_get_size (bfd *abfd);
471
472 DESCRIPTION
473         Return the file size (as read from file system) for the file
474         associated with BFD @var{abfd}.
475
476         The initial motivation for, and use of, this routine is not
477         so we can get the exact size of the object the BFD applies to, since
478         that might not be generally possible (archive members for example).
479         It would be ideal if someone could eventually modify
480         it so that such results were guaranteed.
481
482         Instead, we want to ask questions like "is this NNN byte sized
483         object I'm about to try read from file offset YYY reasonable?"
484         As as example of where we might do this, some object formats
485         use string tables for which the first <<sizeof (long)>> bytes of the
486         table contain the size of the table itself, including the size bytes.
487         If an application tries to read what it thinks is one of these
488         string tables, without some way to validate the size, and for
489         some reason the size is wrong (byte swapping error, wrong location
490         for the string table, etc.), the only clue is likely to be a read
491         error when it tries to read the table, or a "virtual memory
492         exhausted" error when it tries to allocate 15 bazillon bytes
493         of space for the 15 bazillon byte table it is about to read.
494         This function at least allows us to answer the question, "is the
495         size reasonable?".
496 */
497
498 file_ptr
499 bfd_get_size (bfd *abfd)
500 {
501   struct stat buf;
502
503   if ((abfd->flags & BFD_IN_MEMORY) != 0)
504     return ((struct bfd_in_memory *) abfd->iostream)->size;
505
506   if (abfd->iovec == NULL)
507     return 0;
508
509   if (abfd->iovec->bstat (abfd, &buf) != 0)
510     return 0;
511
512   return buf.st_size;
513 }