/* Debug logging for the symbol file functions for the GNU debugger, GDB.

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

   Contributed by Cygnus Support, using pieces from other GDB modules.

   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/>.  */

/* Note: Be careful with functions that can throw errors.
   We want to see a logging message regardless of whether an error was thrown.
   This typically means printing a message before calling the real function
   and then if the function returns a result printing a message after it
   returns.  */

#include "cli/cli-cmds.h"
#include "objfiles.h"
#include "observable.h"
#include "source.h"
#include "symtab.h"
#include "symfile.h"
#include "block.h"
#include "filenames.h"
#include "build-id.h"
#include "debuginfod-support.h"

/* We need to save a pointer to the real symbol functions.
   Plus, the debug versions are malloc'd because we have to NULL out the
   ones that are NULL in the real copy.  */

struct debug_sym_fns_data
{
  const struct sym_fns *real_sf = nullptr;
  struct sym_fns debug_sf {};
};

/* We need to record a pointer to the real set of functions for each
   objfile.  */
static const registry<objfile>::key<debug_sym_fns_data>
  symfile_debug_objfile_data_key;

/* If true all calls to the symfile functions are logged.  */
static bool debug_symfile = false;

/* Return non-zero if symfile debug logging is installed.  */

static int
symfile_debug_installed (struct objfile *objfile)
{
  return (objfile->sf != NULL
	  && symfile_debug_objfile_data_key.get (objfile) != NULL);
}

/* Utility return the name to print for SYMTAB.  */

static const char *
debug_symtab_name (struct symtab *symtab)
{
  return symtab_to_filename_for_display (symtab);
}


/* See objfiles.h.  */

bool
objfile::has_partial_symbols ()
{
  bool retval = false;

  /* If we have not read psymbols, but we have a function capable of reading
     them, then that is an indication that they are in fact available.  Without
     this function the symbols may have been already read in but they also may
     not be present in this objfile.  */
  for (const auto &iter : qf)
    {
      retval = iter->has_symbols (this);
      if (retval)
	break;
    }

  if (debug_symfile)
    gdb_printf (gdb_stdlog, "qf->has_symbols (%s) = %d\n",
		objfile_debug_name (this), retval);

  return retval;
}

/* See objfiles.h.  */
bool
objfile::has_unexpanded_symtabs ()
{
  if (debug_symfile)
    gdb_printf (gdb_stdlog, "qf->has_unexpanded_symtabs (%s)\n",
		objfile_debug_name (this));

  bool result = false;
  for (const auto &iter : qf)
    {
      if (iter->has_unexpanded_symtabs (this))
	{
	  result = true;
	  break;
	}
    }

  if (debug_symfile)
    gdb_printf (gdb_stdlog, "qf->has_unexpanded_symtabs (%s) = %d\n",
		objfile_debug_name (this), (result ? 1 : 0));

  return result;
}

struct symtab *
objfile::find_last_source_symtab ()
{
  struct symtab *retval = nullptr;

  if (debug_symfile)
    gdb_printf (gdb_stdlog, "qf->find_last_source_symtab (%s)\n",
		objfile_debug_name (this));

  for (const auto &iter : qf)
    {
      retval = iter->find_last_source_symtab (this);
      if (retval != nullptr)
	break;
    }

  if (debug_symfile)
    gdb_printf (gdb_stdlog, "qf->find_last_source_symtab (...) = %s\n",
		retval ? debug_symtab_name (retval) : "NULL");

  return retval;
}

void
objfile::forget_cached_source_info ()
{
  if (debug_symfile)
    gdb_printf (gdb_stdlog, "qf->forget_cached_source_info (%s)\n",
		objfile_debug_name (this));

  for (compunit_symtab &cu : compunits ())
    cu.forget_cached_source_info ();

  for (const auto &iter : qf)
    iter->forget_cached_source_info (this);
}

/* Check for a symtab of a specific name by searching some symtabs.

   If NAME is not absolute, then REAL_PATH is NULL
   If NAME is absolute, then REAL_PATH is the gdb_realpath form of NAME.

   The return value, NAME, REAL_PATH and CALLBACK are identical to the
   `map_symtabs_matching_filename' method of quick_symbol_functions.

   CUST indicates which compunit symtab to search.  Each symtab within
   the specified compunit symtab is also searched.  */

