This time the version of the patch that works.
[binutils.git] / bfd / bfdio.c
bloba90cb33ea5f87b3641093bd2433b545fedf5377a
1 /* Low-level I/O routines for BFDs.
3 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
4 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
6 Written by Cygnus Support.
8 This file is part of BFD, the Binary File Descriptor library.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 #include "sysdep.h"
26 #include "bfd.h"
27 #include "libbfd.h"
29 #include <limits.h>
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
41 file_ptr
42 real_ftell (FILE *file)
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
53 int
54 real_fseek (FILE *file, file_ptr offset, int whence)
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
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.
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. */
72 static size_t
73 real_read (void *where, size_t a, size_t b, FILE *file)
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;
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
97 /* Return value is amount read. */
99 bfd_size_type
100 bfd_bread (void *ptr, bfd_size_type size, bfd *abfd)
102 size_t nread;
104 if ((abfd->flags & BFD_IN_MEMORY) != 0)
106 struct bfd_in_memory *bim;
107 bfd_size_type get;
109 bim = abfd->iostream;
110 get = size;
111 if (abfd->where + get > bim->size)
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);
119 memcpy (ptr, bim->buffer + abfd->where, (size_t) get);
120 abfd->where += get;
121 return get;
124 nread = real_read (ptr, 1, (size_t) size, bfd_cache_lookup (abfd));
125 if (nread != (size_t) -1)
126 abfd->where += nread;
128 /* Set bfd_error if we did not read as much data as we expected.
130 If the read failed due to an error set the bfd_error_system_call,
131 else set bfd_error_file_truncated.
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)
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);
143 return nread;
146 bfd_size_type
147 bfd_bwrite (const void *ptr, bfd_size_type size, bfd *abfd)
149 size_t nwrote;
151 if ((abfd->flags & BFD_IN_MEMORY) != 0)
153 struct bfd_in_memory *bim = abfd->iostream;
154 size = (size_t) size;
155 if (abfd->where + size > bim->size)
157 bfd_size_type newsize, oldsize;
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)
165 bim->buffer = bfd_realloc (bim->buffer, newsize);
166 if (bim->buffer == 0)
168 bim->size = 0;
169 return 0;
173 memcpy (bim->buffer + abfd->where, ptr, (size_t) size);
174 abfd->where += size;
175 return size;
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)
183 #ifdef ENOSPC
184 errno = ENOSPC;
185 #endif
186 bfd_set_error (bfd_error_system_call);
188 return nwrote;
191 file_ptr
192 bfd_tell (bfd *abfd)
194 file_ptr ptr;
196 if ((abfd->flags & BFD_IN_MEMORY) != 0)
197 return abfd->where;
199 ptr = real_ftell (bfd_cache_lookup (abfd));
201 if (abfd->my_archive)
202 ptr -= abfd->origin;
203 abfd->where = ptr;
204 return ptr;
208 bfd_flush (bfd *abfd)
210 if ((abfd->flags & BFD_IN_MEMORY) != 0)
211 return 0;
212 return fflush (bfd_cache_lookup(abfd));
215 /* Returns 0 for success, negative value for failure (in which case
216 bfd_get_error can retrieve the error code). */
218 bfd_stat (bfd *abfd, struct stat *statbuf)
220 FILE *f;
221 int result;
223 if ((abfd->flags & BFD_IN_MEMORY) != 0)
224 abort ();
226 f = bfd_cache_lookup (abfd);
227 if (f == NULL)
229 bfd_set_error (bfd_error_system_call);
230 return -1;
232 result = fstat (fileno (f), statbuf);
233 if (result < 0)
234 bfd_set_error (bfd_error_system_call);
235 return result;
238 /* Returns 0 for success, nonzero for failure (in which case bfd_get_error
239 can retrieve the error code). */
242 bfd_seek (bfd *abfd, file_ptr position, int direction)
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. */
251 BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);
253 if (direction == SEEK_CUR && position == 0)
254 return 0;
256 if ((abfd->flags & BFD_IN_MEMORY) != 0)
258 struct bfd_in_memory *bim;
260 bim = abfd->iostream;
262 if (direction == SEEK_SET)
263 abfd->where = position;
264 else
265 abfd->where += position;
267 if (abfd->where > bim->size)
269 if ((abfd->direction == write_direction) ||
270 (abfd->direction == both_direction))
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)
279 bim->buffer = bfd_realloc (bim->buffer, newsize);
280 if (bim->buffer == 0)
282 bim->size = 0;
283 return -1;
287 else
289 abfd->where = bim->size;
290 bfd_set_error (bfd_error_file_truncated);
291 return -1;
294 return 0;
297 if (abfd->format != bfd_archive && abfd->my_archive == 0)
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;
316 else
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.
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.
328 In the meantime, no optimization for archives. */
331 f = bfd_cache_lookup (abfd);
332 file_position = position;
333 if (direction == SEEK_SET && abfd->my_archive != NULL)
334 file_position += abfd->origin;
336 result = real_fseek (f, file_position, direction);
337 if (result != 0)
339 int hold_errno = errno;
341 /* Force redetermination of `where' field. */
342 bfd_tell (abfd);
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
350 bfd_set_error (bfd_error_system_call);
351 errno = hold_errno;
354 else
356 /* Adjust `where' field. */
357 if (direction == SEEK_SET)
358 abfd->where = position;
359 else
360 abfd->where += position;
362 return result;
366 FUNCTION
367 bfd_get_mtime
369 SYNOPSIS
370 long bfd_get_mtime (bfd *abfd);
372 DESCRIPTION
373 Return the file modification time (as read from the file system, or
374 from the archive header for archive members).
378 long
379 bfd_get_mtime (bfd *abfd)
381 FILE *fp;
382 struct stat buf;
384 if (abfd->mtime_set)
385 return abfd->mtime;
387 fp = bfd_cache_lookup (abfd);
388 if (0 != fstat (fileno (fp), &buf))
389 return 0;
391 abfd->mtime = buf.st_mtime; /* Save value in case anyone wants it */
392 return buf.st_mtime;
396 FUNCTION
397 bfd_get_size
399 SYNOPSIS
400 long bfd_get_size (bfd *abfd);
402 DESCRIPTION
403 Return the file size (as read from file system) for the file
404 associated with BFD @var{abfd}.
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.
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?".
428 long
429 bfd_get_size (bfd *abfd)
431 FILE *fp;
432 struct stat buf;
434 if ((abfd->flags & BFD_IN_MEMORY) != 0)
435 return ((struct bfd_in_memory *) abfd->iostream)->size;
437 fp = bfd_cache_lookup (abfd);
438 if (0 != fstat (fileno (fp), & buf))
439 return 0;
441 return buf.st_size;