/* BFD library -- caching of file descriptors.

   Copyright (C) 1990-2026 Free Software Foundation, Inc.

   Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com).

   This file is part of BFD, the Binary File Descriptor library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

/*
SECTION
	File caching

	The file caching mechanism is embedded within BFD and allows
	the application to open as many BFDs as it wants without
	regard to the underlying operating system's file descriptor
	limit (often as low as 20 open files).  The module in
	<<cache.c>> maintains a least recently used list of
	<<bfd_cache_max_open>> files, and exports the name
	<<bfd_cache_lookup>>, which runs around and makes sure that
	the required BFD is open. If not, then it chooses a file to
	close, closes it and opens the one wanted, returning its file
	handle.

SUBSECTION
	Caching functions
*/

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "libiberty.h"

static FILE *_bfd_open_file_unlocked (bfd *abfd);

/* In some cases we can optimize cache operation when reopening files.
   For instance, a flush is entirely unnecessary if the file is already
   closed, so a flush would use CACHE_NO_OPEN.  Similarly, a seek using
   SEEK_SET or SEEK_END need not first seek to the current position.
   For stat we ignore seek errors, just in case the file has changed
   while we weren't looking.  If it has, then it's possible that the
   file is shorter and we don't want a seek error to prevent us doing
   the stat.  */
enum cache_flag {
  CACHE_NORMAL = 0,
  CACHE_NO_OPEN = 1,
  CACHE_NO_SEEK = 2,
  CACHE_NO_SEEK_ERROR = 4
};

/* The maximum number of files which the cache will keep open at
   one time.  When needed call bfd_cache_max_open to initialize.  */

static unsigned max_open_files = 0;

/* Set max_open_files, if not already set, to 12.5% of the allowed open
   file descriptors, but at least 10, and return the value.  */
static unsigned
bfd_cache_max_open (void)
{
  if (max_open_files == 0)
    {
      int max;
#if defined(__sun) && !defined(__sparcv9) && !defined(__x86_64__)
      /* PR ld/19260: 32-bit Solaris has very inelegant handling of the 255
	 file descriptor limit.  The problem is that setrlimit(2) can raise
	 RLIMIT_NOFILE to a value that is not supported by libc, resulting
	 in "Too many open files" errors.  This can happen here even though
	 max_open_files is set to rlim.rlim_cur / 8.  For example, if
	 a parent process has set rlim.rlim_cur to 65536, then max_open_files
	 will be computed as 8192.

	 This check essentially reverts to the behavior from binutils 2.23.1
	 for 32-bit Solaris only.  (It is hoped that the 32-bit libc
	 limitation will be removed soon).  64-bit Solaris libc does not have
	 this limitation.  */
      max = 16;
#else
#ifdef HAVE_GETRLIMIT
      struct rlimit rlim;

      if (getrlimit (RLIMIT_NOFILE, &rlim) == 0
	  && rlim.rlim_cur != (rlim_t) RLIM_INFINITY)
	max = rlim.rlim_cur / 8;
      else
#endif
#ifdef _SC_OPEN_MAX
	max = sysconf (_SC_OPEN_MAX) / 8;
#else
	max = 10;
#endif
#endif /* not 32-bit Solaris */

      max_open_files = max < 10 ? 10 : max;
    }

  return max_open_files;
}

/* The number of BFD files we have open.  */

static unsigned open_files;

/* Zero, or a pointer to the topmost BFD on the chain.  This is
   used by the <<bfd_cache_lookup>> macro in @file{libbfd.h} to
   determine when it can avoid a function call.  */

static bfd *bfd_last_cache = NULL;

/* Insert a BFD into the cache.  */

static void
insert (bfd *abfd)
{
  if (bfd_last_cache == NULL)
    {
      abfd->lru_next = abfd;
      abfd->lru_prev = abfd;
    }
  else
    {
      abfd->lru_next = bfd_last_cache;
      abfd->lru_prev = bfd_last_cache->lru_prev;
      abfd->lru_prev->lru_next = abfd;
      abfd->lru_next->lru_prev = abfd;
    }
  bfd_last_cache = abfd;
}

