/* GDB routines for manipulating the minimal symbol tables.
   Copyright (C) 1992-2025 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/>.  */


/* This file contains support routines for creating, manipulating, and
   destroying minimal symbol tables.

   Minimal symbol tables are used to hold some very basic information about
   all defined global symbols (text, data, bss, abs, etc).  The only two
   required pieces of information are the symbol's name and the address
   associated with that symbol.

   In many cases, even if a file was compiled with no special options for
   debugging at all, as long as was not stripped it will contain sufficient
   information to build useful minimal symbol tables using this structure.

   Even when a file contains enough debugging information to build a full
   symbol table, these minimal symbols are still useful for quickly mapping
   between names and addresses, and vice versa.  They are also sometimes used
   to figure out what full symbol table entries need to be read in.  */


#include <ctype.h>
#include "maint.h"
#include "symtab.h"
#include "bfd.h"
#include "filenames.h"
#include "symfile.h"
#include "objfiles.h"
#include "demangle.h"
#include "value.h"
#include "cp-abi.h"
#include "target.h"
#include "cp-support.h"
#include "language.h"
#include "cli/cli-utils.h"
#include "gdbsupport/symbol.h"
#include <algorithm>
#include "gdbsupport/gdb-safe-ctype.h"
#include "gdbsupport/parallel-for.h"
#include "inferior.h"

#if CXX_STD_THREAD
#include <mutex>
#endif

/* Return true if MINSYM is a cold clone symbol.
   Recognize f.i. these symbols (mangled/demangled):
   - _ZL3foov.cold
     foo() [clone .cold]
   - _ZL9do_rpo_vnP8functionP8edge_defP11bitmap_headbb.cold.138
     do_rpo_vn(function*, edge_def*, bitmap_head*, bool, bool)	\
       [clone .cold.138].  */

static bool
msymbol_is_cold_clone (minimal_symbol *minsym)
{
  const char *name = minsym->natural_name ();
  size_t name_len = strlen (name);
  if (name_len < 1)
    return false;

  const char *last = &name[name_len - 1];
  if (*last != ']')
    return false;

  const char *suffix = " [clone .cold";
  size_t suffix_len = strlen (suffix);
  const char *found = strstr (name, suffix);
  if (found == nullptr)
    return false;

  const char *start = &found[suffix_len];
  if (*start == ']')
    return true;

  if (*start != '.')
    return false;

  const char *p;
  for (p = start + 1; p <= last; ++p)
    {
      if (*p >= '0' && *p <= '9')
	continue;
      break;
    }

  if (p == last)
    return true;

  return false;
}

/* See minsyms.h.  */

bool
msymbol_is_function (struct objfile *objfile, minimal_symbol *minsym,
		     CORE_ADDR *func_address_p)
{
  CORE_ADDR msym_addr = minsym->value_address (objfile);

  switch (minsym->type ())
    {
    case mst_slot_got_plt:
    case mst_data:
    case mst_bss:
    case mst_abs:
    case mst_file_data:
    case mst_file_bss:
    case mst_data_gnu_ifunc:
      {
	struct gdbarch *gdbarch = objfile->arch ();
	CORE_ADDR pc = gdbarch_convert_from_func_ptr_addr
	  (gdbarch, msym_addr, current_inferior ()->top_target ());
	if (pc != msym_addr)
	  {
	    if (func_address_p != NULL)
	      *func_address_p = pc;
	    return true;
	  }
	return false;
      }
    case mst_file_text:
      /* Ignore function symbol that is not a function entry.  */
      if (msymbol_is_cold_clone (minsym))
	return false;
      [[fallthrough]];
    default:
      if (func_address_p != NULL)
	*func_address_p = msym_addr;
      return true;
    }
}

/* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE.
   At the end, copy them all into one newly allocated array.  */

#define BUNCH_SIZE 127

struct msym_bunch
  {
    struct msym_bunch *next;
    struct minimal_symbol contents[BUNCH_SIZE];
  };

/* See minsyms.h.  */

unsigned int
msymbol_hash_iw (const char *string)
{
  unsigned int hash = 0;

  while (*string && *string != '(')
    {
      string = skip_spaces (string);
      if (*string && *string != '(')
	{
	  hash = SYMBOL_HASH_NEXT (hash, *string);
	  ++string;
	}
    }
  return hash;
}

/* See minsyms.h.  */

unsigned int
msymbol_hash (const char *string)
{
  unsigned int hash = 0;

  for (; *string; ++string)
    hash = SYMBOL_HASH_NEXT (hash, *string);
  return hash;
}

/* Add the minimal symbol SYM to an objfile's minsym hash table, TABLE.  */
static void
add_minsym_to_hash_table (struct minimal_symbol *sym,
			  struct minimal_symbol **table,
			  unsigned int hash_value)
{
  if (sym->hash_next == NULL)
    {
      unsigned int hash = hash_value % MINIMAL_SYMBOL_HASH_SIZE;

      sym->hash_next = table[hash];
      table[hash] = sym;
    }
}

/* Add the minimal symbol SYM to an objfile's minsym demangled hash table,
   TABLE.  */
static void
add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
				    struct objfile *objfile,
				    unsigned int hash_value)
{
  if (sym->demangled_hash_next == NULL)
    {
      objfile->per_bfd->demangled_hash_languages.set (sym->language ());

      struct minimal_symbol **table
	= objfile->per_bfd->msymbol_demangled_hash;
      unsigned int hash_index = hash_value % MINIMAL_SYMBOL_HASH_SIZE;
      sym->demangled_hash_next = table[hash_index];
      table[hash_index] = sym;
    }
}

/* Worker object for lookup_minimal_symbol.  Stores temporary results
   while walking the symbol tables.  */

struct found_minimal_symbols
{
  /* External symbols are best.  */
  bound_minimal_symbol external_symbol;

  /* File-local symbols are next best.  */
  bound_minimal_symbol file_symbol;

  /* Symbols for shared library trampolines are next best.  */
  bound_minimal_symbol trampoline_symbol;

  /* Called when a symbol name matches.  Check if the minsym is a
     better type than what we had already found, and record it in one
     of the members fields if so.  Returns true if we collected the
     real symbol, in which case we can stop searching.  */
  bool maybe_collect (const char *sfile, objfile *objf,
		      minimal_symbol *msymbol);
};

/* See declaration above.  */