static bool
iterate_over_one_compunit_symtab (const char *name,
				  const char *real_path,
				  compunit_symtab *cust,
				  gdb::function_view<bool (symtab *)> callback)
{
  const char *base_name = lbasename (name);

  /* Skip included compunits.  */
  if (cust->user != nullptr)
    return false;

  for (symtab *s : cust->filetabs ())
    {
      if (compare_filenames_for_search (s->filename (), name))
	{
	  if (callback (s))
	    return true;
	  continue;
	}

      /* Before we invoke realpath, which can get expensive when many
	 files are involved, do a quick comparison of the basenames.  */
      if (! basenames_may_differ
	  && FILENAME_CMP (base_name, lbasename (s->filename ())) != 0)
	continue;

      if (compare_filenames_for_search (symtab_to_fullname (s), name))
	{
	  if (callback (s))
	    return true;
	  continue;
	}

      /* If the user gave us an absolute path, try to find the file in
	 this symtab and use its absolute path.  */
      if (real_path != NULL)
	{
	  const char *fullname = symtab_to_fullname (s);

	  gdb_assert (IS_ABSOLUTE_PATH (real_path));
	  gdb_assert (IS_ABSOLUTE_PATH (name));
	  gdb::unique_xmalloc_ptr<char> fullname_real_path
	    = gdb_realpath (fullname);
	  fullname = fullname_real_path.get ();
	  if (FILENAME_CMP (real_path, fullname) == 0)
	    {
	      if (callback (s))
		return true;
	      continue;
	    }
	}
    }

  return false;
}

bool
objfile::map_symtabs_matching_filename
  (const char *name, const char *real_path,
   gdb::function_view<bool (symtab *)> callback)
{
  if (debug_symfile)
    gdb_printf (gdb_stdlog,
		"qf->map_symtabs_matching_filename (%s, \"%s\", "
		"\"%s\", %s)\n",
		objfile_debug_name (this), name,
		real_path ? real_path : NULL,
		host_address_to_string (&callback));

  bool retval = false;
  const char *name_basename = lbasename (name);

  auto match_one_filename = [&] (const char *filename, bool basenames)
  {
    if (compare_filenames_for_search (filename, name))
      return true;
    if (basenames && FILENAME_CMP (name_basename, filename) == 0)
      return true;
    if (real_path != nullptr && IS_ABSOLUTE_PATH (filename)
	&& IS_ABSOLUTE_PATH (real_path))
      return filename_cmp (filename, real_path) == 0;
    return false;
  };

  auto listener = [&] (compunit_symtab *symtab)
  {
    /* CALLBACK returns false to keep going and true to continue, so
       we have to invert the result here, for search.  */
    return !iterate_over_one_compunit_symtab (name, real_path, symtab,
					      callback);
  };

  for (const auto &iter : qf)
    {
      if (!iter->search (this, match_one_filename, nullptr, nullptr,
			 listener,
			 SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
			 SEARCH_ALL_DOMAINS))
	{
	  retval = true;
	  break;
	}
    }

  if (debug_symfile)
    gdb_printf (gdb_stdlog,
		"qf->map_symtabs_matching_filename (...) = %d\n",
		retval);

  return retval;
}

struct compunit_symtab *
objfile::lookup_symbol (block_enum kind, const lookup_name_info &name,
			domain_search_flags domain)
{
  struct compunit_symtab *retval = nullptr;

  if (debug_symfile)
    gdb_printf (gdb_stdlog,
		"qf->lookup_symbol (%s, %d, \"%s\", %s)\n",
		objfile_debug_name (this), kind, name.c_str (),
		domain_name (domain).c_str ());

  auto search_one_symtab = [&] (compunit_symtab *stab)
  {
    struct symbol *sym, *with_opaque = NULL;
    const struct blockvector *bv = stab->blockvector ();
    const struct block *block = bv->block (kind);

    sym = block_find_symbol (block, name, domain, &with_opaque);

    /* Some caution must be observed with overloaded functions
       and methods, since the index will not contain any overload
       information (but NAME might contain it).  */

    if (sym != nullptr)
      {
	retval = stab;
	/* Found it.  */
	return false;
      }
    if (with_opaque != nullptr)
      retval = stab;

    /* Keep looking through other psymtabs.  */
    return true;
  };

  for (const auto &iter : qf)
    {
      if (!iter->search (this, nullptr, &name, nullptr, search_one_symtab,
			 kind == GLOBAL_BLOCK
			 ? SEARCH_GLOBAL_BLOCK
			 : SEARCH_STATIC_BLOCK,
			 domain))
	break;
    }

  if (debug_symfile)
    gdb_printf (gdb_stdlog, "qf->lookup_symbol (...) = %s\n",
		retval
		? debug_symtab_name (retval->primary_filetab ())
		: "NULL");

  return retval;
}

