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