/* Remove a BFD from the cache.  */

static void
snip (bfd *abfd)
{
  abfd->lru_prev->lru_next = abfd->lru_next;
  abfd->lru_next->lru_prev = abfd->lru_prev;
  if (abfd == bfd_last_cache)
    {
      bfd_last_cache = abfd->lru_next;
      if (abfd == bfd_last_cache)
	bfd_last_cache = NULL;
    }
}

/* Close a BFD and remove it from the cache.  */

static bool
bfd_cache_delete (bfd *abfd)
{
  bool ret;

  if (fclose ((FILE *) abfd->iostream) == 0)
    ret = true;
  else
    {
      ret = false;
      bfd_set_error (bfd_error_system_call);
    }

  snip (abfd);

  abfd->iostream = NULL;
  BFD_ASSERT (open_files > 0);
  --open_files;
  abfd->flags |= BFD_CLOSED_BY_CACHE;
  abfd->last_io = bfd_io_force;

  return ret;
}

/* We need to open a new file, and the cache is full.  Find the least
   recently used cacheable BFD and close it.  */

static bool
close_one (void)
{
  register bfd *to_kill;

  if (bfd_last_cache == NULL)
    to_kill = NULL;
  else
    {
      for (to_kill = bfd_last_cache->lru_prev;
	   ! to_kill->cacheable;
	   to_kill = to_kill->lru_prev)
	{
	  if (to_kill == bfd_last_cache)
	    {
	      to_kill = NULL;
	      break;
	    }
	}
    }

  if (to_kill == NULL)
    {
      /* There are no open cacheable BFD's.  */
      return true;
    }

  to_kill->where = _bfd_real_ftell ((FILE *) to_kill->iostream);

  return bfd_cache_delete (to_kill);
}

/* Check to see if the required BFD is the same as the last one
   looked up. If so, then it can use the stream in the BFD with
   impunity, since it can't have changed since the last lookup;
   otherwise, it has to perform the complicated lookup function.  */

#define bfd_cache_lookup(x, flag) \
  ((x) == bfd_last_cache			\
   ? (FILE *) (bfd_last_cache->iostream)	\
   : bfd_cache_lookup_worker (x, flag))

/* A helper function that returns true if ABFD can possibly be cached
   -- that is, whether bfd_cache_lookup_worker will accept it.  */

static bool
possibly_cached (bfd *abfd)
{
  if ((abfd->flags & BFD_IN_MEMORY) != 0)
    return false;
  if (abfd->my_archive != NULL
      && !bfd_is_thin_archive (abfd->my_archive))
    return false;
  return true;
}

/* Called when the macro <<bfd_cache_lookup>> fails to find a
   quick answer.  Find a file descriptor for @var{abfd}.  If
   necessary, it open it.  If there are already more than
   <<bfd_cache_max_open>> files open, it tries to close one first, to
   avoid running out of file descriptors.  It will return NULL
   if it is unable to (re)open the @var{abfd}.  */

static FILE *
bfd_cache_lookup_worker (bfd *abfd, enum cache_flag flag)
{
  if (!possibly_cached (abfd))
    abort ();

  /* If the BFD is being processed by bfd_check_format_matches, it
     must already be open and won't be on the list.  */
  if (abfd->in_format_matches)
    {
      if (abfd->iostream == NULL)
	abort ();
      return (FILE *) abfd->iostream;
    }

  if (abfd->iostream != NULL)
    {
      /* Move the file to the start of the cache.  */
      if (abfd != bfd_last_cache)
	{
	  snip (abfd);
	  insert (abfd);
	}
      return (FILE *) abfd->iostream;
    }

  if (flag & CACHE_NO_OPEN)
    return NULL;

  if (_bfd_open_file_unlocked (abfd) == NULL)
    ;
  else if (!(flag & CACHE_NO_SEEK)
	   && _bfd_real_fseek ((FILE *) abfd->iostream,
			       abfd->where, SEEK_SET) != 0
	   && !(flag & CACHE_NO_SEEK_ERROR))
    bfd_set_error (bfd_error_system_call);
  else
    return (FILE *) abfd->iostream;

  /* xgettext:c-format */
  _bfd_error_handler (_("reopening %pB: %s"),
		      abfd, bfd_errmsg (bfd_get_error ()));
  return NULL;
}

