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