/* Handle shared libraries for GDB, the GNU Debugger.

   Copyright (C) 1990-2023 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 "defs.h"

#include <sys/types.h>
#include <fcntl.h>
#include "symtab.h"
#include "bfd.h"
#include "build-id.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdbcore.h"
#include "command.h"
#include "target.h"
#include "frame.h"
#include "gdbsupport/gdb_regex.h"
#include "inferior.h"
#include "gdbsupport/environ.h"
#include "language.h"
#include "gdbcmd.h"
#include "completer.h"
#include "elf/external.h"
#include "elf/common.h"
#include "filenames.h"		/* for DOSish file names */
#include "exec.h"
#include "solist.h"
#include "observable.h"
#include "readline/tilde.h"
#include "remote.h"
#include "solib.h"
#include "interps.h"
#include "filesystem.h"
#include "gdb_bfd.h"
#include "gdbsupport/filestuff.h"
#include "gdbsupport/scoped_fd.h"
#include "debuginfod-support.h"
#include "source.h"
#include "cli/cli-style.h"
#include "solib-target.h"

/* See solib.h.  */

bool debug_solib;

/* If non-empty, this is a search path for loading non-absolute shared library
   symbol files.  This takes precedence over the environment variables PATH
   and LD_LIBRARY_PATH.  */
static std::string solib_search_path;
static void
show_solib_search_path (struct ui_file *file, int from_tty,
			struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("The search path for loading non-absolute "
		      "shared library symbol files is %s.\n"),
	      value);
}

/* Same as HAVE_DOS_BASED_FILE_SYSTEM, but useable as an rvalue.  */
#if (HAVE_DOS_BASED_FILE_SYSTEM)
#  define DOS_BASED_FILE_SYSTEM 1
#else
#  define DOS_BASED_FILE_SYSTEM 0
#endif

/* Return the full pathname of a binary file (the main executable or a
   shared library file), or NULL if not found.  If FD is non-NULL, *FD
   is set to either -1 or an open file handle for the binary file.

   Global variable GDB_SYSROOT is used as a prefix directory
   to search for binary files if they have an absolute path.
   If GDB_SYSROOT starts with "target:" and target filesystem
   is the local filesystem then the "target:" prefix will be
   stripped before the search starts.  This ensures that the
   same search algorithm is used for local files regardless of
   whether a "target:" prefix was used.

   Global variable SOLIB_SEARCH_PATH is used as a prefix directory
   (or set of directories, as in LD_LIBRARY_PATH) to search for all
   shared libraries if not found in either the sysroot (if set) or
   the local filesystem.  SOLIB_SEARCH_PATH is not used when searching
   for the main executable.

   Search algorithm:
   * If a sysroot is set and path is absolute:
   *   Search for sysroot/path.
   * else
   *   Look for it literally (unmodified).
   * If IS_SOLIB is non-zero:
   *   Look in SOLIB_SEARCH_PATH.
   *   If available, use target defined search function.
   * If NO sysroot is set, perform the following two searches:
   *   Look in inferior's $PATH.
   *   If IS_SOLIB is non-zero:
   *     Look in inferior's $LD_LIBRARY_PATH.
   *
   * The last check avoids doing this search when targeting remote
   * machines since a sysroot will almost always be set.
*/