static file_ptr
cache_btell (struct bfd *abfd)
{
  if (!bfd_lock ())
    return -1;
  FILE *f = bfd_cache_lookup (abfd, CACHE_NO_OPEN);
  if (f == NULL)
    {
      if (!bfd_unlock ())
	return -1;
      return abfd->where;
    }
  file_ptr result = _bfd_real_ftell (f);
  if (!bfd_unlock ())
    return -1;
  return result;
}

static int
cache_bseek (struct bfd *abfd, file_ptr offset, int whence)
{
  if (!bfd_lock ())
    return -1;
  FILE *f = bfd_cache_lookup (abfd, whence != SEEK_CUR ? CACHE_NO_SEEK : CACHE_NORMAL);
  if (f == NULL)
    {
      bfd_unlock ();
      return -1;
    }
  int result = _bfd_real_fseek (f, offset, whence);
  if (!bfd_unlock ())
    return -1;
  return result;
}

/* Note that archive entries don't have streams; they share their parent's.
   This allows someone to play with the iostream behind BFD's back.

   Also, note that the origin pointer points to the beginning of a file's
   contents (0 for non-archive elements).  For archive entries this is the
   first octet in the file, NOT the beginning of the archive header.  */

static file_ptr
cache_bread_1 (FILE *f, void *buf, file_ptr nbytes)
{
  file_ptr nread;

#if defined (__VAX) && defined (VMS)
  /* Apparently fread on Vax VMS does not keep the record length
     information.  */
  nread = read (fileno (f), buf, nbytes);
  /* Set bfd_error if we did not read as much data as we expected.  If
     the read failed due to an error set the bfd_error_system_call,
     else set bfd_error_file_truncated.  */
  if (nread == (file_ptr)-1)
    {
      bfd_set_error (bfd_error_system_call);
      return nread;
    }
#else
  nread = fread (buf, 1, nbytes, f);
  /* Set bfd_error if we did not read as much data as we expected.  If
     the read failed due to an error set the bfd_error_system_call,
     else set bfd_error_file_truncated.  */
  if (nread < nbytes && ferror (f))
    {
      bfd_set_error (bfd_error_system_call);
      return nread;
    }
#endif
  if (nread < nbytes)
    /* This may or may not be an error, but in case the calling code
       bails out because of it, set the right error code.  */
    bfd_set_error (bfd_error_file_truncated);
  return nread;
}

static file_ptr
cache_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
{
  if (!bfd_lock ())
    return -1;
  file_ptr nread = 0;
  FILE *f;

  f = bfd_cache_lookup (abfd, CACHE_NORMAL);
  if (f == NULL)
    {
      bfd_unlock ();
      return -1;
    }

  /* Some filesystems are unable to handle reads that are too large
     (for instance, NetApp shares with oplocks turned off).  To avoid
     hitting this limitation, we read the buffer in chunks of 8MB max.  */
  while (nread < nbytes)
    {
      const file_ptr max_chunk_size = 0x800000;
      file_ptr chunk_size = nbytes - nread;
      file_ptr chunk_nread;

      if (chunk_size > max_chunk_size)
	chunk_size = max_chunk_size;

      chunk_nread = cache_bread_1 (f, (char *) buf + nread, chunk_size);

      /* Update the nread count.

	 We just have to be careful of the case when cache_bread_1 returns
	 a negative count:  If this is our first read, then set nread to
	 that negative count in order to return that negative value to the
	 caller.  Otherwise, don't add it to our total count, or we would
	 end up returning a smaller number of bytes read than we actually
	 did.  */
      if (nread == 0 || chunk_nread > 0)
	nread += chunk_nread;

      if (chunk_nread < chunk_size)
	break;
    }

  if (!bfd_unlock ())
    return -1;
  return nread;
}