void
objfile::print_stats (bool print_bcache)
{
  if (debug_symfile)
    gdb_printf (gdb_stdlog, "qf->print_stats (%s, %d)\n",
		objfile_debug_name (this), print_bcache);

  for (const auto &iter : qf)
    iter->print_stats (this, print_bcache);
}

void
objfile::dump ()
{
  if (debug_symfile)
    gdb_printf (gdb_stdlog, "qf->dump (%s)\n",
		objfile_debug_name (this));

  for (const auto &iter : qf)
    iter->dump (this);
}

void
objfile::expand_all_symtabs ()
{
  if (debug_symfile)
    gdb_printf (gdb_stdlog, "qf->expand_all_symtabs (%s)\n",
		objfile_debug_name (this));

  for (const auto &iter : qf)
    iter->expand_all_symtabs (this);
}

void
objfile::expand_symtabs_with_fullname (const char *fullname)
{
  if (debug_symfile)
    gdb_printf (gdb_stdlog,
		"qf->expand_symtabs_with_fullname (%s, \"%s\")\n",
		objfile_debug_name (this), fullname);

  const char *basename = lbasename (fullname);
  auto file_matcher = [&] (const char *filename, bool basenames)
  {
    return filename_cmp (basenames ? basename : fullname, filename) == 0;
  };

  for (const auto &iter : qf)
    iter->search (this, file_matcher, nullptr, nullptr, nullptr,
		  SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
		  SEARCH_ALL_DOMAINS);
}

bool
objfile::search (search_symtabs_file_matcher file_matcher,
		 const lookup_name_info *lookup_name,
		 search_symtabs_symbol_matcher symbol_matcher,
		 search_symtabs_expansion_listener listener,
		 block_search_flags search_flags,
		 domain_search_flags domain,
		 search_symtabs_lang_matcher lang_matcher)
{
  /* This invariant is documented in quick-symbol.h.  */
  gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);

  if (debug_symfile)
    gdb_printf (gdb_stdlog,
		"qf->search (%s, %s, %s, %s, %s)\n",
		objfile_debug_name (this),
		host_address_to_string (&file_matcher),
		host_address_to_string (&symbol_matcher),
		host_address_to_string (&listener),
		domain_name (domain).c_str ());

  for (const auto &iter : qf)
    if (!iter->search (this, file_matcher, lookup_name, symbol_matcher,
		       listener, search_flags, domain, lang_matcher))
      return false;
  return true;
}

struct compunit_symtab *
objfile::find_pc_sect_compunit_symtab (bound_minimal_symbol msymbol,
				       CORE_ADDR pc,
				       struct obj_section *section,
				       int warn_if_readin)
{
  struct compunit_symtab *retval = nullptr;

  if (debug_symfile)
    gdb_printf (gdb_stdlog,
		"qf->find_pc_sect_compunit_symtab (%s, %s, %s, %s, %d)\n",
		objfile_debug_name (this),
		host_address_to_string (msymbol.minsym),
		hex_string (pc),
		host_address_to_string (section),
		warn_if_readin);

  for (const auto &iter : qf)
    {
      retval = iter->find_pc_sect_compunit_symtab (this, msymbol, pc, section,
						   warn_if_readin);
      if (retval != nullptr)
	break;
    }

  if (debug_symfile)
    gdb_printf (gdb_stdlog,
		"qf->find_pc_sect_compunit_symtab (...) = %s\n",
		retval
		? debug_symtab_name (retval->primary_filetab ())
		: "NULL");

  return retval;
}

void
objfile::map_symbol_filenames (symbol_filename_listener fun, bool need_fullname)
{
  if (debug_symfile)
    gdb_printf (gdb_stdlog,
		"qf->map_symbol_filenames (%s, ..., %d)\n",
		objfile_debug_name (this),
		need_fullname);

  for (const auto &iter : qf)
    iter->map_symbol_filenames (this, fun, need_fullname);
}

void
objfile::compute_main_name ()
{
  if (debug_symfile)
    gdb_printf (gdb_stdlog,
		"qf->compute_main_name (%s)\n",
		objfile_debug_name (this));

  for (const auto &iter : qf)
    iter->compute_main_name (this);
}