static gdb::unique_xmalloc_ptr<char>
solib_find_1 (const char *in_pathname, int *fd, bool is_solib)
{
  const struct target_so_ops *ops = gdbarch_so_ops (target_gdbarch ());
  int found_file = -1;
  gdb::unique_xmalloc_ptr<char> temp_pathname;
  const char *fskind = effective_target_file_system_kind ();
  const char *sysroot = gdb_sysroot.c_str ();
  int prefix_len, orig_prefix_len;

  /* If the absolute prefix starts with "target:" but the filesystem
     accessed by the target_fileio_* methods is the local filesystem
     then we strip the "target:" prefix now and work with the local
     filesystem.  This ensures that the same search algorithm is used
     for all local files regardless of whether a "target:" prefix was
     used.  */
  if (is_target_filename (sysroot) && target_filesystem_is_local ())
    sysroot += strlen (TARGET_SYSROOT_PREFIX);

  /* Strip any trailing slashes from the absolute prefix.  */
  prefix_len = orig_prefix_len = strlen (sysroot);

  while (prefix_len > 0 && IS_DIR_SEPARATOR (sysroot[prefix_len - 1]))
    prefix_len--;

  std::string sysroot_holder;
  if (prefix_len == 0)
    sysroot = NULL;
  else if (prefix_len != orig_prefix_len)
    {
      sysroot_holder = std::string (sysroot, prefix_len);
      sysroot = sysroot_holder.c_str ();
    }

  /* If we're on a non-DOS-based system, backslashes won't be
     understood as directory separator, so, convert them to forward
     slashes, iff we're supposed to handle DOS-based file system
     semantics for target paths.  */
  if (!DOS_BASED_FILE_SYSTEM && fskind == file_system_kind_dos_based)
    {
      char *p;

      /* Avoid clobbering our input.  */
      p = (char *) alloca (strlen (in_pathname) + 1);
      strcpy (p, in_pathname);
      in_pathname = p;

      for (; *p; p++)
	{
	  if (*p == '\\')
	    *p = '/';
	}
    }

  /* Note, we're interested in IS_TARGET_ABSOLUTE_PATH, not
     IS_ABSOLUTE_PATH.  The latter is for host paths only, while
     IN_PATHNAME is a target path.  For example, if we're supposed to
     be handling DOS-like semantics we want to consider a
     'c:/foo/bar.dll' path as an absolute path, even on a Unix box.
     With such a path, before giving up on the sysroot, we'll try:

       1st attempt, c:/foo/bar.dll ==> /sysroot/c:/foo/bar.dll
       2nd attempt, c:/foo/bar.dll ==> /sysroot/c/foo/bar.dll
       3rd attempt, c:/foo/bar.dll ==> /sysroot/foo/bar.dll
  */

  if (!IS_TARGET_ABSOLUTE_PATH (fskind, in_pathname) || sysroot == NULL)
    temp_pathname.reset (xstrdup (in_pathname));
  else
    {
      bool need_dir_separator;

      /* Concatenate the sysroot and the target reported filename.  We
	 may need to glue them with a directory separator.  Cases to
	 consider:

	| sysroot         | separator | in_pathname    |
	|-----------------+-----------+----------------|
	| /some/dir       | /         | c:/foo/bar.dll |
	| /some/dir       |           | /foo/bar.dll   |
	| target:         |           | c:/foo/bar.dll |
	| target:         |           | /foo/bar.dll   |
	| target:some/dir | /         | c:/foo/bar.dll |
	| target:some/dir |           | /foo/bar.dll   |

	IOW, we don't need to add a separator if IN_PATHNAME already
	has one, or when the sysroot is exactly "target:".
	There's no need to check for drive spec explicitly, as we only
	get here if IN_PATHNAME is considered an absolute path.  */
      need_dir_separator = !(IS_DIR_SEPARATOR (in_pathname[0])
			     || strcmp (TARGET_SYSROOT_PREFIX, sysroot) == 0);

      /* Cat the prefixed pathname together.  */
      temp_pathname.reset (concat (sysroot,
				   need_dir_separator ? SLASH_STRING : "",
				   in_pathname, (char *) NULL));
    }

  /* Handle files to be accessed via the target.  */
  if (is_target_filename (temp_pathname.get ()))
    {
      if (fd != NULL)
	*fd = -1;
      return temp_pathname;
    }

  /* Now see if we can open it.  */
  found_file = gdb_open_cloexec (temp_pathname.get (),
				 O_RDONLY | O_BINARY, 0).release ();

  /* If the search in gdb_sysroot failed, and the path name has a
     drive spec (e.g, c:/foo), try stripping ':' from the drive spec,
     and retrying in the sysroot:
       c:/foo/bar.dll ==> /sysroot/c/foo/bar.dll.  */

  if (found_file < 0
      && sysroot != NULL
      && HAS_TARGET_DRIVE_SPEC (fskind, in_pathname))
    {
      bool need_dir_separator = !IS_DIR_SEPARATOR (in_pathname[2]);
      char drive[2] = { in_pathname[0], '\0' };

      temp_pathname.reset (concat (sysroot,
				   SLASH_STRING,
				   drive,
				   need_dir_separator ? SLASH_STRING : "",
				   in_pathname + 2, (char *) NULL));

      found_file = gdb_open_cloexec (temp_pathname.get (),
				     O_RDONLY | O_BINARY, 0).release ();
      if (found_file < 0)
	{
	  /* If the search in gdb_sysroot still failed, try fully
	     stripping the drive spec, and trying once more in the
	     sysroot before giving up.

	     c:/foo/bar.dll ==> /sysroot/foo/bar.dll.  */

	  temp_pathname.reset (concat (sysroot,
				       need_dir_separator ? SLASH_STRING : "",
				       in_pathname + 2, (char *) NULL));

	  found_file = gdb_open_cloexec (temp_pathname.get (),
					 O_RDONLY | O_BINARY, 0).release ();
	}
    }

  /* We try to find the library in various ways.  After each attempt,
     either found_file >= 0 and temp_pathname is a malloc'd string, or
     found_file < 0 and temp_pathname does not point to storage that
     needs to be freed.  */

  if (found_file < 0)
    temp_pathname.reset (NULL);

  /* If the search in gdb_sysroot failed, and the path name is
     absolute at this point, make it relative.  (openp will try and open the
     file according to its absolute path otherwise, which is not what we want.)
     Affects subsequent searches for this solib.  */
  if (found_file < 0 && IS_TARGET_ABSOLUTE_PATH (fskind, in_pathname))
    {
      /* First, get rid of any drive letters etc.  */
      while (!IS_TARGET_DIR_SEPARATOR (fskind, *in_pathname))
	in_pathname++;

      /* Next, get rid of all leading dir separators.  */
      while (IS_TARGET_DIR_SEPARATOR (fskind, *in_pathname))
	in_pathname++;
    }

  /* If not found, and we're looking for a solib, search the
     solib_search_path (if any).  */
  if (is_solib && found_file < 0 && !solib_search_path.empty ())
    found_file = openp (solib_search_path.c_str (),
			OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH,
			in_pathname, O_RDONLY | O_BINARY, &temp_pathname);

  /* If not found, and we're looking for a solib, next search the
     solib_search_path (if any) for the basename only (ignoring the
     path).  This is to allow reading solibs from a path that differs
     from the opened path.  */
  if (is_solib && found_file < 0 && !solib_search_path.empty ())
    found_file = openp (solib_search_path.c_str (),
			OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH,
			target_lbasename (fskind, in_pathname),
			O_RDONLY | O_BINARY, &temp_pathname);

  /* If not found, and we're looking for a solib, try to use target
     supplied solib search method.  */
  if (is_solib && found_file < 0 && ops->find_and_open_solib)
    found_file = ops->find_and_open_solib (in_pathname, O_RDONLY | O_BINARY,
					   &temp_pathname);

  /* If not found, next search the inferior's $PATH environment variable.  */
  if (found_file < 0 && sysroot == NULL)
    found_file = openp (current_inferior ()->environment.get ("PATH"),
			OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, in_pathname,
			O_RDONLY | O_BINARY, &temp_pathname);

  /* If not found, and we're looking for a solib, next search the
     inferior's $LD_LIBRARY_PATH environment variable.  */
  if (is_solib && found_file < 0 && sysroot == NULL)
    found_file = openp (current_inferior ()->environment.get
			("LD_LIBRARY_PATH"),
			OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, in_pathname,
			O_RDONLY | O_BINARY, &temp_pathname);

  if (fd == NULL)
    {
      if (found_file >= 0)
	close (found_file);
    }
  else
    *fd = found_file;

  return temp_pathname;
}

/* Return the full pathname of the main executable, or NULL if not
   found.  If FD is non-NULL, *FD is set to either -1 or an open file
   handle for the main executable.  */

gdb::unique_xmalloc_ptr<char>
exec_file_find (const char *in_pathname, int *fd)
{
  gdb::unique_xmalloc_ptr<char> result;
  const char *fskind = effective_target_file_system_kind ();

  if (in_pathname == NULL)
    return NULL;

  if (!gdb_sysroot.empty () && IS_TARGET_ABSOLUTE_PATH (fskind, in_pathname))
    {
      result = solib_find_1 (in_pathname, fd, false);

      if (result == NULL && fskind == file_system_kind_dos_based)
	{
	  char *new_pathname;

	  new_pathname = (char *) alloca (strlen (in_pathname) + 5);
	  strcpy (new_pathname, in_pathname);
	  strcat (new_pathname, ".exe");

	  result = solib_find_1 (new_pathname, fd, false);
	}
    }
  else
    {
      /* It's possible we don't have a full path, but rather just a
	 filename.  Some targets, such as HP-UX, don't provide the
	 full path, sigh.

	 Attempt to qualify the filename against the source path.
	 (If that fails, we'll just fall back on the original
	 filename.  Not much more we can do...)  */

      if (!source_full_path_of (in_pathname, &result))
	result.reset (xstrdup (in_pathname));
      if (fd != NULL)
	*fd = -1;
    }

  return result;
}

/* Return the full pathname of a shared library file, or NULL if not
   found.  If FD is non-NULL, *FD is set to either -1 or an open file
   handle for the shared library.

   The search algorithm used is described in solib_find_1's comment
   above.  */

gdb::unique_xmalloc_ptr<char>
solib_find (const char *in_pathname, int *fd)
{
  const char *solib_symbols_extension
    = gdbarch_solib_symbols_extension (target_gdbarch ());

  /* If solib_symbols_extension is set, replace the file's
     extension.  */
  if (solib_symbols_extension != NULL)
    {
      const char *p = in_pathname + strlen (in_pathname);

      while (p > in_pathname && *p != '.')
	p--;

      if (*p == '.')
	{
	  char *new_pathname;

	  new_pathname
	    = (char *) alloca (p - in_pathname + 1
			       + strlen (solib_symbols_extension) + 1);
	  memcpy (new_pathname, in_pathname, p - in_pathname + 1);
	  strcpy (new_pathname + (p - in_pathname) + 1,
		  solib_symbols_extension);

	  in_pathname = new_pathname;
	}
    }

  return solib_find_1 (in_pathname, fd, true);
}