bool
found_minimal_symbols::maybe_collect (const char *sfile,
				      struct objfile *objfile,
				      minimal_symbol *msymbol)
{
  switch (msymbol->type ())
    {
    case mst_file_text:
    case mst_file_data:
    case mst_file_bss:
      if (sfile == NULL
	  || filename_cmp (msymbol->filename, sfile) == 0)
	{
	  file_symbol.minsym = msymbol;
	  file_symbol.objfile = objfile;
	}
      break;

    case mst_solib_trampoline:

      /* If a trampoline symbol is found, we prefer to keep
	 looking for the *real* symbol.  If the actual symbol
	 is not found, then we'll use the trampoline
	 entry.  */
      if (trampoline_symbol.minsym == NULL)
	{
	  trampoline_symbol.minsym = msymbol;
	  trampoline_symbol.objfile = objfile;
	}
      break;

    case mst_unknown:
    default:
      external_symbol.minsym = msymbol;
      external_symbol.objfile = objfile;
      /* We have the real symbol.  No use looking further.  */
      return true;
    }

  /* Keep looking.  */
  return false;
}

/* Walk the mangled name hash table, and pass each symbol whose name
   matches LOOKUP_NAME according to NAMECMP to FOUND.  */

static void
lookup_minimal_symbol_mangled (const char *lookup_name,
			       const char *sfile,
			       struct objfile *objfile,
			       struct minimal_symbol **table,
			       unsigned int hash,
			       int (*namecmp) (const char *, const char *),
			       found_minimal_symbols &found)
{
  for (minimal_symbol *msymbol = table[hash];
       msymbol != NULL;
       msymbol = msymbol->hash_next)
    {
      const char *symbol_name = msymbol->linkage_name ();

      if (namecmp (symbol_name, lookup_name) == 0
	  && found.maybe_collect (sfile, objfile, msymbol))
	return;
    }
}

/* Walk the demangled name hash table, and pass each symbol whose name
   matches LOOKUP_NAME according to MATCHER to FOUND.  */

static void
lookup_minimal_symbol_demangled (const lookup_name_info &lookup_name,
				 const char *sfile,
				 struct objfile *objfile,
				 struct minimal_symbol **table,
				 unsigned int hash,
				 symbol_name_matcher_ftype *matcher,
				 found_minimal_symbols &found)
{
  for (minimal_symbol *msymbol = table[hash];
       msymbol != NULL;
       msymbol = msymbol->demangled_hash_next)
    {
      const char *symbol_name = msymbol->search_name ();

      if (matcher (symbol_name, lookup_name, NULL)
	  && found.maybe_collect (sfile, objfile, msymbol))
	return;
    }
}

/* Look through all the current minimal symbol tables and find the
   first minimal symbol that matches NAME.  If OBJF is non-NULL, limit
   the search to that objfile.  If SFILE is non-NULL, the only file-scope
   symbols considered will be from that source file (global symbols are
   still preferred).  Returns a pointer to the minimal symbol that
   matches, or NULL if no match is found.

   Note:  One instance where there may be duplicate minimal symbols with
   the same name is when the symbol tables for a shared library and the
   symbol tables for an executable contain global symbols with the same
   names (the dynamic linker deals with the duplication).

   It's also possible to have minimal symbols with different mangled
   names, but identical demangled names.  For example, the GNU C++ v3
   ABI requires the generation of two (or perhaps three) copies of
   constructor functions --- "in-charge", "not-in-charge", and
   "allocate" copies; destructors may be duplicated as well.
   Obviously, there must be distinct mangled names for each of these,
   but the demangled names are all the same: S::S or S::~S.  */

bound_minimal_symbol
lookup_minimal_symbol (program_space *pspace, const char *name, objfile *objf,
		       const char *sfile)
{
  found_minimal_symbols found;

  unsigned int mangled_hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;

  auto *mangled_cmp
    = (case_sensitivity == case_sensitive_on
       ? strcmp
       : strcasecmp);

  if (sfile != NULL)
    sfile = lbasename (sfile);

  lookup_name_info lookup_name (name, symbol_name_match_type::FULL);

  for (objfile *objfile : pspace->objfiles ())
    {
      if (found.external_symbol.minsym != NULL)
	break;

      if (objf == NULL || objf == objfile
	  || objf == objfile->separate_debug_objfile_backlink)
	{
	  symbol_lookup_debug_printf ("lookup_minimal_symbol (%s, %s, %s, %s)",
				      host_address_to_string (pspace),
				      name, sfile != NULL ? sfile : "NULL",
				      objfile_debug_name (objfile));

	  /* Do two passes: the first over the ordinary hash table,
	     and the second over the demangled hash table.  */
	  lookup_minimal_symbol_mangled (name, sfile, objfile,
					 objfile->per_bfd->msymbol_hash,
					 mangled_hash, mangled_cmp, found);

	  /* If not found, try the demangled hash table.  */
	  if (found.external_symbol.minsym == NULL)
	    {
	      /* Once for each language in the demangled hash names
		 table (usually just zero or one languages).  */
	      for (unsigned iter = 0; iter < nr_languages; ++iter)
		{
		  if (!objfile->per_bfd->demangled_hash_languages.test (iter))
		    continue;
		  enum language lang = (enum language) iter;

		  unsigned int hash
		    = (lookup_name.search_name_hash (lang)
		       % MINIMAL_SYMBOL_HASH_SIZE);

		  symbol_name_matcher_ftype *match
		    = language_def (lang)->get_symbol_name_matcher
							(lookup_name);
		  struct minimal_symbol **msymbol_demangled_hash
		    = objfile->per_bfd->msymbol_demangled_hash;

		  lookup_minimal_symbol_demangled (lookup_name, sfile, objfile,
						   msymbol_demangled_hash,
						   hash, match, found);

		  if (found.external_symbol.minsym != NULL)
		    break;
		}
	    }
	}
    }

  /* External symbols are best.  */
  if (found.external_symbol.minsym != NULL)
    {
      if (symbol_lookup_debug)
	{
	  minimal_symbol *minsym = found.external_symbol.minsym;

	  symbol_lookup_debug_printf
	    ("lookup_minimal_symbol (...) = %s (external)",
	     host_address_to_string (minsym));
	}
      return found.external_symbol;
    }

  /* File-local symbols are next best.  */
  if (found.file_symbol.minsym != NULL)
    {
      if (symbol_lookup_debug)
	{
	  minimal_symbol *minsym = found.file_symbol.minsym;

	  symbol_lookup_debug_printf
	    ("lookup_minimal_symbol (...) = %s (file-local)",
	     host_address_to_string (minsym));
	}
      return found.file_symbol;
    }

  /* Symbols for shared library trampolines are next best.  */
  if (found.trampoline_symbol.minsym != NULL)
    {
      if (symbol_lookup_debug)
	{
	  minimal_symbol *minsym = found.trampoline_symbol.minsym;

	  symbol_lookup_debug_printf
	    ("lookup_minimal_symbol (...) = %s (trampoline)",
	     host_address_to_string (minsym));
	}

      return found.trampoline_symbol;
    }

  /* Not found.  */
  symbol_lookup_debug_printf ("lookup_minimal_symbol (...) = NULL");
  return {};
}

