/* Definitions for BFD wrappers used by GDB.

   Copyright (C) 2011-2025 Free Software Foundation, Inc.

   This file is part of GDB.

   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, see <http://www.gnu.org/licenses/>.  */

#include "gdb_bfd.h"
#include "event-top.h"
#include "ui-out.h"
#include "cli/cli-cmds.h"
#include "hashtab.h"
#include "gdbsupport/filestuff.h"
#ifdef HAVE_MMAP
#include <sys/mman.h>
#ifndef MAP_FAILED
#define MAP_FAILED ((void *) -1)
#endif
#endif
#include "target.h"
#include "gdbsupport/fileio.h"
#include "inferior.h"
#include "cli/cli-style.h"
#include "gdbsupport/cxx-thread.h"
#include "gdbsupport/unordered_map.h"
#include "gdbsupport/unordered_set.h"

/* Lock held when doing BFD operations.  A recursive mutex is used
   because we use this mutex internally and also for BFD, just to make
   life a bit simpler, and we may sometimes hold it while calling into
   BFD.  */
static gdb::recursive_mutex gdb_bfd_mutex;

/* BFD locking function.  */

static bool
gdb_bfd_lock (void *ignore)
{
  gdb_bfd_mutex.lock ();
  return true;
}

/* BFD unlocking function.  */

static bool
gdb_bfd_unlock (void *ignore)
{
  gdb_bfd_mutex.unlock ();
  return true;
}

/* An object of this type is stored in the section's user data when
   mapping a section.  */

struct gdb_bfd_section_data
{
  /* Size of the data.  */
  size_t size;
  /* If the data was mmapped, this is the length of the map.  */
  size_t map_len;
  /* The data.  If NULL, the section data has not been read.  */
  void *data;
  /* If the data was mmapped, this is the map address.  */
  void *map_addr;
};

/* A hash set holding every BFD that gdb knows about.  This is not
   to be confused with 'gdb_bfd_cache', which is used for sharing
   BFDs; in contrast, this hash is used just to implement
   "maint info bfd".  */

static gdb::unordered_set<bfd *> all_bfds;

/* An object of this type is stored in each BFD's user data.  */

struct gdb_bfd_data
{
  /* Note that if ST is nullptr, then we simply fill in zeroes.  */
  gdb_bfd_data (bfd *abfd, struct stat *st)
    : mtime (st == nullptr ? 0 : st->st_mtime),
      size (st == nullptr ? 0 : st->st_size),
      inode (st == nullptr ? 0 : st->st_ino),
      device_id (st == nullptr ? 0 : st->st_dev),
      relocation_computed (0),
      needs_relocations (0),
      crc_computed (0)
  {
  }

  ~gdb_bfd_data ()
  {
  }

  /* The reference count.  */
  int refc = 1;

  /* The mtime of the BFD at the point the cache entry was made.  */
  time_t mtime;

  /* The file size (in bytes) at the point the cache entry was made.  */
  off_t size;

  /* The inode of the file at the point the cache entry was made.  */
  ino_t inode;

  /* The device id of the file at the point the cache entry was made.  */
  dev_t device_id;

  /* This is true if we have determined whether this BFD has any
     sections requiring relocation.  */
  unsigned int relocation_computed : 1;

  /* This is true if any section needs relocation.  */
  unsigned int needs_relocations : 1;

  /* This is true if we have successfully computed the file's CRC.  */
  unsigned int crc_computed : 1;

  /* The file's CRC.  */
  unsigned long crc = 0;

  /* If the BFD comes from an archive, this points to the archive's
     BFD.  Otherwise, this is NULL.  */
  bfd *archive_bfd = nullptr;

  /* Table of all the bfds this bfd has included.  */
  std::vector<gdb_bfd_ref_ptr> included_bfds;

  /* This is used by gdb_bfd_canonicalize_symtab to hold the symbols
     returned by canonicalization.  */
  std::optional<gdb::def_vector<asymbol *>> symbol_table;
  /* If an error occurred while canonicalizing the symtab, this holds
     the error message.  */
  std::string symbol_error;

  /* The registry.  */
  registry<bfd> registry_fields;

  /* Most of the locking needed for multi-threaded operation is
     handled by BFD itself.  However, the current BFD model is that
     locking is only needed for global operations -- but it turned out
     that the background DWARF reader could race with the auto-load
     code reading the .debug_gdb_scripts section from the same BFD.

     This lock is the fix: wrappers for important BFD functions will
     acquire this lock before performing operations that might modify
     the state of this BFD.  */
  gdb::mutex per_bfd_mutex;
};

registry<bfd> *
registry_accessor<bfd>::get (bfd *abfd)
{
  struct gdb_bfd_data *gdata = (struct gdb_bfd_data *) bfd_usrdata (abfd);
  return &gdata->registry_fields;
}

/* When true gdb will reuse an existing bfd object if the filename,
   modification time, and file size all match.  */