/* Open and return a BFD for the shared library PATHNAME.  If FD is not -1,
   it is used as file handle to open the file.  Throws an error if the file
   could not be opened.  Handles both local and remote file access.

   If unsuccessful, the FD will be closed (unless FD was -1).  */

gdb_bfd_ref_ptr
solib_bfd_fopen (const char *pathname, int fd)
{
  gdb_bfd_ref_ptr abfd (gdb_bfd_open (pathname, gnutarget, fd));

  if (abfd != NULL && !gdb_bfd_has_target_filename (abfd.get ()))
    bfd_set_cacheable (abfd.get (), 1);

  if (abfd == NULL)
    {
      /* Arrange to free PATHNAME when the error is thrown.  */
      error (_("Could not open `%s' as an executable file: %s"),
	     pathname, bfd_errmsg (bfd_get_error ()));
    }

  return abfd;
}

/* Find shared library PATHNAME and open a BFD for it.  */

gdb_bfd_ref_ptr
solib_bfd_open (const char *pathname)
{
  int found_file;
  const struct bfd_arch_info *b;

  /* Search for shared library file.  */
  gdb::unique_xmalloc_ptr<char> found_pathname
    = solib_find (pathname, &found_file);
  if (found_pathname == NULL)
    {
      /* Return failure if the file could not be found, so that we can
	 accumulate messages about missing libraries.  */
      if (errno == ENOENT)
	return NULL;

      perror_with_name (pathname);
    }

  /* Open bfd for shared library.  */
  gdb_bfd_ref_ptr abfd (solib_bfd_fopen (found_pathname.get (), found_file));

  /* Check bfd format.  */
  if (!bfd_check_format (abfd.get (), bfd_object))
    error (_("`%s': not in executable format: %s"),
	   bfd_get_filename (abfd.get ()), bfd_errmsg (bfd_get_error ()));

  /* Check bfd arch.  */
  b = gdbarch_bfd_arch_info (target_gdbarch ());
  if (!b->compatible (b, bfd_get_arch_info (abfd.get ())))
    error (_("`%s': Shared library architecture %s is not compatible "
	     "with target architecture %s."), bfd_get_filename (abfd.get ()),
	   bfd_get_arch_info (abfd.get ())->printable_name,
	   b->printable_name);

  return abfd;
}

/* Mapping of a core file's shared library sonames to their respective
   build-ids.  Added to the registries of core file bfds.  */

typedef std::unordered_map<std::string, std::string> soname_build_id_map;

/* Key used to associate a soname_build_id_map to a core file bfd.  */

static const struct registry<bfd>::key<soname_build_id_map>
     cbfd_soname_build_id_data_key;

/* See solib.h.  */

void
set_cbfd_soname_build_id (gdb_bfd_ref_ptr abfd,
			  const char *soname,
			  const bfd_build_id *build_id)
{
  gdb_assert (abfd.get () != nullptr);
  gdb_assert (soname != nullptr);
  gdb_assert (build_id != nullptr);

  soname_build_id_map *mapptr = cbfd_soname_build_id_data_key.get (abfd.get ());

  if (mapptr == nullptr)
    mapptr = cbfd_soname_build_id_data_key.emplace (abfd.get ());

  (*mapptr)[soname] = build_id_to_string (build_id);
}

/* See solib.h.  */

gdb::unique_xmalloc_ptr<char>
get_cbfd_soname_build_id (gdb_bfd_ref_ptr abfd, const char *soname)
{
  if (abfd.get () == nullptr || soname == nullptr)
    return {};

  soname_build_id_map *mapptr
    = cbfd_soname_build_id_data_key.get (abfd.get ());

  if (mapptr == nullptr)
    return {};

  auto it = mapptr->find (lbasename (soname));
  if (it == mapptr->end ())
    return {};

  return make_unique_xstrdup (it->second.c_str ());
}

/* Given a pointer to one of the shared objects in our list of mapped
   objects, use the recorded name to open a bfd descriptor for the
   object, build a section table, relocate all the section addresses
   by the base address at which the shared object was mapped, and then
   add the sections to the target's section table.

   FIXME: In most (all?) cases the shared object file name recorded in
   the dynamic linkage tables will be a fully qualified pathname.  For
   cases where it isn't, do we really mimic the systems search
   mechanism correctly in the below code (particularly the tilde
   expansion stuff?).  */

static int
solib_map_sections (struct so_list *so)
{
  const struct target_so_ops *ops = gdbarch_so_ops (target_gdbarch ());

  gdb::unique_xmalloc_ptr<char> filename (tilde_expand (so->so_name));
  gdb_bfd_ref_ptr abfd (ops->bfd_open (filename.get ()));
  gdb::unique_xmalloc_ptr<char> build_id_hexstr
    = get_cbfd_soname_build_id (current_program_space->cbfd, so->so_name);

  /* If we already know the build-id of this solib from a core file, verify
     it matches ABFD's build-id.  If there is a mismatch or the solib wasn't
     found, attempt to query debuginfod for the correct solib.  */
  if (build_id_hexstr.get () != nullptr)
    {
      bool mismatch = false;

      if (abfd != nullptr && abfd->build_id != nullptr)
	{
	  std::string build_id = build_id_to_string (abfd->build_id);

	  if (build_id != build_id_hexstr.get ())
	    mismatch = true;
	}
      if (abfd == nullptr || mismatch)
	{
	  scoped_fd fd = debuginfod_exec_query ((const unsigned char*)
						build_id_hexstr.get (),
						0, so->so_name, &filename);

	  if (fd.get () >= 0)
	    abfd = ops->bfd_open (filename.get ());
	  else if (mismatch)
	    warning (_("Build-id of %ps does not match core file."),
		     styled_string (file_name_style.style (), filename.get ()));
	}
    }

  if (abfd == NULL)
    return 0;

  /* Leave bfd open, core_xfer_memory and "info files" need it.  */
  so->abfd = abfd.release ();

  /* Copy the full path name into so_name, allowing symbol_file_add
     to find it later.  This also affects the =library-loaded GDB/MI
     event, and in particular the part of that notification providing
     the library's host-side path.  If we let the target dictate
     that objfile's path, and the target is different from the host,
     GDB/MI will not provide the correct host-side path.  */
  if (strlen (bfd_get_filename (so->abfd)) >= SO_NAME_MAX_PATH_SIZE)
    error (_("Shared library file name is too long."));
  strcpy (so->so_name, bfd_get_filename (so->abfd));

  if (so->sections == nullptr)
    so->sections = new target_section_table;
  *so->sections = build_section_table (so->abfd);

  for (target_section &p : *so->sections)
    {
      /* Relocate the section binding addresses as recorded in the shared
	 object's file by the base address to which the object was actually
	 mapped.  */
      ops->relocate_section_addresses (so, &p);

      /* If the target didn't provide information about the address
	 range of the shared object, assume we want the location of
	 the .text section.  */
      if (so->addr_low == 0 && so->addr_high == 0
	  && strcmp (p.the_bfd_section->name, ".text") == 0)
	{
	  so->addr_low = p.addr;
	  so->addr_high = p.endaddr;
	}
    }

  /* Add the shared object's sections to the current set of file
     section tables.  Do this immediately after mapping the object so
     that later nodes in the list can query this object, as is needed
     in solib-osf.c.  */
  current_program_space->add_target_sections (so, *so->sections);

  return 1;
}