/* See gdbsupport/symbol.h.  */

int
find_minimal_symbol_address (const char *name, CORE_ADDR *addr,
			     struct objfile *objfile)
{
  bound_minimal_symbol sym
    = lookup_minimal_symbol (current_program_space, name, objfile);
  if (sym.minsym != NULL)
    *addr = sym.value_address ();

  return sym.minsym == NULL;
}

/* Get the lookup name form best suitable for linkage name
   matching.  */

static const char *
linkage_name_str (const lookup_name_info &lookup_name)
{
  /* Unlike most languages (including C++), Ada uses the
     encoded/linkage name as the search name recorded in symbols.  So
     if debugging in Ada mode, prefer the Ada-encoded name.  This also
     makes Ada's verbatim match syntax ("<...>") work, because
     "lookup_name.name()" includes the "<>"s, while
     "lookup_name.ada().lookup_name()" is the encoded name with "<>"s
     stripped.  */
  if (current_language->la_language == language_ada)
    return lookup_name.ada ().lookup_name ().c_str ();

  return lookup_name.c_str ();
}

/* See minsyms.h.  */

void
iterate_over_minimal_symbols
    (struct objfile *objf, const lookup_name_info &lookup_name,
     gdb::function_view<bool (struct minimal_symbol *)> callback)
{
  /* The first pass is over the ordinary hash table.  */
    {
      const char *name = linkage_name_str (lookup_name);
      unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
      auto *mangled_cmp
	= (case_sensitivity == case_sensitive_on
	   ? strcmp
	   : strcasecmp);

      for (minimal_symbol *iter = objf->per_bfd->msymbol_hash[hash];
	   iter != NULL;
	   iter = iter->hash_next)
	{
	  if (mangled_cmp (iter->linkage_name (), name) == 0)
	    if (callback (iter))
	      return;
	}
    }

  /* The second pass is over the demangled table.  Once for each
     language in the demangled hash names table (usually just zero or
     one).  */
  for (unsigned liter = 0; liter < nr_languages; ++liter)
    {
      if (!objf->per_bfd->demangled_hash_languages.test (liter))
	continue;

      enum language lang = (enum language) liter;
      const language_defn *lang_def = language_def (lang);
      symbol_name_matcher_ftype *name_match
	= lang_def->get_symbol_name_matcher (lookup_name);

      unsigned int hash
	= lookup_name.search_name_hash (lang) % MINIMAL_SYMBOL_HASH_SIZE;
      for (minimal_symbol *iter = objf->per_bfd->msymbol_demangled_hash[hash];
	   iter != NULL;
	   iter = iter->demangled_hash_next)
	if (name_match (iter->search_name (), lookup_name, NULL))
	  if (callback (iter))
	    return;
    }
}

/* See minsyms.h.  */

bound_minimal_symbol
lookup_minimal_symbol_linkage (const char *name, struct objfile *objf,
			       bool match_static_type)
{
  unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;

  for (objfile *objfile : objf->separate_debug_objfiles ())
    {
      for (minimal_symbol *msymbol = objfile->per_bfd->msymbol_hash[hash];
	   msymbol != NULL;
	   msymbol = msymbol->hash_next)
	{
	  if (strcmp (msymbol->linkage_name (), name) == 0
	      && (msymbol->type () == mst_data
		  || msymbol->type () == mst_bss
		  || (match_static_type
		      && (msymbol->type () == mst_file_data
			  || msymbol->type () == mst_file_bss))))
	    return {msymbol, objfile};
	}
    }

  return {};
}

/* See minsyms.h.  */

bound_minimal_symbol
lookup_minimal_symbol_linkage (program_space *pspace, const char *name,
			       bool match_static_type, bool only_main)
{
  for (objfile *objfile : pspace->objfiles ())
    {
      if (objfile->separate_debug_objfile_backlink != nullptr)
	continue;

      if (only_main && (objfile->flags & OBJF_MAINLINE) == 0)
	continue;

      bound_minimal_symbol minsym
	= lookup_minimal_symbol_linkage (name, objfile, match_static_type);
      if (minsym.minsym != nullptr)
	return minsym;
    }

  return {};
}

/* See minsyms.h.  */

bound_minimal_symbol
lookup_minimal_symbol_text (program_space *pspace, const char *name,
			    objfile *objf)
{
  struct minimal_symbol *msymbol;
  bound_minimal_symbol found_symbol;
  bound_minimal_symbol found_file_symbol;

  unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;

  auto search = [&] (struct objfile *objfile)
  {
    for (msymbol = objfile->per_bfd->msymbol_hash[hash];
	 msymbol != NULL && found_symbol.minsym == NULL;
	 msymbol = msymbol->hash_next)
      {
	if (strcmp (msymbol->linkage_name (), name) == 0 &&
	    (msymbol->type () == mst_text
	     || msymbol->type () == mst_text_gnu_ifunc
	     || msymbol->type () == mst_file_text))
	  {
	    switch (msymbol->type ())
	      {
	      case mst_file_text:
		found_file_symbol.minsym = msymbol;
		found_file_symbol.objfile = objfile;
		break;
	      default:
		found_symbol.minsym = msymbol;
		found_symbol.objfile = objfile;
		break;
	      }
	  }
      }
  };

  if (objf == nullptr)
    {
      for (objfile *objfile : pspace->objfiles ())
	{
	  if (found_symbol.minsym != NULL)
	    break;
	  search (objfile);
	}
    }
  else
    {
      for (objfile *objfile : objf->separate_debug_objfiles ())
	{
	  if (found_symbol.minsym != NULL)
	    break;
	  search (objfile);
	}
    }

  /* External symbols are best.  */
  if (found_symbol.minsym)
    return found_symbol;

  /* File-local symbols are next best.  */
  return found_file_symbol;
}

/* See minsyms.h.  */

struct minimal_symbol *
lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name,
				  struct objfile *objf)
{
  struct minimal_symbol *msymbol;

  unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;

  for (objfile *objfile : current_program_space->objfiles ())
    {
      if (objf == NULL || objf == objfile
	  || objf == objfile->separate_debug_objfile_backlink)
	{
	  for (msymbol = objfile->per_bfd->msymbol_hash[hash];
	       msymbol != NULL;
	       msymbol = msymbol->hash_next)
	    {
	      if (msymbol->value_address (objfile) == pc
		  && strcmp (msymbol->linkage_name (), name) == 0)
		return msymbol;
	    }
	}
    }

  return NULL;
}

/* A helper function that makes *PC section-relative.  This searches
   the sections of OBJFILE and if *PC is in a section, it subtracts
   the section offset, stores the result into UNREL_ADDR, and returns
   true.  Otherwise it returns false.  */

