133965Sjdp/* BFD library -- caching of file descriptors. 2130561Sobrien 3130561Sobrien Copyright 1990, 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002, 4218822Sdim 2003, 2004, 2005, 2007 Free Software Foundation, Inc. 5130561Sobrien 633965Sjdp Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com). 733965Sjdp 833965SjdpThis file is part of BFD, the Binary File Descriptor library. 933965Sjdp 1033965SjdpThis program is free software; you can redistribute it and/or modify 1133965Sjdpit under the terms of the GNU General Public License as published by 1233965Sjdpthe Free Software Foundation; either version 2 of the License, or 1333965Sjdp(at your option) any later version. 1433965Sjdp 1533965SjdpThis program is distributed in the hope that it will be useful, 1633965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1733965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1833965SjdpGNU General Public License for more details. 1933965Sjdp 2033965SjdpYou should have received a copy of the GNU General Public License 2133965Sjdpalong with this program; if not, write to the Free Software 22218822SdimFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2333965Sjdp 2433965Sjdp/* 2533965SjdpSECTION 2633965Sjdp File caching 2733965Sjdp 2833965Sjdp The file caching mechanism is embedded within BFD and allows 2933965Sjdp the application to open as many BFDs as it wants without 3033965Sjdp regard to the underlying operating system's file descriptor 3133965Sjdp limit (often as low as 20 open files). The module in 3233965Sjdp <<cache.c>> maintains a least recently used list of 3333965Sjdp <<BFD_CACHE_MAX_OPEN>> files, and exports the name 3433965Sjdp <<bfd_cache_lookup>>, which runs around and makes sure that 3533965Sjdp the required BFD is open. If not, then it chooses a file to 3633965Sjdp close, closes it and opens the one wanted, returning its file 3777298Sobrien handle. 3833965Sjdp 39218822SdimSUBSECTION 40218822Sdim Caching functions 4133965Sjdp*/ 4233965Sjdp 43218822Sdim#include "sysdep.h" 4433965Sjdp#include "bfd.h" 4533965Sjdp#include "libbfd.h" 46218822Sdim#include "libiberty.h" 4733965Sjdp 48218822Sdim/* In some cases we can optimize cache operation when reopening files. 49218822Sdim For instance, a flush is entirely unnecessary if the file is already 50218822Sdim closed, so a flush would use CACHE_NO_OPEN. Similarly, a seek using 51218822Sdim SEEK_SET or SEEK_END need not first seek to the current position. 52218822Sdim For stat we ignore seek errors, just in case the file has changed 53218822Sdim while we weren't looking. If it has, then it's possible that the 54218822Sdim file is shorter and we don't want a seek error to prevent us doing 55218822Sdim the stat. */ 56218822Sdimenum cache_flag { 57218822Sdim CACHE_NORMAL = 0, 58218822Sdim CACHE_NO_OPEN = 1, 59218822Sdim CACHE_NO_SEEK = 2, 60218822Sdim CACHE_NO_SEEK_ERROR = 4 61218822Sdim}; 6233965Sjdp 63218822Sdim/* The maximum number of files which the cache will keep open at 64218822Sdim one time. */ 6533965Sjdp 66218822Sdim#define BFD_CACHE_MAX_OPEN 10 6733965Sjdp 6833965Sjdp/* The number of BFD files we have open. */ 6933965Sjdp 7033965Sjdpstatic int open_files; 7133965Sjdp 72218822Sdim/* Zero, or a pointer to the topmost BFD on the chain. This is 73218822Sdim used by the <<bfd_cache_lookup>> macro in @file{libbfd.h} to 74218822Sdim determine when it can avoid a function call. */ 7533965Sjdp 76218822Sdimstatic bfd *bfd_last_cache = NULL; 7733965Sjdp 7833965Sjdp/* Insert a BFD into the cache. */ 7933965Sjdp 80130561Sobrienstatic void 81130561Sobrieninsert (bfd *abfd) 8233965Sjdp{ 8333965Sjdp if (bfd_last_cache == NULL) 8433965Sjdp { 8533965Sjdp abfd->lru_next = abfd; 8633965Sjdp abfd->lru_prev = abfd; 8733965Sjdp } 8833965Sjdp else 8933965Sjdp { 9033965Sjdp abfd->lru_next = bfd_last_cache; 9133965Sjdp abfd->lru_prev = bfd_last_cache->lru_prev; 9233965Sjdp abfd->lru_prev->lru_next = abfd; 9333965Sjdp abfd->lru_next->lru_prev = abfd; 9433965Sjdp } 9533965Sjdp bfd_last_cache = abfd; 9633965Sjdp} 9733965Sjdp 9833965Sjdp/* Remove a BFD from the cache. */ 9933965Sjdp 100130561Sobrienstatic void 101130561Sobriensnip (bfd *abfd) 10233965Sjdp{ 10333965Sjdp abfd->lru_prev->lru_next = abfd->lru_next; 10433965Sjdp abfd->lru_next->lru_prev = abfd->lru_prev; 10533965Sjdp if (abfd == bfd_last_cache) 10633965Sjdp { 10733965Sjdp bfd_last_cache = abfd->lru_next; 10833965Sjdp if (abfd == bfd_last_cache) 10933965Sjdp bfd_last_cache = NULL; 11033965Sjdp } 11133965Sjdp} 11233965Sjdp 113218822Sdim/* Close a BFD and remove it from the cache. */ 114218822Sdim 115218822Sdimstatic bfd_boolean 116218822Sdimbfd_cache_delete (bfd *abfd) 117218822Sdim{ 118218822Sdim bfd_boolean ret; 119218822Sdim 120218822Sdim if (fclose ((FILE *) abfd->iostream) == 0) 121218822Sdim ret = TRUE; 122218822Sdim else 123218822Sdim { 124218822Sdim ret = FALSE; 125218822Sdim bfd_set_error (bfd_error_system_call); 126218822Sdim } 127218822Sdim 128218822Sdim snip (abfd); 129218822Sdim 130218822Sdim abfd->iostream = NULL; 131218822Sdim --open_files; 132218822Sdim 133218822Sdim return ret; 134218822Sdim} 135218822Sdim 13633965Sjdp/* We need to open a new file, and the cache is full. Find the least 13733965Sjdp recently used cacheable BFD and close it. */ 13833965Sjdp 139130561Sobrienstatic bfd_boolean 140130561Sobrienclose_one (void) 14133965Sjdp{ 14233965Sjdp register bfd *kill; 14333965Sjdp 14433965Sjdp if (bfd_last_cache == NULL) 14533965Sjdp kill = NULL; 14633965Sjdp else 14733965Sjdp { 14833965Sjdp for (kill = bfd_last_cache->lru_prev; 14933965Sjdp ! kill->cacheable; 15033965Sjdp kill = kill->lru_prev) 15133965Sjdp { 15233965Sjdp if (kill == bfd_last_cache) 15333965Sjdp { 15433965Sjdp kill = NULL; 15533965Sjdp break; 15633965Sjdp } 15733965Sjdp } 15833965Sjdp } 15933965Sjdp 16033965Sjdp if (kill == NULL) 16133965Sjdp { 16233965Sjdp /* There are no open cacheable BFD's. */ 163130561Sobrien return TRUE; 16433965Sjdp } 16533965Sjdp 166130561Sobrien kill->where = real_ftell ((FILE *) kill->iostream); 16733965Sjdp 168218822Sdim /* Save the file st_mtime. This is a hack so that gdb can detect when 169218822Sdim an executable has been deleted and recreated. The only thing that 170218822Sdim makes this reasonable is that st_mtime doesn't change when a file 171218822Sdim is unlinked, so saving st_mtime makes BFD's file cache operation 172218822Sdim a little more transparent for this particular usage pattern. If we 173218822Sdim hadn't closed the file then we would not have lost the original 174218822Sdim contents, st_mtime etc. Of course, if something is writing to an 175218822Sdim existing file, then this is the wrong thing to do. 176218822Sdim FIXME: gdb should save these times itself on first opening a file, 177218822Sdim and this hack be removed. */ 178218822Sdim if (kill->direction == no_direction || kill->direction == read_direction) 179218822Sdim { 180218822Sdim bfd_get_mtime (kill); 181218822Sdim kill->mtime_set = TRUE; 182218822Sdim } 183218822Sdim 18433965Sjdp return bfd_cache_delete (kill); 18533965Sjdp} 18633965Sjdp 187218822Sdim/* Check to see if the required BFD is the same as the last one 188218822Sdim looked up. If so, then it can use the stream in the BFD with 189218822Sdim impunity, since it can't have changed since the last lookup; 190218822Sdim otherwise, it has to perform the complicated lookup function. */ 19133965Sjdp 192218822Sdim#define bfd_cache_lookup(x, flag) \ 193218822Sdim ((x) == bfd_last_cache \ 194218822Sdim ? (FILE *) (bfd_last_cache->iostream) \ 195218822Sdim : bfd_cache_lookup_worker (x, flag)) 196218822Sdim 197218822Sdim/* Called when the macro <<bfd_cache_lookup>> fails to find a 198218822Sdim quick answer. Find a file descriptor for @var{abfd}. If 199218822Sdim necessary, it open it. If there are already more than 200218822Sdim <<BFD_CACHE_MAX_OPEN>> files open, it tries to close one first, to 201218822Sdim avoid running out of file descriptors. It will return NULL 202218822Sdim if it is unable to (re)open the @var{abfd}. */ 203218822Sdim 204218822Sdimstatic FILE * 205218822Sdimbfd_cache_lookup_worker (bfd *abfd, enum cache_flag flag) 20633965Sjdp{ 207218822Sdim bfd *orig_bfd = abfd; 208218822Sdim if ((abfd->flags & BFD_IN_MEMORY) != 0) 209218822Sdim abort (); 21033965Sjdp 211218822Sdim if (abfd->my_archive) 212218822Sdim abfd = abfd->my_archive; 213218822Sdim 214218822Sdim if (abfd->iostream != NULL) 215218822Sdim { 216218822Sdim /* Move the file to the start of the cache. */ 217218822Sdim if (abfd != bfd_last_cache) 218218822Sdim { 219218822Sdim snip (abfd); 220218822Sdim insert (abfd); 221218822Sdim } 222218822Sdim return (FILE *) abfd->iostream; 223218822Sdim } 224218822Sdim 225218822Sdim if (flag & CACHE_NO_OPEN) 226218822Sdim return NULL; 227218822Sdim 228218822Sdim if (bfd_open_file (abfd) == NULL) 229218822Sdim ; 230218822Sdim else if (!(flag & CACHE_NO_SEEK) 231218822Sdim && real_fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0 232218822Sdim && !(flag & CACHE_NO_SEEK_ERROR)) 233218822Sdim bfd_set_error (bfd_error_system_call); 23433965Sjdp else 235218822Sdim return (FILE *) abfd->iostream; 236218822Sdim 237218822Sdim (*_bfd_error_handler) (_("reopening %B: %s\n"), 238218822Sdim orig_bfd, bfd_errmsg (bfd_get_error ())); 239218822Sdim return NULL; 240218822Sdim} 241218822Sdim 242218822Sdimstatic file_ptr 243218822Sdimcache_btell (struct bfd *abfd) 244218822Sdim{ 245218822Sdim FILE *f = bfd_cache_lookup (abfd, CACHE_NO_OPEN); 246218822Sdim if (f == NULL) 247218822Sdim return abfd->where; 248218822Sdim return real_ftell (f); 249218822Sdim} 250218822Sdim 251218822Sdimstatic int 252218822Sdimcache_bseek (struct bfd *abfd, file_ptr offset, int whence) 253218822Sdim{ 254218822Sdim FILE *f = bfd_cache_lookup (abfd, whence != SEEK_CUR ? CACHE_NO_SEEK : 0); 255218822Sdim if (f == NULL) 256218822Sdim return -1; 257218822Sdim return real_fseek (f, offset, whence); 258218822Sdim} 259218822Sdim 260218822Sdim/* Note that archive entries don't have streams; they share their parent's. 261218822Sdim This allows someone to play with the iostream behind BFD's back. 262218822Sdim 263218822Sdim Also, note that the origin pointer points to the beginning of a file's 264218822Sdim contents (0 for non-archive elements). For archive entries this is the 265218822Sdim first octet in the file, NOT the beginning of the archive header. */ 266218822Sdim 267218822Sdimstatic file_ptr 268218822Sdimcache_bread (struct bfd *abfd, void *buf, file_ptr nbytes) 269218822Sdim{ 270218822Sdim FILE *f; 271218822Sdim file_ptr nread; 272218822Sdim /* FIXME - this looks like an optimization, but it's really to cover 273218822Sdim up for a feature of some OSs (not solaris - sigh) that 274218822Sdim ld/pe-dll.c takes advantage of (apparently) when it creates BFDs 275218822Sdim internally and tries to link against them. BFD seems to be smart 276218822Sdim enough to realize there are no symbol records in the "file" that 277218822Sdim doesn't exist but attempts to read them anyway. On Solaris, 278218822Sdim attempting to read zero bytes from a NULL file results in a core 279218822Sdim dump, but on other platforms it just returns zero bytes read. 280218822Sdim This makes it to something reasonable. - DJ */ 281218822Sdim if (nbytes == 0) 282218822Sdim return 0; 283218822Sdim 284218822Sdim f = bfd_cache_lookup (abfd, 0); 285218822Sdim if (f == NULL) 286218822Sdim return 0; 287218822Sdim 288218822Sdim#if defined (__VAX) && defined (VMS) 289218822Sdim /* Apparently fread on Vax VMS does not keep the record length 290218822Sdim information. */ 291218822Sdim nread = read (fileno (f), buf, nbytes); 292218822Sdim /* Set bfd_error if we did not read as much data as we expected. If 293218822Sdim the read failed due to an error set the bfd_error_system_call, 294218822Sdim else set bfd_error_file_truncated. */ 295218822Sdim if (nread == (file_ptr)-1) 29633965Sjdp { 29733965Sjdp bfd_set_error (bfd_error_system_call); 298218822Sdim return -1; 29933965Sjdp } 300218822Sdim#else 301218822Sdim nread = fread (buf, 1, nbytes, f); 302218822Sdim /* Set bfd_error if we did not read as much data as we expected. If 303218822Sdim the read failed due to an error set the bfd_error_system_call, 304218822Sdim else set bfd_error_file_truncated. */ 305218822Sdim if (nread < nbytes && ferror (f)) 306218822Sdim { 307218822Sdim bfd_set_error (bfd_error_system_call); 308218822Sdim return -1; 309218822Sdim } 310218822Sdim#endif 311218822Sdim return nread; 312218822Sdim} 31333965Sjdp 314218822Sdimstatic file_ptr 315218822Sdimcache_bwrite (struct bfd *abfd, const void *where, file_ptr nbytes) 316218822Sdim{ 317218822Sdim file_ptr nwrite; 318218822Sdim FILE *f = bfd_cache_lookup (abfd, 0); 319218822Sdim if (f == NULL) 320218822Sdim return 0; 321218822Sdim nwrite = fwrite (where, 1, nbytes, f); 322218822Sdim if (nwrite < nbytes && ferror (f)) 323218822Sdim { 324218822Sdim bfd_set_error (bfd_error_system_call); 325218822Sdim return -1; 326218822Sdim } 327218822Sdim return nwrite; 328218822Sdim} 32933965Sjdp 330218822Sdimstatic int 331218822Sdimcache_bclose (struct bfd *abfd) 332218822Sdim{ 333218822Sdim return bfd_cache_close (abfd); 334218822Sdim} 33533965Sjdp 336218822Sdimstatic int 337218822Sdimcache_bflush (struct bfd *abfd) 338218822Sdim{ 339218822Sdim int sts; 340218822Sdim FILE *f = bfd_cache_lookup (abfd, CACHE_NO_OPEN); 341218822Sdim if (f == NULL) 342218822Sdim return 0; 343218822Sdim sts = fflush (f); 344218822Sdim if (sts < 0) 345218822Sdim bfd_set_error (bfd_error_system_call); 346218822Sdim return sts; 34733965Sjdp} 34833965Sjdp 349218822Sdimstatic int 350218822Sdimcache_bstat (struct bfd *abfd, struct stat *sb) 351218822Sdim{ 352218822Sdim int sts; 353218822Sdim FILE *f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR); 354218822Sdim if (f == NULL) 355218822Sdim return -1; 356218822Sdim sts = fstat (fileno (f), sb); 357218822Sdim if (sts < 0) 358218822Sdim bfd_set_error (bfd_error_system_call); 359218822Sdim return sts; 360218822Sdim} 361218822Sdim 362218822Sdimstatic const struct bfd_iovec cache_iovec = { 363218822Sdim &cache_bread, &cache_bwrite, &cache_btell, &cache_bseek, 364218822Sdim &cache_bclose, &cache_bflush, &cache_bstat 365218822Sdim}; 366218822Sdim 36733965Sjdp/* 36833965SjdpINTERNAL_FUNCTION 36933965Sjdp bfd_cache_init 37033965Sjdp 37133965SjdpSYNOPSIS 372130561Sobrien bfd_boolean bfd_cache_init (bfd *abfd); 37333965Sjdp 37433965SjdpDESCRIPTION 37533965Sjdp Add a newly opened BFD to the cache. 37633965Sjdp*/ 37733965Sjdp 378130561Sobrienbfd_boolean 379130561Sobrienbfd_cache_init (bfd *abfd) 38033965Sjdp{ 38133965Sjdp BFD_ASSERT (abfd->iostream != NULL); 38233965Sjdp if (open_files >= BFD_CACHE_MAX_OPEN) 38333965Sjdp { 38433965Sjdp if (! close_one ()) 385130561Sobrien return FALSE; 38633965Sjdp } 387218822Sdim abfd->iovec = &cache_iovec; 38833965Sjdp insert (abfd); 38933965Sjdp ++open_files; 390130561Sobrien return TRUE; 39133965Sjdp} 39233965Sjdp 39333965Sjdp/* 39433965SjdpINTERNAL_FUNCTION 39533965Sjdp bfd_cache_close 39633965Sjdp 39733965SjdpSYNOPSIS 398130561Sobrien bfd_boolean bfd_cache_close (bfd *abfd); 39933965Sjdp 40033965SjdpDESCRIPTION 40133965Sjdp Remove the BFD @var{abfd} from the cache. If the attached file is open, 40233965Sjdp then close it too. 40333965Sjdp 40433965SjdpRETURNS 405130561Sobrien <<FALSE>> is returned if closing the file fails, <<TRUE>> is 40633965Sjdp returned if all is well. 40733965Sjdp*/ 40833965Sjdp 409130561Sobrienbfd_boolean 410130561Sobrienbfd_cache_close (bfd *abfd) 41133965Sjdp{ 412218822Sdim if (abfd->iovec != &cache_iovec) 413130561Sobrien return TRUE; 41433965Sjdp 415218822Sdim if (abfd->iostream == NULL) 416218822Sdim /* Previously closed. */ 417218822Sdim return TRUE; 418218822Sdim 41933965Sjdp return bfd_cache_delete (abfd); 42033965Sjdp} 42133965Sjdp 42233965Sjdp/* 423218822SdimFUNCTION 424218822Sdim bfd_cache_close_all 425218822Sdim 426218822SdimSYNOPSIS 427218822Sdim bfd_boolean bfd_cache_close_all (void); 428218822Sdim 429218822SdimDESCRIPTION 430218822Sdim Remove all BFDs from the cache. If the attached file is open, 431218822Sdim then close it too. 432218822Sdim 433218822SdimRETURNS 434218822Sdim <<FALSE>> is returned if closing one of the file fails, <<TRUE>> is 435218822Sdim returned if all is well. 436218822Sdim*/ 437218822Sdim 438218822Sdimbfd_boolean 439218822Sdimbfd_cache_close_all () 440218822Sdim{ 441218822Sdim bfd_boolean ret = TRUE; 442218822Sdim 443218822Sdim while (bfd_last_cache != NULL) 444218822Sdim ret &= bfd_cache_close (bfd_last_cache); 445218822Sdim 446218822Sdim return ret; 447218822Sdim} 448218822Sdim 449218822Sdim/* 45033965SjdpINTERNAL_FUNCTION 45133965Sjdp bfd_open_file 45233965Sjdp 45333965SjdpSYNOPSIS 454130561Sobrien FILE* bfd_open_file (bfd *abfd); 45533965Sjdp 45633965SjdpDESCRIPTION 45733965Sjdp Call the OS to open a file for @var{abfd}. Return the <<FILE *>> 45833965Sjdp (possibly <<NULL>>) that results from this operation. Set up the 45933965Sjdp BFD so that future accesses know the file is open. If the <<FILE *>> 46033965Sjdp returned is <<NULL>>, then it won't have been put in the 46133965Sjdp cache, so it won't have to be removed from it. 46233965Sjdp*/ 46333965Sjdp 46433965SjdpFILE * 465130561Sobrienbfd_open_file (bfd *abfd) 46633965Sjdp{ 467130561Sobrien abfd->cacheable = TRUE; /* Allow it to be closed later. */ 46833965Sjdp 46933965Sjdp if (open_files >= BFD_CACHE_MAX_OPEN) 47033965Sjdp { 47133965Sjdp if (! close_one ()) 47233965Sjdp return NULL; 47333965Sjdp } 47433965Sjdp 47533965Sjdp switch (abfd->direction) 47633965Sjdp { 47733965Sjdp case read_direction: 47833965Sjdp case no_direction: 479218822Sdim abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_RB); 48033965Sjdp break; 48133965Sjdp case both_direction: 48233965Sjdp case write_direction: 483104834Sobrien if (abfd->opened_once) 48433965Sjdp { 485218822Sdim abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_RUB); 48633965Sjdp if (abfd->iostream == NULL) 487218822Sdim abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_WUB); 48833965Sjdp } 48933965Sjdp else 49033965Sjdp { 49160484Sobrien /* Create the file. 49260484Sobrien 49360484Sobrien Some operating systems won't let us overwrite a running 49460484Sobrien binary. For them, we want to unlink the file first. 49560484Sobrien 49660484Sobrien However, gcc 2.95 will create temporary files using 49760484Sobrien O_EXCL and tight permissions to prevent other users from 49860484Sobrien substituting other .o files during the compilation. gcc 49960484Sobrien will then tell the assembler to use the newly created 50060484Sobrien file as an output file. If we unlink the file here, we 50160484Sobrien open a brief window when another user could still 50260484Sobrien substitute a file. 50360484Sobrien 50460484Sobrien So we unlink the output file if and only if it has 50560484Sobrien non-zero size. */ 50661843Sobrien#ifndef __MSDOS__ 50761843Sobrien /* Don't do this for MSDOS: it doesn't care about overwriting 50861843Sobrien a running binary, but if this file is already open by 50961843Sobrien another BFD, we will be in deep trouble if we delete an 51061843Sobrien open file. In fact, objdump does just that if invoked with 51161843Sobrien the --info option. */ 51260484Sobrien struct stat s; 51360484Sobrien 51460484Sobrien if (stat (abfd->filename, &s) == 0 && s.st_size != 0) 515218822Sdim unlink_if_ordinary (abfd->filename); 51661843Sobrien#endif 517218822Sdim abfd->iostream = (PTR) real_fopen (abfd->filename, FOPEN_WUB); 518130561Sobrien abfd->opened_once = TRUE; 51933965Sjdp } 52033965Sjdp break; 52133965Sjdp } 52233965Sjdp 523218822Sdim if (abfd->iostream == NULL) 524218822Sdim bfd_set_error (bfd_error_system_call); 525218822Sdim else 52633965Sjdp { 52733965Sjdp if (! bfd_cache_init (abfd)) 52833965Sjdp return NULL; 52933965Sjdp } 53033965Sjdp 53133965Sjdp return (FILE *) abfd->iostream; 53233965Sjdp} 533