static bool bfd_sharing = true;
static void
show_bfd_sharing  (struct ui_file *file, int from_tty,
		   struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("BFD sharing is %s.\n"), value);
}

/* When true debugging of the bfd caches is enabled.  */

static bool debug_bfd_cache;

/* Print an "bfd-cache" debug statement.  */

#define bfd_cache_debug_printf(fmt, ...) \
  debug_prefixed_printf_cond (debug_bfd_cache, "bfd-cache", fmt, ##__VA_ARGS__)

static void
show_bfd_cache_debug (struct ui_file *file, int from_tty,
		      struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("BFD cache debugging is %s.\n"), value);
}

/* The type of an object being looked up in gdb_bfd_cache.  We use
   htab's capability of storing one kind of object (BFD in this case)
   and using a different sort of object for searching.  */

struct gdb_bfd_cache_search
{
  /* The filename.  */
  const char *filename;
  /* The mtime.  */
  time_t mtime;
  /* The file size (in bytes).  */
  off_t size;
  /* The inode of the file.  */
  ino_t inode;
  /* The device id of the file.  */
  dev_t device_id;
};

struct bfd_cache_hash
{
  using is_transparent = void;

  std::size_t operator() (bfd *abfd) const noexcept
  {
    /* It is simplest to just hash the filename.  */
    return htab_hash_string (bfd_get_filename (abfd));
  }

  std::size_t operator() (const gdb_bfd_cache_search &search) const noexcept
  { return htab_hash_string (search.filename); }
};

struct bfd_cache_eq
{
  using is_transparent = void;

  bool operator() (bfd *lhs, bfd *rhs) const noexcept
  { return lhs == rhs; }

  bool operator() (const gdb_bfd_cache_search &s, bfd *abfd) const noexcept
  {
    auto gdata = static_cast<gdb_bfd_data *> (bfd_usrdata (abfd));

    return (gdata->mtime == s.mtime
	    && gdata->size == s.size
	    && gdata->inode == s.inode
	    && gdata->device_id == s.device_id
	    && strcmp (bfd_get_filename (abfd), s.filename) == 0);
  }
};

/* A hash set storing all the BFDs maintained in the cache.  */

static gdb::unordered_set<bfd *, bfd_cache_hash, bfd_cache_eq> gdb_bfd_cache;

/* See gdb_bfd.h.  */

int
is_target_filename (const char *name)
{
  return startswith (name, TARGET_SYSROOT_PREFIX);
}

/* See gdb_bfd.h.  */

int
gdb_bfd_has_target_filename (struct bfd *abfd)
{
  return is_target_filename (bfd_get_filename (abfd));
}

/* For `gdb_bfd_open_from_target_memory`.  An object that manages the
   details of a BFD in target memory.  */

struct target_buffer : public gdb_bfd_iovec_base
{
  /* Constructor.  BASE and SIZE define where the BFD can be found in
     target memory.  */
  target_buffer (CORE_ADDR base, ULONGEST size)
    : m_base (base),
      m_size (size),
      m_filename (xstrprintf ("<in-memory@%s-%s>",
			      core_addr_to_string_nz (m_base),
			      core_addr_to_string_nz (m_base + m_size)))
  {
  }

  /* Return the size of the in-memory BFD file.  */
  ULONGEST size () const
  { return m_size; }

  /* Return the base address of the in-memory BFD file.  */
  CORE_ADDR base () const
  { return m_base; }

  /* Return a generated filename for the in-memory BFD file.  The generated
     name will include the begin and end address of the in-memory file.  */
  const char *filename () const
  { return m_filename.get (); }

  file_ptr read (bfd *abfd, void *buffer, file_ptr nbytes,
		 file_ptr offset) override;

  int stat (struct bfd *abfd, struct stat *sb) override;

private:
  /* The base address of the in-memory BFD file.  */
  CORE_ADDR m_base;

  /* The size (in-bytes) of the in-memory BFD file.  */
  ULONGEST m_size;

  /* Holds the generated name of the in-memory BFD file.  */
  gdb::unique_xmalloc_ptr<char> m_filename;
};

/* For `gdb_bfd_open_from_target_memory`.  For reading the file, we just need to
   pass through to target_read_memory and fix up the arguments and return
   values.  */

file_ptr
target_buffer::read (struct bfd *abfd, void *buf,
		     file_ptr nbytes, file_ptr offset)
{
  /* If this read will read all of the file, limit it to just the rest.  */
  if (offset + nbytes > size ())
    nbytes = size () - offset;

  /* If there are no more bytes left, we've reached EOF.  */
  if (nbytes == 0)
    return 0;

  int err = target_read_memory (base () + offset, (gdb_byte *) buf, nbytes);
  if (err)
    return -1;

  return nbytes;
}

/* For `gdb_bfd_open_from_target_memory`.  For statting the file, we only
   support the st_size attribute.  */

int
target_buffer::stat (struct bfd *abfd, struct stat *sb)
{
  memset (sb, 0, sizeof (struct stat));
  sb->st_size = size ();
  return 0;
}

