cache.c revision 77298
1/* BFD library -- caching of file descriptors.
2   Copyright 1990, 91, 92, 93, 94, 95, 1996, 2000, 2001
3   Free Software Foundation, Inc.
4   Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
5
6This file is part of BFD, the Binary File Descriptor library.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
22/*
23SECTION
24	File caching
25
26	The file caching mechanism is embedded within BFD and allows
27	the application to open as many BFDs as it wants without
28	regard to the underlying operating system's file descriptor
29	limit (often as low as 20 open files).  The module in
30	<<cache.c>> maintains a least recently used list of
31	<<BFD_CACHE_MAX_OPEN>> files, and exports the name
32	<<bfd_cache_lookup>>, which runs around and makes sure that
33	the required BFD is open. If not, then it chooses a file to
34	close, closes it and opens the one wanted, returning its file
35	handle.
36
37*/
38
39#include "bfd.h"
40#include "sysdep.h"
41#include "libbfd.h"
42
43static void insert PARAMS ((bfd *));
44static void snip PARAMS ((bfd *));
45static boolean close_one PARAMS ((void));
46static boolean bfd_cache_delete PARAMS ((bfd *));
47
48/*
49INTERNAL_FUNCTION
50	BFD_CACHE_MAX_OPEN macro
51
52DESCRIPTION
53	The maximum number of files which the cache will keep open at
54	one time.
55
56.#define BFD_CACHE_MAX_OPEN 10
57
58*/
59
60/* The number of BFD files we have open.  */
61
62static int open_files;
63
64/*
65INTERNAL_FUNCTION
66	bfd_last_cache
67
68SYNOPSIS
69	extern bfd *bfd_last_cache;
70
71DESCRIPTION
72	Zero, or a pointer to the topmost BFD on the chain.  This is
73	used by the <<bfd_cache_lookup>> macro in @file{libbfd.h} to
74	determine when it can avoid a function call.
75*/
76
77bfd *bfd_last_cache;
78
79/*
80  INTERNAL_FUNCTION
81  	bfd_cache_lookup
82
83  DESCRIPTION
84 	Check to see if the required BFD is the same as the last one
85 	looked up. If so, then it can use the stream in the BFD with
86 	impunity, since it can't have changed since the last lookup;
87 	otherwise, it has to perform the complicated lookup function.
88
89  .#define bfd_cache_lookup(x) \
90  .    ((x)==bfd_last_cache? \
91  .      (FILE*) (bfd_last_cache->iostream): \
92  .       bfd_cache_lookup_worker(x))
93
94 */
95
96/* Insert a BFD into the cache.  */
97
98static INLINE void
99insert (abfd)
100     bfd *abfd;
101{
102  if (bfd_last_cache == NULL)
103    {
104      abfd->lru_next = abfd;
105      abfd->lru_prev = abfd;
106    }
107  else
108    {
109      abfd->lru_next = bfd_last_cache;
110      abfd->lru_prev = bfd_last_cache->lru_prev;
111      abfd->lru_prev->lru_next = abfd;
112      abfd->lru_next->lru_prev = abfd;
113    }
114  bfd_last_cache = abfd;
115}
116
117/* Remove a BFD from the cache.  */
118
119static INLINE void
120snip (abfd)
121     bfd *abfd;
122{
123  abfd->lru_prev->lru_next = abfd->lru_next;
124  abfd->lru_next->lru_prev = abfd->lru_prev;
125  if (abfd == bfd_last_cache)
126    {
127      bfd_last_cache = abfd->lru_next;
128      if (abfd == bfd_last_cache)
129	bfd_last_cache = NULL;
130    }
131}
132
133/* We need to open a new file, and the cache is full.  Find the least
134   recently used cacheable BFD and close it.  */
135
136static boolean
137close_one ()
138{
139  register bfd *kill;
140
141  if (bfd_last_cache == NULL)
142    kill = NULL;
143  else
144    {
145      for (kill = bfd_last_cache->lru_prev;
146	   ! kill->cacheable;
147	   kill = kill->lru_prev)
148	{
149	  if (kill == bfd_last_cache)
150	    {
151	      kill = NULL;
152	      break;
153	    }
154	}
155    }
156
157  if (kill == NULL)
158    {
159      /* There are no open cacheable BFD's.  */
160      return true;
161    }
162
163  kill->where = ftell ((FILE *) kill->iostream);
164
165  return bfd_cache_delete (kill);
166}
167
168/* Close a BFD and remove it from the cache.  */
169
170static boolean
171bfd_cache_delete (abfd)
172     bfd *abfd;
173{
174  boolean ret;
175
176  if (fclose ((FILE *) abfd->iostream) == 0)
177    ret = true;
178  else
179    {
180      ret = false;
181      bfd_set_error (bfd_error_system_call);
182    }
183
184  snip (abfd);
185
186  abfd->iostream = NULL;
187  --open_files;
188
189  return ret;
190}
191
192/*
193INTERNAL_FUNCTION
194	bfd_cache_init
195
196SYNOPSIS
197	boolean bfd_cache_init (bfd *abfd);
198
199DESCRIPTION
200	Add a newly opened BFD to the cache.
201*/
202
203boolean
204bfd_cache_init (abfd)
205     bfd *abfd;
206{
207  BFD_ASSERT (abfd->iostream != NULL);
208  if (open_files >= BFD_CACHE_MAX_OPEN)
209    {
210      if (! close_one ())
211	return false;
212    }
213  insert (abfd);
214  ++open_files;
215  return true;
216}
217
218/*
219INTERNAL_FUNCTION
220	bfd_cache_close
221
222SYNOPSIS
223	boolean bfd_cache_close (bfd *abfd);
224
225DESCRIPTION
226	Remove the BFD @var{abfd} from the cache. If the attached file is open,
227	then close it too.
228
229RETURNS
230	<<false>> is returned if closing the file fails, <<true>> is
231	returned if all is well.
232*/
233
234boolean
235bfd_cache_close (abfd)
236     bfd *abfd;
237{
238  if (abfd->iostream == NULL
239      || (abfd->flags & BFD_IN_MEMORY) != 0)
240    return true;
241
242  return bfd_cache_delete (abfd);
243}
244
245/*
246INTERNAL_FUNCTION
247	bfd_open_file
248
249SYNOPSIS
250	FILE* bfd_open_file(bfd *abfd);
251
252DESCRIPTION
253	Call the OS to open a file for @var{abfd}.  Return the <<FILE *>>
254	(possibly <<NULL>>) that results from this operation.  Set up the
255	BFD so that future accesses know the file is open. If the <<FILE *>>
256	returned is <<NULL>>, then it won't have been put in the
257	cache, so it won't have to be removed from it.
258*/
259
260FILE *
261bfd_open_file (abfd)
262     bfd *abfd;
263{
264  abfd->cacheable = true;	/* Allow it to be closed later.  */
265
266  if (open_files >= BFD_CACHE_MAX_OPEN)
267    {
268      if (! close_one ())
269	return NULL;
270    }
271
272  switch (abfd->direction)
273    {
274    case read_direction:
275    case no_direction:
276      abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RB);
277      break;
278    case both_direction:
279    case write_direction:
280      if (abfd->opened_once == true)
281	{
282	  abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RUB);
283	  if (abfd->iostream == NULL)
284	    abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WUB);
285	}
286      else
287	{
288	  /* Create the file.
289
290	     Some operating systems won't let us overwrite a running
291	     binary.  For them, we want to unlink the file first.
292
293	     However, gcc 2.95 will create temporary files using
294	     O_EXCL and tight permissions to prevent other users from
295	     substituting other .o files during the compilation.  gcc
296	     will then tell the assembler to use the newly created
297	     file as an output file.  If we unlink the file here, we
298	     open a brief window when another user could still
299	     substitute a file.
300
301	     So we unlink the output file if and only if it has
302	     non-zero size.  */
303#ifndef __MSDOS__
304	  /* Don't do this for MSDOS: it doesn't care about overwriting
305	     a running binary, but if this file is already open by
306	     another BFD, we will be in deep trouble if we delete an
307	     open file.  In fact, objdump does just that if invoked with
308	     the --info option.  */
309	  struct stat s;
310
311	  if (stat (abfd->filename, &s) == 0 && s.st_size != 0)
312	    unlink (abfd->filename);
313#endif
314	  abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WUB);
315	  abfd->opened_once = true;
316	}
317      break;
318    }
319
320  if (abfd->iostream != NULL)
321    {
322      if (! bfd_cache_init (abfd))
323	return NULL;
324    }
325
326  return (FILE *) abfd->iostream;
327}
328
329/*
330INTERNAL_FUNCTION
331	bfd_cache_lookup_worker
332
333SYNOPSIS
334	FILE *bfd_cache_lookup_worker(bfd *abfd);
335
336DESCRIPTION
337	Called when the macro <<bfd_cache_lookup>> fails to find a
338	quick answer.  Find a file descriptor for @var{abfd}.  If
339	necessary, it open it.  If there are already more than
340	<<BFD_CACHE_MAX_OPEN>> files open, it tries to close one first, to
341	avoid running out of file descriptors.
342*/
343
344FILE *
345bfd_cache_lookup_worker (abfd)
346     bfd *abfd;
347{
348  if ((abfd->flags & BFD_IN_MEMORY) != 0)
349    abort ();
350
351  if (abfd->my_archive)
352    abfd = abfd->my_archive;
353
354  if (abfd->iostream != NULL)
355    {
356      /* Move the file to the start of the cache.  */
357      if (abfd != bfd_last_cache)
358	{
359	  snip (abfd);
360	  insert (abfd);
361	}
362    }
363  else
364    {
365      if (bfd_open_file (abfd) == NULL)
366	return NULL;
367      if (fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0)
368	return NULL;
369    }
370
371  return (FILE *) abfd->iostream;
372}
373