bfdio.c revision 130562
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 Free Software Foundation, Inc.
5
6   Written by Cygnus Support.
7
8This file is part of BFD, the Binary File Descriptor library.
9
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2 of the License, or
13(at your option) any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
23
24#include "sysdep.h"
25
26#include "bfd.h"
27#include "libbfd.h"
28
29#include <limits.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
41file_ptr
42real_ftell (FILE *file)
43{
44#if defined (HAVE_FTELLO64)
45  return ftello64 (file);
46#elif defined (HAVE_FTELLO)
47  return ftello (file);
48#else
49  return ftell (file);
50#endif
51}
52
53int
54real_fseek (FILE *file, file_ptr offset, int whence)
55{
56#if defined (HAVE_FSEEKO64)
57  return fseeko64 (file, offset, whence);
58#elif defined (HAVE_FSEEKO)
59  return fseeko (file, offset, whence);
60#else
61  return fseek (file, offset, whence);
62#endif
63}
64
65/* Note that archive entries don't have streams; they share their parent's.
66   This allows someone to play with the iostream behind BFD's back.
67
68   Also, note that the origin pointer points to the beginning of a file's
69   contents (0 for non-archive elements).  For archive entries this is the
70   first octet in the file, NOT the beginning of the archive header.  */
71
72static size_t
73real_read (void *where, size_t a, size_t b, FILE *file)
74{
75  /* FIXME - this looks like an optimization, but it's really to cover
76     up for a feature of some OSs (not solaris - sigh) that
77     ld/pe-dll.c takes advantage of (apparently) when it creates BFDs
78     internally and tries to link against them.  BFD seems to be smart
79     enough to realize there are no symbol records in the "file" that
80     doesn't exist but attempts to read them anyway.  On Solaris,
81     attempting to read zero bytes from a NULL file results in a core
82     dump, but on other platforms it just returns zero bytes read.
83     This makes it to something reasonable. - DJ */
84  if (a == 0 || b == 0)
85    return 0;
86
87
88#if defined (__VAX) && defined (VMS)
89  /* Apparently fread on Vax VMS does not keep the record length
90     information.  */
91  return read (fileno (file), where, a * b);
92#else
93  return fread (where, a, b, file);
94#endif
95}
96
97/* Return value is amount read.  */
98
99bfd_size_type
100bfd_bread (void *ptr, bfd_size_type size, bfd *abfd)
101{
102  size_t nread;
103
104  if ((abfd->flags & BFD_IN_MEMORY) != 0)
105    {
106      struct bfd_in_memory *bim;
107      bfd_size_type get;
108
109      bim = abfd->iostream;
110      get = size;
111      if (abfd->where + get > bim->size)
112	{
113	  if (bim->size < (bfd_size_type) abfd->where)
114	    get = 0;
115	  else
116	    get = bim->size - abfd->where;
117	  bfd_set_error (bfd_error_file_truncated);
118	}
119      memcpy (ptr, bim->buffer + abfd->where, (size_t) get);
120      abfd->where += get;
121      return get;
122    }
123
124  nread = real_read (ptr, 1, (size_t) size, bfd_cache_lookup (abfd));
125  if (nread != (size_t) -1)
126    abfd->where += nread;
127
128  /* Set bfd_error if we did not read as much data as we expected.
129
130     If the read failed due to an error set the bfd_error_system_call,
131     else set bfd_error_file_truncated.
132
133     A BFD backend may wish to override bfd_error_file_truncated to
134     provide something more useful (eg. no_symbols or wrong_format).  */
135  if (nread != size)
136    {
137      if (ferror (bfd_cache_lookup (abfd)))
138	bfd_set_error (bfd_error_system_call);
139      else
140	bfd_set_error (bfd_error_file_truncated);
141    }
142
143  return nread;
144}
145
146bfd_size_type
147bfd_bwrite (const void *ptr, bfd_size_type size, bfd *abfd)
148{
149  size_t nwrote;
150
151  if ((abfd->flags & BFD_IN_MEMORY) != 0)
152    {
153      struct bfd_in_memory *bim = abfd->iostream;
154      size = (size_t) size;
155      if (abfd->where + size > bim->size)
156	{
157	  bfd_size_type newsize, oldsize;
158
159	  oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
160	  bim->size = abfd->where + size;
161	  /* Round up to cut down on memory fragmentation */
162	  newsize = (bim->size + 127) & ~(bfd_size_type) 127;
163	  if (newsize > oldsize)
164	    {
165	      bim->buffer = bfd_realloc (bim->buffer, newsize);
166	      if (bim->buffer == 0)
167		{
168		  bim->size = 0;
169		  return 0;
170		}
171	    }
172	}
173      memcpy (bim->buffer + abfd->where, ptr, (size_t) size);
174      abfd->where += size;
175      return size;
176    }
177
178  nwrote = fwrite (ptr, 1, (size_t) size, bfd_cache_lookup (abfd));
179  if (nwrote != (size_t) -1)
180    abfd->where += nwrote;
181  if (nwrote != size)
182    {
183#ifdef ENOSPC
184      errno = ENOSPC;
185#endif
186      bfd_set_error (bfd_error_system_call);
187    }
188  return nwrote;
189}
190
191file_ptr
192bfd_tell (bfd *abfd)
193{
194  file_ptr ptr;
195
196  if ((abfd->flags & BFD_IN_MEMORY) != 0)
197    return abfd->where;
198
199  ptr = real_ftell (bfd_cache_lookup (abfd));
200
201  if (abfd->my_archive)
202    ptr -= abfd->origin;
203  abfd->where = ptr;
204  return ptr;
205}
206
207int
208bfd_flush (bfd *abfd)
209{
210  if ((abfd->flags & BFD_IN_MEMORY) != 0)
211    return 0;
212  return fflush (bfd_cache_lookup(abfd));
213}
214
215/* Returns 0 for success, negative value for failure (in which case
216   bfd_get_error can retrieve the error code).  */
217int
218bfd_stat (bfd *abfd, struct stat *statbuf)
219{
220  FILE *f;
221  int result;
222
223  if ((abfd->flags & BFD_IN_MEMORY) != 0)
224    abort ();
225
226  f = bfd_cache_lookup (abfd);
227  if (f == NULL)
228    {
229      bfd_set_error (bfd_error_system_call);
230      return -1;
231    }
232  result = fstat (fileno (f), statbuf);
233  if (result < 0)
234    bfd_set_error (bfd_error_system_call);
235  return result;
236}
237
238/* Returns 0 for success, nonzero for failure (in which case bfd_get_error
239   can retrieve the error code).  */
240
241int
242bfd_seek (bfd *abfd, file_ptr position, int direction)
243{
244  int result;
245  FILE *f;
246  file_ptr file_position;
247  /* For the time being, a BFD may not seek to it's end.  The problem
248     is that we don't easily have a way to recognize the end of an
249     element in an archive.  */
250
251  BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);
252
253  if (direction == SEEK_CUR && position == 0)
254    return 0;
255
256  if ((abfd->flags & BFD_IN_MEMORY) != 0)
257    {
258      struct bfd_in_memory *bim;
259
260      bim = abfd->iostream;
261
262      if (direction == SEEK_SET)
263	abfd->where = position;
264      else
265	abfd->where += position;
266
267      if (abfd->where > bim->size)
268	{
269	  if ((abfd->direction == write_direction) ||
270	      (abfd->direction == both_direction))
271	    {
272	      bfd_size_type newsize, oldsize;
273	      oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
274	      bim->size = abfd->where;
275	      /* Round up to cut down on memory fragmentation */
276	      newsize = (bim->size + 127) & ~(bfd_size_type) 127;
277	      if (newsize > oldsize)
278	        {
279		  bim->buffer = bfd_realloc (bim->buffer, newsize);
280		  if (bim->buffer == 0)
281		    {
282		      bim->size = 0;
283		      return -1;
284		    }
285	        }
286	    }
287	  else
288	    {
289	      abfd->where = bim->size;
290	      bfd_set_error (bfd_error_file_truncated);
291	      return -1;
292	    }
293	}
294      return 0;
295    }
296
297  if (abfd->format != bfd_archive && abfd->my_archive == 0)
298    {
299#if 0
300      /* Explanation for this code: I'm only about 95+% sure that the above
301	 conditions are sufficient and that all i/o calls are properly
302	 adjusting the `where' field.  So this is sort of an `assert'
303	 that the `where' field is correct.  If we can go a while without
304	 tripping the abort, we can probably safely disable this code,
305	 so that the real optimizations happen.  */
306      file_ptr where_am_i_now;
307      where_am_i_now = real_ftell (bfd_cache_lookup (abfd));
308      if (abfd->my_archive)
309	where_am_i_now -= abfd->origin;
310      if (where_am_i_now != abfd->where)
311	abort ();
312#endif
313      if (direction == SEEK_SET && (bfd_vma) position == abfd->where)
314	return 0;
315    }
316  else
317    {
318      /* We need something smarter to optimize access to archives.
319	 Currently, anything inside an archive is read via the file
320	 handle for the archive.  Which means that a bfd_seek on one
321	 component affects the `current position' in the archive, as
322	 well as in any other component.
323
324	 It might be sufficient to put a spike through the cache
325	 abstraction, and look to the archive for the file position,
326	 but I think we should try for something cleaner.
327
328	 In the meantime, no optimization for archives.  */
329    }
330
331  f = bfd_cache_lookup (abfd);
332  file_position = position;
333  if (direction == SEEK_SET && abfd->my_archive != NULL)
334    file_position += abfd->origin;
335
336  result = real_fseek (f, file_position, direction);
337  if (result != 0)
338    {
339      int hold_errno = errno;
340
341      /* Force redetermination of `where' field.  */
342      bfd_tell (abfd);
343
344      /* An EINVAL error probably means that the file offset was
345         absurd.  */
346      if (hold_errno == EINVAL)
347	bfd_set_error (bfd_error_file_truncated);
348      else
349	{
350	  bfd_set_error (bfd_error_system_call);
351	  errno = hold_errno;
352	}
353    }
354  else
355    {
356      /* Adjust `where' field.  */
357      if (direction == SEEK_SET)
358	abfd->where = position;
359      else
360	abfd->where += position;
361    }
362  return result;
363}
364
365/*
366FUNCTION
367	bfd_get_mtime
368
369SYNOPSIS
370	long bfd_get_mtime (bfd *abfd);
371
372DESCRIPTION
373	Return the file modification time (as read from the file system, or
374	from the archive header for archive members).
375
376*/
377
378long
379bfd_get_mtime (bfd *abfd)
380{
381  FILE *fp;
382  struct stat buf;
383
384  if (abfd->mtime_set)
385    return abfd->mtime;
386
387  fp = bfd_cache_lookup (abfd);
388  if (0 != fstat (fileno (fp), &buf))
389    return 0;
390
391  abfd->mtime = buf.st_mtime;		/* Save value in case anyone wants it */
392  return buf.st_mtime;
393}
394
395/*
396FUNCTION
397	bfd_get_size
398
399SYNOPSIS
400	long bfd_get_size (bfd *abfd);
401
402DESCRIPTION
403	Return the file size (as read from file system) for the file
404	associated with BFD @var{abfd}.
405
406	The initial motivation for, and use of, this routine is not
407	so we can get the exact size of the object the BFD applies to, since
408	that might not be generally possible (archive members for example).
409	It would be ideal if someone could eventually modify
410	it so that such results were guaranteed.
411
412	Instead, we want to ask questions like "is this NNN byte sized
413	object I'm about to try read from file offset YYY reasonable?"
414	As as example of where we might do this, some object formats
415	use string tables for which the first <<sizeof (long)>> bytes of the
416	table contain the size of the table itself, including the size bytes.
417	If an application tries to read what it thinks is one of these
418	string tables, without some way to validate the size, and for
419	some reason the size is wrong (byte swapping error, wrong location
420	for the string table, etc.), the only clue is likely to be a read
421	error when it tries to read the table, or a "virtual memory
422	exhausted" error when it tries to allocate 15 bazillon bytes
423	of space for the 15 bazillon byte table it is about to read.
424	This function at least allows us to answer the question, "is the
425	size reasonable?".
426*/
427
428long
429bfd_get_size (bfd *abfd)
430{
431  FILE *fp;
432  struct stat buf;
433
434  if ((abfd->flags & BFD_IN_MEMORY) != 0)
435    return ((struct bfd_in_memory *) abfd->iostream)->size;
436
437  fp = bfd_cache_lookup (abfd);
438  if (0 != fstat (fileno (fp), & buf))
439    return 0;
440
441  return buf.st_size;
442}
443