/* Free symbol-file related contents of SO and reset for possible reloading
   of SO.  If we have opened a BFD for SO, close it.  If we have placed SO's
   sections in some target's section table, the caller is responsible for
   removing them.

   This function doesn't mess with objfiles at all.  If there is an
   objfile associated with SO that needs to be removed, the caller is
   responsible for taking care of that.  */

static void
clear_so (struct so_list *so)
{
  const struct target_so_ops *ops = gdbarch_so_ops (target_gdbarch ());

  delete so->sections;
  so->sections = NULL;

  gdb_bfd_unref (so->abfd);
  so->abfd = NULL;

  /* Our caller closed the objfile, possibly via objfile_purge_solibs.  */
  so->symbols_loaded = 0;
  so->objfile = NULL;

  so->addr_low = so->addr_high = 0;

  /* Restore the target-supplied file name.  SO_NAME may be the path
     of the symbol file.  */
  strcpy (so->so_name, so->so_original_name);

  /* Do the same for target-specific data.  */
  if (ops->clear_so != NULL)
    ops->clear_so (so);
}

/* Free the storage associated with the `struct so_list' object SO.
   If we have opened a BFD for SO, close it.

   The caller is responsible for removing SO from whatever list it is
   a member of.  If we have placed SO's sections in some target's
   section table, the caller is responsible for removing them.

   This function doesn't mess with objfiles at all.  If there is an
   objfile associated with SO that needs to be removed, the caller is
   responsible for taking care of that.  */

void
free_so (struct so_list *so)
{
  const struct target_so_ops *ops = gdbarch_so_ops (target_gdbarch ());

  clear_so (so);
  ops->free_so (so);

  xfree (so);
}


/* Read in symbols for shared object SO.  If SYMFILE_VERBOSE is set in FLAGS,
   be chatty about it.  Return true if any symbols were actually loaded.  */

bool
solib_read_symbols (struct so_list *so, symfile_add_flags flags)
{
  if (so->symbols_loaded)
    {
      /* If needed, we've already warned in our caller.  */
    }
  else if (so->abfd == NULL)
    {
      /* We've already warned about this library, when trying to open
	 it.  */
    }
  else
    {

      flags |= current_inferior ()->symfile_flags;

      try
	{
	  /* Have we already loaded this shared object?  */
	  so->objfile = nullptr;
	  for (objfile *objfile : current_program_space->objfiles ())
	    {
	      if (filename_cmp (objfile_name (objfile), so->so_name) == 0
		  && objfile->addr_low == so->addr_low)
		{
		  so->objfile = objfile;
		  break;
		}
	    }
	  if (so->objfile == NULL)
	    {
	      section_addr_info sap
		= build_section_addr_info_from_section_table (*so->sections);
	      gdb_bfd_ref_ptr tmp_bfd
		(gdb_bfd_ref_ptr::new_reference (so->abfd));
	      so->objfile = symbol_file_add_from_bfd (tmp_bfd, so->so_name,
						      flags, &sap,
						      OBJF_SHARED, NULL);
	      so->objfile->addr_low = so->addr_low;
	    }

	  so->symbols_loaded = 1;
	}
      catch (const gdb_exception_error &e)
	{
	  exception_fprintf (gdb_stderr, e, _("Error while reading shared"
					      " library symbols for %s:\n"),
			     so->so_name);
	}

      return true;
    }

  return false;
}

/* Return true if KNOWN->objfile is used by any other so_list object
   in the list of shared libraries.  Return false otherwise.  */

static bool
solib_used (const struct so_list *const known)
{
  for (const struct so_list *pivot : current_program_space->solibs ())
    if (pivot != known && pivot->objfile == known->objfile)
      return true;
  return false;
}

/* Notify interpreters and observers that solib SO has been loaded.  */

static void
notify_solib_loaded (so_list *so)
{
  interps_notify_solib_loaded (so);
  gdb::observers::solib_loaded.notify (so);
}

/* Notify interpreters and observers that solib SO has been unloaded.  */

static void
notify_solib_unloaded (so_list *so)
{
  interps_notify_solib_unloaded (so);
  gdb::observers::solib_unloaded.notify (so);
}

/* See solib.h.  */

void
update_solib_list (int from_tty)
{
  const struct target_so_ops *ops = gdbarch_so_ops (target_gdbarch ());
  struct so_list *inferior = ops->current_sos();
  struct so_list *gdb, **gdb_link;

  /* We can reach here due to changing solib-search-path or the
     sysroot, before having any inferior.  */
  if (target_has_execution () && inferior_ptid != null_ptid)
    {
      struct inferior *inf = current_inferior ();

      /* If we are attaching to a running process for which we
	 have not opened a symbol file, we may be able to get its
	 symbols now!  */
      if (inf->attach_flag
	  && current_program_space->symfile_object_file == NULL)
	{
	  try
	    {
	      ops->open_symbol_file_object (from_tty);
	    }
	  catch (const gdb_exception_error &ex)
	    {
	      exception_fprintf (gdb_stderr, ex,
				 "Error reading attached "
				 "process's symbol file.\n");
	    }
	}
    }

  /* GDB and the inferior's dynamic linker each maintain their own
     list of currently loaded shared objects; we want to bring the
     former in sync with the latter.  Scan both lists, seeing which
     shared objects appear where.  There are three cases:

     - A shared object appears on both lists.  This means that GDB
     knows about it already, and it's still loaded in the inferior.
     Nothing needs to happen.

     - A shared object appears only on GDB's list.  This means that
     the inferior has unloaded it.  We should remove the shared
     object from GDB's tables.

     - A shared object appears only on the inferior's list.  This
     means that it's just been loaded.  We should add it to GDB's
     tables.

     So we walk GDB's list, checking each entry to see if it appears
     in the inferior's list too.  If it does, no action is needed, and
     we remove it from the inferior's list.  If it doesn't, the
     inferior has unloaded it, and we remove it from GDB's list.  By
     the time we're done walking GDB's list, the inferior's list
     contains only the new shared objects, which we then add.  */

  gdb = current_program_space->so_list;
  gdb_link = &current_program_space->so_list;
  while (gdb)
    {
      struct so_list *i = inferior;
      struct so_list **i_link = &inferior;

      /* Check to see whether the shared object *gdb also appears in
	 the inferior's current list.  */
      while (i)
	{
	  if (ops->same)
	    {
	      if (ops->same (gdb, i))
		break;
	    }
	  else
	    {
	      if (! filename_cmp (gdb->so_original_name, i->so_original_name))
		break;	      
	    }

	  i_link = &i->next;
	  i = *i_link;
	}

      /* If the shared object appears on the inferior's list too, then
	 it's still loaded, so we don't need to do anything.  Delete
	 it from the inferior's list, and leave it on GDB's list.  */
      if (i)
	{
	  *i_link = i->next;
	  free_so (i);
	  gdb_link = &gdb->next;
	  gdb = *gdb_link;
	}

      /* If it's not on the inferior's list, remove it from GDB's tables.  */
      else
	{
	  /* Notify any observer that the shared object has been
	     unloaded before we remove it from GDB's tables.  */
	  notify_solib_unloaded (gdb);

	  current_program_space->deleted_solibs.push_back (gdb->so_name);

	  *gdb_link = gdb->next;

	  /* Unless the user loaded it explicitly, free SO's objfile.  */
	  if (gdb->objfile && ! (gdb->objfile->flags & OBJF_USERLOADED)
	      && !solib_used (gdb))
	    gdb->objfile->unlink ();

	  /* Some targets' section tables might be referring to
	     sections from so->abfd; remove them.  */
	  current_program_space->remove_target_sections (gdb);

	  free_so (gdb);
	  gdb = *gdb_link;
	}
    }

  /* Now the inferior's list contains only shared objects that don't
     appear in GDB's list --- those that are newly loaded.  Add them
     to GDB's shared object list.  */
  if (inferior)
    {
      int not_found = 0;
      const char *not_found_filename = NULL;

      struct so_list *i;

      /* Add the new shared objects to GDB's list.  */
      *gdb_link = inferior;

      /* Fill in the rest of each of the `struct so_list' nodes.  */
      for (i = inferior; i; i = i->next)
	{

	  i->pspace = current_program_space;
	  current_program_space->added_solibs.push_back (i);

	  try
	    {
	      /* Fill in the rest of the `struct so_list' node.  */
	      if (!solib_map_sections (i))
		{
		  not_found++;
		  if (not_found_filename == NULL)
		    not_found_filename = i->so_original_name;
		}
	    }

	  catch (const gdb_exception_error &e)
	    {
	      exception_fprintf (gdb_stderr, e,
				 _("Error while mapping shared "
				   "library sections:\n"));
	    }

	  /* Notify any observer that the shared object has been
	     loaded now that we've added it to GDB's tables.  */
	  notify_solib_loaded (i);
	}

      /* If a library was not found, issue an appropriate warning
	 message.  We have to use a single call to warning in case the
	 front end does something special with warnings, e.g., pop up
	 a dialog box.  It Would Be Nice if we could get a "warning: "
	 prefix on each line in the CLI front end, though - it doesn't
	 stand out well.  */

      if (not_found == 1)
	warning (_("Could not load shared library symbols for %s.\n"
		   "Do you need \"set solib-search-path\" "
		   "or \"set sysroot\"?"),
		 not_found_filename);
      else if (not_found > 1)
	warning (_("\
Could not load shared library symbols for %d libraries, e.g. %s.\n\
Use the \"info sharedlibrary\" command to see the complete listing.\n\
Do you need \"set solib-search-path\" or \"set sysroot\"?"),
		 not_found, not_found_filename);
    }
}


