xref: /openbsd/gnu/usr.bin/binutils/bfd/cache.c (revision 2c46a28c)
12159047fSniklas /* BFD library -- caching of file descriptors.
2007c2a45Smiod 
3007c2a45Smiod    Copyright 1990, 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002,
4007c2a45Smiod    2003, 2004 Free Software Foundation, Inc.
5007c2a45Smiod 
62159047fSniklas    Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
72159047fSniklas 
82159047fSniklas This file is part of BFD, the Binary File Descriptor library.
92159047fSniklas 
102159047fSniklas This program is free software; you can redistribute it and/or modify
112159047fSniklas it under the terms of the GNU General Public License as published by
122159047fSniklas the Free Software Foundation; either version 2 of the License, or
132159047fSniklas (at your option) any later version.
142159047fSniklas 
152159047fSniklas This program is distributed in the hope that it will be useful,
162159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
172159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
182159047fSniklas GNU General Public License for more details.
192159047fSniklas 
202159047fSniklas You should have received a copy of the GNU General Public License
212159047fSniklas along with this program; if not, write to the Free Software
222159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
232159047fSniklas 
242159047fSniklas /*
252159047fSniklas SECTION
262159047fSniklas 	File caching
272159047fSniklas 
282159047fSniklas 	The file caching mechanism is embedded within BFD and allows
292159047fSniklas 	the application to open as many BFDs as it wants without
302159047fSniklas 	regard to the underlying operating system's file descriptor
312159047fSniklas 	limit (often as low as 20 open files).  The module in
322159047fSniklas 	<<cache.c>> maintains a least recently used list of
332159047fSniklas 	<<BFD_CACHE_MAX_OPEN>> files, and exports the name
342159047fSniklas 	<<bfd_cache_lookup>>, which runs around and makes sure that
352159047fSniklas 	the required BFD is open. If not, then it chooses a file to
362159047fSniklas 	close, closes it and opens the one wanted, returning its file
372159047fSniklas 	handle.
382159047fSniklas 
392159047fSniklas */
402159047fSniklas 
412159047fSniklas #include "bfd.h"
422159047fSniklas #include "sysdep.h"
432159047fSniklas #include "libbfd.h"
442159047fSniklas 
45007c2a45Smiod static bfd_boolean bfd_cache_delete (bfd *);
462159047fSniklas 
472159047fSniklas /*
482159047fSniklas INTERNAL_FUNCTION
492159047fSniklas 	BFD_CACHE_MAX_OPEN macro
502159047fSniklas 
512159047fSniklas DESCRIPTION
522159047fSniklas 	The maximum number of files which the cache will keep open at
532159047fSniklas 	one time.
542159047fSniklas 
552159047fSniklas .#define BFD_CACHE_MAX_OPEN 10
562159047fSniklas 
572159047fSniklas */
582159047fSniklas 
592159047fSniklas /* The number of BFD files we have open.  */
602159047fSniklas 
612159047fSniklas static int open_files;
622159047fSniklas 
632159047fSniklas /*
642159047fSniklas INTERNAL_FUNCTION
652159047fSniklas 	bfd_last_cache
662159047fSniklas 
672159047fSniklas SYNOPSIS
682159047fSniklas 	extern bfd *bfd_last_cache;
692159047fSniklas 
702159047fSniklas DESCRIPTION
712159047fSniklas 	Zero, or a pointer to the topmost BFD on the chain.  This is
722159047fSniklas 	used by the <<bfd_cache_lookup>> macro in @file{libbfd.h} to
732159047fSniklas 	determine when it can avoid a function call.
742159047fSniklas */
752159047fSniklas 
762159047fSniklas bfd *bfd_last_cache;
772159047fSniklas 
782159047fSniklas /*
792159047fSniklas   INTERNAL_FUNCTION
802159047fSniklas   	bfd_cache_lookup
812159047fSniklas 
822159047fSniklas   DESCRIPTION
832159047fSniklas  	Check to see if the required BFD is the same as the last one
842159047fSniklas  	looked up. If so, then it can use the stream in the BFD with
852159047fSniklas  	impunity, since it can't have changed since the last lookup;
862159047fSniklas  	otherwise, it has to perform the complicated lookup function.
872159047fSniklas 
882159047fSniklas   .#define bfd_cache_lookup(x) \
892159047fSniklas   .    ((x)==bfd_last_cache? \
902159047fSniklas   .      (FILE*) (bfd_last_cache->iostream): \
912159047fSniklas   .       bfd_cache_lookup_worker(x))
922159047fSniklas 
932159047fSniklas  */
942159047fSniklas 
952159047fSniklas /* Insert a BFD into the cache.  */
962159047fSniklas 
97007c2a45Smiod static void
insert(bfd * abfd)98007c2a45Smiod insert (bfd *abfd)
992159047fSniklas {
1002159047fSniklas   if (bfd_last_cache == NULL)
1012159047fSniklas     {
1022159047fSniklas       abfd->lru_next = abfd;
1032159047fSniklas       abfd->lru_prev = abfd;
1042159047fSniklas     }
1052159047fSniklas   else
1062159047fSniklas     {
1072159047fSniklas       abfd->lru_next = bfd_last_cache;
1082159047fSniklas       abfd->lru_prev = bfd_last_cache->lru_prev;
1092159047fSniklas       abfd->lru_prev->lru_next = abfd;
1102159047fSniklas       abfd->lru_next->lru_prev = abfd;
1112159047fSniklas     }
1122159047fSniklas   bfd_last_cache = abfd;
1132159047fSniklas }
1142159047fSniklas 
1152159047fSniklas /* Remove a BFD from the cache.  */
1162159047fSniklas 
117007c2a45Smiod static void
snip(bfd * abfd)118007c2a45Smiod snip (bfd *abfd)
1192159047fSniklas {
1202159047fSniklas   abfd->lru_prev->lru_next = abfd->lru_next;
1212159047fSniklas   abfd->lru_next->lru_prev = abfd->lru_prev;
1222159047fSniklas   if (abfd == bfd_last_cache)
1232159047fSniklas     {
1242159047fSniklas       bfd_last_cache = abfd->lru_next;
1252159047fSniklas       if (abfd == bfd_last_cache)
1262159047fSniklas 	bfd_last_cache = NULL;
1272159047fSniklas     }
1282159047fSniklas }
1292159047fSniklas 
1302159047fSniklas /* We need to open a new file, and the cache is full.  Find the least
1312159047fSniklas    recently used cacheable BFD and close it.  */
1322159047fSniklas 
133c074d1c9Sdrahn static bfd_boolean
close_one(void)134007c2a45Smiod close_one (void)
1352159047fSniklas {
1362159047fSniklas   register bfd *kill;
1372159047fSniklas 
1382159047fSniklas   if (bfd_last_cache == NULL)
1392159047fSniklas     kill = NULL;
1402159047fSniklas   else
1412159047fSniklas     {
1422159047fSniklas       for (kill = bfd_last_cache->lru_prev;
1432159047fSniklas 	   ! kill->cacheable;
1442159047fSniklas 	   kill = kill->lru_prev)
1452159047fSniklas 	{
1462159047fSniklas 	  if (kill == bfd_last_cache)
1472159047fSniklas 	    {
1482159047fSniklas 	      kill = NULL;
1492159047fSniklas 	      break;
1502159047fSniklas 	    }
1512159047fSniklas 	}
1522159047fSniklas     }
1532159047fSniklas 
1542159047fSniklas   if (kill == NULL)
1552159047fSniklas     {
1562159047fSniklas       /* There are no open cacheable BFD's.  */
157c074d1c9Sdrahn       return TRUE;
1582159047fSniklas     }
1592159047fSniklas 
160007c2a45Smiod   kill->where = real_ftell ((FILE *) kill->iostream);
1612159047fSniklas 
1622159047fSniklas   return bfd_cache_delete (kill);
1632159047fSniklas }
1642159047fSniklas 
1652159047fSniklas /* Close a BFD and remove it from the cache.  */
1662159047fSniklas 
167c074d1c9Sdrahn static bfd_boolean
bfd_cache_delete(bfd * abfd)168007c2a45Smiod bfd_cache_delete (bfd *abfd)
1692159047fSniklas {
170c074d1c9Sdrahn   bfd_boolean ret;
1712159047fSniklas 
1722159047fSniklas   if (fclose ((FILE *) abfd->iostream) == 0)
173c074d1c9Sdrahn     ret = TRUE;
1742159047fSniklas   else
1752159047fSniklas     {
176c074d1c9Sdrahn       ret = FALSE;
1772159047fSniklas       bfd_set_error (bfd_error_system_call);
1782159047fSniklas     }
1792159047fSniklas 
1802159047fSniklas   snip (abfd);
1812159047fSniklas 
1822159047fSniklas   abfd->iostream = NULL;
1832159047fSniklas   --open_files;
1842159047fSniklas 
1852159047fSniklas   return ret;
1862159047fSniklas }
1872159047fSniklas 
1882159047fSniklas /*
1892159047fSniklas INTERNAL_FUNCTION
1902159047fSniklas 	bfd_cache_init
1912159047fSniklas 
1922159047fSniklas SYNOPSIS
193c074d1c9Sdrahn 	bfd_boolean bfd_cache_init (bfd *abfd);
1942159047fSniklas 
1952159047fSniklas DESCRIPTION
1962159047fSniklas 	Add a newly opened BFD to the cache.
1972159047fSniklas */
1982159047fSniklas 
199c074d1c9Sdrahn bfd_boolean
bfd_cache_init(bfd * abfd)200007c2a45Smiod bfd_cache_init (bfd *abfd)
2012159047fSniklas {
2022159047fSniklas   BFD_ASSERT (abfd->iostream != NULL);
2032159047fSniklas   if (open_files >= BFD_CACHE_MAX_OPEN)
2042159047fSniklas     {
2052159047fSniklas       if (! close_one ())
206c074d1c9Sdrahn 	return FALSE;
2072159047fSniklas     }
2082159047fSniklas   insert (abfd);
2092159047fSniklas   ++open_files;
210c074d1c9Sdrahn   return TRUE;
2112159047fSniklas }
2122159047fSniklas 
2132159047fSniklas /*
2142159047fSniklas INTERNAL_FUNCTION
2152159047fSniklas 	bfd_cache_close
2162159047fSniklas 
2172159047fSniklas SYNOPSIS
218c074d1c9Sdrahn 	bfd_boolean bfd_cache_close (bfd *abfd);
2192159047fSniklas 
2202159047fSniklas DESCRIPTION
2212159047fSniklas 	Remove the BFD @var{abfd} from the cache. If the attached file is open,
2222159047fSniklas 	then close it too.
2232159047fSniklas 
2242159047fSniklas RETURNS
225c074d1c9Sdrahn 	<<FALSE>> is returned if closing the file fails, <<TRUE>> is
2262159047fSniklas 	returned if all is well.
2272159047fSniklas */
2282159047fSniklas 
229c074d1c9Sdrahn bfd_boolean
bfd_cache_close(bfd * abfd)230007c2a45Smiod bfd_cache_close (bfd *abfd)
2312159047fSniklas {
232c88b1d6cSniklas   if (abfd->iostream == NULL
233c88b1d6cSniklas       || (abfd->flags & BFD_IN_MEMORY) != 0)
234c074d1c9Sdrahn     return TRUE;
2352159047fSniklas 
2362159047fSniklas   return bfd_cache_delete (abfd);
2372159047fSniklas }
2382159047fSniklas 
2392159047fSniklas /*
240*2c46a28cSkettenis FUNCTION
241*2c46a28cSkettenis 	bfd_cache_close_all
242*2c46a28cSkettenis 
243*2c46a28cSkettenis SYNOPSIS
244*2c46a28cSkettenis 	bfd_boolean bfd_cache_close_all (void);
245*2c46a28cSkettenis 
246*2c46a28cSkettenis DESCRIPTION
247*2c46a28cSkettenis 	Remove all BFDs from the cache. If the attached file is open,
248*2c46a28cSkettenis 	then close it too.
249*2c46a28cSkettenis 
250*2c46a28cSkettenis RETURNS
251*2c46a28cSkettenis 	<<FALSE>> is returned if closing one of the file fails, <<TRUE>> is
252*2c46a28cSkettenis 	returned if all is well.
253*2c46a28cSkettenis */
254*2c46a28cSkettenis 
255*2c46a28cSkettenis bfd_boolean
bfd_cache_close_all()256*2c46a28cSkettenis bfd_cache_close_all ()
257*2c46a28cSkettenis {
258*2c46a28cSkettenis   bfd_boolean ret = TRUE;
259*2c46a28cSkettenis 
260*2c46a28cSkettenis   while (bfd_last_cache != NULL)
261*2c46a28cSkettenis     ret &= bfd_cache_close (bfd_last_cache);
262*2c46a28cSkettenis 
263*2c46a28cSkettenis   return ret;
264*2c46a28cSkettenis }
265*2c46a28cSkettenis 
266*2c46a28cSkettenis /*
2672159047fSniklas INTERNAL_FUNCTION
2682159047fSniklas 	bfd_open_file
2692159047fSniklas 
2702159047fSniklas SYNOPSIS
2712159047fSniklas 	FILE* bfd_open_file (bfd *abfd);
2722159047fSniklas 
2732159047fSniklas DESCRIPTION
2742159047fSniklas 	Call the OS to open a file for @var{abfd}.  Return the <<FILE *>>
2752159047fSniklas 	(possibly <<NULL>>) that results from this operation.  Set up the
2762159047fSniklas 	BFD so that future accesses know the file is open. If the <<FILE *>>
2772159047fSniklas 	returned is <<NULL>>, then it won't have been put in the
2782159047fSniklas 	cache, so it won't have to be removed from it.
2792159047fSniklas */
2802159047fSniklas 
2812159047fSniklas FILE *
bfd_open_file(bfd * abfd)282007c2a45Smiod bfd_open_file (bfd *abfd)
2832159047fSniklas {
284c074d1c9Sdrahn   abfd->cacheable = TRUE;	/* Allow it to be closed later.  */
2852159047fSniklas 
2862159047fSniklas   if (open_files >= BFD_CACHE_MAX_OPEN)
2872159047fSniklas     {
2882159047fSniklas       if (! close_one ())
2892159047fSniklas 	return NULL;
2902159047fSniklas     }
2912159047fSniklas 
2922159047fSniklas   switch (abfd->direction)
2932159047fSniklas     {
2942159047fSniklas     case read_direction:
2952159047fSniklas     case no_direction:
296c88b1d6cSniklas       abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RB);
2972159047fSniklas       break;
2982159047fSniklas     case both_direction:
2992159047fSniklas     case write_direction:
300c074d1c9Sdrahn       if (abfd->opened_once)
3012159047fSniklas 	{
302c88b1d6cSniklas 	  abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RUB);
3032159047fSniklas 	  if (abfd->iostream == NULL)
304c88b1d6cSniklas 	    abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WUB);
3052159047fSniklas 	}
3062159047fSniklas       else
3072159047fSniklas 	{
308b305b0f1Sespie 	  /* Create the file.
309b305b0f1Sespie 
310b305b0f1Sespie 	     Some operating systems won't let us overwrite a running
311b305b0f1Sespie 	     binary.  For them, we want to unlink the file first.
312b305b0f1Sespie 
313b305b0f1Sespie 	     However, gcc 2.95 will create temporary files using
314b305b0f1Sespie 	     O_EXCL and tight permissions to prevent other users from
315b305b0f1Sespie 	     substituting other .o files during the compilation.  gcc
316b305b0f1Sespie 	     will then tell the assembler to use the newly created
317b305b0f1Sespie 	     file as an output file.  If we unlink the file here, we
318b305b0f1Sespie 	     open a brief window when another user could still
319b305b0f1Sespie 	     substitute a file.
320b305b0f1Sespie 
321b305b0f1Sespie 	     So we unlink the output file if and only if it has
322b305b0f1Sespie 	     non-zero size.  */
323b305b0f1Sespie #ifndef __MSDOS__
324b305b0f1Sespie 	  /* Don't do this for MSDOS: it doesn't care about overwriting
325b305b0f1Sespie 	     a running binary, but if this file is already open by
326b305b0f1Sespie 	     another BFD, we will be in deep trouble if we delete an
327b305b0f1Sespie 	     open file.  In fact, objdump does just that if invoked with
328b305b0f1Sespie 	     the --info option.  */
329b305b0f1Sespie 	  struct stat s;
330b305b0f1Sespie 
331b305b0f1Sespie 	  if (stat (abfd->filename, &s) == 0 && s.st_size != 0)
332c88b1d6cSniklas 	    unlink (abfd->filename);
333b305b0f1Sespie #endif
334b55d4692Sfgsch 	  abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WUB);
335c074d1c9Sdrahn 	  abfd->opened_once = TRUE;
3362159047fSniklas 	}
3372159047fSniklas       break;
3382159047fSniklas     }
3392159047fSniklas 
3402159047fSniklas   if (abfd->iostream != NULL)
3412159047fSniklas     {
3422159047fSniklas       if (! bfd_cache_init (abfd))
3432159047fSniklas 	return NULL;
3442159047fSniklas     }
3452159047fSniklas 
3462159047fSniklas   return (FILE *) abfd->iostream;
3472159047fSniklas }
3482159047fSniklas 
3492159047fSniklas /*
3502159047fSniklas INTERNAL_FUNCTION
3512159047fSniklas 	bfd_cache_lookup_worker
3522159047fSniklas 
3532159047fSniklas SYNOPSIS
3542159047fSniklas 	FILE *bfd_cache_lookup_worker (bfd *abfd);
3552159047fSniklas 
3562159047fSniklas DESCRIPTION
3572159047fSniklas 	Called when the macro <<bfd_cache_lookup>> fails to find a
3582159047fSniklas 	quick answer.  Find a file descriptor for @var{abfd}.  If
3592159047fSniklas 	necessary, it open it.  If there are already more than
3602159047fSniklas 	<<BFD_CACHE_MAX_OPEN>> files open, it tries to close one first, to
3612159047fSniklas 	avoid running out of file descriptors.
3622159047fSniklas */
3632159047fSniklas 
3642159047fSniklas FILE *
bfd_cache_lookup_worker(bfd * abfd)365007c2a45Smiod bfd_cache_lookup_worker (bfd *abfd)
3662159047fSniklas {
367c88b1d6cSniklas   if ((abfd->flags & BFD_IN_MEMORY) != 0)
368c88b1d6cSniklas     abort ();
369c88b1d6cSniklas 
3702159047fSniklas   if (abfd->my_archive)
3712159047fSniklas     abfd = abfd->my_archive;
3722159047fSniklas 
3732159047fSniklas   if (abfd->iostream != NULL)
3742159047fSniklas     {
3752159047fSniklas       /* Move the file to the start of the cache.  */
3762159047fSniklas       if (abfd != bfd_last_cache)
3772159047fSniklas 	{
3782159047fSniklas 	  snip (abfd);
3792159047fSniklas 	  insert (abfd);
3802159047fSniklas 	}
3812159047fSniklas     }
3822159047fSniklas   else
3832159047fSniklas     {
3842159047fSniklas       if (bfd_open_file (abfd) == NULL)
3852159047fSniklas 	return NULL;
386c074d1c9Sdrahn       if (abfd->where != (unsigned long) abfd->where)
387c074d1c9Sdrahn 	return NULL;
388007c2a45Smiod       if (real_fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0)
3892159047fSniklas 	return NULL;
3902159047fSniklas     }
3912159047fSniklas 
3922159047fSniklas   return (FILE *) abfd->iostream;
3932159047fSniklas }
394