static file_ptr
cache_bwrite (struct bfd *abfd, const void *from, file_ptr nbytes)
{
  if (!bfd_lock ())
    return -1;
  file_ptr nwrite;
  FILE *f = bfd_cache_lookup (abfd, CACHE_NORMAL);

  if (f == NULL)
    {
      if (!bfd_unlock ())
	return -1;
      return 0;
    }
  nwrite = fwrite (from, 1, nbytes, f);
  if (nwrite < nbytes && ferror (f))
    {
      bfd_set_error (bfd_error_system_call);
      bfd_unlock ();
      return -1;
    }
  if (!bfd_unlock ())
    return -1;
  return nwrite;
}

static int
cache_bclose (struct bfd *abfd)
{
  /* No locking needed here, it's handled by the callee.  */
  return bfd_cache_close (abfd) - 1;
}

static int
cache_bflush (struct bfd *abfd)
{
  if (!bfd_lock ())
    return -1;
  int sts;
  FILE *f = bfd_cache_lookup (abfd, CACHE_NO_OPEN);

  if (f == NULL)
    {
      if (!bfd_unlock ())
	return -1;
      return 0;
    }
  sts = fflush (f);
  if (sts < 0)
    bfd_set_error (bfd_error_system_call);
  if (!bfd_unlock ())
    return -1;
  return sts;
}

static int
cache_bstat (struct bfd *abfd, struct stat *sb)
{
  if (!bfd_lock ())
    return -1;
  int sts;
  FILE *f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR);

  if (f == NULL)
    {
      bfd_unlock ();
      return -1;
    }
  sts = fstat (fileno (f), sb);
  if (sts < 0)
    bfd_set_error (bfd_error_system_call);
  if (!bfd_unlock ())
    return -1;
  return sts;
}

static void *
cache_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
	     void *addr ATTRIBUTE_UNUSED,
	     size_t len ATTRIBUTE_UNUSED,
	     int prot ATTRIBUTE_UNUSED,
	     int flags ATTRIBUTE_UNUSED,
	     file_ptr offset ATTRIBUTE_UNUSED,
	     void **map_addr ATTRIBUTE_UNUSED,
	     size_t *map_len ATTRIBUTE_UNUSED)
{
  void *ret = MAP_FAILED;

  if (!bfd_lock ())
    return ret;
  if ((abfd->flags & BFD_IN_MEMORY) != 0)
    abort ();
#ifdef HAVE_MMAP
  else
    {
      uintptr_t pagesize_m1 = _bfd_pagesize_m1;
      FILE *f;
      file_ptr pg_offset;
      size_t pg_len;

      f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR);
      if (f == NULL)
	{
	  bfd_unlock ();
	  return ret;
	}

      /* Align.  */
      pg_offset = offset & ~pagesize_m1;
      pg_len = (len + (offset - pg_offset) + pagesize_m1) & ~pagesize_m1;

      ret = mmap (addr, pg_len, prot, flags, fileno (f), pg_offset);
      if (ret == MAP_FAILED)
	bfd_set_error (bfd_error_system_call);
      else
	{
	  *map_addr = ret;
	  *map_len = pg_len;
	  ret = (char *) ret + (offset & pagesize_m1);
	}
    }
#endif

  if (!bfd_unlock ())
    return MAP_FAILED;
  return ret;
}