static int
frob_address (struct objfile *objfile, CORE_ADDR pc,
	      unrelocated_addr *unrel_addr)
{
  for (obj_section *iter : objfile->sections ())
    {
      if (iter->contains (pc))
	{
	  *unrel_addr = unrelocated_addr (pc - iter->offset ());
	  return 1;
	}
    }

  return 0;
}

/* Helper for lookup_minimal_symbol_by_pc_section.  Convert a
   lookup_msym_prefer to a minimal_symbol_type.  */

static minimal_symbol_type
msym_prefer_to_msym_type (lookup_msym_prefer prefer)
{
  switch (prefer)
    {
    case lookup_msym_prefer::TEXT:
      return mst_text;
    case lookup_msym_prefer::TRAMPOLINE:
      return mst_solib_trampoline;
    case lookup_msym_prefer::GNU_IFUNC:
      return mst_text_gnu_ifunc;
    }

  /* Assert here instead of in a default switch case above so that
     -Wswitch warns if a new enumerator is added.  */
  gdb_assert_not_reached ("unhandled lookup_msym_prefer");
}

/* See minsyms.h.

   Note that we need to look through ALL the minimal symbol tables
   before deciding on the symbol that comes closest to the specified PC.
   This is because objfiles can overlap, for example objfile A has .text
   at 0x100 and .data at 0x40000 and objfile B has .text at 0x234 and
   .data at 0x40048.  */

bound_minimal_symbol
lookup_minimal_symbol_by_pc_section (CORE_ADDR pc_in, struct obj_section *section,
				     lookup_msym_prefer prefer,
				     bound_minimal_symbol *previous)
{
  int lo;
  int hi;
  int newobj;
  struct minimal_symbol *msymbol;
  struct minimal_symbol *best_symbol = NULL;
  struct objfile *best_objfile = NULL;

  if (previous != nullptr)
    {
      previous->minsym = nullptr;
      previous->objfile = nullptr;
    }

  if (section == NULL)
    {
      section = find_pc_section (pc_in);
      if (section == NULL)
	return {};
    }

  minimal_symbol_type want_type = msym_prefer_to_msym_type (prefer);

  /* We can not require the symbol found to be in section, because
     e.g. IRIX 6.5 mdebug relies on this code returning an absolute
     symbol - but find_pc_section won't return an absolute section and
     hence the code below would skip over absolute symbols.  We can
     still take advantage of the call to find_pc_section, though - the
     object file still must match.  In case we have separate debug
     files, search both the file and its separate debug file.  There's
     no telling which one will have the minimal symbols.  */

  gdb_assert (section != NULL);

  for (objfile *objfile : section->objfile->separate_debug_objfiles ())
    {
      CORE_ADDR pc = pc_in;

      /* If this objfile has a minimal symbol table, go search it
	 using a binary search.  */

      if (objfile->per_bfd->minimal_symbol_count > 0)
	{
	  int best_zero_sized = -1;

	  msymbol = objfile->per_bfd->msymbols.get ();
	  lo = 0;
	  hi = objfile->per_bfd->minimal_symbol_count - 1;

	  /* This code assumes that the minimal symbols are sorted by
	     ascending address values.  If the pc value is greater than or
	     equal to the first symbol's address, then some symbol in this
	     minimal symbol table is a suitable candidate for being the
	     "best" symbol.  This includes the last real symbol, for cases
	     where the pc value is larger than any address in this vector.

	     By iterating until the address associated with the current
	     hi index (the endpoint of the test interval) is less than
	     or equal to the desired pc value, we accomplish two things:
	     (1) the case where the pc value is larger than any minimal
	     symbol address is trivially solved, (2) the address associated
	     with the hi index is always the one we want when the iteration
	     terminates.  In essence, we are iterating the test interval
	     down until the pc value is pushed out of it from the high end.

	     Warning: this code is trickier than it would appear at first.  */

	  unrelocated_addr unrel_pc;
	  if (frob_address (objfile, pc, &unrel_pc)
	      && unrel_pc >= msymbol[lo].unrelocated_address ())
	    {
	      while (msymbol[hi].unrelocated_address () > unrel_pc)
		{
		  /* pc is still strictly less than highest address.  */
		  /* Note "new" will always be >= lo.  */
		  newobj = (lo + hi) / 2;
		  if ((msymbol[newobj].unrelocated_address () >= unrel_pc)
		      || (lo == newobj))
		    {
		      hi = newobj;
		    }
		  else
		    {
		      lo = newobj;
		    }
		}

	      /* If we have multiple symbols at the same address, we want
		 hi to point to the last one.  That way we can find the
		 right symbol if it has an index greater than hi.  */
	      while (hi < objfile->per_bfd->minimal_symbol_count - 1
		     && (msymbol[hi].unrelocated_address ()
			 == msymbol[hi + 1].unrelocated_address ()))
		hi++;

	      /* Skip various undesirable symbols.  */
	      while (hi >= 0)
		{
		  /* Skip any absolute symbols.  This is apparently
		     what adb and dbx do, and is needed for the CM-5.
		     There are two known possible problems: (1) on
		     ELF, apparently end, edata, etc. are absolute.
		     Not sure ignoring them here is a big deal, but if
		     we want to use them, the fix would go in
		     elfread.c.  (2) I think shared library entry
		     points on the NeXT are absolute.  If we want
		     special handling for this it probably should be
		     triggered by a special mst_abs_or_lib or some
		     such.  */

		  if (msymbol[hi].type () == mst_abs)
		    {
		      hi--;
		      continue;
		    }

		  /* If SECTION was specified, skip any symbol from
		     wrong section.  */
		  if (section
		      /* Some types of debug info, such as COFF,
			 don't fill the bfd_section member, so don't
			 throw away symbols on those platforms.  */
		      && msymbol[hi].obj_section (objfile) != nullptr
		      && (!matching_obj_sections
			  (msymbol[hi].obj_section (objfile),
			   section)))
		    {
		      hi--;
		      continue;
		    }

		  /* If we are looking for a trampoline and this is a
		     text symbol, or the other way around, check the
		     preceding symbol too.  If they are otherwise
		     identical prefer that one.  */
		  if (hi > 0
		      && msymbol[hi].type () != want_type
		      && msymbol[hi - 1].type () == want_type
		      && (msymbol[hi].size () == msymbol[hi - 1].size ())
		      && (msymbol[hi].unrelocated_address ()
			  == msymbol[hi - 1].unrelocated_address ())
		      && (msymbol[hi].obj_section (objfile)
			  == msymbol[hi - 1].obj_section (objfile)))
		    {
		      hi--;
		      continue;
		    }

		  /* If the minimal symbol has a zero size, save it
		     but keep scanning backwards looking for one with
		     a non-zero size.  A zero size may mean that the
		     symbol isn't an object or function (e.g. a
		     label), or it may just mean that the size was not
		     specified.  */
		  if (msymbol[hi].size () == 0)
		    {
		      if (best_zero_sized == -1)
			best_zero_sized = hi;
		      hi--;
		      continue;
		    }

		  /* If we are past the end of the current symbol, try
		     the previous symbol if it has a larger overlapping
		     size.  This happens on i686-pc-linux-gnu with glibc;
		     the nocancel variants of system calls are inside
		     the cancellable variants, but both have sizes.  */
		  if (hi > 0
		      && msymbol[hi].size () != 0
		      && unrel_pc >= msymbol[hi].unrelocated_end_address ()
		      && unrel_pc < msymbol[hi - 1].unrelocated_end_address ())
		    {
		      hi--;
		      continue;
		    }

		  /* Otherwise, this symbol must be as good as we're going
		     to get.  */
		  break;
		}

	      /* If HI has a zero size, and best_zero_sized is set,
		 then we had two or more zero-sized symbols; prefer
		 the first one we found (which may have a higher
		 address).  Also, if we ran off the end, be sure
		 to back up.  */
	      if (best_zero_sized != -1
		  && (hi < 0 || msymbol[hi].size () == 0))
		hi = best_zero_sized;

	      /* If the minimal symbol has a non-zero size, and this
		 PC appears to be outside the symbol's contents, then
		 refuse to use this symbol.  If we found a zero-sized
		 symbol with an address greater than this symbol's,
		 use that instead.  We assume that if symbols have
		 specified sizes, they do not overlap.  */

	      if (hi >= 0
		  && msymbol[hi].size () != 0
		  && unrel_pc >= msymbol[hi].unrelocated_end_address ())
		{
		  if (best_zero_sized != -1)
		    hi = best_zero_sized;
		  else
		    {
		      /* If needed record this symbol as the closest
			 previous symbol.  */
		      if (previous != nullptr)
			{
			  if (previous->minsym == nullptr
			      || (msymbol[hi].unrelocated_address ()
				  > previous->minsym->unrelocated_address ()))
			    {
			      previous->minsym = &msymbol[hi];
			      previous->objfile = objfile;
			    }
			}
		      /* Go on to the next object file.  */
		      continue;
		    }
		}

	      /* The minimal symbol indexed by hi now is the best one in this
		 objfile's minimal symbol table.  See if it is the best one
		 overall.  */

	      if (hi >= 0
		  && ((best_symbol == NULL) ||
		      (best_symbol->unrelocated_address () <
		       msymbol[hi].unrelocated_address ())))
		{
		  best_symbol = &msymbol[hi];
		  best_objfile = objfile;
		}
	    }
	}
    }

  bound_minimal_symbol result;
  result.minsym = best_symbol;
  result.objfile = best_objfile;
  return result;
}