struct symbol *
objfile::find_symbol_by_address (CORE_ADDR address)
{
  if (debug_symfile)
    gdb_printf (gdb_stdlog,
		"qf->find_symbol_by_address (%s, %s)\n",
		objfile_debug_name (this),
		hex_string (address));

  struct symbol *result = NULL;
  for (const auto &iter : qf)
    {
      result = iter->find_symbol_by_address (this, address);
      if (result != nullptr)
	break;
    }

  if (debug_symfile)
    gdb_printf (gdb_stdlog,
		"qf->find_symbol_by_address (...) = %s\n",
		result
		? result->print_name ()
		: "NULL");

  return result;
}

enum language
objfile::lookup_global_symbol_language (const char *name,
					domain_search_flags domain,
					bool *symbol_found_p)
{
  enum language result = language_unknown;
  *symbol_found_p = false;

  for (const auto &iter : qf)
    {
      result = iter->lookup_global_symbol_language (this, name, domain,
						    symbol_found_p);
      if (*symbol_found_p)
	break;
    }

  return result;
}

/* Call LOOKUP_FUNC to find the filename of a file containing the separate
   debug information matching OBJFILE.  If LOOKUP_FUNC does return a
   filename then open this file and return a std::pair containing the
   gdb_bfd_ref_ptr of the open file and the filename returned by
   LOOKUP_FUNC, otherwise this function returns an empty pair; the first
   item will be nullptr, and the second will be an empty string.

   Any warnings generated by this function, or by calling LOOKUP_FUNC are
   placed into WARNINGS, these warnings are only displayed to the user if
   GDB is unable to find the separate debug information via any route.  */
static std::pair<gdb_bfd_ref_ptr, std::string>
simple_find_and_open_separate_symbol_file
  (struct objfile *objfile,
   std::string (*lookup_func) (struct objfile *, deferred_warnings *),
   deferred_warnings *warnings)
{
  std::string filename = lookup_func (objfile, warnings);

  if (!filename.empty ())
    {
      gdb_bfd_ref_ptr symfile_bfd
	= symfile_bfd_open_no_error (filename.c_str ());
      if (symfile_bfd != nullptr)
	return { symfile_bfd, filename };
    }

  return {};
}

/* Lookup separate debug information for OBJFILE via debuginfod.  If
   successful the debug information will be have been downloaded into the
   debuginfod cache and this function will return a std::pair containing a
   gdb_bfd_ref_ptr of the open debug information file and the filename for
   the file within the debuginfod cache.  If no debug information could be
   found then this function returns an empty pair; the first item will be
   nullptr, and the second will be an empty string.  */

static std::pair<gdb_bfd_ref_ptr, std::string>
debuginfod_find_and_open_separate_symbol_file (struct objfile * objfile)
{
  const struct bfd_build_id *build_id
    = build_id_bfd_get (objfile->obfd.get ());
  const char *filename = bfd_get_filename (objfile->obfd.get ());

  if (build_id != nullptr)
    {
      gdb::unique_xmalloc_ptr<char> symfile_path;
      scoped_fd fd (debuginfod_debuginfo_query (build_id->data, build_id->size,
						filename, &symfile_path));

      if (fd.get () >= 0)
	{
	  /* File successfully retrieved from server.  */
	  gdb_bfd_ref_ptr debug_bfd
	    (symfile_bfd_open_no_error (symfile_path.get ()));

	  if (debug_bfd != nullptr
	      && build_id_verify (debug_bfd.get (),
				  build_id->size, build_id->data))
	    return { debug_bfd, std::string (symfile_path.get ()) };
	}
    }

  return {};
}

/* See objfiles.h.  */

