2004-02-11 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / bfd / cache.c
CommitLineData
252b5132 1/* BFD library -- caching of file descriptors.
7c192733
AC
2
3 Copyright 1990, 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002,
4 2003, 2004 Free Software Foundation, Inc.
5
252b5132
RH
6 Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
7
8This file is part of BFD, the Binary File Descriptor library.
9
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2 of the License, or
13(at your option) any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23
24/*
25SECTION
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
e60b52c6 37 handle.
252b5132
RH
38
39*/
40
41#include "bfd.h"
42#include "sysdep.h"
43#include "libbfd.h"
44
c58b9523 45static bfd_boolean bfd_cache_delete (bfd *);
252b5132
RH
46
47/*
48INTERNAL_FUNCTION
49 BFD_CACHE_MAX_OPEN macro
50
51DESCRIPTION
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
61static int open_files;
62
63/*
64INTERNAL_FUNCTION
65 bfd_last_cache
66
67SYNOPSIS
68 extern bfd *bfd_last_cache;
69
70DESCRIPTION
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
76bfd *bfd_last_cache;
77
78/*
79 INTERNAL_FUNCTION
80 bfd_cache_lookup
e60b52c6 81
252b5132
RH
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.
e60b52c6 87
252b5132
RH
88 .#define bfd_cache_lookup(x) \
89 . ((x)==bfd_last_cache? \
e60b52c6 90 . (FILE*) (bfd_last_cache->iostream): \
252b5132 91 . bfd_cache_lookup_worker(x))
e60b52c6 92
252b5132
RH
93 */
94
95/* Insert a BFD into the cache. */
96
c58b9523
AM
97static void
98insert (bfd *abfd)
252b5132
RH
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
c58b9523
AM
117static void
118snip (bfd *abfd)
252b5132
RH
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
b34976b6 133static bfd_boolean
c58b9523 134close_one (void)
252b5132
RH
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. */
b34976b6 157 return TRUE;
252b5132
RH
158 }
159
7c192733 160 kill->where = real_ftell ((FILE *) kill->iostream);
252b5132
RH
161
162 return bfd_cache_delete (kill);
163}
164
165/* Close a BFD and remove it from the cache. */
166
b34976b6 167static bfd_boolean
c58b9523 168bfd_cache_delete (bfd *abfd)
252b5132 169{
b34976b6 170 bfd_boolean ret;
252b5132
RH
171
172 if (fclose ((FILE *) abfd->iostream) == 0)
b34976b6 173 ret = TRUE;
252b5132
RH
174 else
175 {
b34976b6 176 ret = FALSE;
252b5132
RH
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/*
189INTERNAL_FUNCTION
190 bfd_cache_init
191
192SYNOPSIS
b34976b6 193 bfd_boolean bfd_cache_init (bfd *abfd);
252b5132
RH
194
195DESCRIPTION
196 Add a newly opened BFD to the cache.
197*/
198
b34976b6 199bfd_boolean
c58b9523 200bfd_cache_init (bfd *abfd)
252b5132
RH
201{
202 BFD_ASSERT (abfd->iostream != NULL);
203 if (open_files >= BFD_CACHE_MAX_OPEN)
204 {
205 if (! close_one ())
b34976b6 206 return FALSE;
252b5132
RH
207 }
208 insert (abfd);
209 ++open_files;
b34976b6 210 return TRUE;
252b5132
RH
211}
212
213/*
214INTERNAL_FUNCTION
215 bfd_cache_close
216
217SYNOPSIS
b34976b6 218 bfd_boolean bfd_cache_close (bfd *abfd);
252b5132
RH
219
220DESCRIPTION
221 Remove the BFD @var{abfd} from the cache. If the attached file is open,
222 then close it too.
223
224RETURNS
b34976b6 225 <<FALSE>> is returned if closing the file fails, <<TRUE>> is
252b5132
RH
226 returned if all is well.
227*/
228
b34976b6 229bfd_boolean
c58b9523 230bfd_cache_close (bfd *abfd)
252b5132
RH
231{
232 if (abfd->iostream == NULL
233 || (abfd->flags & BFD_IN_MEMORY) != 0)
b34976b6 234 return TRUE;
252b5132
RH
235
236 return bfd_cache_delete (abfd);
237}
238
239/*
240INTERNAL_FUNCTION
241 bfd_open_file
242
243SYNOPSIS
c58b9523 244 FILE* bfd_open_file (bfd *abfd);
252b5132
RH
245
246DESCRIPTION
247 Call the OS to open a file for @var{abfd}. Return the <<FILE *>>
248 (possibly <<NULL>>) that results from this operation. Set up the
249 BFD so that future accesses know the file is open. If the <<FILE *>>
250 returned is <<NULL>>, then it won't have been put in the
251 cache, so it won't have to be removed from it.
252*/
253
254FILE *
c58b9523 255bfd_open_file (bfd *abfd)
252b5132 256{
b34976b6 257 abfd->cacheable = TRUE; /* Allow it to be closed later. */
252b5132
RH
258
259 if (open_files >= BFD_CACHE_MAX_OPEN)
260 {
261 if (! close_one ())
262 return NULL;
263 }
264
265 switch (abfd->direction)
266 {
267 case read_direction:
268 case no_direction:
269 abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RB);
270 break;
271 case both_direction:
272 case write_direction:
82e51918 273 if (abfd->opened_once)
252b5132
RH
274 {
275 abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RUB);
276 if (abfd->iostream == NULL)
277 abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WUB);
278 }
279 else
280 {
9e422a2e
ILT
281 /* Create the file.
282
283 Some operating systems won't let us overwrite a running
284 binary. For them, we want to unlink the file first.
285
286 However, gcc 2.95 will create temporary files using
287 O_EXCL and tight permissions to prevent other users from
288 substituting other .o files during the compilation. gcc
289 will then tell the assembler to use the newly created
290 file as an output file. If we unlink the file here, we
291 open a brief window when another user could still
292 substitute a file.
293
294 So we unlink the output file if and only if it has
295 non-zero size. */
5af11cab
AM
296#ifndef __MSDOS__
297 /* Don't do this for MSDOS: it doesn't care about overwriting
298 a running binary, but if this file is already open by
299 another BFD, we will be in deep trouble if we delete an
300 open file. In fact, objdump does just that if invoked with
301 the --info option. */
9e422a2e
ILT
302 struct stat s;
303
304 if (stat (abfd->filename, &s) == 0 && s.st_size != 0)
305 unlink (abfd->filename);
5af11cab 306#endif
c46b7515 307 abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WUB);
b34976b6 308 abfd->opened_once = TRUE;
252b5132
RH
309 }
310 break;
311 }
312
313 if (abfd->iostream != NULL)
314 {
315 if (! bfd_cache_init (abfd))
316 return NULL;
317 }
318
319 return (FILE *) abfd->iostream;
320}
321
322/*
323INTERNAL_FUNCTION
324 bfd_cache_lookup_worker
325
326SYNOPSIS
c58b9523 327 FILE *bfd_cache_lookup_worker (bfd *abfd);
252b5132
RH
328
329DESCRIPTION
330 Called when the macro <<bfd_cache_lookup>> fails to find a
331 quick answer. Find a file descriptor for @var{abfd}. If
332 necessary, it open it. If there are already more than
333 <<BFD_CACHE_MAX_OPEN>> files open, it tries to close one first, to
e60b52c6 334 avoid running out of file descriptors.
252b5132
RH
335*/
336
337FILE *
c58b9523 338bfd_cache_lookup_worker (bfd *abfd)
252b5132
RH
339{
340 if ((abfd->flags & BFD_IN_MEMORY) != 0)
341 abort ();
342
e60b52c6 343 if (abfd->my_archive)
252b5132
RH
344 abfd = abfd->my_archive;
345
346 if (abfd->iostream != NULL)
347 {
348 /* Move the file to the start of the cache. */
349 if (abfd != bfd_last_cache)
350 {
351 snip (abfd);
352 insert (abfd);
353 }
354 }
355 else
356 {
357 if (bfd_open_file (abfd) == NULL)
358 return NULL;
dc810e39
AM
359 if (abfd->where != (unsigned long) abfd->where)
360 return NULL;
7c192733 361 if (real_fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0)
252b5132
RH
362 return NULL;
363 }
364
365 return (FILE *) abfd->iostream;
366}
This page took 0.225448 seconds and 4 git commands to generate.