/* Return non-zero if NAME is the libpthread shared library.

   Uses a fairly simplistic heuristic approach where we check
   the file name against "/libpthread".  This can lead to false
   positives, but this should be good enough in practice.

   As of glibc-2.34, functions formerly residing in libpthread have
   been moved to libc, so "/libc." needs to be checked too.  (Matching
   the "." will avoid matching libraries such as libcrypt.) */

bool
libpthread_name_p (const char *name)
{
  return (strstr (name, "/libpthread") != NULL
	  || strstr (name, "/libc.") != NULL );
}

/* Return non-zero if SO is the libpthread shared library.  */

static bool
libpthread_solib_p (struct so_list *so)
{
  return libpthread_name_p (so->so_name);
}

/* Read in symbolic information for any shared objects whose names
   match PATTERN.  (If we've already read a shared object's symbol
   info, leave it alone.)  If PATTERN is zero, read them all.

   If READSYMS is 0, defer reading symbolic information until later
   but still do any needed low level processing.

   FROM_TTY is described for update_solib_list, above.  */

void
solib_add (const char *pattern, int from_tty, int readsyms)
{
  if (print_symbol_loading_p (from_tty, 0, 0))
    {
      if (pattern != NULL)
	{
	  gdb_printf (_("Loading symbols for shared libraries: %s\n"),
		      pattern);
	}
      else
	gdb_printf (_("Loading symbols for shared libraries.\n"));
    }

  current_program_space->solib_add_generation++;

  if (pattern)
    {
      char *re_err = re_comp (pattern);

      if (re_err)
	error (_("Invalid regexp: %s"), re_err);
    }

  update_solib_list (from_tty);

  /* Walk the list of currently loaded shared libraries, and read
     symbols for any that match the pattern --- or any whose symbols
     aren't already loaded, if no pattern was given.  */
  {
    bool any_matches = false;
    bool loaded_any_symbols = false;
    symfile_add_flags add_flags = SYMFILE_DEFER_BP_RESET;

    if (from_tty)
	add_flags |= SYMFILE_VERBOSE;

    for (struct so_list *gdb : current_program_space->solibs ())
      if (! pattern || re_exec (gdb->so_name))
	{
	  /* Normally, we would read the symbols from that library
	     only if READSYMS is set.  However, we're making a small
	     exception for the pthread library, because we sometimes
	     need the library symbols to be loaded in order to provide
	     thread support (x86-linux for instance).  */
	  const int add_this_solib =
	    (readsyms || libpthread_solib_p (gdb));

	  any_matches = true;
	  if (add_this_solib)
	    {
	      if (gdb->symbols_loaded)
		{
		  /* If no pattern was given, be quiet for shared
		     libraries we have already loaded.  */
		  if (pattern && (from_tty || info_verbose))
		    gdb_printf (_("Symbols already loaded for %s\n"),
				gdb->so_name);
		}
	      else if (solib_read_symbols (gdb, add_flags))
		loaded_any_symbols = true;
	    }
	}

    if (loaded_any_symbols)
      breakpoint_re_set ();

    if (from_tty && pattern && ! any_matches)
      gdb_printf
	("No loaded shared libraries match the pattern `%s'.\n", pattern);

    if (loaded_any_symbols)
      {
	/* Getting new symbols may change our opinion about what is
	   frameless.  */
	reinit_frame_cache ();
      }
  }
}

/* Implement the "info sharedlibrary" command.  Walk through the
   shared library list and print information about each attached
   library matching PATTERN.  If PATTERN is elided, print them
   all.  */