bool
objfile::find_and_add_separate_symbol_file (symfile_add_flags symfile_flags)
{
  bool has_dwarf2 = false;

  /* Usually we only make a single pass when looking for separate debug
     information.  However, it is possible for an extension language hook
     to request that GDB make a second pass, in which case max_attempts
     will be updated, and the loop restarted.  */
  for (unsigned attempt = 0, max_attempts = 1;
       attempt < max_attempts && !has_dwarf2;
       ++attempt)
    {
      gdb_assert (max_attempts <= 2);

      deferred_warnings warnings;
      gdb_bfd_ref_ptr debug_bfd;
      std::string filename;

      std::tie (debug_bfd, filename)
	= simple_find_and_open_separate_symbol_file
	    (this, find_separate_debug_file_by_buildid, &warnings);

      if (debug_bfd == nullptr)
	std::tie (debug_bfd, filename)
	  = simple_find_and_open_separate_symbol_file
	      (this, find_separate_debug_file_by_debuglink, &warnings);

      /* Only try debuginfod on the first attempt.  Sure, we could imagine
	 an extension that somehow adds the required debug info to the
	 debuginfod server but, at least for now, we don't support this
	 scenario.  Better for the extension to return new debug info
	 directly to GDB.  Plus, going to the debuginfod server might be
	 slow, so that's a good argument for only doing this once.  */
      if (debug_bfd == nullptr && attempt == 0)
	std::tie (debug_bfd, filename)
	  = debuginfod_find_and_open_separate_symbol_file (this);

      if (debug_bfd != nullptr)
	{
	  /* We found a separate debug info symbol file.  If this is our
	     first attempt then setting HAS_DWARF2 will cause us to break
	     from the attempt loop.  */
	  symbol_file_add_separate (debug_bfd, filename.c_str (),
				    symfile_flags, this);
	  has_dwarf2 = true;
	}
      else if (attempt == 0)
	{
	  /* Failed to find a separate debug info symbol file.  Call out to
	     the extension languages.  The user might have registered an
	     extension that can find the debug info for us, or maybe give
	     the user a system specific message that guides them to finding
	     the missing debug info.  */

	  ext_lang_missing_file_result ext_result
	    = ext_lang_handle_missing_debuginfo (this);
	  if (!ext_result.filename ().empty ())
	    {
	      /* Extension found a suitable debug file for us.  */
	      debug_bfd
		= symfile_bfd_open_no_error (ext_result.filename ().c_str ());

	      if (debug_bfd != nullptr)
		{
		  symbol_file_add_separate (debug_bfd,
					    ext_result.filename ().c_str (),
					    symfile_flags, this);
		  has_dwarf2 = true;
		}
	    }
	  else if (ext_result.try_again ())
	    {
	      max_attempts = 2;
	      continue;
	    }
	}

      /* If we still have not got a separate debug symbol file, then
	 emit any warnings we've collected so far.  */
      if (!has_dwarf2)
	warnings.emit ();
    }

  return has_dwarf2;
}


/* Debugging version of struct sym_probe_fns.  */

static const std::vector<std::unique_ptr<probe>> &
debug_sym_get_probes (struct objfile *objfile)
{
  const struct debug_sym_fns_data *debug_data
    = symfile_debug_objfile_data_key.get (objfile);

  const std::vector<std::unique_ptr<probe>> &retval
    = debug_data->real_sf->sym_probe_fns->sym_get_probes (objfile);

  gdb_printf (gdb_stdlog,
	      "probes->sym_get_probes (%s) = %s\n",
	      objfile_debug_name (objfile),
	      host_address_to_string (retval.data ()));

  return retval;
}

static const struct sym_probe_fns debug_sym_probe_fns =
{
  debug_sym_get_probes,
};

/* Debugging version of struct sym_fns.  */

static void
debug_sym_init (struct objfile *objfile)
{
  const struct debug_sym_fns_data *debug_data
    = symfile_debug_objfile_data_key.get (objfile);

  gdb_printf (gdb_stdlog, "sf->sym_init (%s)\n",
	      objfile_debug_name (objfile));

  debug_data->real_sf->sym_init (objfile);
}

static void
debug_sym_read (struct objfile *objfile, symfile_add_flags symfile_flags)
{
  const struct debug_sym_fns_data *debug_data
    = symfile_debug_objfile_data_key.get (objfile);

  gdb_printf (gdb_stdlog, "sf->sym_read (%s, 0x%x)\n",
	      objfile_debug_name (objfile), (unsigned) symfile_flags);

  debug_data->real_sf->sym_read (objfile, symfile_flags);
}

static void
debug_sym_offsets (struct objfile *objfile,
		   const section_addr_info &info)
{
  const struct debug_sym_fns_data *debug_data
    = symfile_debug_objfile_data_key.get (objfile);

  gdb_printf (gdb_stdlog, "sf->sym_offsets (%s, %s)\n",
	      objfile_debug_name (objfile),
	      host_address_to_string (&info));

  debug_data->real_sf->sym_offsets (objfile, info);
}

static symfile_segment_data_up
debug_sym_segments (bfd *abfd)
{
  /* This API function is annoying, it doesn't take a "this" pointer.
     Fortunately it is only used in one place where we (re-)lookup the
     sym_fns table to use.  Thus we will never be called.  */
  gdb_assert_not_reached ("debug_sym_segments called");
}