/* See minsyms.h.  */

bound_minimal_symbol
lookup_minimal_symbol_by_pc (CORE_ADDR pc)
{
  return lookup_minimal_symbol_by_pc_section (pc, NULL);
}

/* Return non-zero iff PC is in an STT_GNU_IFUNC function resolver.  */

bool
in_gnu_ifunc_stub (CORE_ADDR pc)
{
  bound_minimal_symbol msymbol
    = lookup_minimal_symbol_by_pc_section (pc, NULL,
					   lookup_msym_prefer::GNU_IFUNC);
  return msymbol.minsym && msymbol.minsym->type () == mst_text_gnu_ifunc;
}

/* See elf_gnu_ifunc_resolve_addr for its real implementation.  */

static CORE_ADDR
stub_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  error (_("GDB cannot resolve STT_GNU_IFUNC symbol at address %s without "
	   "the ELF support compiled in."),
	 paddress (gdbarch, pc));
}

/* See elf_gnu_ifunc_resolve_name for its real implementation.  */

static bool
stub_gnu_ifunc_resolve_name (const char *function_name,
			     CORE_ADDR *function_address_p)
{
  error (_("GDB cannot resolve STT_GNU_IFUNC symbol \"%s\" without "
	   "the ELF support compiled in."),
	 function_name);
}

/* See elf_gnu_ifunc_resolver_stop for its real implementation.  */

static void
stub_gnu_ifunc_resolver_stop (code_breakpoint *b)
{
  internal_error (_("elf_gnu_ifunc_resolver_stop cannot be reached."));
}

/* See elf_gnu_ifunc_resolver_return_stop for its real implementation.  */

static void
stub_gnu_ifunc_resolver_return_stop (code_breakpoint *b)
{
  internal_error (_("elf_gnu_ifunc_resolver_return_stop cannot be reached."));
}

/* See elf_gnu_ifunc_fns for its real implementation.  */

static const struct gnu_ifunc_fns stub_gnu_ifunc_fns =
{
  stub_gnu_ifunc_resolve_addr,
  stub_gnu_ifunc_resolve_name,
  stub_gnu_ifunc_resolver_stop,
  stub_gnu_ifunc_resolver_return_stop,
};

/* A placeholder for &elf_gnu_ifunc_fns.  */

const struct gnu_ifunc_fns *gnu_ifunc_fns_p = &stub_gnu_ifunc_fns;



/* Return the leading symbol character for BFD ABFD.  If ABFD is nullptr,
   return the leading symbol character from the the main objfile of PSPACE..  */

static int
get_symbol_leading_char (program_space *pspace, bfd *abfd)
{
  if (abfd != NULL)
    return bfd_get_symbol_leading_char (abfd);

  if (objfile *objf = pspace->symfile_object_file;
      objf != nullptr && objf->obfd != nullptr)
    return bfd_get_symbol_leading_char (objf->obfd.get ());

  return 0;
}

/* See minsyms.h.  */

minimal_symbol_reader::minimal_symbol_reader (struct objfile *obj)
: m_objfile (obj),
  m_msym_bunch (NULL),
  /* Note that presetting m_msym_bunch_index to BUNCH_SIZE causes the
     first call to save a minimal symbol to allocate the memory for
     the first bunch.  */
  m_msym_bunch_index (BUNCH_SIZE),
  m_msym_count (0)
{
}

/* Discard the currently collected minimal symbols, if any.  If we wish
   to save them for later use, we must have already copied them somewhere
   else before calling this function.  */

minimal_symbol_reader::~minimal_symbol_reader ()
{
  struct msym_bunch *next;

  while (m_msym_bunch != NULL)
    {
      next = m_msym_bunch->next;
      xfree (m_msym_bunch);
      m_msym_bunch = next;
    }
}

/* See minsyms.h.  */

void
minimal_symbol_reader::record (const char *name, unrelocated_addr address,
			       enum minimal_symbol_type ms_type)
{
  int section;