/* See gdb_bfd.h.  */

gdb_bfd_ref_ptr
gdb_bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size,
				 const char *target)
{
  std::unique_ptr<target_buffer> buffer
    = std::make_unique<target_buffer> (addr, size);

  return gdb_bfd_openr_iovec (buffer->filename (), target,
			      [&] (bfd *nbfd)
			      {
				return buffer.release ();
			      });
}

/* An object that manages the underlying stream for a BFD, using
   target file I/O.  */

struct target_fileio_stream : public gdb_bfd_iovec_base
{
  target_fileio_stream (bfd *nbfd, int fd)
    : m_bfd (nbfd),
      m_fd (fd)
  {
  }

  ~target_fileio_stream ();

  file_ptr read (bfd *abfd, void *buffer, file_ptr nbytes,
		 file_ptr offset) override;

  int stat (struct bfd *abfd, struct stat *sb) override;

private:

  /* The BFD.  Saved for the destructor.  */
  bfd *m_bfd;

  /* The file descriptor.  */
  int m_fd;
};

/* Wrapper for target_fileio_open suitable for use as a helper
   function for gdb_bfd_openr_iovec.  */

static target_fileio_stream *
gdb_bfd_iovec_fileio_open (struct bfd *abfd, inferior *inf, bool warn_if_slow)
{
  const char *filename = bfd_get_filename (abfd);
  int fd;
  fileio_error target_errno;

  gdb_assert (is_target_filename (filename));

  fd = target_fileio_open (inf,
			   filename + strlen (TARGET_SYSROOT_PREFIX),
			   FILEIO_O_RDONLY, 0, warn_if_slow,
			   &target_errno);
  if (fd == -1)
    {
      errno = fileio_error_to_host (target_errno);
      bfd_set_error (bfd_error_system_call);
      return NULL;
    }

  return new target_fileio_stream (abfd, fd);
}

/* Wrapper for target_fileio_pread.  */

file_ptr
target_fileio_stream::read (struct bfd *abfd, void *buf,
			    file_ptr nbytes, file_ptr offset)
{
  fileio_error target_errno;
  file_ptr pos, bytes;

  pos = 0;
  while (nbytes > pos)
    {
      QUIT;

      bytes = target_fileio_pread (m_fd, (gdb_byte *) buf + pos,
				   nbytes - pos, offset + pos,
				   &target_errno);
      if (bytes == 0)
	/* Success, but no bytes, means end-of-file.  */
	break;
      if (bytes == -1)
	{
	  errno = fileio_error_to_host (target_errno);
	  bfd_set_error (bfd_error_system_call);
	  return -1;
	}

      pos += bytes;
    }

  return pos;
}

/* Warn that it wasn't possible to close a bfd for file NAME, because
   of REASON.  */

static void
gdb_bfd_close_warning (const char *name, const char *reason)
{
  warning (_("cannot close \"%s\": %s"), name, reason);
}

/* Wrapper for target_fileio_close.  */

target_fileio_stream::~target_fileio_stream ()
{
  fileio_error target_errno;

  /* Ignore errors on close.  These may happen with remote
     targets if the connection has already been torn down.  */
  try
    {
      target_fileio_close (m_fd, &target_errno);
    }
  catch (const gdb_exception &ex)
    {
      /* Also avoid crossing exceptions over bfd.  */
      gdb_bfd_close_warning (bfd_get_filename (m_bfd),
			     ex.message->c_str ());
    }
}

/* Wrapper for target_fileio_fstat.  */

int
target_fileio_stream::stat (struct bfd *abfd, struct stat *sb)
{
  fileio_error target_errno;
  int result;

  result = target_fileio_fstat (m_fd, sb, &target_errno);
  if (result == -1)
    {
      errno = fileio_error_to_host (target_errno);
      bfd_set_error (bfd_error_system_call);
    }

  return result;
}

/* A helper function to initialize the data that gdb attaches to each
   BFD.  */

static void
gdb_bfd_init_data (struct bfd *abfd, struct stat *st)
{
  struct gdb_bfd_data *gdata;

  gdb_assert (bfd_usrdata (abfd) == nullptr);

  /* Ask BFD to decompress sections in bfd_get_full_section_contents.  */
  abfd->flags |= BFD_DECOMPRESS;

  gdata = new gdb_bfd_data (abfd, st);
  bfd_set_usrdata (abfd, gdata);

  /* This is the first we've seen it, so add it to the hash table.  */
  bool inserted = all_bfds.emplace (abfd).second;
  gdb_assert (inserted);
}

/* See gdb_bfd.h.  */