static bfd_byte *
debug_sym_relocate (struct objfile *objfile, asection *sectp, bfd_byte *buf)
{
  const struct debug_sym_fns_data *debug_data
    = symfile_debug_objfile_data_key.get (objfile);
  bfd_byte *retval;

  retval = debug_data->real_sf->sym_relocate (objfile, sectp, buf);

  gdb_printf (gdb_stdlog,
	      "sf->sym_relocate (%s, %s, %s) = %s\n",
	      objfile_debug_name (objfile),
	      host_address_to_string (sectp),
	      host_address_to_string (buf),
	      host_address_to_string (retval));

  return retval;
}

/* Install the debugging versions of the symfile functions for OBJFILE.
   Do not call this if the debug versions are already installed.  */

static void
install_symfile_debug_logging (struct objfile *objfile)
{
  const struct sym_fns *real_sf;
  struct debug_sym_fns_data *debug_data;

  /* The debug versions should not already be installed.  */
  gdb_assert (!symfile_debug_installed (objfile));

  real_sf = objfile->sf;

  /* Alas we have to preserve NULL entries in REAL_SF.  */
  debug_data = new struct debug_sym_fns_data;

#define COPY_SF_PTR(from, to, name, func)	\
  do {						\
    if ((from)->name)				\
      (to)->debug_sf.name = func;		\
  } while (0)

  COPY_SF_PTR (real_sf, debug_data, sym_init, debug_sym_init);
  COPY_SF_PTR (real_sf, debug_data, sym_read, debug_sym_read);
  COPY_SF_PTR (real_sf, debug_data, sym_offsets, debug_sym_offsets);
  COPY_SF_PTR (real_sf, debug_data, sym_segments, debug_sym_segments);
  COPY_SF_PTR (real_sf, debug_data, sym_relocate, debug_sym_relocate);
  if (real_sf->sym_probe_fns)
    debug_data->debug_sf.sym_probe_fns = &debug_sym_probe_fns;

#undef COPY_SF_PTR

  debug_data->real_sf = real_sf;
  symfile_debug_objfile_data_key.set (objfile, debug_data);
  objfile->sf = &debug_data->debug_sf;
}

/* Uninstall the debugging versions of the symfile functions for OBJFILE.
   Do not call this if the debug versions are not installed.  */

static void
uninstall_symfile_debug_logging (struct objfile *objfile)
{
  struct debug_sym_fns_data *debug_data;

  /* The debug versions should be currently installed.  */
  gdb_assert (symfile_debug_installed (objfile));

  debug_data = symfile_debug_objfile_data_key.get (objfile);

  objfile->sf = debug_data->real_sf;
  symfile_debug_objfile_data_key.clear (objfile);
}

/* Call this function to set OBJFILE->SF.
   Do not set OBJFILE->SF directly.  */

void
objfile_set_sym_fns (struct objfile *objfile, const struct sym_fns *sf)
{
  if (symfile_debug_installed (objfile))
    {
      gdb_assert (debug_symfile);
      /* Remove the current one, and reinstall a new one later.  */
      uninstall_symfile_debug_logging (objfile);
    }

  /* Assume debug logging is disabled.  */
  objfile->sf = sf;

  /* Turn debug logging on if enabled.  */
  if (debug_symfile)
    install_symfile_debug_logging (objfile);
}

static void
set_debug_symfile (const char *args, int from_tty, struct cmd_list_element *c)
{
  for (struct program_space *pspace : program_spaces)
    for (objfile &objfile : pspace->objfiles ())
      {
	if (debug_symfile)
	  {
	    if (!symfile_debug_installed (&objfile))
	      install_symfile_debug_logging (&objfile);
	  }
	else
	  {
	    if (symfile_debug_installed (&objfile))
	      uninstall_symfile_debug_logging (&objfile);
	  }
      }
}

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

INIT_GDB_FILE (symfile_debug)
{
  add_setshow_boolean_cmd ("symfile", no_class, &debug_symfile, _("\
Set debugging of the symfile functions."), _("\
Show debugging of the symfile functions."), _("\
When enabled, all calls to the symfile functions are logged."),
			   set_debug_symfile, show_debug_symfile,
			   &setdebuglist, &showdebuglist);

  /* Note: We don't need a new-objfile observer because debug logging
     will be installed when objfile init'n calls objfile_set_sym_fns.  */
}
