1ed0d50c3Schristos /* BFD library -- caching of file descriptors.
2ed0d50c3Schristos 
3*b88e3e88Schristos    Copyright (C) 1990-2020 Free Software Foundation, Inc.
4ed0d50c3Schristos 
5ed0d50c3Schristos    Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
6ed0d50c3Schristos 
7ed0d50c3Schristos    This file is part of BFD, the Binary File Descriptor library.
8ed0d50c3Schristos 
9ed0d50c3Schristos    This program is free software; you can redistribute it and/or modify
10ed0d50c3Schristos    it under the terms of the GNU General Public License as published by
11ed0d50c3Schristos    the Free Software Foundation; either version 3 of the License, or
12ed0d50c3Schristos    (at your option) any later version.
13ed0d50c3Schristos 
14ed0d50c3Schristos    This program is distributed in the hope that it will be useful,
15ed0d50c3Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
16ed0d50c3Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17ed0d50c3Schristos    GNU General Public License for more details.
18ed0d50c3Schristos 
19ed0d50c3Schristos    You should have received a copy of the GNU General Public License
20ed0d50c3Schristos    along with this program; if not, write to the Free Software
21ed0d50c3Schristos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22ed0d50c3Schristos    MA 02110-1301, USA.  */
23ed0d50c3Schristos 
24ed0d50c3Schristos /*
25ed0d50c3Schristos SECTION
26ed0d50c3Schristos 	File caching
27ed0d50c3Schristos 
28ed0d50c3Schristos 	The file caching mechanism is embedded within BFD and allows
29ed0d50c3Schristos 	the application to open as many BFDs as it wants without
30ed0d50c3Schristos 	regard to the underlying operating system's file descriptor
31ed0d50c3Schristos 	limit (often as low as 20 open files).  The module in
32ed0d50c3Schristos 	<<cache.c>> maintains a least recently used list of
33ed0d50c3Schristos 	<<bfd_cache_max_open>> files, and exports the name
34ed0d50c3Schristos 	<<bfd_cache_lookup>>, which runs around and makes sure that
35ed0d50c3Schristos 	the required BFD is open. If not, then it chooses a file to
36ed0d50c3Schristos 	close, closes it and opens the one wanted, returning its file
37ed0d50c3Schristos 	handle.
38ed0d50c3Schristos 
39ed0d50c3Schristos SUBSECTION
40ed0d50c3Schristos 	Caching functions
41ed0d50c3Schristos */
42ed0d50c3Schristos 
43ed0d50c3Schristos #include "sysdep.h"
44ed0d50c3Schristos #include "bfd.h"
45ed0d50c3Schristos #include "libbfd.h"
46ed0d50c3Schristos #include "libiberty.h"
47ed0d50c3Schristos 
48ed0d50c3Schristos #ifdef HAVE_MMAP
49ed0d50c3Schristos #include <sys/mman.h>
50ed0d50c3Schristos #endif
51ed0d50c3Schristos 
52ed0d50c3Schristos /* In some cases we can optimize cache operation when reopening files.
53ed0d50c3Schristos    For instance, a flush is entirely unnecessary if the file is already
54ed0d50c3Schristos    closed, so a flush would use CACHE_NO_OPEN.  Similarly, a seek using
55ed0d50c3Schristos    SEEK_SET or SEEK_END need not first seek to the current position.
56ed0d50c3Schristos    For stat we ignore seek errors, just in case the file has changed
57ed0d50c3Schristos    while we weren't looking.  If it has, then it's possible that the
58ed0d50c3Schristos    file is shorter and we don't want a seek error to prevent us doing
59ed0d50c3Schristos    the stat.  */
60ed0d50c3Schristos enum cache_flag {
61ed0d50c3Schristos   CACHE_NORMAL = 0,
62ed0d50c3Schristos   CACHE_NO_OPEN = 1,
63ed0d50c3Schristos   CACHE_NO_SEEK = 2,
64ed0d50c3Schristos   CACHE_NO_SEEK_ERROR = 4
65ed0d50c3Schristos };
66ed0d50c3Schristos 
67ed0d50c3Schristos /* The maximum number of files which the cache will keep open at
68ed0d50c3Schristos    one time.  When needed call bfd_cache_max_open to initialize.  */
69ed0d50c3Schristos 
70ed0d50c3Schristos static int max_open_files = 0;
71ed0d50c3Schristos 
72ed0d50c3Schristos /* Set max_open_files, if not already set, to 12.5% of the allowed open
73ed0d50c3Schristos    file descriptors, but at least 10, and return the value.  */
74ed0d50c3Schristos static int
bfd_cache_max_open(void)75ed0d50c3Schristos bfd_cache_max_open (void)
76ed0d50c3Schristos {
77ed0d50c3Schristos   if (max_open_files == 0)
78ed0d50c3Schristos     {
79ed0d50c3Schristos       int max;
80ed0d50c3Schristos #if defined(__sun) && !defined(__sparcv9) && !defined(__x86_64__)
81ed0d50c3Schristos       /* PR ld/19260: 32-bit Solaris has very inelegant handling of the 255
82ed0d50c3Schristos 	 file descriptor limit.  The problem is that setrlimit(2) can raise
83ed0d50c3Schristos 	 RLIMIT_NOFILE to a value that is not supported by libc, resulting
84ed0d50c3Schristos 	 in "Too many open files" errors.  This can happen here even though
85ed0d50c3Schristos 	 max_open_files is set to rlim.rlim_cur / 8.  For example, if
86ed0d50c3Schristos 	 a parent process has set rlim.rlim_cur to 65536, then max_open_files
87ed0d50c3Schristos 	 will be computed as 8192.
88ed0d50c3Schristos 
89ed0d50c3Schristos 	 This check essentially reverts to the behavior from binutils 2.23.1
90ed0d50c3Schristos 	 for 32-bit Solaris only.  (It is hoped that the 32-bit libc
91ed0d50c3Schristos 	 limitation will be removed soon).  64-bit Solaris libc does not have
92ed0d50c3Schristos 	 this limitation.  */
93ed0d50c3Schristos       max = 16;
94ed0d50c3Schristos #else
95ed0d50c3Schristos #ifdef HAVE_GETRLIMIT
96ed0d50c3Schristos       struct rlimit rlim;
97ed0d50c3Schristos 
98ed0d50c3Schristos       if (getrlimit (RLIMIT_NOFILE, &rlim) == 0
99ed0d50c3Schristos 	  && rlim.rlim_cur != (rlim_t) RLIM_INFINITY)
100ed0d50c3Schristos 	max = rlim.rlim_cur / 8;
101ed0d50c3Schristos       else
102ed0d50c3Schristos #endif
103ed0d50c3Schristos #ifdef _SC_OPEN_MAX
104ed0d50c3Schristos 	max = sysconf (_SC_OPEN_MAX) / 8;
105ed0d50c3Schristos #else
106ed0d50c3Schristos 	max = 10;
107ed0d50c3Schristos #endif
108ed0d50c3Schristos #endif /* not 32-bit Solaris */
109ed0d50c3Schristos 
110ed0d50c3Schristos       max_open_files = max < 10 ? 10 : max;
111ed0d50c3Schristos     }
112ed0d50c3Schristos 
113ed0d50c3Schristos   return max_open_files;
114ed0d50c3Schristos }
115ed0d50c3Schristos 
116ed0d50c3Schristos /* The number of BFD files we have open.  */
117ed0d50c3Schristos 
118ed0d50c3Schristos static int open_files;
119ed0d50c3Schristos 
120ed0d50c3Schristos /* Zero, or a pointer to the topmost BFD on the chain.  This is
121ed0d50c3Schristos    used by the <<bfd_cache_lookup>> macro in @file{libbfd.h} to
122ed0d50c3Schristos    determine when it can avoid a function call.  */
123ed0d50c3Schristos 
124ed0d50c3Schristos static bfd *bfd_last_cache = NULL;
125ed0d50c3Schristos 
126ed0d50c3Schristos /* Insert a BFD into the cache.  */
127ed0d50c3Schristos 
128ed0d50c3Schristos static void
insert(bfd * abfd)129ed0d50c3Schristos insert (bfd *abfd)
130ed0d50c3Schristos {
131ed0d50c3Schristos   if (bfd_last_cache == NULL)
132ed0d50c3Schristos     {
133ed0d50c3Schristos       abfd->lru_next = abfd;
134ed0d50c3Schristos       abfd->lru_prev = abfd;
135ed0d50c3Schristos     }
136ed0d50c3Schristos   else
137ed0d50c3Schristos     {
138ed0d50c3Schristos       abfd->lru_next = bfd_last_cache;
139ed0d50c3Schristos       abfd->lru_prev = bfd_last_cache->lru_prev;
140ed0d50c3Schristos       abfd->lru_prev->lru_next = abfd;
141ed0d50c3Schristos       abfd->lru_next->lru_prev = abfd;
142ed0d50c3Schristos     }
143ed0d50c3Schristos   bfd_last_cache = abfd;
144ed0d50c3Schristos }
145ed0d50c3Schristos 
146ed0d50c3Schristos /* Remove a BFD from the cache.  */
147ed0d50c3Schristos 
148ed0d50c3Schristos static void
snip(bfd * abfd)149ed0d50c3Schristos snip (bfd *abfd)
150ed0d50c3Schristos {
151ed0d50c3Schristos   abfd->lru_prev->lru_next = abfd->lru_next;
152ed0d50c3Schristos   abfd->lru_next->lru_prev = abfd->lru_prev;
153ed0d50c3Schristos   if (abfd == bfd_last_cache)
154ed0d50c3Schristos     {
155ed0d50c3Schristos       bfd_last_cache = abfd->lru_next;
156ed0d50c3Schristos       if (abfd == bfd_last_cache)
157ed0d50c3Schristos 	bfd_last_cache = NULL;
158ed0d50c3Schristos     }
159ed0d50c3Schristos }
160ed0d50c3Schristos 
161ed0d50c3Schristos /* Close a BFD and remove it from the cache.  */
162ed0d50c3Schristos 
163ed0d50c3Schristos static bfd_boolean
bfd_cache_delete(bfd * abfd)164ed0d50c3Schristos bfd_cache_delete (bfd *abfd)
165ed0d50c3Schristos {
166ed0d50c3Schristos   bfd_boolean ret;
167ed0d50c3Schristos 
168ed0d50c3Schristos   if (fclose ((FILE *) abfd->iostream) == 0)
169ed0d50c3Schristos     ret = TRUE;
170ed0d50c3Schristos   else
171ed0d50c3Schristos     {
172ed0d50c3Schristos       ret = FALSE;
173ed0d50c3Schristos       bfd_set_error (bfd_error_system_call);
174ed0d50c3Schristos     }
175ed0d50c3Schristos 
176ed0d50c3Schristos   snip (abfd);
177ed0d50c3Schristos 
178ed0d50c3Schristos   abfd->iostream = NULL;
179ed0d50c3Schristos   --open_files;
180ed0d50c3Schristos 
181ed0d50c3Schristos   return ret;
182ed0d50c3Schristos }
183ed0d50c3Schristos 
184ed0d50c3Schristos /* We need to open a new file, and the cache is full.  Find the least
185ed0d50c3Schristos    recently used cacheable BFD and close it.  */
186ed0d50c3Schristos 
187ed0d50c3Schristos static bfd_boolean
close_one(void)188ed0d50c3Schristos close_one (void)
189ed0d50c3Schristos {
190ed0d50c3Schristos   register bfd *to_kill;
191ed0d50c3Schristos 
192ed0d50c3Schristos   if (bfd_last_cache == NULL)
193ed0d50c3Schristos     to_kill = NULL;
194ed0d50c3Schristos   else
195ed0d50c3Schristos     {
196ed0d50c3Schristos       for (to_kill = bfd_last_cache->lru_prev;
197ed0d50c3Schristos 	   ! to_kill->cacheable;
198ed0d50c3Schristos 	   to_kill = to_kill->lru_prev)
199ed0d50c3Schristos 	{
200ed0d50c3Schristos 	  if (to_kill == bfd_last_cache)
201ed0d50c3Schristos 	    {
202ed0d50c3Schristos 	      to_kill = NULL;
203ed0d50c3Schristos 	      break;
204ed0d50c3Schristos 	    }
205ed0d50c3Schristos 	}
206ed0d50c3Schristos     }
207ed0d50c3Schristos 
208ed0d50c3Schristos   if (to_kill == NULL)
209ed0d50c3Schristos     {
210ed0d50c3Schristos       /* There are no open cacheable BFD's.  */
211ed0d50c3Schristos       return TRUE;
212ed0d50c3Schristos     }
213ed0d50c3Schristos 
21406324dcfSchristos   to_kill->where = _bfd_real_ftell ((FILE *) to_kill->iostream);
215ed0d50c3Schristos 
216ed0d50c3Schristos   return bfd_cache_delete (to_kill);
217ed0d50c3Schristos }
218ed0d50c3Schristos 
219ed0d50c3Schristos /* Check to see if the required BFD is the same as the last one
220ed0d50c3Schristos    looked up. If so, then it can use the stream in the BFD with
221ed0d50c3Schristos    impunity, since it can't have changed since the last lookup;
222ed0d50c3Schristos    otherwise, it has to perform the complicated lookup function.  */
223ed0d50c3Schristos 
224ed0d50c3Schristos #define bfd_cache_lookup(x, flag) \
225ed0d50c3Schristos   ((x) == bfd_last_cache			\
226ed0d50c3Schristos    ? (FILE *) (bfd_last_cache->iostream)	\
227ed0d50c3Schristos    : bfd_cache_lookup_worker (x, flag))
228ed0d50c3Schristos 
229ed0d50c3Schristos /* Called when the macro <<bfd_cache_lookup>> fails to find a
230ed0d50c3Schristos    quick answer.  Find a file descriptor for @var{abfd}.  If
231ed0d50c3Schristos    necessary, it open it.  If there are already more than
232ed0d50c3Schristos    <<bfd_cache_max_open>> files open, it tries to close one first, to
233ed0d50c3Schristos    avoid running out of file descriptors.  It will return NULL
234ed0d50c3Schristos    if it is unable to (re)open the @var{abfd}.  */
235ed0d50c3Schristos 
236ed0d50c3Schristos static FILE *
bfd_cache_lookup_worker(bfd * abfd,enum cache_flag flag)237ed0d50c3Schristos bfd_cache_lookup_worker (bfd *abfd, enum cache_flag flag)
238ed0d50c3Schristos {
239ed0d50c3Schristos   if ((abfd->flags & BFD_IN_MEMORY) != 0)
240ed0d50c3Schristos     abort ();
241ed0d50c3Schristos 
24206324dcfSchristos   if (abfd->my_archive != NULL
243ed0d50c3Schristos       && !bfd_is_thin_archive (abfd->my_archive))
24406324dcfSchristos     abort ();
245ed0d50c3Schristos 
246ed0d50c3Schristos   if (abfd->iostream != NULL)
247ed0d50c3Schristos     {
248ed0d50c3Schristos       /* Move the file to the start of the cache.  */
249ed0d50c3Schristos       if (abfd != bfd_last_cache)
250ed0d50c3Schristos 	{
251ed0d50c3Schristos 	  snip (abfd);
252ed0d50c3Schristos 	  insert (abfd);
253ed0d50c3Schristos 	}
254ed0d50c3Schristos       return (FILE *) abfd->iostream;
255ed0d50c3Schristos     }
256ed0d50c3Schristos 
257ed0d50c3Schristos   if (flag & CACHE_NO_OPEN)
258ed0d50c3Schristos     return NULL;
259ed0d50c3Schristos 
260ed0d50c3Schristos   if (bfd_open_file (abfd) == NULL)
261ed0d50c3Schristos     ;
262ed0d50c3Schristos   else if (!(flag & CACHE_NO_SEEK)
26306324dcfSchristos 	   && _bfd_real_fseek ((FILE *) abfd->iostream,
26406324dcfSchristos 			       abfd->where, SEEK_SET) != 0
265ed0d50c3Schristos 	   && !(flag & CACHE_NO_SEEK_ERROR))
266ed0d50c3Schristos     bfd_set_error (bfd_error_system_call);
267ed0d50c3Schristos   else
268ed0d50c3Schristos     return (FILE *) abfd->iostream;
269ed0d50c3Schristos 
27006324dcfSchristos   /* xgettext:c-format */
27106324dcfSchristos   _bfd_error_handler (_("reopening %pB: %s\n"),
27206324dcfSchristos 		      abfd, bfd_errmsg (bfd_get_error ()));
273ed0d50c3Schristos   return NULL;
274ed0d50c3Schristos }
275ed0d50c3Schristos 
276ed0d50c3Schristos static file_ptr
cache_btell(struct bfd * abfd)277ed0d50c3Schristos cache_btell (struct bfd *abfd)
278ed0d50c3Schristos {
279ed0d50c3Schristos   FILE *f = bfd_cache_lookup (abfd, CACHE_NO_OPEN);
280ed0d50c3Schristos   if (f == NULL)
281ed0d50c3Schristos     return abfd->where;
28206324dcfSchristos   return _bfd_real_ftell (f);
283ed0d50c3Schristos }
284ed0d50c3Schristos 
285ed0d50c3Schristos static int
cache_bseek(struct bfd * abfd,file_ptr offset,int whence)286ed0d50c3Schristos cache_bseek (struct bfd *abfd, file_ptr offset, int whence)
287ed0d50c3Schristos {
288ed0d50c3Schristos   FILE *f = bfd_cache_lookup (abfd, whence != SEEK_CUR ? CACHE_NO_SEEK : CACHE_NORMAL);
289ed0d50c3Schristos   if (f == NULL)
290ed0d50c3Schristos     return -1;
29106324dcfSchristos   return _bfd_real_fseek (f, offset, whence);
292ed0d50c3Schristos }
293ed0d50c3Schristos 
294ed0d50c3Schristos /* Note that archive entries don't have streams; they share their parent's.
295ed0d50c3Schristos    This allows someone to play with the iostream behind BFD's back.
296ed0d50c3Schristos 
297ed0d50c3Schristos    Also, note that the origin pointer points to the beginning of a file's
298ed0d50c3Schristos    contents (0 for non-archive elements).  For archive entries this is the
299ed0d50c3Schristos    first octet in the file, NOT the beginning of the archive header.  */
300ed0d50c3Schristos 
301ed0d50c3Schristos static file_ptr
cache_bread_1(FILE * f,void * buf,file_ptr nbytes)30206324dcfSchristos cache_bread_1 (FILE *f, void *buf, file_ptr nbytes)
303ed0d50c3Schristos {
304ed0d50c3Schristos   file_ptr nread;
305ed0d50c3Schristos 
306ed0d50c3Schristos #if defined (__VAX) && defined (VMS)
307ed0d50c3Schristos   /* Apparently fread on Vax VMS does not keep the record length
308ed0d50c3Schristos      information.  */
309ed0d50c3Schristos   nread = read (fileno (f), buf, nbytes);
310ed0d50c3Schristos   /* Set bfd_error if we did not read as much data as we expected.  If
311ed0d50c3Schristos      the read failed due to an error set the bfd_error_system_call,
312ed0d50c3Schristos      else set bfd_error_file_truncated.  */
313ed0d50c3Schristos   if (nread == (file_ptr)-1)
314ed0d50c3Schristos     {
315ed0d50c3Schristos       bfd_set_error (bfd_error_system_call);
316ed0d50c3Schristos       return nread;
317ed0d50c3Schristos     }
318ed0d50c3Schristos #else
319ed0d50c3Schristos   nread = fread (buf, 1, nbytes, f);
320ed0d50c3Schristos   /* Set bfd_error if we did not read as much data as we expected.  If
321ed0d50c3Schristos      the read failed due to an error set the bfd_error_system_call,
322ed0d50c3Schristos      else set bfd_error_file_truncated.  */
323ed0d50c3Schristos   if (nread < nbytes && ferror (f))
324ed0d50c3Schristos     {
325ed0d50c3Schristos       bfd_set_error (bfd_error_system_call);
326ed0d50c3Schristos       return nread;
327ed0d50c3Schristos     }
328ed0d50c3Schristos #endif
329ed0d50c3Schristos   if (nread < nbytes)
330ed0d50c3Schristos     /* This may or may not be an error, but in case the calling code
331ed0d50c3Schristos        bails out because of it, set the right error code.  */
332ed0d50c3Schristos     bfd_set_error (bfd_error_file_truncated);
333ed0d50c3Schristos   return nread;
334ed0d50c3Schristos }
335ed0d50c3Schristos 
336ed0d50c3Schristos static file_ptr
cache_bread(struct bfd * abfd,void * buf,file_ptr nbytes)337ed0d50c3Schristos cache_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
338ed0d50c3Schristos {
339ed0d50c3Schristos   file_ptr nread = 0;
34006324dcfSchristos   FILE *f;
34106324dcfSchristos 
34206324dcfSchristos   f = bfd_cache_lookup (abfd, CACHE_NORMAL);
34306324dcfSchristos   if (f == NULL)
34406324dcfSchristos     return -1;
345ed0d50c3Schristos 
346ed0d50c3Schristos   /* Some filesystems are unable to handle reads that are too large
347ed0d50c3Schristos      (for instance, NetApp shares with oplocks turned off).  To avoid
348ed0d50c3Schristos      hitting this limitation, we read the buffer in chunks of 8MB max.  */
349ed0d50c3Schristos   while (nread < nbytes)
350ed0d50c3Schristos     {
351ed0d50c3Schristos       const file_ptr max_chunk_size = 0x800000;
352ed0d50c3Schristos       file_ptr chunk_size = nbytes - nread;
353ed0d50c3Schristos       file_ptr chunk_nread;
354ed0d50c3Schristos 
355ed0d50c3Schristos       if (chunk_size > max_chunk_size)
356ed0d50c3Schristos 	chunk_size = max_chunk_size;
357ed0d50c3Schristos 
35806324dcfSchristos       chunk_nread = cache_bread_1 (f, (char *) buf + nread, chunk_size);
359ed0d50c3Schristos 
360ed0d50c3Schristos       /* Update the nread count.
361ed0d50c3Schristos 
362ed0d50c3Schristos 	 We just have to be careful of the case when cache_bread_1 returns
363ed0d50c3Schristos 	 a negative count:  If this is our first read, then set nread to
364ed0d50c3Schristos 	 that negative count in order to return that negative value to the
365ed0d50c3Schristos 	 caller.  Otherwise, don't add it to our total count, or we would
366ed0d50c3Schristos 	 end up returning a smaller number of bytes read than we actually
367ed0d50c3Schristos 	 did.  */
368ed0d50c3Schristos       if (nread == 0 || chunk_nread > 0)
369ed0d50c3Schristos 	nread += chunk_nread;
370ed0d50c3Schristos 
371ed0d50c3Schristos       if (chunk_nread < chunk_size)
372ed0d50c3Schristos 	break;
373ed0d50c3Schristos     }
374ed0d50c3Schristos 
375ed0d50c3Schristos   return nread;
376ed0d50c3Schristos }
377ed0d50c3Schristos 
378ed0d50c3Schristos static file_ptr
cache_bwrite(struct bfd * abfd,const void * from,file_ptr nbytes)37906324dcfSchristos cache_bwrite (struct bfd *abfd, const void *from, file_ptr nbytes)
380ed0d50c3Schristos {
381ed0d50c3Schristos   file_ptr nwrite;
382ed0d50c3Schristos   FILE *f = bfd_cache_lookup (abfd, CACHE_NORMAL);
383ed0d50c3Schristos 
384ed0d50c3Schristos   if (f == NULL)
385ed0d50c3Schristos     return 0;
38606324dcfSchristos   nwrite = fwrite (from, 1, nbytes, f);
387ed0d50c3Schristos   if (nwrite < nbytes && ferror (f))
388ed0d50c3Schristos     {
389ed0d50c3Schristos       bfd_set_error (bfd_error_system_call);
390ed0d50c3Schristos       return -1;
391ed0d50c3Schristos     }
392ed0d50c3Schristos   return nwrite;
393ed0d50c3Schristos }
394ed0d50c3Schristos 
395ed0d50c3Schristos static int
cache_bclose(struct bfd * abfd)396ed0d50c3Schristos cache_bclose (struct bfd *abfd)
397ed0d50c3Schristos {
398ed0d50c3Schristos   return bfd_cache_close (abfd) - 1;
399ed0d50c3Schristos }
400ed0d50c3Schristos 
401ed0d50c3Schristos static int
cache_bflush(struct bfd * abfd)402ed0d50c3Schristos cache_bflush (struct bfd *abfd)
403ed0d50c3Schristos {
404ed0d50c3Schristos   int sts;
405ed0d50c3Schristos   FILE *f = bfd_cache_lookup (abfd, CACHE_NO_OPEN);
406ed0d50c3Schristos 
407ed0d50c3Schristos   if (f == NULL)
408ed0d50c3Schristos     return 0;
409ed0d50c3Schristos   sts = fflush (f);
410ed0d50c3Schristos   if (sts < 0)
411ed0d50c3Schristos     bfd_set_error (bfd_error_system_call);
412ed0d50c3Schristos   return sts;
413ed0d50c3Schristos }
414ed0d50c3Schristos 
415ed0d50c3Schristos static int
cache_bstat(struct bfd * abfd,struct stat * sb)416ed0d50c3Schristos cache_bstat (struct bfd *abfd, struct stat *sb)
417ed0d50c3Schristos {
418ed0d50c3Schristos   int sts;
419ed0d50c3Schristos   FILE *f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR);
420ed0d50c3Schristos 
421ed0d50c3Schristos   if (f == NULL)
422ed0d50c3Schristos     return -1;
423ed0d50c3Schristos   sts = fstat (fileno (f), sb);
424ed0d50c3Schristos   if (sts < 0)
425ed0d50c3Schristos     bfd_set_error (bfd_error_system_call);
426ed0d50c3Schristos   return sts;
427ed0d50c3Schristos }
428ed0d50c3Schristos 
429ed0d50c3Schristos static void *
cache_bmmap(struct bfd * abfd ATTRIBUTE_UNUSED,void * addr ATTRIBUTE_UNUSED,bfd_size_type len ATTRIBUTE_UNUSED,int prot ATTRIBUTE_UNUSED,int flags ATTRIBUTE_UNUSED,file_ptr offset ATTRIBUTE_UNUSED,void ** map_addr ATTRIBUTE_UNUSED,bfd_size_type * map_len ATTRIBUTE_UNUSED)430ed0d50c3Schristos cache_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
431ed0d50c3Schristos 	     void *addr ATTRIBUTE_UNUSED,
432ed0d50c3Schristos 	     bfd_size_type len ATTRIBUTE_UNUSED,
433ed0d50c3Schristos 	     int prot ATTRIBUTE_UNUSED,
434ed0d50c3Schristos 	     int flags ATTRIBUTE_UNUSED,
435ed0d50c3Schristos 	     file_ptr offset ATTRIBUTE_UNUSED,
436ed0d50c3Schristos 	     void **map_addr ATTRIBUTE_UNUSED,
437ed0d50c3Schristos 	     bfd_size_type *map_len ATTRIBUTE_UNUSED)
438ed0d50c3Schristos {
439ed0d50c3Schristos   void *ret = (void *) -1;
440ed0d50c3Schristos 
441ed0d50c3Schristos   if ((abfd->flags & BFD_IN_MEMORY) != 0)
442ed0d50c3Schristos     abort ();
443ed0d50c3Schristos #ifdef HAVE_MMAP
444ed0d50c3Schristos   else
445ed0d50c3Schristos     {
446ed0d50c3Schristos       static uintptr_t pagesize_m1;
447ed0d50c3Schristos       FILE *f;
448ed0d50c3Schristos       file_ptr pg_offset;
449ed0d50c3Schristos       bfd_size_type pg_len;
450ed0d50c3Schristos 
451ed0d50c3Schristos       f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR);
452ed0d50c3Schristos       if (f == NULL)
453ed0d50c3Schristos 	return ret;
454ed0d50c3Schristos 
455ed0d50c3Schristos       if (pagesize_m1 == 0)
456ed0d50c3Schristos 	pagesize_m1 = getpagesize () - 1;
457ed0d50c3Schristos 
458ed0d50c3Schristos       /* Align.  */
459ed0d50c3Schristos       pg_offset = offset & ~pagesize_m1;
460ed0d50c3Schristos       pg_len = (len + (offset - pg_offset) + pagesize_m1) & ~pagesize_m1;
461ed0d50c3Schristos 
462ed0d50c3Schristos       ret = mmap (addr, pg_len, prot, flags, fileno (f), pg_offset);
463ed0d50c3Schristos       if (ret == (void *) -1)
464ed0d50c3Schristos 	bfd_set_error (bfd_error_system_call);
465ed0d50c3Schristos       else
466ed0d50c3Schristos 	{
467ed0d50c3Schristos 	  *map_addr = ret;
468ed0d50c3Schristos 	  *map_len = pg_len;
469ed0d50c3Schristos 	  ret = (char *) ret + (offset & pagesize_m1);
470ed0d50c3Schristos 	}
471ed0d50c3Schristos     }
472ed0d50c3Schristos #endif
473ed0d50c3Schristos 
474ed0d50c3Schristos   return ret;
475ed0d50c3Schristos }
476ed0d50c3Schristos 
477ed0d50c3Schristos static const struct bfd_iovec cache_iovec =
478ed0d50c3Schristos {
479ed0d50c3Schristos   &cache_bread, &cache_bwrite, &cache_btell, &cache_bseek,
480ed0d50c3Schristos   &cache_bclose, &cache_bflush, &cache_bstat, &cache_bmmap
481ed0d50c3Schristos };
482ed0d50c3Schristos 
483ed0d50c3Schristos /*
484ed0d50c3Schristos INTERNAL_FUNCTION
485ed0d50c3Schristos 	bfd_cache_init
486ed0d50c3Schristos 
487ed0d50c3Schristos SYNOPSIS
488ed0d50c3Schristos 	bfd_boolean bfd_cache_init (bfd *abfd);
489ed0d50c3Schristos 
490ed0d50c3Schristos DESCRIPTION
491ed0d50c3Schristos 	Add a newly opened BFD to the cache.
492ed0d50c3Schristos */
493ed0d50c3Schristos 
494ed0d50c3Schristos bfd_boolean
bfd_cache_init(bfd * abfd)495ed0d50c3Schristos bfd_cache_init (bfd *abfd)
496ed0d50c3Schristos {
497ed0d50c3Schristos   BFD_ASSERT (abfd->iostream != NULL);
498ed0d50c3Schristos   if (open_files >= bfd_cache_max_open ())
499ed0d50c3Schristos     {
500ed0d50c3Schristos       if (! close_one ())
501ed0d50c3Schristos 	return FALSE;
502ed0d50c3Schristos     }
503ed0d50c3Schristos   abfd->iovec = &cache_iovec;
504ed0d50c3Schristos   insert (abfd);
505ed0d50c3Schristos   ++open_files;
506ed0d50c3Schristos   return TRUE;
507ed0d50c3Schristos }
508ed0d50c3Schristos 
509ed0d50c3Schristos /*
510ed0d50c3Schristos INTERNAL_FUNCTION
511ed0d50c3Schristos 	bfd_cache_close
512ed0d50c3Schristos 
513ed0d50c3Schristos SYNOPSIS
514ed0d50c3Schristos 	bfd_boolean bfd_cache_close (bfd *abfd);
515ed0d50c3Schristos 
516ed0d50c3Schristos DESCRIPTION
517ed0d50c3Schristos 	Remove the BFD @var{abfd} from the cache. If the attached file is open,
518ed0d50c3Schristos 	then close it too.
519ed0d50c3Schristos 
520ed0d50c3Schristos RETURNS
521ed0d50c3Schristos 	<<FALSE>> is returned if closing the file fails, <<TRUE>> is
522ed0d50c3Schristos 	returned if all is well.
523ed0d50c3Schristos */
524ed0d50c3Schristos 
525ed0d50c3Schristos bfd_boolean
bfd_cache_close(bfd * abfd)526ed0d50c3Schristos bfd_cache_close (bfd *abfd)
527ed0d50c3Schristos {
528ed0d50c3Schristos   if (abfd->iovec != &cache_iovec)
529ed0d50c3Schristos     return TRUE;
530ed0d50c3Schristos 
531ed0d50c3Schristos   if (abfd->iostream == NULL)
532ed0d50c3Schristos     /* Previously closed.  */
533ed0d50c3Schristos     return TRUE;
534ed0d50c3Schristos 
535ed0d50c3Schristos   return bfd_cache_delete (abfd);
536ed0d50c3Schristos }
537ed0d50c3Schristos 
538ed0d50c3Schristos /*
539ed0d50c3Schristos FUNCTION
540ed0d50c3Schristos 	bfd_cache_close_all
541ed0d50c3Schristos 
542ed0d50c3Schristos SYNOPSIS
543ed0d50c3Schristos 	bfd_boolean bfd_cache_close_all (void);
544ed0d50c3Schristos 
545ed0d50c3Schristos DESCRIPTION
546ed0d50c3Schristos 	Remove all BFDs from the cache. If the attached file is open,
547ed0d50c3Schristos 	then close it too.
548ed0d50c3Schristos 
549ed0d50c3Schristos RETURNS
550ed0d50c3Schristos 	<<FALSE>> is returned if closing one of the file fails, <<TRUE>> is
551ed0d50c3Schristos 	returned if all is well.
552ed0d50c3Schristos */
553ed0d50c3Schristos 
554ed0d50c3Schristos bfd_boolean
bfd_cache_close_all(void)555ed0d50c3Schristos bfd_cache_close_all (void)
556ed0d50c3Schristos {
557ed0d50c3Schristos   bfd_boolean ret = TRUE;
558ed0d50c3Schristos 
559ed0d50c3Schristos   while (bfd_last_cache != NULL)
560ed0d50c3Schristos     ret &= bfd_cache_close (bfd_last_cache);
561ed0d50c3Schristos 
562ed0d50c3Schristos   return ret;
563ed0d50c3Schristos }
564ed0d50c3Schristos 
565ed0d50c3Schristos /*
566ed0d50c3Schristos INTERNAL_FUNCTION
567ed0d50c3Schristos 	bfd_open_file
568ed0d50c3Schristos 
569ed0d50c3Schristos SYNOPSIS
570ed0d50c3Schristos 	FILE* bfd_open_file (bfd *abfd);
571ed0d50c3Schristos 
572ed0d50c3Schristos DESCRIPTION
573ed0d50c3Schristos 	Call the OS to open a file for @var{abfd}.  Return the <<FILE *>>
574ed0d50c3Schristos 	(possibly <<NULL>>) that results from this operation.  Set up the
575ed0d50c3Schristos 	BFD so that future accesses know the file is open. If the <<FILE *>>
576ed0d50c3Schristos 	returned is <<NULL>>, then it won't have been put in the
577ed0d50c3Schristos 	cache, so it won't have to be removed from it.
578ed0d50c3Schristos */
579ed0d50c3Schristos 
580ed0d50c3Schristos FILE *
bfd_open_file(bfd * abfd)581ed0d50c3Schristos bfd_open_file (bfd *abfd)
582ed0d50c3Schristos {
583ed0d50c3Schristos   abfd->cacheable = TRUE;	/* Allow it to be closed later.  */
584ed0d50c3Schristos 
585ed0d50c3Schristos   if (open_files >= bfd_cache_max_open ())
586ed0d50c3Schristos     {
587ed0d50c3Schristos       if (! close_one ())
588ed0d50c3Schristos 	return NULL;
589ed0d50c3Schristos     }
590ed0d50c3Schristos 
591ed0d50c3Schristos   switch (abfd->direction)
592ed0d50c3Schristos     {
593ed0d50c3Schristos     case read_direction:
594ed0d50c3Schristos     case no_direction:
59506324dcfSchristos       abfd->iostream = _bfd_real_fopen (abfd->filename, FOPEN_RB);
596ed0d50c3Schristos       break;
597ed0d50c3Schristos     case both_direction:
598ed0d50c3Schristos     case write_direction:
599ed0d50c3Schristos       if (abfd->opened_once)
600ed0d50c3Schristos 	{
60106324dcfSchristos 	  abfd->iostream = _bfd_real_fopen (abfd->filename, FOPEN_RUB);
602ed0d50c3Schristos 	  if (abfd->iostream == NULL)
60306324dcfSchristos 	    abfd->iostream = _bfd_real_fopen (abfd->filename, FOPEN_WUB);
604ed0d50c3Schristos 	}
605ed0d50c3Schristos       else
606ed0d50c3Schristos 	{
607ed0d50c3Schristos 	  /* Create the file.
608ed0d50c3Schristos 
609ed0d50c3Schristos 	     Some operating systems won't let us overwrite a running
610ed0d50c3Schristos 	     binary.  For them, we want to unlink the file first.
611ed0d50c3Schristos 
612ed0d50c3Schristos 	     However, gcc 2.95 will create temporary files using
613ed0d50c3Schristos 	     O_EXCL and tight permissions to prevent other users from
614ed0d50c3Schristos 	     substituting other .o files during the compilation.  gcc
615ed0d50c3Schristos 	     will then tell the assembler to use the newly created
616ed0d50c3Schristos 	     file as an output file.  If we unlink the file here, we
617ed0d50c3Schristos 	     open a brief window when another user could still
618ed0d50c3Schristos 	     substitute a file.
619ed0d50c3Schristos 
620ed0d50c3Schristos 	     So we unlink the output file if and only if it has
621ed0d50c3Schristos 	     non-zero size.  */
622ed0d50c3Schristos #ifndef __MSDOS__
623ed0d50c3Schristos 	  /* Don't do this for MSDOS: it doesn't care about overwriting
624ed0d50c3Schristos 	     a running binary, but if this file is already open by
625ed0d50c3Schristos 	     another BFD, we will be in deep trouble if we delete an
626ed0d50c3Schristos 	     open file.  In fact, objdump does just that if invoked with
627ed0d50c3Schristos 	     the --info option.  */
628ed0d50c3Schristos 	  struct stat s;
629ed0d50c3Schristos 
630ed0d50c3Schristos 	  if (stat (abfd->filename, &s) == 0 && s.st_size != 0)
631ed0d50c3Schristos 	    unlink_if_ordinary (abfd->filename);
632ed0d50c3Schristos #endif
63306324dcfSchristos 	  abfd->iostream = _bfd_real_fopen (abfd->filename, FOPEN_WUB);
634ed0d50c3Schristos 	  abfd->opened_once = TRUE;
635ed0d50c3Schristos 	}
636ed0d50c3Schristos       break;
637ed0d50c3Schristos     }
638ed0d50c3Schristos 
639ed0d50c3Schristos   if (abfd->iostream == NULL)
640ed0d50c3Schristos     bfd_set_error (bfd_error_system_call);
641ed0d50c3Schristos   else
642ed0d50c3Schristos     {
643ed0d50c3Schristos       if (! bfd_cache_init (abfd))
644ed0d50c3Schristos 	return NULL;
645ed0d50c3Schristos     }
646ed0d50c3Schristos 
647ed0d50c3Schristos   return (FILE *) abfd->iostream;
648ed0d50c3Schristos }
649