gdb_bfd_ref_ptr
gdb_bfd_open (const char *name, const char *target, int fd,
	      bool warn_if_slow)
{
  bfd *abfd;
  struct stat st;

  if (is_target_filename (name))
    {
      if (!target_filesystem_is_local ())
	{
	  gdb_assert (fd == -1);

	  auto open = [&] (bfd *nbfd) -> gdb_bfd_iovec_base *
	  {
	    return gdb_bfd_iovec_fileio_open (nbfd, current_inferior (),
					      warn_if_slow);
	  };

	  return gdb_bfd_openr_iovec (name, target, open);
	}

      name += strlen (TARGET_SYSROOT_PREFIX);
    }

  gdb::lock_guard<gdb::recursive_mutex> guard (gdb_bfd_mutex);

  if (fd == -1)
    {
      fd = gdb_open_cloexec (name, O_RDONLY | O_BINARY, 0).release ();
      if (fd == -1)
	{
	  bfd_set_error (bfd_error_system_call);
	  return NULL;
	}
    }

  if (fstat (fd, &st) < 0)
    {
      /* Weird situation here -- don't cache if we can't stat.  */
      bfd_cache_debug_printf ("Could not stat %s - not caching", name);
      abfd = bfd_fopen (name, target, FOPEN_RB, fd);
      if (abfd == nullptr)
	return nullptr;
      return gdb_bfd_ref_ptr::new_reference (abfd);
    }

  gdb_bfd_cache_search search;

  search.filename = name;
  search.mtime = st.st_mtime;
  search.size = st.st_size;
  search.inode = st.st_ino;
  search.device_id = st.st_dev;

  if (bfd_sharing)
    {
      if (auto iter = gdb_bfd_cache.find (search);
	  iter != gdb_bfd_cache.end ())
	{
	  abfd = *iter;
	  bfd_cache_debug_printf ("Reusing cached bfd %s for %s",
				  host_address_to_string (abfd),
				  bfd_get_filename (abfd));
	  close (fd);
	  return gdb_bfd_ref_ptr::new_reference (abfd);
	}
    }

  abfd = bfd_fopen (name, target, FOPEN_RB, fd);
  if (abfd == NULL)
    return NULL;

  bfd_set_cacheable (abfd, 1);

  bfd_cache_debug_printf ("Creating new bfd %s for %s",
			  host_address_to_string (abfd),
			  bfd_get_filename (abfd));

  /* It's important to pass the already-computed stat info here,
     rather than, say, calling gdb_bfd_ref_ptr::new_reference.  BFD by
     default will "stat" the file each time bfd_get_mtime is called --
     and since we will enter it into the hash table using this
     mtime, if the file changed at the wrong moment, the race would
     lead to a hash table corruption.  */
  gdb_bfd_init_data (abfd, &st);

  if (bfd_sharing)
    {
      bool inserted = gdb_bfd_cache.emplace (abfd).second;
      gdb_assert (inserted);
    }

  return gdb_bfd_ref_ptr (abfd);
}

/* A helper function that releases any section data attached to the
   BFD.  */

static void
free_one_bfd_section (asection *sectp)
{
  struct gdb_bfd_section_data *sect
    = (struct gdb_bfd_section_data *) bfd_section_userdata (sectp);

  if (sect != NULL && sect->data != NULL)
    {
#ifdef HAVE_MMAP
      if (sect->map_addr != NULL)
	{
	  int res;

	  res = munmap (sect->map_addr, sect->map_len);
	  gdb_assert (res == 0);
	}
      else
#endif
	xfree (sect->data);
    }
}

/* Close ABFD, and warn if that fails.  */

static int
gdb_bfd_close_or_warn (struct bfd *abfd)
{
  int ret;
  gdb::unique_xmalloc_ptr<char> name
    = make_unique_xstrdup (bfd_get_filename (abfd));

  for (asection *sect : gdb_bfd_sections (abfd))
    free_one_bfd_section (sect);

  ret = bfd_close (abfd);

  if (!ret)
    gdb_bfd_close_warning (name.get (),
			   bfd_errmsg (bfd_get_error ()));

  return ret;
}

/* See gdb_bfd.h.  */

void
gdb_bfd_ref (struct bfd *abfd)
{
  struct gdb_bfd_data *gdata;

  if (abfd == NULL)
    return;

  gdb::lock_guard<gdb::recursive_mutex> guard (gdb_bfd_mutex);

  gdata = (struct gdb_bfd_data *) bfd_usrdata (abfd);

  bfd_cache_debug_printf ("Increase reference count on bfd %s (%s)",
			  host_address_to_string (abfd),
			  bfd_get_filename (abfd));

  if (gdata != NULL)
    {
      gdata->refc += 1;
      return;
    }

  /* Caching only happens via gdb_bfd_open, so passing nullptr here is
     fine.  */
  gdb_bfd_init_data (abfd, nullptr);
}

/* See gdb_bfd.h.  */

