cache.c revision 61843
1/* BFD library -- caching of file descriptors.
2   Copyright 1990, 91, 92, 93, 94, 95, 1996, 2000
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
97/* Insert a BFD into the cache.  */
98
99static INLINE void
100insert (abfd)
101     bfd *abfd;
102{
103  if (bfd_last_cache == NULL)
104    {
105      abfd->lru_next = abfd;
106      abfd->lru_prev = abfd;
107    }
108  else
109    {
110      abfd->lru_next = bfd_last_cache;
111      abfd->lru_prev = bfd_last_cache->lru_prev;
112      abfd->lru_prev->lru_next = abfd;
113      abfd->lru_next->lru_prev = abfd;
114    }
115  bfd_last_cache = abfd;
116}
117
118/* Remove a BFD from the cache.  */
119
120static INLINE void
121snip (abfd)
122     bfd *abfd;
123{
124  abfd->lru_prev->lru_next = abfd->lru_next;
125  abfd->lru_next->lru_prev = abfd->lru_prev;
126  if (abfd == bfd_last_cache)
127    {
128      bfd_last_cache = abfd->lru_next;
129      if (abfd == bfd_last_cache)
130	bfd_last_cache = NULL;
131    }
132}
133
134/* We need to open a new file, and the cache is full.  Find the least
135   recently used cacheable BFD and close it.  */
136
137static boolean
138close_one ()
139{
140  register bfd *kill;
141
142  if (bfd_last_cache == NULL)
143    kill = NULL;
144  else
145    {
146      for (kill = bfd_last_cache->lru_prev;
147	   ! kill->cacheable;
148	   kill = kill->lru_prev)
149	{
150	  if (kill == bfd_last_cache)
151	    {
152	      kill = NULL;
153	      break;
154	    }
155	}
156    }
157
158  if (kill == NULL)
159    {
160      /* There are no open cacheable BFD's.  */
161      return true;
162    }
163
164  kill->where = ftell ((FILE *) kill->iostream);
165
166  return bfd_cache_delete (kill);
167}
168
169/* Close a BFD and remove it from the cache.  */
170
171static boolean
172bfd_cache_delete (abfd)
173     bfd *abfd;
174{
175  boolean ret;
176
177  if (fclose ((FILE *) abfd->iostream) == 0)
178    ret = true;
179  else
180    {
181      ret = false;
182      bfd_set_error (bfd_error_system_call);
183    }
184
185  snip (abfd);
186
187  abfd->iostream = NULL;
188  --open_files;
189
190  return ret;
191}
192
193/*
194INTERNAL_FUNCTION
195	bfd_cache_init
196
197SYNOPSIS
198	boolean bfd_cache_init (bfd *abfd);
199
200DESCRIPTION
201	Add a newly opened BFD to the cache.
202*/
203
204boolean
205bfd_cache_init (abfd)
206     bfd *abfd;
207{
208  BFD_ASSERT (abfd->iostream != NULL);
209  if (open_files >= BFD_CACHE_MAX_OPEN)
210    {
211      if (! close_one ())
212	return false;
213    }
214  insert (abfd);
215  ++open_files;
216  return true;
217}
218
219/*
220INTERNAL_FUNCTION
221	bfd_cache_close
222
223SYNOPSIS
224	boolean bfd_cache_close (bfd *abfd);
225
226DESCRIPTION
227	Remove the BFD @var{abfd} from the cache. If the attached file is open,
228	then close it too.
229
230RETURNS
231	<<false>> is returned if closing the file fails, <<true>> is
232	returned if all is well.
233*/
234
235boolean
236bfd_cache_close (abfd)
237     bfd *abfd;
238{
239  if (abfd->iostream == NULL
240      || (abfd->flags & BFD_IN_MEMORY) != 0)
241    return true;
242
243  return bfd_cache_delete (abfd);
244}
245
246/*
247INTERNAL_FUNCTION
248	bfd_open_file
249
250SYNOPSIS
251	FILE* bfd_open_file(bfd *abfd);
252
253DESCRIPTION
254	Call the OS to open a file for @var{abfd}.  Return the <<FILE *>>
255	(possibly <<NULL>>) that results from this operation.  Set up the
256	BFD so that future accesses know the file is open. If the <<FILE *>>
257	returned is <<NULL>>, then it won't have been put in the
258	cache, so it won't have to be removed from it.
259*/
260
261FILE *
262bfd_open_file (abfd)
263     bfd *abfd;
264{
265  abfd->cacheable = true;	/* Allow it to be closed later. */
266
267  if (open_files >= BFD_CACHE_MAX_OPEN)
268    {
269      if (! close_one ())
270	return NULL;
271    }
272
273  switch (abfd->direction)
274    {
275    case read_direction:
276    case no_direction:
277      abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RB);
278      break;
279    case both_direction:
280    case write_direction:
281      if (abfd->opened_once == true)
282	{
283	  abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RUB);
284	  if (abfd->iostream == NULL)
285	    abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WUB);
286	}
287      else
288	{
289	  /* Create the file.
290
291	     Some operating systems won't let us overwrite a running
292	     binary.  For them, we want to unlink the file first.
293
294	     However, gcc 2.95 will create temporary files using
295	     O_EXCL and tight permissions to prevent other users from
296	     substituting other .o files during the compilation.  gcc
297	     will then tell the assembler to use the newly created
298	     file as an output file.  If we unlink the file here, we
299	     open a brief window when another user could still
300	     substitute a file.
301
302	     So we unlink the output file if and only if it has
303	     non-zero size.  */
304#ifndef __MSDOS__
305	  /* Don't do this for MSDOS: it doesn't care about overwriting
306	     a running binary, but if this file is already open by
307	     another BFD, we will be in deep trouble if we delete an
308	     open file.  In fact, objdump does just that if invoked with
309	     the --info option.  */
310	  struct stat s;
311
312	  if (stat (abfd->filename, &s) == 0 && s.st_size != 0)
313	    unlink (abfd->filename);
314#endif
315	  abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WB);
316	  abfd->opened_once = true;
317	}
318      break;
319    }
320
321  if (abfd->iostream != NULL)
322    {
323      if (! bfd_cache_init (abfd))
324	return NULL;
325    }
326
327  return (FILE *) abfd->iostream;
328}
329
330/*
331INTERNAL_FUNCTION
332	bfd_cache_lookup_worker
333
334SYNOPSIS
335	FILE *bfd_cache_lookup_worker(bfd *abfd);
336
337DESCRIPTION
338	Called when the macro <<bfd_cache_lookup>> fails to find a
339	quick answer.  Find a file descriptor for @var{abfd}.  If
340	necessary, it open it.  If there are already more than
341	<<BFD_CACHE_MAX_OPEN>> files open, it tries to close one first, to
342	avoid running out of file descriptors.
343*/
344
345FILE *
346bfd_cache_lookup_worker (abfd)
347     bfd *abfd;
348{
349  if ((abfd->flags & BFD_IN_MEMORY) != 0)
350    abort ();
351
352  if (abfd->my_archive)
353    abfd = abfd->my_archive;
354
355  if (abfd->iostream != NULL)
356    {
357      /* Move the file to the start of the cache.  */
358      if (abfd != bfd_last_cache)
359	{
360	  snip (abfd);
361	  insert (abfd);
362	}
363    }
364  else
365    {
366      if (bfd_open_file (abfd) == NULL)
367	return NULL;
368      if (fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0)
369	return NULL;
370    }
371
372  return (FILE *) abfd->iostream;
373}
374