~ubuntu-branches/ubuntu/hoary/binutils/hoary

« back to all changes in this revision

Viewing changes to bfd/bfdio.c

  • Committer: Bazaar Package Importer
  • Author(s): James Troup
  • Date: 2004-05-19 10:35:44 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040519103544-17h3o6e8pwndydrg
Tags: 2.14.90.0.7-8
debian/rules: don't use gcc-2.95 on m68k.  Thanks to Adam Conrad for
pointing this out.

Show diffs side-by-side

added added

removed removed

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