2004-02-11 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.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 Free Software Foundation, Inc.
5
6 Written by Cygnus Support.
7
8 This file is part of BFD, the Binary File Descriptor library.
9
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.
14
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.
19
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. */
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
41 file_ptr
42 real_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
53 int
54 real_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
72 static size_t
73 real_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
99 bfd_size_type
100 bfd_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
146 bfd_size_type
147 bfd_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
191 file_ptr
192 bfd_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
207 int
208 bfd_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). */
217 int
218 bfd_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
241 int
242 bfd_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 /*
366 FUNCTION
367 bfd_get_mtime
368
369 SYNOPSIS
370 long bfd_get_mtime (bfd *abfd);
371
372 DESCRIPTION
373 Return the file modification time (as read from the file system, or
374 from the archive header for archive members).
375
376 */
377
378 long
379 bfd_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 /*
396 FUNCTION
397 bfd_get_size
398
399 SYNOPSIS
400 long bfd_get_size (bfd *abfd);
401
402 DESCRIPTION
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
428 long
429 bfd_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 }
This page took 0.039363 seconds and 5 git commands to generate.