/* BFD library -- caching of file descriptors.

   Copyright (C) 1990-2024 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;

  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;
}