static void
info_sharedlibrary_command (const char *pattern, int from_tty)
{
  bool so_missing_debug_info = false;
  int addr_width;
  int nr_libs;
  struct gdbarch *gdbarch = target_gdbarch ();
  struct ui_out *uiout = current_uiout;

  if (pattern)
    {
      char *re_err = re_comp (pattern);

      if (re_err)
	error (_("Invalid regexp: %s"), re_err);
    }

  /* "0x", a little whitespace, and two hex digits per byte of pointers.  */
  addr_width = 4 + (gdbarch_ptr_bit (gdbarch) / 4);

  update_solib_list (from_tty);

  /* ui_out_emit_table table_emitter needs to know the number of rows,
     so we need to make two passes over the libs.  */

  nr_libs = 0;
  for (struct so_list *so : current_program_space->solibs ())
    {
      if (so->so_name[0])
	{
	  if (pattern && ! re_exec (so->so_name))
	    continue;
	  ++nr_libs;
	}
    }

  {
    ui_out_emit_table table_emitter (uiout, 4, nr_libs, "SharedLibraryTable");

    /* The "- 1" is because ui_out adds one space between columns.  */
    uiout->table_header (addr_width - 1, ui_left, "from", "From");
    uiout->table_header (addr_width - 1, ui_left, "to", "To");
    uiout->table_header (12 - 1, ui_left, "syms-read", "Syms Read");
    uiout->table_header (0, ui_noalign, "name", "Shared Object Library");

    uiout->table_body ();

    for (struct so_list *so : current_program_space->solibs ())
      {
	if (! so->so_name[0])
	  continue;
	if (pattern && ! re_exec (so->so_name))
	  continue;

	ui_out_emit_tuple tuple_emitter (uiout, "lib");

	if (so->addr_high != 0)
	  {
	    uiout->field_core_addr ("from", gdbarch, so->addr_low);
	    uiout->field_core_addr ("to", gdbarch, so->addr_high);
	  }
	else
	  {
	    uiout->field_skip ("from");
	    uiout->field_skip ("to");
	  }

	if (! top_level_interpreter ()->interp_ui_out ()->is_mi_like_p ()
	    && so->symbols_loaded
	    && !objfile_has_symbols (so->objfile))
	  {
	    so_missing_debug_info = true;
	    uiout->field_string ("syms-read", "Yes (*)");
	  }
	else
	  uiout->field_string ("syms-read", so->symbols_loaded ? "Yes" : "No");

	uiout->field_string ("name", so->so_name, file_name_style.style ());

	uiout->text ("\n");
      }
  }

  if (nr_libs == 0)
    {
      if (pattern)
	uiout->message (_("No shared libraries matched.\n"));
      else
	uiout->message (_("No shared libraries loaded at this time.\n"));
    }
  else
    {
      if (so_missing_debug_info)
	uiout->message (_("(*): Shared library is missing "
			  "debugging information.\n"));
    }
}

/* See solib.h.  */

bool
solib_contains_address_p (const struct so_list *const solib,
			  CORE_ADDR address)
{
  if (solib->sections == nullptr)
    return false;

  for (target_section &p : *solib->sections)
    if (p.addr <= address && address < p.endaddr)
      return true;

  return false;
}

/* If ADDRESS is in a shared lib in program space PSPACE, return its
   name.

   Provides a hook for other gdb routines to discover whether or not a
   particular address is within the mapped address space of a shared
   library.

   For example, this routine is called at one point to disable
   breakpoints which are in shared libraries that are not currently
   mapped in.  */

const char *
solib_name_from_address (struct program_space *pspace, CORE_ADDR address)
{
  struct so_list *so = NULL;

  for (so = pspace->so_list; so; so = so->next)
    if (solib_contains_address_p (so, address))
      return (so->so_name);

  return (0);
}

/* See solib.h.  */

bool
solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
{
  const struct target_so_ops *ops = gdbarch_so_ops (target_gdbarch ());

  if (ops->keep_data_in_core)
    return ops->keep_data_in_core (vaddr, size) != 0;
  else
    return false;
}

/* Called by free_all_symtabs */

void
clear_solib (void)
{
  const struct target_so_ops *ops = gdbarch_so_ops (target_gdbarch ());

  disable_breakpoints_in_shlibs ();

  while (current_program_space->so_list)
    {
      struct so_list *so = current_program_space->so_list;

      current_program_space->so_list = so->next;
      notify_solib_unloaded (so);
      current_program_space->remove_target_sections (so);
      free_so (so);
    }

  ops->clear_solib ();
}

/* Shared library startup support.  When GDB starts up the inferior,
   it nurses it along (through the shell) until it is ready to execute
   its first instruction.  At this point, this function gets
   called.  */

void
solib_create_inferior_hook (int from_tty)
{
  const struct target_so_ops *ops = gdbarch_so_ops (target_gdbarch ());

  ops->solib_create_inferior_hook (from_tty);
}

/* See solib.h.  */

bool
in_solib_dynsym_resolve_code (CORE_ADDR pc)
{
  const struct target_so_ops *ops = gdbarch_so_ops (target_gdbarch ());

  return ops->in_dynsym_resolve_code (pc) != 0;
}

/* Implements the "sharedlibrary" command.  */

static void
sharedlibrary_command (const char *args, int from_tty)
{
  dont_repeat ();
  solib_add (args, from_tty, 1);
}

/* Implements the command "nosharedlibrary", which discards symbols
   that have been auto-loaded from shared libraries.  Symbols from
   shared libraries that were added by explicit request of the user
   are not discarded.  Also called from remote.c.  */

void
no_shared_libraries (const char *ignored, int from_tty)
{
  /* The order of the two routines below is important: clear_solib notifies
     the solib_unloaded observers, and some of these observers might need
     access to their associated objfiles.  Therefore, we can not purge the
     solibs' objfiles before clear_solib has been called.  */

  clear_solib ();
  objfile_purge_solibs ();
}

/* See solib.h.  */

void
update_solib_breakpoints (void)
{
  const struct target_so_ops *ops = gdbarch_so_ops (target_gdbarch ());

  if (ops->update_breakpoints != NULL)
    ops->update_breakpoints ();
}

/* See solib.h.  */

void
handle_solib_event (void)
{
  const struct target_so_ops *ops = gdbarch_so_ops (target_gdbarch ());

  if (ops->handle_event != NULL)
    ops->handle_event ();

  current_inferior ()->pspace->clear_solib_cache ();

  /* Check for any newly added shared libraries if we're supposed to
     be adding them automatically.  Switch terminal for any messages
     produced by breakpoint_re_set.  */
  target_terminal::ours_for_output ();
  solib_add (NULL, 0, auto_solib_add);
  target_terminal::inferior ();
}

/* Reload shared libraries, but avoid reloading the same symbol file
   we already have loaded.  */

static void
reload_shared_libraries_1 (int from_tty)
{
  if (print_symbol_loading_p (from_tty, 0, 0))
    gdb_printf (_("Loading symbols for shared libraries.\n"));

  for (struct so_list *so : current_program_space->solibs ())
    {
      const char *found_pathname = NULL;
      bool was_loaded = so->symbols_loaded != 0;
      symfile_add_flags add_flags = SYMFILE_DEFER_BP_RESET;

      if (from_tty)
	add_flags |= SYMFILE_VERBOSE;

      gdb::unique_xmalloc_ptr<char> filename
	(tilde_expand (so->so_original_name));
      gdb_bfd_ref_ptr abfd (solib_bfd_open (filename.get ()));
      if (abfd != NULL)
	found_pathname = bfd_get_filename (abfd.get ());

      /* If this shared library is no longer associated with its previous
	 symbol file, close that.  */
      if ((found_pathname == NULL && was_loaded)
	  || (found_pathname != NULL
	      && filename_cmp (found_pathname, so->so_name) != 0))
	{
	  if (so->objfile && ! (so->objfile->flags & OBJF_USERLOADED)
	      && !solib_used (so))
	    so->objfile->unlink ();
	  current_program_space->remove_target_sections (so);
	  clear_so (so);
	}

      /* If this shared library is now associated with a new symbol
	 file, open it.  */
      if (found_pathname != NULL
	  && (!was_loaded
	      || filename_cmp (found_pathname, so->so_name) != 0))
	{
	  bool got_error = false;

	  try
	    {
	      solib_map_sections (so);
	    }

	  catch (const gdb_exception_error &e)
	    {
	      exception_fprintf (gdb_stderr, e,
				 _("Error while mapping "
				   "shared library sections:\n"));
	      got_error = true;
	    }

	    if (!got_error
		&& (auto_solib_add || was_loaded || libpthread_solib_p (so)))
	      solib_read_symbols (so, add_flags);
	}
    }
}

