/[gcl]/gcl/binutils/bfd/cache.c
ViewVC logotype

Diff of /gcl/binutils/bfd/cache.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.1.1 by camm, Fri Aug 9 05:34:48 2002 UTC revision 1.1.1.1.20.1 by camm, Fri Sep 30 02:08:54 2005 UTC
# Line 1  Line 1 
1  /* BFD library -- caching of file descriptors.  /* BFD library -- caching of file descriptors.
2     Copyright 1990, 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002  
3     Free Software Foundation, Inc.     Copyright 1990, 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002,
4       2003, 2004 Free Software Foundation, Inc.
5    
6     Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com).     Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
7    
8  This file is part of BFD, the Binary File Descriptor library.  This file is part of BFD, the Binary File Descriptor library.
# Line 39  SECTION Line 41  SECTION
41  #include "bfd.h"  #include "bfd.h"
42  #include "sysdep.h"  #include "sysdep.h"
43  #include "libbfd.h"  #include "libbfd.h"
44    #include "libiberty.h"
45    
46    static bfd_boolean bfd_cache_delete (bfd *);
47    
48    
49    static file_ptr
50    cache_btell (struct bfd *abfd)
51    {
52      return real_ftell (bfd_cache_lookup (abfd));
53    }
54    
55    static int
56    cache_bseek (struct bfd *abfd, file_ptr offset, int whence)
57    {
58      return real_fseek (bfd_cache_lookup (abfd), offset, whence);
59    }
60    
61    /* Note that archive entries don't have streams; they share their parent's.
62       This allows someone to play with the iostream behind BFD's back.
63    
64       Also, note that the origin pointer points to the beginning of a file's
65       contents (0 for non-archive elements).  For archive entries this is the
66       first octet in the file, NOT the beginning of the archive header.  */
67    
68    static file_ptr
69    cache_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
70    {
71      file_ptr nread;
72      /* FIXME - this looks like an optimization, but it's really to cover
73         up for a feature of some OSs (not solaris - sigh) that
74         ld/pe-dll.c takes advantage of (apparently) when it creates BFDs
75         internally and tries to link against them.  BFD seems to be smart
76         enough to realize there are no symbol records in the "file" that
77         doesn't exist but attempts to read them anyway.  On Solaris,
78         attempting to read zero bytes from a NULL file results in a core
79         dump, but on other platforms it just returns zero bytes read.
80         This makes it to something reasonable. - DJ */
81      if (nbytes == 0)
82        return 0;
83    
84    #if defined (__VAX) && defined (VMS)
85      /* Apparently fread on Vax VMS does not keep the record length
86         information.  */
87      nread = read (fileno (bfd_cache_lookup (abfd)), buf, nbytes);
88      /* Set bfd_error if we did not read as much data as we expected.  If
89         the read failed due to an error set the bfd_error_system_call,
90         else set bfd_error_file_truncated.  */
91      if (nread == (file_ptr)-1)
92        {
93          bfd_set_error (bfd_error_system_call);
94          return -1;
95        }
96    #else
97      nread = fread (buf, 1, nbytes, bfd_cache_lookup (abfd));
98      /* Set bfd_error if we did not read as much data as we expected.  If
99         the read failed due to an error set the bfd_error_system_call,
100         else set bfd_error_file_truncated.  */
101      if (nread < nbytes && ferror (bfd_cache_lookup (abfd)))
102        {
103          bfd_set_error (bfd_error_system_call);
104          return -1;
105        }
106    #endif
107      return nread;
108    }
109    
110  static void insert PARAMS ((bfd *));  static file_ptr
111  static void snip PARAMS ((bfd *));  cache_bwrite (struct bfd *abfd, const void *where, file_ptr nbytes)
112  static boolean close_one PARAMS ((void));  {
113  static boolean bfd_cache_delete PARAMS ((bfd *));    file_ptr nwrite = fwrite (where, 1, nbytes, bfd_cache_lookup (abfd));
114      if (nwrite < nbytes && ferror (bfd_cache_lookup (abfd)))
115        {
116          bfd_set_error (bfd_error_system_call);
117          return -1;
118        }
119      return nwrite;
120    }
121    
122    static int
123    cache_bclose (struct bfd *abfd)
124    {
125      return bfd_cache_close (abfd);
126    }
127    
128    static int
129    cache_bflush (struct bfd *abfd)
130    {
131      int sts = fflush (bfd_cache_lookup (abfd));
132      if (sts < 0)
133        bfd_set_error (bfd_error_system_call);
134      return sts;
135    }
136    
137    static int
138    cache_bstat (struct bfd *abfd, struct stat *sb)
139    {
140      int sts = fstat (fileno (bfd_cache_lookup (abfd)), sb);
141      if (sts < 0)
142        bfd_set_error (bfd_error_system_call);
143      return sts;
144    }
145    
146    static const struct bfd_iovec cache_iovec = {
147      &cache_bread, &cache_bwrite, &cache_btell, &cache_bseek,
148      &cache_bclose, &cache_bflush, &cache_bstat
149    };
150    
151  /*  /*
152  INTERNAL_FUNCTION  INTERNAL_FUNCTION
# Line 87  bfd *bfd_last_cache; Line 190  bfd *bfd_last_cache;
190          otherwise, it has to perform the complicated lookup function.          otherwise, it has to perform the complicated lookup function.
191    
192    .#define bfd_cache_lookup(x) \    .#define bfd_cache_lookup(x) \
193    .    ((x)==bfd_last_cache? \    .    ((x) == bfd_last_cache ? \
194    .      (FILE*) (bfd_last_cache->iostream): \    .      (FILE *) (bfd_last_cache->iostream): \
195    .       bfd_cache_lookup_worker(x))    .       bfd_cache_lookup_worker (x))
196    
197   */   */
198    
199  /* Insert a BFD into the cache.  */  /* Insert a BFD into the cache.  */
200    
201  static INLINE void  static void
202  insert (abfd)  insert (bfd *abfd)
      bfd *abfd;  