static const struct bfd_iovec cache_iovec =
{
  &cache_bread, &cache_bwrite, &cache_btell, &cache_bseek,
  &cache_bclose, &cache_bflush, &cache_bstat, &cache_bmmap
};

static bool
_bfd_cache_init_unlocked (bfd *abfd)
{
  BFD_ASSERT (abfd->iostream != NULL);
  if (open_files >= bfd_cache_max_open ())
    {
      if (! close_one ())
	return false;
    }
  abfd->iovec = &cache_iovec;
  insert (abfd);
  abfd->flags &= ~BFD_CLOSED_BY_CACHE;
  ++open_files;
  return true;
}

/*
INTERNAL_FUNCTION
	bfd_cache_init

SYNOPSIS
	bool bfd_cache_init (bfd *abfd);

DESCRIPTION
	Add a newly opened BFD to the cache.
*/

bool
bfd_cache_init (bfd *abfd)
{
  if (!bfd_lock ())
    return false;
  bool result = _bfd_cache_init_unlocked (abfd);
  if (!bfd_unlock ())
    return false;
  return result;
}

static bool
_bfd_cache_close_unlocked (bfd *abfd)
{
  /* Don't remove this test.  bfd_reinit depends on it.  */
  if (abfd->iovec != &cache_iovec)
    return true;

  if (abfd->iostream == NULL)
    /* Previously closed.  */
    return true;

  /* Note: no locking needed in this function, as it is handled by
     bfd_cache_delete.  */
  return bfd_cache_delete (abfd);
}

/*
FUNCTION
	bfd_cache_close

SYNOPSIS
	bool bfd_cache_close (bfd *abfd);

DESCRIPTION
	Remove the BFD @var{abfd} from the cache. If the attached file is open,
	then close it too.

	<<FALSE>> is returned if closing the file fails, <<TRUE>> is
	returned if all is well.
*/

bool
bfd_cache_close (bfd *abfd)
{
  if (!bfd_lock ())
    return false;
  bool result = _bfd_cache_close_unlocked (abfd);
  if (!bfd_unlock ())
    return false;
  return result;
}

/*
FUNCTION
	bfd_cache_close_all

SYNOPSIS
	bool bfd_cache_close_all (void);

DESCRIPTION
	Remove all BFDs from the cache. If the attached file is open,
	then close it too.  Note - despite its name this function will
	close a BFD even if it is not marked as being cacheable, ie
	even if bfd_get_cacheable() returns false.

	<<FALSE>> is returned if closing one of the file fails, <<TRUE>> is
	returned if all is well.
*/

bool
bfd_cache_close_all (void)
{
  bool ret = true;

  if (!bfd_lock ())
    return false;
  while (bfd_last_cache != NULL)
    {
      bfd *prev_bfd_last_cache = bfd_last_cache;

      ret &= _bfd_cache_close_unlocked (bfd_last_cache);

      /* Stop a potential infinite loop should bfd_cache_close()
	 not update bfd_last_cache.  */
      if (bfd_last_cache == prev_bfd_last_cache)
	break;
    }

  if (!bfd_unlock ())
    return false;
  return ret;
}

/*
INTERNAL_FUNCTION
	bfd_cache_set_uncloseable

SYNOPSIS
	bool bfd_cache_set_uncloseable (bfd *abfd, bool value, bool *old);

DESCRIPTION
	Internal function to mark ABFD as either closeable or not.
	This is used by bfd_check_format_matches to avoid races
	where bfd_cache_close_all is called in another thread.
	VALUE is true to mark the BFD as temporarily uncloseable
	by the cache; false to mark it as closeable once again.
	OLD, if non-NULL, is set to the previous value of the flag.
	Returns false on error, true on success.
*/