static void
reload_shared_libraries (const char *ignored, int from_tty,
			 struct cmd_list_element *e)
{
  const struct target_so_ops *ops;

  reload_shared_libraries_1 (from_tty);

  ops = gdbarch_so_ops (target_gdbarch ());

  /* Creating inferior hooks here has two purposes.  First, if we reload 
     shared libraries then the address of solib breakpoint we've computed
     previously might be no longer valid.  For example, if we forgot to set
     solib-absolute-prefix and are setting it right now, then the previous
     breakpoint address is plain wrong.  Second, installing solib hooks
     also implicitly figures were ld.so is and loads symbols for it.
     Absent this call, if we've just connected to a target and set 
     solib-absolute-prefix or solib-search-path, we'll lose all information
     about ld.so.  */
  if (target_has_execution ())
    {
      /* Reset or free private data structures not associated with
	 so_list entries.  */
      ops->clear_solib ();

      /* Remove any previous solib event breakpoint.  This is usually
	 done in common code, at breakpoint_init_inferior time, but
	 we're not really starting up the inferior here.  */
      remove_solib_event_breakpoints ();

      solib_create_inferior_hook (from_tty);
    }

  /* Sometimes the platform-specific hook loads initial shared
     libraries, and sometimes it doesn't.  If it doesn't FROM_TTY will be
     incorrectly 0 but such solib targets should be fixed anyway.  If we
     made all the inferior hook methods consistent, this call could be
     removed.  Call it only after the solib target has been initialized by
     solib_create_inferior_hook.  */

  solib_add (NULL, 0, auto_solib_add);

  breakpoint_re_set ();

  /* We may have loaded or unloaded debug info for some (or all)
     shared libraries.  However, frames may still reference them.  For
     example, a frame's unwinder might still point at DWARF FDE
     structures that are now freed.  Also, getting new symbols may
     change our opinion about what is frameless.  */
  reinit_frame_cache ();
}

/* Wrapper for reload_shared_libraries that replaces "remote:"
   at the start of gdb_sysroot with "target:".  */

static void
gdb_sysroot_changed (const char *ignored, int from_tty,
		     struct cmd_list_element *e)
{
  const char *old_prefix = "remote:";
  const char *new_prefix = TARGET_SYSROOT_PREFIX;

  if (startswith (gdb_sysroot.c_str (), old_prefix))
    {
      static bool warning_issued = false;

      gdb_assert (strlen (old_prefix) == strlen (new_prefix));
      gdb_sysroot = new_prefix + gdb_sysroot.substr (strlen (old_prefix));

      if (!warning_issued)
	{
	  warning (_("\"%s\" is deprecated, use \"%s\" instead."),
		   old_prefix, new_prefix);
	  warning (_("sysroot set to \"%s\"."), gdb_sysroot.c_str ());

	  warning_issued = true;
	}
    }

  reload_shared_libraries (ignored, from_tty, e);
}

static void
show_auto_solib_add (struct ui_file *file, int from_tty,
		     struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Autoloading of shared library symbols is %s.\n"),
	      value);
}


/* Lookup the value for a specific symbol from dynamic symbol table.  Look
   up symbol from ABFD.  MATCH_SYM is a callback function to determine
   whether to pick up a symbol.  DATA is the input of this callback
   function.  Return 0 if symbol is not found.  */

CORE_ADDR
gdb_bfd_lookup_symbol_from_symtab
     (bfd *abfd, gdb::function_view<bool (const asymbol *)> match_sym)
{
  long storage_needed = bfd_get_symtab_upper_bound (abfd);
  CORE_ADDR symaddr = 0;

  if (storage_needed > 0)
    {
      unsigned int i;

      gdb::def_vector<asymbol *> storage (storage_needed / sizeof (asymbol *));
      asymbol **symbol_table = storage.data ();
      unsigned int number_of_symbols =
	bfd_canonicalize_symtab (abfd, symbol_table);

      for (i = 0; i < number_of_symbols; i++)
	{
	  asymbol *sym  = *symbol_table++;

	  if (match_sym (sym))
	    {
	      struct gdbarch *gdbarch = target_gdbarch ();
	      symaddr = sym->value;

	      /* Some ELF targets fiddle with addresses of symbols they
		 consider special.  They use minimal symbols to do that
		 and this is needed for correct breakpoint placement,
		 but we do not have full data here to build a complete
		 minimal symbol, so just set the address and let the
		 targets cope with that.  */
	      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
		  && gdbarch_elf_make_msymbol_special_p (gdbarch))
		{
		  struct minimal_symbol msym {};

		  msym.set_value_address (symaddr);
		  gdbarch_elf_make_msymbol_special (gdbarch, sym, &msym);
		  symaddr = CORE_ADDR (msym.unrelocated_address ());
		}

	      /* BFD symbols are section relative.  */
	      symaddr += sym->section->vma;
	      break;
	    }
	}
    }

  return symaddr;
}

/* See solib.h.  */

int
gdb_bfd_scan_elf_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr,
			 CORE_ADDR *ptr_addr)
{
  int arch_size, step, sect_size;
  long current_dyntag;
  CORE_ADDR dyn_ptr, dyn_addr;
  gdb_byte *bufend, *bufstart, *buf;
  Elf32_External_Dyn *x_dynp_32;
  Elf64_External_Dyn *x_dynp_64;
  struct bfd_section *sect;

  if (abfd == NULL)
    return 0;

  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
    return 0;

  arch_size = bfd_get_arch_size (abfd);
  if (arch_size == -1)
    return 0;

  /* Find the start address of the .dynamic section.  */
  sect = bfd_get_section_by_name (abfd, ".dynamic");
  if (sect == NULL)
    return 0;

  bool found = false;
  for (const target_section &target_section
	 : current_program_space->target_sections ())
    if (sect == target_section.the_bfd_section)
      {
	dyn_addr = target_section.addr;
	found = true;
	break;
      }
  if (!found)
    {
      /* ABFD may come from OBJFILE acting only as a symbol file without being
	 loaded into the target (see add_symbol_file_command).  This case is
	 such fallback to the file VMA address without the possibility of
	 having the section relocated to its actual in-memory address.  */

      dyn_addr = bfd_section_vma (sect);
    }

  /* Read in .dynamic from the BFD.  We will get the actual value
     from memory later.  */
  sect_size = bfd_section_size (sect);
  buf = bufstart = (gdb_byte *) alloca (sect_size);
  if (!bfd_get_section_contents (abfd, sect,
				 buf, 0, sect_size))
    return 0;

  /* Iterate over BUF and scan for DYNTAG.  If found, set PTR and return.  */
  step = (arch_size == 32) ? sizeof (Elf32_External_Dyn)
			   : sizeof (Elf64_External_Dyn);
  for (bufend = buf + sect_size;
       buf < bufend;
       buf += step)
  {
    if (arch_size == 32)
      {
	x_dynp_32 = (Elf32_External_Dyn *) buf;
	current_dyntag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
	dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr);
      }
    else
      {
	x_dynp_64 = (Elf64_External_Dyn *) buf;
	current_dyntag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
	dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr);
      }
    if (current_dyntag == DT_NULL)
      return 0;
    if (current_dyntag == desired_dyntag)
      {
	/* If requested, try to read the runtime value of this .dynamic
	   entry.  */
	if (ptr)
	  {
	    struct type *ptr_type;
	    gdb_byte ptr_buf[8];
	    CORE_ADDR ptr_addr_1;

	    ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
	    ptr_addr_1 = dyn_addr + (buf - bufstart) + arch_size / 8;
	    if (target_read_memory (ptr_addr_1, ptr_buf, arch_size / 8) == 0)
	      dyn_ptr = extract_typed_address (ptr_buf, ptr_type);
	    *ptr = dyn_ptr;
	    if (ptr_addr)
	      *ptr_addr = dyn_addr + (buf - bufstart);
	  }
	return 1;
      }
  }

  return 0;
}