203  {  {
204    if (bfd_last_cache == NULL)    if (bfd_last_cache == NULL)
205      {      {
# Line 116  insert (abfd) Line 218  insert (abfd)
218    
219  /* Remove a BFD from the cache.  */  /* Remove a BFD from the cache.  */
220    
221  static INLINE void  static void
222  snip (abfd)  snip (bfd *abfd)
      bfd *abfd;  
223  {  {
224    abfd->lru_prev->lru_next = abfd->lru_next;    abfd->lru_prev->lru_next = abfd->lru_next;
225    abfd->lru_next->lru_prev = abfd->lru_prev;    abfd->lru_next->lru_prev = abfd->lru_prev;
# Line 133  snip (abfd) Line 234  snip (abfd)
234  /* We need to open a new file, and the cache is full.  Find the least  /* We need to open a new file, and the cache is full.  Find the least
235     recently used cacheable BFD and close it.  */     recently used cacheable BFD and close it.  */
236    
237  static boolean  static bfd_boolean
238  close_one ()  close_one (void)
239  {  {
240    register bfd *kill;    register bfd *kill;
241    
# Line 157  close_one () Line 258  close_one ()
258    if (kill == NULL)    if (kill == NULL)
259      {      {
260        /* There are no open cacheable BFD's.  */        /* There are no open cacheable BFD's.  */
261        return true;        return TRUE;
262      }      }
263    
264    kill->where = ftell ((FILE *) kill->iostream);    kill->where = real_ftell ((FILE *) kill->iostream);
265    
266    return bfd_cache_delete (kill);    return bfd_cache_delete (kill);
267  }  }
268    
269  /* Close a BFD and remove it from the cache.  */  /* Close a BFD and remove it from the cache.  */
270    
271  static boolean  static bfd_boolean
272  bfd_cache_delete (abfd)  bfd_cache_delete (bfd *abfd)
      bfd *abfd;  
273  {  {
274    boolean ret;    bfd_boolean ret;
275    
276    if (fclose ((FILE *) abfd->iostream) == 0)    if (fclose ((FILE *) abfd->iostream) == 0)
277      ret = true;      ret = TRUE;
278    else    else
279      {      {
280        ret = false;        ret = FALSE;
281        bfd_set_error (bfd_error_system_call);        bfd_set_error (bfd_error_system_call);
282      }      }
283    
# Line 194  INTERNAL_FUNCTION Line 294  INTERNAL_FUNCTION
294          bfd_cache_init          bfd_cache_init
295    
296  SYNOPSIS  SYNOPSIS
297          boolean bfd_cache_init (bfd *abfd);          bfd_boolean bfd_cache_init (bfd *abfd);
298    
299  DESCRIPTION  DESCRIPTION
300          Add a newly opened BFD to the cache.          Add a newly opened BFD to the cache.
301  */  */
302    
303  boolean  bfd_boolean
304  bfd_cache_init (abfd)  bfd_cache_init (bfd *abfd)
      bfd *abfd;  
305  {  {
306    BFD_ASSERT (abfd->iostream != NULL);    BFD_ASSERT (abfd->iostream != NULL);
307    if (open_files >= BFD_CACHE_MAX_OPEN)    if (open_files >= BFD_CACHE_MAX_OPEN)
308      {      {
309        if (! close_one ())        if (! close_one ())
310          return false;          return FALSE;
311      }      }
312      abfd->iovec = &cache_iovec;
313    insert (abfd);    insert (abfd);
314    ++open_files;    ++open_files;
315    return true;    return TRUE;
316  }  }
317    
318  /*  /*
# Line 220  INTERNAL_FUNCTION Line 320  INTERNAL_FUNCTION
320          bfd_cache_close          bfd_cache_close
321    
322  SYNOPSIS  SYNOPSIS
323          boolean bfd_cache_close (bfd *abfd);          bfd_boolean bfd_cache_close (bfd *abfd);
324    
325  DESCRIPTION  DESCRIPTION
326          Remove the BFD @var{abfd} from the cache. If the attached file is open,          Remove the BFD @var{abfd} from the cache. If the attached file is open,
327          then close it too.          then close it too.
328    
329  RETURNS  RETURNS
330          <<false>> is returned if closing the file fails, <<true>> is          <<FALSE>> is returned if closing the file fails, <<TRUE>> is
331          returned if all is well.          returned if all is well.
332  */  */
333    
334  boolean  bfd_boolean
335  bfd_cache_close (abfd)  bfd_cache_close (bfd *abfd)
336       bfd *abfd;  {
337  {    if (abfd->iovec != &cache_iovec)
338    if (abfd->iostream == NULL      return TRUE;
339        || (abfd->flags & BFD_IN_MEMORY) != 0)  
340      return true;    if (abfd->iostream == NULL)
341        /* Previously closed.  */
342        return TRUE;
343    
344    return bfd_cache_delete (abfd);    return bfd_cache_delete (abfd);
345  }  }
346    
347  /*  /*
348    FUNCTION
349            bfd_cache_close_all
350    
351    SYNOPSIS
352            bfd_boolean bfd_cache_close_all (void);
353    
354    DESCRIPTION
355            Remove all BFDs from the cache. If the attached file is open,
356            then close it too.
357    
358    RETURNS
359            <<FALSE>> is returned if closing one of the file fails, <<TRUE>> is
360            returned if all is well.
361    */
362    
363    bfd_boolean
364    bfd_cache_close_all ()
365    {
366      bfd_boolean ret = TRUE;
367    
368      while (bfd_last_cache != NULL)
369        ret &= bfd_cache_close (bfd_last_cache);
370    
371      return ret;
372    }
373    
374    /*
375  INTERNAL_FUNCTION  INTERNAL_FUNCTION
376          bfd_open_file          bfd_open_file
377    
378  SYNOPSIS  SYNOPSIS
379          FILE* bfd_open_file(bfd *abfd);          FILE* bfd_open_file (bfd *abfd);
380    
381  DESCRIPTION  DESCRIPTION
382          Call the OS to open a file for @var{abfd}.  Return the <<FILE *>>          Call the OS to open a file for @var{abfd}.  Return the <<FILE *>>
# Line 258  DESCRIPTION Line 387  DESCRIPTION
387  */  */
388    
389  FILE *  FILE *
390  bfd_open_file (abfd)  bfd_open_file (bfd *abfd)
      bfd *abfd;  
391  {  {
392    abfd->cacheable = true;       /* Allow it to be closed later.  */    abfd->cacheable = TRUE;       /* Allow it to be closed later.  */
393    
394    if (open_files >= BFD_CACHE_MAX_OPEN)    if (open_files >= BFD_CACHE_MAX_OPEN)
395      {      {
# Line 309  bfd_open_file (abfd) Line 437  bfd_open_file (abfd)
437            struct stat s;            struct stat s;
438    
439            if (stat (abfd->filename, &s) == 0 && s.st_size != 0)            if (stat (abfd->filename, &s) == 0 && s.st_size != 0)
440              unlink (abfd->filename);              unlink_if_ordinary (abfd->filename);
441  #endif  #endif
442            abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WUB);            abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WUB);
443            abfd->opened_once = true;            abfd->opened_once = TRUE;
444          }          }
445        break;        break;
446      }      }
# Line 331  INTERNAL_FUNCTION Line 459  INTERNAL_FUNCTION
459          bfd_cache_lookup_worker          bfd_cache_lookup_worker
460    
461  SYNOPSIS  SYNOPSIS
462          FILE *bfd_cache_lookup_worker(bfd *abfd);          FILE *bfd_cache_lookup_worker (bfd *abfd);
463    
464  DESCRIPTION  DESCRIPTION
465          Called when the macro <<bfd_cache_lookup>> fails to find a          Called when the macro <<bfd_cache_lookup>> fails to find a
466          quick answer.  Find a file descriptor for @var{abfd}.  If          quick answer.  Find a file descriptor for @var{abfd}.  If
467          necessary, it open it.  If there are already more than          necessary, it open it.  If there are already more than
468          <<BFD_CACHE_MAX_OPEN>> files open, it tries to close one first, to          <<BFD_CACHE_MAX_OPEN>> files open, it tries to close one first, to
469          avoid running out of file descriptors.          avoid running out of file descriptors.  It will abort rather than
470            returning NULL if it is unable to (re)open the @var{abfd}.
471  */  */
472    
473  FILE *  FILE *
474  bfd_cache_lookup_worker (abfd)  bfd_cache_lookup_worker (bfd *abfd)
      bfd *abfd;  
475  {  {
476    if ((abfd->flags & BFD_IN_MEMORY) != 0)    if ((abfd->flags & BFD_IN_MEMORY) != 0)
477      abort ();      abort ();
# Line 362  bfd_cache_lookup_worker (abfd) Line 490  bfd_cache_lookup_worker (abfd)
490      }      }
491    else    else
492      {      {
493        if (bfd_open_file (abfd) == NULL)        if (bfd_open_file (abfd) == NULL
494          return NULL;            || abfd->where != (unsigned long) abfd->where
495        if (abfd->where != (unsigned long) abfd->where)            || real_fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0)
496          return NULL;          abort ();
       if (fseek ((FILE *) abfd->iostream, (long) abfd->where, SEEK_SET) != 0)  
         return NULL;  
497      }      }
498    
499    return (FILE *) abfd->iostream;    return (FILE *) abfd->iostream;

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.1.20.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26