void
gdb_bfd_unref (struct bfd *abfd)
{
  struct gdb_bfd_data *gdata;
  bfd *archive_bfd;

  if (abfd == NULL)
    return;

  gdb::lock_guard<gdb::recursive_mutex> guard (gdb_bfd_mutex);

  gdata = (struct gdb_bfd_data *) bfd_usrdata (abfd);
  gdb_assert (gdata->refc >= 1);

  gdata->refc -= 1;
  if (gdata->refc > 0)
    {
      bfd_cache_debug_printf ("Decrease reference count on bfd %s (%s)",
			      host_address_to_string (abfd),
			      bfd_get_filename (abfd));
      return;
    }

  bfd_cache_debug_printf ("Delete final reference count on bfd %s (%s)",
			  host_address_to_string (abfd),
			  bfd_get_filename (abfd));

  archive_bfd = gdata->archive_bfd;

  if (bfd_get_filename (abfd) != nullptr)
    gdb_bfd_cache.erase (abfd);

  delete gdata;
  bfd_set_usrdata (abfd, NULL);  /* Paranoia.  */

  all_bfds.erase (abfd);

  gdb_bfd_close_or_warn (abfd);

  gdb_bfd_unref (archive_bfd);
}

/* A helper function that returns the section data descriptor
   associated with SECTION.  If no such descriptor exists, a new one
   is allocated and cleared.  */

static struct gdb_bfd_section_data *
get_section_descriptor (asection *section)
{
  struct gdb_bfd_section_data *result;

  result = (struct gdb_bfd_section_data *) bfd_section_userdata (section);

  if (result == NULL)
    {
      result = ((struct gdb_bfd_section_data *)
		bfd_zalloc (section->owner, sizeof (*result)));
      bfd_set_section_userdata (section, result);
    }

  return result;
}

/* See gdb_bfd.h.  */

const gdb_byte *
gdb_bfd_map_section (asection *sectp, bfd_size_type *size)
{
  bfd *abfd;
  struct gdb_bfd_section_data *descriptor;
  bfd_byte *data;

  gdb_assert ((sectp->flags & SEC_RELOC) == 0);
  gdb_assert (size != NULL);

  abfd = sectp->owner;

  gdb_bfd_data *gdata = (gdb_bfd_data *) bfd_usrdata (abfd);
  gdb::lock_guard<gdb::mutex> guard (gdata->per_bfd_mutex);

  descriptor = get_section_descriptor (sectp);

  /* If the data was already read for this BFD, just reuse it.  */
  if (descriptor->data != NULL)
    goto done;

#ifdef HAVE_MMAP
  if (!bfd_is_section_compressed (abfd, sectp))
    {
      /* The page size, used when mmapping.  */
      static int pagesize;

      if (pagesize == 0)
	pagesize = getpagesize ();

      /* Only try to mmap sections which are large enough: we don't want
	 to waste space due to fragmentation.  */

      if (bfd_section_size (sectp) > 4 * pagesize)
	{
	  descriptor->size = bfd_section_size (sectp);
	  descriptor->data = bfd_mmap (abfd, 0, descriptor->size, PROT_READ,
				       MAP_PRIVATE, sectp->filepos,
				       &descriptor->map_addr,
				       &descriptor->map_len);

	  if ((caddr_t)descriptor->data != MAP_FAILED)
	    {
#if HAVE_POSIX_MADVISE
	      posix_madvise (descriptor->map_addr, descriptor->map_len,
			     POSIX_MADV_WILLNEED);
#endif
	      goto done;
	    }

	  /* On failure, clear out the section data and try again.  */
	  memset (descriptor, 0, sizeof (*descriptor));
	}
    }
#endif /* HAVE_MMAP */

  /* Handle compressed sections, or ordinary uncompressed sections in
     the no-mmap case.  */

  descriptor->size = bfd_section_size (sectp);
  descriptor->data = NULL;

  data = NULL;
  if (!bfd_get_full_section_contents (abfd, sectp, &data))
    {
      warning (_("Can't read data for section '%s' in file '%s'"),
	       bfd_section_name (sectp),
	       bfd_get_filename (abfd));
      /* Set size to 0 to prevent further attempts to read the invalid
	 section.  */
      *size = 0;
      return NULL;
    }
  descriptor->data = data;

 done:
  gdb_assert (descriptor->data != NULL);
  *size = descriptor->size;
  return (const gdb_byte *) descriptor->data;
}

/* Return 32-bit CRC for ABFD.  If successful store it to *FILE_CRC_RETURN and
   return 1.  Otherwise print a warning and return 0.  ABFD seek position is
   not preserved.  */