/* See solib.h.  */

gdb::unique_xmalloc_ptr<char>
gdb_bfd_read_elf_soname (const char *filename)
{
  gdb_bfd_ref_ptr abfd = gdb_bfd_open (filename, gnutarget);

  if (abfd == nullptr)
    return {};

  /* Check that ABFD is an ET_DYN ELF file.  */
  if (!bfd_check_format (abfd.get (), bfd_object)
      || !(bfd_get_file_flags (abfd.get ()) & DYNAMIC))
    return {};

  CORE_ADDR idx;
  if (!gdb_bfd_scan_elf_dyntag (DT_SONAME, abfd.get (), &idx, nullptr))
    return {};

  struct bfd_section *dynstr = bfd_get_section_by_name (abfd.get (), ".dynstr");
  int sect_size = bfd_section_size (dynstr);
  if (dynstr == nullptr || sect_size <= idx)
    return {};

  /* Read soname from the string table.  */
  gdb::byte_vector dynstr_buf;
  if (!gdb_bfd_get_full_section_contents (abfd.get (), dynstr, &dynstr_buf))
    return {};

  /* Ensure soname is null-terminated before returning a copy.  */
  char *soname = (char *) dynstr_buf.data () + idx;
  if (strnlen (soname, sect_size - idx) == sect_size - idx)
    return {};

  return make_unique_xstrdup (soname);
}

/* Lookup the value for a specific symbol from symbol table.  Look up symbol
   from ABFD.  MATCH_SYM is a callback function to determine whether to pick
   up a symbol.  DATA is the input of this callback function.  Return 0
   if symbol is not found.  */

static CORE_ADDR
bfd_lookup_symbol_from_dyn_symtab
     (bfd *abfd, gdb::function_view<bool (const asymbol *)> match_sym)
{
  long storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);
  CORE_ADDR symaddr = 0;

  if (storage_needed > 0)
    {
      unsigned int i;
      gdb::def_vector<asymbol *> storage (storage_needed / sizeof (asymbol *));
      asymbol **symbol_table = storage.data ();
      unsigned int number_of_symbols =
	bfd_canonicalize_dynamic_symtab (abfd, symbol_table);

      for (i = 0; i < number_of_symbols; i++)
	{
	  asymbol *sym = *symbol_table++;

	  if (match_sym (sym))
	    {
	      /* BFD symbols are section relative.  */
	      symaddr = sym->value + sym->section->vma;
	      break;
	    }
	}
    }
  return symaddr;
}

/* Lookup the value for a specific symbol from symbol table and dynamic
   symbol table.  Look up symbol from ABFD.  MATCH_SYM is a callback
   function to determine whether to pick up a symbol.  DATA is the
   input of this callback function.  Return 0 if symbol is not
   found.  */

CORE_ADDR
gdb_bfd_lookup_symbol
     (bfd *abfd, gdb::function_view<bool (const asymbol *)> match_sym)
{
  CORE_ADDR symaddr = gdb_bfd_lookup_symbol_from_symtab (abfd, match_sym);

  /* On FreeBSD, the dynamic linker is stripped by default.  So we'll
     have to check the dynamic string table too.  */
  if (symaddr == 0)
    symaddr = bfd_lookup_symbol_from_dyn_symtab (abfd, match_sym);

  return symaddr;
}

/* The shared library list may contain user-loaded object files that
   can be removed out-of-band by the user.  So upon notification of
   free_objfile remove all references to any user-loaded file that is
   about to be freed.  */

static void
remove_user_added_objfile (struct objfile *objfile)
{
  if (objfile != 0 && objfile->flags & OBJF_USERLOADED)
    {
      for (struct so_list *so : current_program_space->solibs ())
	if (so->objfile == objfile)
	  so->objfile = NULL;
    }
}

void _initialize_solib ();
void
_initialize_solib ()
{
  gdb::observers::free_objfile.attach (remove_user_added_objfile,
				       "solib");
  gdb::observers::inferior_execd.attach ([] (inferior *exec_inf,
					     inferior *follow_inf)
    {
      solib_create_inferior_hook (0);
    }, "solib");

  add_com ("sharedlibrary", class_files, sharedlibrary_command,
	   _("Load shared object library symbols for files matching REGEXP."));
  cmd_list_element *info_sharedlibrary_cmd
    = add_info ("sharedlibrary", info_sharedlibrary_command,
		_("Status of loaded shared object libraries."));
  add_info_alias ("dll", info_sharedlibrary_cmd, 1);
  add_com ("nosharedlibrary", class_files, no_shared_libraries,
	   _("Unload all shared object library symbols."));

  add_setshow_boolean_cmd ("auto-solib-add", class_support,
			   &auto_solib_add, _("\
Set autoloading of shared library symbols."), _("\
Show autoloading of shared library symbols."), _("\
If \"on\", symbols from all shared object libraries will be loaded\n\
automatically when the inferior begins execution, when the dynamic linker\n\
informs gdb that a new library has been loaded, or when attaching to the\n\
inferior.  Otherwise, symbols must be loaded manually, using \
`sharedlibrary'."),
			   NULL,
			   show_auto_solib_add,
			   &setlist, &showlist);

  set_show_commands sysroot_cmds
    = add_setshow_optional_filename_cmd ("sysroot", class_support,
					 &gdb_sysroot, _("\
Set an alternate system root."), _("\
Show the current system root."), _("\
The system root is used to load absolute shared library symbol files.\n\
For other (relative) files, you can add directories using\n\
`set solib-search-path'."),
					 gdb_sysroot_changed,
					 NULL,
					 &setlist, &showlist);

  add_alias_cmd ("solib-absolute-prefix", sysroot_cmds.set, class_support, 0,
		 &setlist);
  add_alias_cmd ("solib-absolute-prefix", sysroot_cmds.show, class_support, 0,
		 &showlist);

  add_setshow_optional_filename_cmd ("solib-search-path", class_support,
				     &solib_search_path, _("\
Set the search path for loading non-absolute shared library symbol files."),
				     _("\
Show the search path for loading non-absolute shared library symbol files."),
				     _("\
This takes precedence over the environment variables \
PATH and LD_LIBRARY_PATH."),
				     reload_shared_libraries,
				     show_solib_search_path,
				     &setlist, &showlist);

  add_setshow_boolean_cmd ("solib", class_maintenance,
			   &debug_solib, _("\
Set solib debugging."), _("\
Show solib debugging."), _("\
When true, solib-related debugging output is enabled."),
			    nullptr, nullptr,
			    &setdebuglist, &showdebuglist);
}