  switch (ms_type)
    {
    case mst_text:
    case mst_text_gnu_ifunc:
    case mst_file_text:
    case mst_solib_trampoline:
      section = SECT_OFF_TEXT (m_objfile);
      break;
    case mst_data:
    case mst_data_gnu_ifunc:
    case mst_file_data:
      section = SECT_OFF_DATA (m_objfile);
      break;
    case mst_bss:
    case mst_file_bss:
      section = SECT_OFF_BSS (m_objfile);
      break;
    default:
      section = -1;
    }

  record_with_info (name, address, ms_type, section);
}

/* Convert an enumerator of type minimal_symbol_type to its string
   representation.  */

static const char *
mst_str (minimal_symbol_type t)
{
#define MST_TO_STR(x) case x: return #x;
  switch (t)
  {
    MST_TO_STR (mst_unknown);
    MST_TO_STR (mst_text);
    MST_TO_STR (mst_text_gnu_ifunc);
    MST_TO_STR (mst_slot_got_plt);
    MST_TO_STR (mst_data);
    MST_TO_STR (mst_bss);
    MST_TO_STR (mst_abs);
    MST_TO_STR (mst_solib_trampoline);
    MST_TO_STR (mst_file_text);
    MST_TO_STR (mst_file_data);
    MST_TO_STR (mst_file_bss);

    default:
      return "mst_???";
  }
#undef MST_TO_STR
}

/* See minsyms.h.  */

struct minimal_symbol *
minimal_symbol_reader::record_full (std::string_view name,
				    bool copy_name, unrelocated_addr address,
				    enum minimal_symbol_type ms_type,
				    int section)
{
  struct msym_bunch *newobj;
  struct minimal_symbol *msymbol;

  /* Don't put gcc_compiled, __gnu_compiled_cplus, and friends into
     the minimal symbols, because if there is also another symbol
     at the same address (e.g. the first function of the file),
     lookup_minimal_symbol_by_pc would have no way of getting the
     right one.  */
  if (ms_type == mst_file_text && name[0] == 'g'
      && (name == GCC_COMPILED_FLAG_SYMBOL
	  || name == GCC2_COMPILED_FLAG_SYMBOL))
    return (NULL);

  /* It's safe to strip the leading char here once, since the name
     is also stored stripped in the minimal symbol table.  */
  if (name[0] == get_symbol_leading_char (m_objfile->pspace (),
					  m_objfile->obfd.get ()))
    name = name.substr (1);

  if (ms_type == mst_file_text && startswith (name, "__gnu_compiled"))
    return (NULL);

  symtab_create_debug_printf_v ("recording minsym:  %-21s  %18s  %4d  %.*s",
				mst_str (ms_type),
				hex_string (LONGEST (address)),
				section, (int) name.size (), name.data ());

  if (m_msym_bunch_index == BUNCH_SIZE)
    {
      newobj = XCNEW (struct msym_bunch);
      m_msym_bunch_index = 0;
      newobj->next = m_msym_bunch;
      m_msym_bunch = newobj;
    }
  msymbol = &m_msym_bunch->contents[m_msym_bunch_index];
  msymbol->set_language (language_unknown,
			 &m_objfile->per_bfd->storage_obstack);

  if (copy_name)
    msymbol->m_name = obstack_strndup (&m_objfile->per_bfd->storage_obstack,
				       name.data (), name.size ());
  else
    msymbol->m_name = name.data ();

  msymbol->set_unrelocated_address (address);
  msymbol->set_section_index (section);

  msymbol->set_type (ms_type);

  /* If we already read minimal symbols for this objfile, then don't
     ever allocate a new one.  */
  if (!m_objfile->per_bfd->minsyms_read)
    {
      m_msym_bunch_index++;
      m_objfile->per_bfd->n_minsyms++;
    }
  m_msym_count++;
  return msymbol;
}

/* Compare two minimal symbols by address and return true if FN1's address
   is less than FN2's, so that we sort into unsigned numeric order.
   Within groups with the same address, sort by name.  */

static inline bool
minimal_symbol_is_less_than (const minimal_symbol &fn1,
			     const minimal_symbol &fn2)
{
  if ((&fn1)->unrelocated_address () < (&fn2)->unrelocated_address ())
    {
      return true;		/* addr 1 is less than addr 2.  */
    }
  else if ((&fn1)->unrelocated_address () > (&fn2)->unrelocated_address ())
    {
      return false;		/* addr 1 is greater than addr 2.  */
    }
  else
    /* addrs are equal: sort by name */
    {
      const char *name1 = fn1.linkage_name ();
      const char *name2 = fn2.linkage_name ();

      if (name1 && name2)	/* both have names */
	return strcmp (name1, name2) < 0;
      else if (name2)
	return true;		/* fn1 has no name, so it is "less".  */
      else if (name1)		/* fn2 has no name, so it is "less".  */
	return false;
      else
	return false;		/* Neither has a name, so they're equal.  */
    }
}

/* Compact duplicate entries out of a minimal symbol table by walking
   through the table and compacting out entries with duplicate addresses
   and matching names.  Return the number of entries remaining.

   On entry, the table resides between msymbol[0] and msymbol[mcount].
   On exit, it resides between msymbol[0] and msymbol[result_count].

   When files contain multiple sources of symbol information, it is
   possible for the minimal symbol table to contain many duplicate entries.
   As an example, SVR4 systems use ELF formatted object files, which
   usually contain at least two different types of symbol tables (a
   standard ELF one and a smaller dynamic linking table), as well as
   DWARF debugging information for files compiled with -g.

   Without compacting, the minimal symbol table for gdb itself contains
   over a 1000 duplicates, about a third of the total table size.  Aside
   from the potential trap of not noticing that two successive entries
   identify the same location, this duplication impacts the time required
   to linearly scan the table, which is done in a number of places.  So we
   just do one linear scan here and toss out the duplicates.

   Since the different sources of information for each symbol may
   have different levels of "completeness", we may have duplicates
   that have one entry with type "mst_unknown" and the other with a
   known type.  So if the one we are leaving alone has type mst_unknown,
   overwrite its type with the type from the one we are compacting out.  */

static int
compact_minimal_symbols (struct minimal_symbol *msymbol, int mcount,
			 struct objfile *objfile)
{
  struct minimal_symbol *copyfrom;
  struct minimal_symbol *copyto;

  if (mcount > 0)
    {
      copyfrom = copyto = msymbol;
      while (copyfrom < msymbol + mcount - 1)
	{
	  if (copyfrom->unrelocated_address ()
	      == (copyfrom + 1)->unrelocated_address ()
	      && (copyfrom->section_index ()
		  == (copyfrom + 1)->section_index ())
	      && strcmp (copyfrom->linkage_name (),
			 (copyfrom + 1)->linkage_name ()) == 0)
	    {
	      if ((copyfrom + 1)->type () == mst_unknown)
		(copyfrom + 1)->set_type (copyfrom->type ());

	      copyfrom++;
	    }
	  else
	    *copyto++ = *copyfrom++;
	}
      *copyto++ = *copyfrom++;
      mcount = copyto - msymbol;
    }
  return (mcount);
}