bool
bfd_cache_set_uncloseable (bfd *abfd, bool value, bool *old)
{
  bool result = true;

  if (!bfd_lock ())
    return false;
  if (old != NULL)
    *old = abfd->in_format_matches;

  /* Only perform any action when the state changes,and only when this
     BFD is actually using the cache.  */
  if (value != abfd->in_format_matches
      && abfd->iovec == &cache_iovec
      && possibly_cached (abfd))
    {
      if (value)
	{
	  /* Marking as uncloseable for the first time.  Ensure the
	     file is open, and remove from the cache list.  */
	  FILE *f = bfd_cache_lookup (abfd, CACHE_NORMAL);
	  if (f == NULL)
	    result = false;
	  else
	    snip (abfd);
	}
      else
	{
	  /* Mark as closeable again.  */
	  insert (abfd);
	}

      abfd->in_format_matches = value;
    }

  if (!bfd_unlock ())
    return false;
  return result;
}

/*
FUNCTION
	bfd_cache_size

SYNOPSIS
	unsigned bfd_cache_size (void);

DESCRIPTION
	Return the number of open files in the cache.
*/

unsigned
bfd_cache_size (void)
{
  return open_files;
}

static FILE *
_bfd_open_file_unlocked (bfd *abfd)
{
  abfd->cacheable = true;	/* Allow it to be closed later.  */

  if (open_files >= bfd_cache_max_open ())
    {
      if (! close_one ())
	return NULL;
    }

  switch (abfd->direction)
    {
    case read_direction:
    case no_direction:
      abfd->iostream = _bfd_real_fopen (bfd_get_filename (abfd), FOPEN_RB);
      break;
    case both_direction:
    case write_direction:
      if (abfd->opened_once)
	{
	  abfd->iostream = _bfd_real_fopen (bfd_get_filename (abfd),
					    FOPEN_RUB);
	  if (abfd->iostream == NULL)
	    abfd->iostream = _bfd_real_fopen (bfd_get_filename (abfd),
					      FOPEN_WUB);
	}
      else
	{
	  /* Create the file.

	     Some operating systems won't let us overwrite a running
	     binary.  For them, we want to unlink the file first.

	     However, gcc 2.95 will create temporary files using
	     O_EXCL and tight permissions to prevent other users from
	     substituting other .o files during the compilation.  gcc
	     will then tell the assembler to use the newly created
	     file as an output file.  If we unlink the file here, we
	     open a brief window when another user could still
	     substitute a file.

	     So we unlink the output file if and only if it has
	     non-zero size.  */
#ifndef __MSDOS__
	  /* Don't do this for MSDOS: it doesn't care about overwriting
	     a running binary, but if this file is already open by
	     another BFD, we will be in deep trouble if we delete an
	     open file.  In fact, objdump does just that if invoked with
	     the --info option.  */
	  struct stat s;

	  if (stat (bfd_get_filename (abfd), &s) == 0 && s.st_size != 0)
	    unlink_if_ordinary (bfd_get_filename (abfd));
#endif
	  abfd->iostream = _bfd_real_fopen (bfd_get_filename (abfd),
					    FOPEN_WUB);
	  abfd->opened_once = true;
	}
      break;
    }

  if (abfd->iostream == NULL)
    bfd_set_error (bfd_error_system_call);
  else
    {
      if (! _bfd_cache_init_unlocked (abfd))
	return NULL;
    }

  return (FILE *) abfd->iostream;
}

/*
INTERNAL_FUNCTION
	bfd_open_file

SYNOPSIS
	FILE* bfd_open_file (bfd *abfd);

DESCRIPTION
	Call the OS to open a file for @var{abfd}.  Return the <<FILE *>>
	(possibly <<NULL>>) that results from this operation.  Set up the
	BFD so that future accesses know the file is open. If the <<FILE *>>
	returned is <<NULL>>, then it won't have been put in the
	cache, so it won't have to be removed from it.
*/

FILE *
bfd_open_file (bfd *abfd)
{
  if (!bfd_lock ())
    return NULL;
  FILE *result = _bfd_open_file_unlocked (abfd);
  if (!bfd_unlock ())
    return NULL;
  return result;
}