static int
get_file_crc (bfd *abfd, unsigned long *file_crc_return)
{
  uint32_t file_crc = 0;

  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
    {
      warning (_("Problem reading \"%s\" for CRC: %s"),
	       bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
      return 0;
    }

  for (;;)
    {
      gdb_byte buffer[8 * 1024];
      bfd_size_type count;

      count = bfd_read (buffer, sizeof (buffer), abfd);
      if (count == (bfd_size_type) -1)
	{
	  warning (_("Problem reading \"%s\" for CRC: %s"),
		   bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
	  return 0;
	}
      if (count == 0)
	break;
      file_crc = bfd_calc_gnu_debuglink_crc32 (file_crc, buffer, count);
    }

  *file_crc_return = file_crc;
  return 1;
}

/* See gdb_bfd.h.  */

int
gdb_bfd_crc (struct bfd *abfd, unsigned long *crc_out)
{
  struct gdb_bfd_data *gdata = (struct gdb_bfd_data *) bfd_usrdata (abfd);

  if (!gdata->crc_computed)
    gdata->crc_computed = get_file_crc (abfd, &gdata->crc);

  if (gdata->crc_computed)
    *crc_out = gdata->crc;
  return gdata->crc_computed;
}



/* See gdb_bfd.h.  */

gdb_bfd_ref_ptr
gdb_bfd_fopen (const char *filename, const char *target, const char *mode,
	       int fd)
{
  bfd *result = bfd_fopen (filename, target, mode, fd);

  if (result != nullptr)
    bfd_set_cacheable (result, 1);

  return gdb_bfd_ref_ptr::new_reference (result);
}

/* See gdb_bfd.h.  */

gdb_bfd_ref_ptr
gdb_bfd_openr (const char *filename, const char *target)
{
  bfd *result = bfd_openr (filename, target);

  return gdb_bfd_ref_ptr::new_reference (result);
}

/* See gdb_bfd.h.  */

gdb_bfd_ref_ptr
gdb_bfd_openw (const char *filename, const char *target)
{
  bfd *result = bfd_openw (filename, target);

  return gdb_bfd_ref_ptr::new_reference (result);
}

/* See gdb_bfd.h.  */

gdb_bfd_ref_ptr
gdb_bfd_openr_iovec (const char *filename, const char *target,
		     gdb_iovec_opener_ftype open_fn)
{
  auto do_open = [] (bfd *nbfd, void *closure) -> void *
  {
    auto real_opener = static_cast<gdb_iovec_opener_ftype *> (closure);
    /* Prevent exceptions from escaping to C code and triggering an abort.  */
    auto res = catch_exceptions<gdb_bfd_iovec_base *, nullptr> ([&]
      {
	return (*real_opener) (nbfd);
      });
    if (res == nullptr)
      {
	errno = EIO;
	bfd_set_error (bfd_error_system_call);
      }
      return res;
  };

  auto read_trampoline = [] (bfd *nbfd, void *stream, void *buf,
			     file_ptr nbytes, file_ptr offset) -> file_ptr
  {
    gdb_bfd_iovec_base *obj = static_cast<gdb_bfd_iovec_base *> (stream);
    /* Prevent exceptions from escaping to C code and triggering an abort.  */
    auto res = catch_exceptions<long int, -1> ([&]
      {
	return obj->read (nbfd, buf, nbytes, offset);
      });
    if (res == -1)
      {
	errno = EIO;
	bfd_set_error (bfd_error_system_call);
      }
    return res;
  };

  auto stat_trampoline = [] (struct bfd *abfd, void *stream,
			     struct stat *sb) -> int
  {
    gdb_bfd_iovec_base *obj = static_cast<gdb_bfd_iovec_base *> (stream);
    /* Prevent exceptions from escaping to C code and triggering an abort.  */
    auto res = catch_exceptions<int, -1> ([&]
      {
	return obj->stat (abfd, sb);
      });
    if (res == -1)
      {
	errno = EIO;
	bfd_set_error (bfd_error_system_call);
      }
    return res;
  };

  auto close_trampoline = [] (struct bfd *nbfd, void *stream) -> int
  {
    gdb_bfd_iovec_base *obj = static_cast<gdb_bfd_iovec_base *> (stream);
    delete obj;
    /* Success.  */
    return 0;
  };

  bfd *result = bfd_openr_iovec (filename, target,
				 do_open, &open_fn,
				 read_trampoline, close_trampoline,
				 stat_trampoline);

  return gdb_bfd_ref_ptr::new_reference (result);
}

/* See gdb_bfd.h.  */

void
gdb_bfd_mark_parent (bfd *child, bfd *parent)
{
  struct gdb_bfd_data *gdata;

  gdb_bfd_ref (child);
  /* No need to stash the filename here, because we also keep a
     reference on the parent archive.  */

  gdata = (struct gdb_bfd_data *) bfd_usrdata (child);
  if (gdata->archive_bfd == NULL)
    {
      gdata->archive_bfd = parent;
      gdb_bfd_ref (parent);
    }
  else
    gdb_assert (gdata->archive_bfd == parent);
}

/* See gdb_bfd.h.  */

gdb_bfd_ref_ptr
gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous)
{
  bfd *result = bfd_openr_next_archived_file (archive, previous);

  if (result)
    gdb_bfd_mark_parent (result, archive);

  return gdb_bfd_ref_ptr (result);
}

/* See gdb_bfd.h.  */

void
gdb_bfd_record_inclusion (bfd *includer, bfd *includee)
{
  struct gdb_bfd_data *gdata;

  gdata = (struct gdb_bfd_data *) bfd_usrdata (includer);
  gdata->included_bfds.push_back (gdb_bfd_ref_ptr::new_reference (includee));
}



static_assert (ARRAY_SIZE (_bfd_std_section) == 4);

/* See gdb_bfd.h.  */

int
gdb_bfd_section_index (bfd *abfd, asection *section)
{
  if (section == NULL)
    return -1;
  else if (section == bfd_com_section_ptr)
    return bfd_count_sections (abfd);
  else if (section == bfd_und_section_ptr)
    return bfd_count_sections (abfd) + 1;
  else if (section == bfd_abs_section_ptr)
    return bfd_count_sections (abfd) + 2;
  else if (section == bfd_ind_section_ptr)
    return bfd_count_sections (abfd) + 3;
  return section->index;
}

/* See gdb_bfd.h.  */

int
gdb_bfd_count_sections (bfd *abfd)
{
  return bfd_count_sections (abfd) + 4;
}

/* See gdb_bfd.h.  */

int
gdb_bfd_requires_relocations (bfd *abfd)
{
  struct gdb_bfd_data *gdata = (struct gdb_bfd_data *) bfd_usrdata (abfd);

  if (gdata->relocation_computed == 0)
    {
      asection *sect;

      for (sect = abfd->sections; sect != NULL; sect = sect->next)
	if ((sect->flags & SEC_RELOC) != 0)
	  {
	    gdata->needs_relocations = 1;
	    break;
	  }

      gdata->relocation_computed = 1;
    }

  return gdata->needs_relocations;
}

/* See gdb_bfd.h.  */

bool
gdb_bfd_get_full_section_contents (bfd *abfd, asection *section,
				   gdb::byte_vector *contents)
{
  gdb_bfd_data *gdata = (gdb_bfd_data *) bfd_usrdata (abfd);
  gdb::lock_guard<gdb::mutex> guard (gdata->per_bfd_mutex);

  bfd_size_type section_size = bfd_get_section_alloc_size (abfd, section);

  contents->resize (section_size);

  auto data = contents->data ();
  return bfd_get_full_section_contents (abfd, section, &data);
}

/* See gdb_bfd.h.  */

int
gdb_bfd_stat (bfd *abfd, struct stat *sbuf)
{
  gdb_bfd_data *gdata = (gdb_bfd_data *) bfd_usrdata (abfd);
  gdb::lock_guard<gdb::mutex> guard (gdata->per_bfd_mutex);

  return bfd_stat (abfd, sbuf);
}

/* See gdb_bfd.h.  */

long
gdb_bfd_get_mtime (bfd *abfd)
{
  gdb_bfd_data *gdata = (gdb_bfd_data *) bfd_usrdata (abfd);
  gdb::lock_guard<gdb::mutex> guard (gdata->per_bfd_mutex);

  return bfd_get_mtime (abfd);
}

#define AMBIGUOUS_MESS1	".\nMatching formats:"
#define AMBIGUOUS_MESS2	\
  ".\nUse \"set gnutarget format-name\" to specify the format."

/* See gdb_bfd.h.  */

std::string
gdb_bfd_errmsg (bfd_error_type error_tag, char **matching)
{
  char **p;

  /* Check if errmsg just need simple return.  */
  if (error_tag != bfd_error_file_ambiguously_recognized || matching == NULL)
    return bfd_errmsg (error_tag);

  std::string ret (bfd_errmsg (error_tag));
  ret += AMBIGUOUS_MESS1;

  for (p = matching; *p; p++)
    {
      ret += " ";
      ret += *p;
    }
  ret += AMBIGUOUS_MESS2;

  xfree (matching);

  return ret;
}

/* See gdb_bfd.h.  */

gdb::array_view<asymbol *>
gdb_bfd_canonicalize_symtab (bfd *abfd, bool should_throw)
{
  struct gdb_bfd_data *gdata = (struct gdb_bfd_data *) bfd_usrdata (abfd);

  if (!gdata->symbol_table.has_value ())
    {
      /* Ensure it exists.  */
      gdb::def_vector<asymbol *> &symbol_table
	= gdata->symbol_table.emplace ();

      long storage_needed = bfd_get_symtab_upper_bound (abfd);
      if (storage_needed < 0)
	gdata->symbol_error = bfd_errmsg (bfd_get_error ());
      else if (storage_needed > 0)
	{
	  symbol_table.resize (storage_needed / sizeof (asymbol *));
	  long number_of_symbols
	    = bfd_canonicalize_symtab (abfd, symbol_table.data ());
	  if (number_of_symbols < 0)
	    {
	      symbol_table.clear ();
	      gdata->symbol_error = bfd_errmsg (bfd_get_error ());
	    }
	}
    }

  if (!gdata->symbol_error.empty ())
    {
      if (should_throw)
	error (_("Cannot parse symbols of \"%s\": %s"),
	       bfd_get_filename (abfd), gdata->symbol_error.c_str ());
      return {};
    }

  gdb::def_vector<asymbol *> &symbol_table = *gdata->symbol_table;
  if (symbol_table.empty ())
    return {};

  /* bfd_canonicalize_symtab adds a trailing NULL, but don't include
     this in the array view.  */
  gdb_assert (symbol_table.back () == nullptr);
  return gdb::make_array_view (symbol_table.data (),
			       symbol_table.size () - 1);
}

/* Implement the 'maint info bfd' command.  */

static void
maintenance_info_bfds (const char *arg, int from_tty)
{
  struct ui_out *uiout = current_uiout;

  ui_out_emit_table table_emitter (uiout, 3, -1, "bfds");
  uiout->table_header (10, ui_left, "refcount", "Refcount");
  uiout->table_header (18, ui_left, "addr", "Address");
  uiout->table_header (40, ui_left, "filename", "Filename");

  uiout->table_body ();

  for (auto abfd : all_bfds)
    {
      auto gdata = static_cast<gdb_bfd_data *> (bfd_usrdata (abfd));
      ui_out_emit_tuple tuple_emitter (uiout, nullptr);
      uiout->field_signed ("refcount", gdata->refc);
      uiout->field_string ("addr", host_address_to_string (abfd));
      uiout->field_string ("filename", bfd_get_filename (abfd),
			   file_name_style.style ());
      uiout->text ("\n");
    }
}

/* BFD related per-inferior data.  */

struct bfd_inferior_data
{
  gdb::unordered_map<std::string, unsigned long> bfd_error_string_counts;
};

/* Per-inferior data key.  */

static const registry<inferior>::key<bfd_inferior_data> bfd_inferior_data_key;

/* Fetch per-inferior BFD data.  It always returns a valid pointer to
   a bfd_inferior_data struct.  */

static struct bfd_inferior_data *
get_bfd_inferior_data (struct inferior *inf)
{
  struct bfd_inferior_data *data;

  data = bfd_inferior_data_key.get (inf);
  if (data == nullptr)
    data = bfd_inferior_data_key.emplace (inf);

  return data;
}

/* Increment the BFD error count for STR and return the updated
   count.  */

static unsigned long
increment_bfd_error_count (const std::string &str)
{
  gdb::lock_guard<gdb::recursive_mutex> guard (gdb_bfd_mutex);
  struct bfd_inferior_data *bid = get_bfd_inferior_data (current_inferior ());

  auto &map = bid->bfd_error_string_counts;
  return ++map[str];
}

/* A print callback for bfd_print_error.  */

static int ATTRIBUTE_PRINTF (2, 0)
print_error_callback (void *stream, const char *fmt, ...)
{
  string_file *file = (string_file *) stream;
  size_t in_size = file->size ();
  va_list ap;
  va_start (ap, fmt);
  file->vprintf (fmt, ap);
  va_end (ap);
  return file->size () - in_size;
}

/* Define a BFD error handler which will suppress the printing of
   messages which have been printed once already.  This is done on a
   per-inferior basis.  */

static void
gdb_bfd_error_handler (const char *fmt, va_list ap)
{
  string_file output;
  bfd_print_error (print_error_callback, &output, fmt, ap);
  std::string str = output.release ();

  if (increment_bfd_error_count (str) > 1)
    return;

  warning ("%s", str.c_str ());
}

/* See gdb_bfd.h.  */

void
gdb_bfd_init ()
{
  if (bfd_init () == BFD_INIT_MAGIC)
    {
      if (bfd_thread_init (gdb_bfd_lock, gdb_bfd_unlock, nullptr))
	return;
    }

  error (_("fatal error: libbfd ABI mismatch"));
}

INIT_GDB_FILE (gdb_bfd)
{
  add_cmd ("bfds", class_maintenance, maintenance_info_bfds, _("\
List the BFDs that are currently open."),
	   &maintenanceinfolist);

  add_setshow_boolean_cmd ("bfd-sharing", no_class,
			   &bfd_sharing, _("\
Set whether gdb will share bfds that appear to be the same file."), _("\
Show whether gdb will share bfds that appear to be the same file."), _("\
When enabled gdb will reuse existing bfds rather than reopening the\n\
same file.  To decide if two files are the same then gdb compares the\n\
filename, file size, file modification time, and file inode."),
			   NULL,
			   &show_bfd_sharing,
			   &maintenance_set_cmdlist,
			   &maintenance_show_cmdlist);

  add_setshow_boolean_cmd ("bfd-cache", class_maintenance,
			   &debug_bfd_cache,
			   _("Set bfd cache debugging."),
			   _("Show bfd cache debugging."),
			   _("\
When non-zero, bfd cache specific debugging is enabled."),
			   NULL,
			   &show_bfd_cache_debug,
			   &setdebuglist, &showdebuglist);

  /* Hook the BFD error/warning handler to limit amount of output.  */
  bfd_set_error_handler (gdb_bfd_error_handler);
}