static void
clear_minimal_symbol_hash_tables (struct objfile *objfile)
{
  for (size_t i = 0; i < MINIMAL_SYMBOL_HASH_SIZE; i++)
    {
      objfile->per_bfd->msymbol_hash[i] = 0;
      objfile->per_bfd->msymbol_demangled_hash[i] = 0;
    }
}

/* This struct is used to store values we compute for msymbols on the
   background threads but don't need to keep around long term.  */
struct computed_hash_values
{
  /* Length of the linkage_name of the symbol.  */
  size_t name_length;
  /* Hash code (using fast_hash) of the linkage_name.  */
  hashval_t mangled_name_hash;
  /* The msymbol_hash of the linkage_name.  */
  unsigned int minsym_hash;
  /* The msymbol_hash of the search_name.  */
  unsigned int minsym_demangled_hash;
};

/* Build (or rebuild) the minimal symbol hash tables.  This is necessary
   after compacting or sorting the table since the entries move around
   thus causing the internal minimal_symbol pointers to become jumbled.  */
  
static void
build_minimal_symbol_hash_tables
  (struct objfile *objfile,
   const std::vector<computed_hash_values>& hash_values)
{
  int i;
  struct minimal_symbol *msym;

  /* (Re)insert the actual entries.  */
  int mcount = objfile->per_bfd->minimal_symbol_count;
  for ((i = 0,
	msym = objfile->per_bfd->msymbols.get ());
       i < mcount;
       i++, msym++)
    {
      msym->hash_next = 0;
      add_minsym_to_hash_table (msym, objfile->per_bfd->msymbol_hash,
				hash_values[i].minsym_hash);

      msym->demangled_hash_next = 0;
      if (msym->search_name () != msym->linkage_name ())
	add_minsym_to_demangled_hash_table
	  (msym, objfile, hash_values[i].minsym_demangled_hash);
    }
}

/* Add the minimal symbols in the existing bunches to the objfile's official
   minimal symbol table.  In most cases there is no minimal symbol table yet
   for this objfile, and the existing bunches are used to create one.  Once
   in a while (for shared libraries for example), we add symbols (e.g. common
   symbols) to an existing objfile.  */

void
minimal_symbol_reader::install ()
{
  int mcount;
  struct msym_bunch *bunch;
  struct minimal_symbol *msymbols;
  int alloc_count;

  if (m_objfile->per_bfd->minsyms_read)
    return;

  if (m_msym_count > 0)
    {
      symtab_create_debug_printf ("installing %d minimal symbols of objfile %s",
				  m_msym_count, objfile_name (m_objfile));

      /* Allocate enough space, into which we will gather the bunches
	 of new and existing minimal symbols, sort them, and then
	 compact out the duplicate entries.  Once we have a final
	 table, we will give back the excess space.  */

      alloc_count = m_msym_count + m_objfile->per_bfd->minimal_symbol_count;
      gdb::unique_xmalloc_ptr<minimal_symbol>
	msym_holder (XNEWVEC (minimal_symbol, alloc_count));
      msymbols = msym_holder.get ();

      /* Copy in the existing minimal symbols, if there are any.  */

      if (m_objfile->per_bfd->minimal_symbol_count)
	memcpy (msymbols, m_objfile->per_bfd->msymbols.get (),
		m_objfile->per_bfd->minimal_symbol_count
		* sizeof (struct minimal_symbol));

      /* Walk through the list of minimal symbol bunches, adding each symbol
	 to the new contiguous array of symbols.  Note that we start with the
	 current, possibly partially filled bunch (thus we use the current
	 msym_bunch_index for the first bunch we copy over), and thereafter
	 each bunch is full.  */

      mcount = m_objfile->per_bfd->minimal_symbol_count;

      for (bunch = m_msym_bunch; bunch != NULL; bunch = bunch->next)
	{
	  memcpy (&msymbols[mcount], &bunch->contents[0],
		  m_msym_bunch_index * sizeof (struct minimal_symbol));
	  mcount += m_msym_bunch_index;
	  m_msym_bunch_index = BUNCH_SIZE;
	}

      /* Sort the minimal symbols by address.  */

      std::sort (msymbols, msymbols + mcount, minimal_symbol_is_less_than);

      /* Compact out any duplicates, and free up whatever space we are
	 no longer using.  */

      mcount = compact_minimal_symbols (msymbols, mcount, m_objfile);
      msym_holder.reset (XRESIZEVEC (struct minimal_symbol,
				     msym_holder.release (),
				     mcount));

      /* Attach the minimal symbol table to the specified objfile.
	 The strings themselves are also located in the storage_obstack
	 of this objfile.  */

      if (m_objfile->per_bfd->minimal_symbol_count != 0)
	clear_minimal_symbol_hash_tables (m_objfile);

      m_objfile->per_bfd->minimal_symbol_count = mcount;
      m_objfile->per_bfd->msymbols = std::move (msym_holder);

#if CXX_STD_THREAD
      /* Mutex that is used when modifying or accessing the demangled
	 hash table.  */
      std::mutex demangled_mutex;
#endif

      std::vector<computed_hash_values> hash_values (mcount);

      msymbols = m_objfile->per_bfd->msymbols.get ();
      /* Arbitrarily require at least 10 elements in a thread.  */
      gdb::parallel_for_each<10> (&msymbols[0], &msymbols[mcount],
	 [&] (minimal_symbol *start, minimal_symbol *end)
	 {
	   scoped_time_it time_it ("minsyms install worker");

	   for (minimal_symbol *msym = start; msym < end; ++msym)
	     {
	       size_t idx = msym - msymbols;
	       hash_values[idx].name_length = strlen (msym->linkage_name ());
	       if (!msym->name_set)
		 {
		   /* This will be freed later, by compute_and_set_names.  */
		   gdb::unique_xmalloc_ptr<char> demangled_name
		     = symbol_find_demangled_name (msym, msym->linkage_name ());
		   msym->set_demangled_name
		     (demangled_name.release (),
		      &m_objfile->per_bfd->storage_obstack);
		   msym->name_set = 1;
		 }
	       /* This mangled_name_hash computation has to be outside of
		  the name_set check, or compute_and_set_names below will
		  be called with an invalid hash value.  */
	       hash_values[idx].mangled_name_hash
		 = fast_hash (msym->linkage_name (),
			      hash_values[idx].name_length);
	       hash_values[idx].minsym_hash
		 = msymbol_hash (msym->linkage_name ());
	       /* We only use this hash code if the search name differs
		  from the linkage name.  See the code in
		  build_minimal_symbol_hash_tables.  */
	       if (msym->search_name () != msym->linkage_name ())
		 hash_values[idx].minsym_demangled_hash
		   = search_name_hash (msym->language (), msym->search_name ());
	     }
	   {
	     /* To limit how long we hold the lock, we only acquire it here
		and not while we demangle the names above.  */
#if CXX_STD_THREAD
	     std::lock_guard<std::mutex> guard (demangled_mutex);
#endif
	     for (minimal_symbol *msym = start; msym < end; ++msym)
	       {
		 size_t idx = msym - msymbols;
		 msym->compute_and_set_names
		   (std::string_view (msym->linkage_name (),
				      hash_values[idx].name_length),
		    false,
		    m_objfile->per_bfd,
		    hash_values[idx].mangled_name_hash);
	       }
	   }
	 });

      build_minimal_symbol_hash_tables (m_objfile, hash_values);
    }
}

