OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [final_interface/] [gdb-5.0/] [bfd/] [cache.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 104 markom
/* BFD library -- caching of file descriptors.
2
   Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
3
   Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
4
 
5
This file is part of BFD, the Binary File Descriptor library.
6
 
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
/*
22
SECTION
23
        File caching
24
 
25
        The file caching mechanism is embedded within BFD and allows
26
        the application to open as many BFDs as it wants without
27
        regard to the underlying operating system's file descriptor
28
        limit (often as low as 20 open files).  The module in
29
        <<cache.c>> maintains a least recently used list of
30
        <<BFD_CACHE_MAX_OPEN>> files, and exports the name
31
        <<bfd_cache_lookup>>, which runs around and makes sure that
32
        the required BFD is open. If not, then it chooses a file to
33
        close, closes it and opens the one wanted, returning its file
34
        handle.
35
 
36
*/
37
 
38
#include "bfd.h"
39
#include "sysdep.h"
40
#include "libbfd.h"
41
 
42
static void insert PARAMS ((bfd *));
43
static void snip PARAMS ((bfd *));
44
static boolean close_one PARAMS ((void));
45
static boolean bfd_cache_delete PARAMS ((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
 
96
/* Insert a BFD into the cache.  */
97
 
98
static INLINE void
99
insert (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
 
119
static INLINE void
120
snip (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
 
136
static boolean
137
close_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
 
170
static boolean
171
bfd_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
/*
193
INTERNAL_FUNCTION
194
        bfd_cache_init
195
 
196
SYNOPSIS
197
        boolean bfd_cache_init (bfd *abfd);
198
 
199
DESCRIPTION
200
        Add a newly opened BFD to the cache.
201
*/
202
 
203
boolean
204
bfd_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
/*
219
INTERNAL_FUNCTION
220
        bfd_cache_close
221
 
222
SYNOPSIS
223
        boolean bfd_cache_close (bfd *abfd);
224
 
225
DESCRIPTION
226
        Remove the BFD @var{abfd} from the cache. If the attached file is open,
227
        then close it too.
228
 
229
RETURNS
230
        <<false>> is returned if closing the file fails, <<true>> is
231
        returned if all is well.
232
*/
233
 
234
boolean
235
bfd_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
/*
246
INTERNAL_FUNCTION
247
        bfd_open_file
248
 
249
SYNOPSIS
250
        FILE* bfd_open_file(bfd *abfd);
251
 
252
DESCRIPTION
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
 
260
FILE *
261
bfd_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
          struct stat s;
304
 
305
          if (stat (abfd->filename, &s) == 0 && s.st_size != 0)
306
            unlink (abfd->filename);
307
          abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WB);
308
          abfd->opened_once = true;
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
/*
323
INTERNAL_FUNCTION
324
        bfd_cache_lookup_worker
325
 
326
SYNOPSIS
327
        FILE *bfd_cache_lookup_worker(bfd *abfd);
328
 
329
DESCRIPTION
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
334
        avoid running out of file descriptors.
335
*/
336
 
337
FILE *
338
bfd_cache_lookup_worker (abfd)
339
     bfd *abfd;
340
{
341
  if ((abfd->flags & BFD_IN_MEMORY) != 0)
342
    abort ();
343
 
344
  if (abfd->my_archive)
345
    abfd = abfd->my_archive;
346
 
347
  if (abfd->iostream != NULL)
348
    {
349
      /* Move the file to the start of the cache.  */
350
      if (abfd != bfd_last_cache)
351
        {
352
          snip (abfd);
353
          insert (abfd);
354
        }
355
    }
356
  else
357
    {
358
      if (bfd_open_file (abfd) == NULL)
359
        return NULL;
360
      if (fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0)
361
        return NULL;
362
    }
363
 
364
  return (FILE *) abfd->iostream;
365
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.