/* Check if PC is in a shared library trampoline code stub.
   Return minimal symbol for the trampoline entry or NULL if PC is not
   in a trampoline code stub.  */

static struct minimal_symbol *
lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc)
{
  bound_minimal_symbol msymbol
    = lookup_minimal_symbol_by_pc_section (pc, NULL,
					   lookup_msym_prefer::TRAMPOLINE);

  if (msymbol.minsym != NULL
      && msymbol.minsym->type () == mst_solib_trampoline)
    return msymbol.minsym;
  return NULL;
}

/* If PC is in a shared library trampoline code stub, return the
   address of the `real' function belonging to the stub.
   Return 0 if PC is not in a trampoline code stub or if the real
   function is not found in the minimal symbol table.

   We may fail to find the right function if a function with the
   same name is defined in more than one shared library, but this
   is considered bad programming style.  We could return 0 if we find
   a duplicate function in case this matters someday.  */

CORE_ADDR
find_solib_trampoline_target (const frame_info_ptr &frame, CORE_ADDR pc)
{
  struct minimal_symbol *tsymbol = lookup_solib_trampoline_symbol_by_pc (pc);

  if (tsymbol != NULL)
    {
      for (objfile *objfile : current_program_space->objfiles ())
	{
	  for (minimal_symbol *msymbol : objfile->msymbols ())
	    {
	      /* Also handle minimal symbols pointing to function
		 descriptors.  */
	      if ((msymbol->type () == mst_text
		   || msymbol->type () == mst_text_gnu_ifunc
		   || msymbol->type () == mst_data
		   || msymbol->type () == mst_data_gnu_ifunc)
		  && strcmp (msymbol->linkage_name (),
			     tsymbol->linkage_name ()) == 0)
		{
		  CORE_ADDR func;

		  /* Ignore data symbols that are not function
		     descriptors.  */
		  if (msymbol_is_function (objfile, msymbol, &func))
		    return func;
		}
	    }
	}
    }
  return 0;
}

/* See minsyms.h.  */

CORE_ADDR
minimal_symbol_upper_bound (bound_minimal_symbol minsym)
{
  struct obj_section *obj_section;
  CORE_ADDR result;
  struct minimal_symbol *iter, *msymbol;

  gdb_assert (minsym.minsym != NULL);

  /* If the minimal symbol has a size, use it.  Otherwise use the
     lesser of the next minimal symbol in the same section, or the end
     of the section, as the end of the function.  */

  if (minsym.minsym->size () != 0)
    return minsym.value_address () + minsym.minsym->size ();

  /* Step over other symbols at this same address, and symbols in
     other sections, to find the next symbol in this section with a
     different address.  */

  struct minimal_symbol *past_the_end
    = (minsym.objfile->per_bfd->msymbols.get ()
       + minsym.objfile->per_bfd->minimal_symbol_count);
  msymbol = minsym.minsym;
  int section = msymbol->section_index ();
  for (iter = msymbol + 1; iter != past_the_end; ++iter)
    {
      if ((iter->unrelocated_address ()
	   != msymbol->unrelocated_address ())
	  && iter->section_index () == section)
	break;
    }

  obj_section = minsym.obj_section ();
  if (iter != past_the_end
      && (iter->value_address (minsym.objfile)
	  < obj_section->endaddr ()))
    result = iter->value_address (minsym.objfile);
  else
    /* We got the start address from the last msymbol in the objfile.
       So the end address is the end of the section.  */
    result = obj_section->endaddr ();

  return result;
}

/* See minsyms.h.  */

type *
find_minsym_type_and_address (minimal_symbol *msymbol,
			      struct objfile *objfile,
			      CORE_ADDR *address_p)
{
  bound_minimal_symbol bound_msym = {msymbol, objfile};
  struct obj_section *section = msymbol->obj_section (objfile);
  enum minimal_symbol_type type = msymbol->type ();

  bool is_tls = (section != NULL
		 && section->the_bfd_section->flags & SEC_THREAD_LOCAL);

  /* The minimal symbol might point to a function descriptor;
     resolve it to the actual code address instead.  */
  CORE_ADDR addr;
  if (is_tls)
    {
      /* Addresses of TLS symbols are really offsets into a
	 per-objfile/per-thread storage block.  */
      addr = CORE_ADDR (bound_msym.minsym->unrelocated_address ());
    }
  else if (msymbol_is_function (objfile, msymbol, &addr))
    {
      if (addr != bound_msym.value_address ())
	{
	  /* This means we resolved a function descriptor, and we now
	     have an address for a code/text symbol instead of a data
	     symbol.  */
	  if (msymbol->type () == mst_data_gnu_ifunc)
	    type = mst_text_gnu_ifunc;
	  else
	    type = mst_text;
	  section = NULL;
	}
    }
  else
    addr = bound_msym.value_address ();

  if (overlay_debugging)
    addr = symbol_overlayed_address (addr, section);

  if (is_tls)
    {
      /* Skip translation if caller does not need the address.  */
      if (address_p != NULL)
	*address_p = target_translate_tls_address
		       (objfile, addr, bound_msym.minsym->print_name ());
      return builtin_type (objfile)->nodebug_tls_symbol;
    }

  if (address_p != NULL)
    *address_p = addr;

  switch (type)
    {
    case mst_text:
    case mst_file_text:
    case mst_solib_trampoline:
      return builtin_type (objfile)->nodebug_text_symbol;

    case mst_text_gnu_ifunc:
      return builtin_type (objfile)->nodebug_text_gnu_ifunc_symbol;

    case mst_data:
    case mst_file_data:
    case mst_bss:
    case mst_file_bss:
      return builtin_type (objfile)->nodebug_data_symbol;

    case mst_slot_got_plt:
      return builtin_type (objfile)->nodebug_got_plt_symbol;

    default:
      return builtin_type (objfile)->nodebug_unknown_symbol;
    }
}
