/* Generic symbol file reading for the GNU debugger, GDB.

   Copyright (C) 1990-2021 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/>.  */

#include "defs.h"
#include "arch-utils.h"
#include "bfdlink.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "gdbcore.h"
#include "frame.h"
#include "target.h"
#include "value.h"
#include "symfile.h"
#include "objfiles.h"
#include "source.h"
#include "gdbcmd.h"
#include "breakpoint.h"
#include "language.h"
#include "complaints.h"
#include "demangle.h"
#include "inferior.h"
#include "regcache.h"
#include "filenames.h"		/* for DOSish file names */
#include "gdb-stabs.h"
#include "gdb_obstack.h"
#include "completer.h"
#include "bcache.h"
#include "hashtab.h"
#include "readline/tilde.h"
#include "block.h"
#include "observable.h"
#include "exec.h"
#include "parser-defs.h"
#include "varobj.h"
#include "elf-bfd.h"
#include "solib.h"
#include "remote.h"
#include "stack.h"
#include "gdb_bfd.h"
#include "cli/cli-utils.h"
#include "gdbsupport/byte-vector.h"
#include "gdbsupport/pathstuff.h"
#include "gdbsupport/selftest.h"
#include "cli/cli-style.h"
#include "gdbsupport/forward-scope-exit.h"

#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <ctype.h>
#include <chrono>
#include <algorithm>

int (*deprecated_ui_load_progress_hook) (const char *section,
					 unsigned long num);
void (*deprecated_show_load_progress) (const char *section,
			    unsigned long section_sent,
			    unsigned long section_size,
			    unsigned long total_sent,
			    unsigned long total_size);
void (*deprecated_pre_add_symbol_hook) (const char *);
void (*deprecated_post_add_symbol_hook) (void);

using clear_symtab_users_cleanup
  = FORWARD_SCOPE_EXIT (clear_symtab_users);

/* Global variables owned by this file.  */

/* See symfile.h.  */

int readnow_symbol_files;

/* See symfile.h.  */

int readnever_symbol_files;

/* Functions this file defines.  */

static void symbol_file_add_main_1 (const char *args, symfile_add_flags add_flags,
				    objfile_flags flags, CORE_ADDR reloff);

static const struct sym_fns *find_sym_fns (bfd *);

static void overlay_invalidate_all (void);

static void simple_free_overlay_table (void);

static void read_target_long_array (CORE_ADDR, unsigned int *, int, int,
				    enum bfd_endian);

static int simple_read_overlay_table (void);

static int simple_overlay_update_1 (struct obj_section *);

static void symfile_find_segment_sections (struct objfile *objfile);

/* List of all available sym_fns.  On gdb startup, each object file reader
   calls add_symtab_fns() to register information on each format it is
   prepared to read.  */

struct registered_sym_fns
{
  registered_sym_fns (bfd_flavour sym_flavour_, const struct sym_fns *sym_fns_)
  : sym_flavour (sym_flavour_), sym_fns (sym_fns_)
  {}

  /* BFD flavour that we handle.  */
  enum bfd_flavour sym_flavour;

  /* The "vtable" of symbol functions.  */
  const struct sym_fns *sym_fns;
};

static std::vector<registered_sym_fns> symtab_fns;

/* Values for "set print symbol-loading".  */

const char print_symbol_loading_off[] = "off";
const char print_symbol_loading_brief[] = "brief";
const char print_symbol_loading_full[] = "full";
static const char *print_symbol_loading_enums[] =
{
  print_symbol_loading_off,
  print_symbol_loading_brief,
  print_symbol_loading_full,
  NULL
};
static const char *print_symbol_loading = print_symbol_loading_full;

/* See symfile.h.  */

bool auto_solib_add = true;


/* Return non-zero if symbol-loading messages should be printed.
   FROM_TTY is the standard from_tty argument to gdb commands.
   If EXEC is non-zero the messages are for the executable.
   Otherwise, messages are for shared libraries.
   If FULL is non-zero then the caller is printing a detailed message.
   E.g., the message includes the shared library name.
   Otherwise, the caller is printing a brief "summary" message.  */

int
print_symbol_loading_p (int from_tty, int exec, int full)
{
  if (!from_tty && !info_verbose)
    return 0;

  if (exec)
    {
      /* We don't check FULL for executables, there are few such
	 messages, therefore brief == full.  */
      return print_symbol_loading != print_symbol_loading_off;
    }
  if (full)
    return print_symbol_loading == print_symbol_loading_full;
  return print_symbol_loading == print_symbol_loading_brief;
}

/* True if we are reading a symbol table.  */

int currently_reading_symtab = 0;

/* Increment currently_reading_symtab and return a cleanup that can be
   used to decrement it.  */

scoped_restore_tmpl<int>
increment_reading_symtab (void)
{
  gdb_assert (currently_reading_symtab >= 0);
  return make_scoped_restore (&currently_reading_symtab,
			      currently_reading_symtab + 1);
}

/* Remember the lowest-addressed loadable section we've seen.

   In case of equal vmas, the section with the largest size becomes the
   lowest-addressed loadable section.

   If the vmas and sizes are equal, the last section is considered the
   lowest-addressed loadable section.  */

static void
find_lowest_section (asection *sect, asection **lowest)
{
  if (0 == (bfd_section_flags (sect) & (SEC_ALLOC | SEC_LOAD)))
    return;
  if (!*lowest)
    *lowest = sect;		/* First loadable section */
  else if (bfd_section_vma (*lowest) > bfd_section_vma (sect))
    *lowest = sect;		/* A lower loadable section */
  else if (bfd_section_vma (*lowest) == bfd_section_vma (sect)
	   && (bfd_section_size (*lowest) <= bfd_section_size (sect)))
    *lowest = sect;
}

/* Build (allocate and populate) a section_addr_info struct from
   an existing section table.  */

section_addr_info
build_section_addr_info_from_section_table (const target_section_table &table)
{
  section_addr_info sap;

  for (const target_section &stp : table)
    {
      struct bfd_section *asect = stp.the_bfd_section;
      bfd *abfd = asect->owner;

      if (bfd_section_flags (asect) & (SEC_ALLOC | SEC_LOAD)
	  && sap.size () < table.size ())
	sap.emplace_back (stp.addr,
			  bfd_section_name (asect),
			  gdb_bfd_section_index (abfd, asect));
    }

  return sap;
}

/* Create a section_addr_info from section offsets in ABFD.  */

static section_addr_info
build_section_addr_info_from_bfd (bfd *abfd)
{
  struct bfd_section *sec;

  section_addr_info sap;
  for (sec = abfd->sections; sec != NULL; sec = sec->next)
    if (bfd_section_flags (sec) & (SEC_ALLOC | SEC_LOAD))
      sap.emplace_back (bfd_section_vma (sec),
			bfd_section_name (sec),
			gdb_bfd_section_index (abfd, sec));

  return sap;
}

/* Create a section_addr_info from section offsets in OBJFILE.  */

section_addr_info
build_section_addr_info_from_objfile (const struct objfile *objfile)
{
  int i;

  /* Before reread_symbols gets rewritten it is not safe to call:
     gdb_assert (objfile->num_sections == bfd_count_sections (objfile->obfd));
     */
  section_addr_info sap = build_section_addr_info_from_bfd (objfile->obfd);
  for (i = 0; i < sap.size (); i++)
    {
      int sectindex = sap[i].sectindex;

      sap[i].addr += objfile->section_offsets[sectindex];
    }
  return sap;
}

/* Initialize OBJFILE's sect_index_* members.  */

static void
init_objfile_sect_indices (struct objfile *objfile)
{
  asection *sect;
  int i;

  sect = bfd_get_section_by_name (objfile->obfd, ".text");
  if (sect)
    objfile->sect_index_text = sect->index;

  sect = bfd_get_section_by_name (objfile->obfd, ".data");
  if (sect)
    objfile->sect_index_data = sect->index;

  sect = bfd_get_section_by_name (objfile->obfd, ".bss");
  if (sect)
    objfile->sect_index_bss = sect->index;

  sect = bfd_get_section_by_name (objfile->obfd, ".rodata");
  if (sect)
    objfile->sect_index_rodata = sect->index;

  /* This is where things get really weird...  We MUST have valid
     indices for the various sect_index_* members or gdb will abort.
     So if for example, there is no ".text" section, we have to
     accomodate that.  First, check for a file with the standard
     one or two segments.  */

  symfile_find_segment_sections (objfile);

  /* Except when explicitly adding symbol files at some address,
     section_offsets contains nothing but zeros, so it doesn't matter
     which slot in section_offsets the individual sect_index_* members
     index into.  So if they are all zero, it is safe to just point
     all the currently uninitialized indices to the first slot.  But
     beware: if this is the main executable, it may be relocated
     later, e.g. by the remote qOffsets packet, and then this will
     be wrong!  That's why we try segments first.  */

  for (i = 0; i < objfile->section_offsets.size (); i++)
    {
      if (objfile->section_offsets[i] != 0)
	{
	  break;
	}
    }
  if (i == objfile->section_offsets.size ())
    {
      if (objfile->sect_index_text == -1)
	objfile->sect_index_text = 0;
      if (objfile->sect_index_data == -1)
	objfile->sect_index_data = 0;
      if (objfile->sect_index_bss == -1)
	objfile->sect_index_bss = 0;
      if (objfile->sect_index_rodata == -1)
	objfile->sect_index_rodata = 0;
    }
}

/* Find a unique offset to use for loadable section SECT if
   the user did not provide an offset.  */

static void
place_section (bfd *abfd, asection *sect, section_offsets &offsets,
	       CORE_ADDR &lowest)
{
  CORE_ADDR start_addr;
  int done;
  ULONGEST align = ((ULONGEST) 1) << bfd_section_alignment (sect);

  /* We are only interested in allocated sections.  */
  if ((bfd_section_flags (sect) & SEC_ALLOC) == 0)
    return;

  /* If the user specified an offset, honor it.  */
  if (offsets[gdb_bfd_section_index (abfd, sect)] != 0)
    return;

  /* Otherwise, let's try to find a place for the section.  */
  start_addr = (lowest + align - 1) & -align;

  do {
    asection *cur_sec;

    done = 1;

    for (cur_sec = abfd->sections; cur_sec != NULL; cur_sec = cur_sec->next)
      {
	int indx = cur_sec->index;

	/* We don't need to compare against ourself.  */
	if (cur_sec == sect)
	  continue;

	/* We can only conflict with allocated sections.  */
	if ((bfd_section_flags (cur_sec) & SEC_ALLOC) == 0)
	  continue;

	/* If the section offset is 0, either the section has not been placed
	   yet, or it was the lowest section placed (in which case LOWEST
	   will be past its end).  */
	if (offsets[indx] == 0)
	  continue;

	/* If this section would overlap us, then we must move up.  */
	if (start_addr + bfd_section_size (sect) > offsets[indx]
	    && start_addr < offsets[indx] + bfd_section_size (cur_sec))
	  {
	    start_addr = offsets[indx] + bfd_section_size (cur_sec);
	    start_addr = (start_addr + align - 1) & -align;
	    done = 0;
	    break;
	  }

	/* Otherwise, we appear to be OK.  So far.  */
      }
    }
  while (!done);

  offsets[gdb_bfd_section_index (abfd, sect)] = start_addr;
  lowest = start_addr + bfd_section_size (sect);
}

/* Store section_addr_info as prepared (made relative and with SECTINDEX
   filled-in) by addr_info_make_relative into SECTION_OFFSETS.  */

void
relative_addr_info_to_section_offsets (section_offsets &section_offsets,
				       const section_addr_info &addrs)
{
  int i;

  section_offsets.assign (section_offsets.size (), 0);

  /* Now calculate offsets for section that were specified by the caller.  */
  for (i = 0; i < addrs.size (); i++)
    {
      const struct other_sections *osp;

      osp = &addrs[i];
      if (osp->sectindex == -1)
	continue;

      /* Record all sections in offsets.  */
      /* The section_offsets in the objfile are here filled in using
	 the BFD index.  */
      section_offsets[osp->sectindex] = osp->addr;
    }
}

/* Transform section name S for a name comparison.  prelink can split section
   `.bss' into two sections `.dynbss' and `.bss' (in this order).  Similarly
   prelink can split `.sbss' into `.sdynbss' and `.sbss'.  Use virtual address
   of the new `.dynbss' (`.sdynbss') section as the adjacent new `.bss'
   (`.sbss') section has invalid (increased) virtual address.  */

static const char *
addr_section_name (const char *s)
{
  if (strcmp (s, ".dynbss") == 0)
    return ".bss";
  if (strcmp (s, ".sdynbss") == 0)
    return ".sbss";

  return s;
}

/* std::sort comparator for addrs_section_sort.  Sort entries in
   ascending order by their (name, sectindex) pair.  sectindex makes
   the sort by name stable.  */

static bool
addrs_section_compar (const struct other_sections *a,
		      const struct other_sections *b)
{
  int retval;

  retval = strcmp (addr_section_name (a->name.c_str ()),
		   addr_section_name (b->name.c_str ()));
  if (retval != 0)
    return retval < 0;

  return a->sectindex < b->sectindex;
}

/* Provide sorted array of pointers to sections of ADDRS.  */

static std::vector<const struct other_sections *>
addrs_section_sort (const section_addr_info &addrs)
{
  int i;

  std::vector<const struct other_sections *> array (addrs.size ());
  for (i = 0; i < addrs.size (); i++)
    array[i] = &addrs[i];

  std::sort (array.begin (), array.end (), addrs_section_compar);

  return array;
}

/* Relativize absolute addresses in ADDRS into offsets based on ABFD.  Fill-in
   also SECTINDEXes specific to ABFD there.  This function can be used to
   rebase ADDRS to start referencing different BFD than before.  */

void
addr_info_make_relative (section_addr_info *addrs, bfd *abfd)
{
  asection *lower_sect;
  CORE_ADDR lower_offset;
  int i;

  /* Find lowest loadable section to be used as starting point for
     contiguous sections.  */
  lower_sect = NULL;
  for (asection *iter : gdb_bfd_sections (abfd))
    find_lowest_section (iter, &lower_sect);
  if (lower_sect == NULL)
    {
      warning (_("no loadable sections found in added symbol-file %s"),
	       bfd_get_filename (abfd));
      lower_offset = 0;
    }
  else
    lower_offset = bfd_section_vma (lower_sect);

  /* Create ADDRS_TO_ABFD_ADDRS array to map the sections in ADDRS to sections
     in ABFD.  Section names are not unique - there can be multiple sections of
     the same name.  Also the sections of the same name do not have to be
     adjacent to each other.  Some sections may be present only in one of the
     files.  Even sections present in both files do not have to be in the same
     order.

     Use stable sort by name for the sections in both files.  Then linearly
     scan both lists matching as most of the entries as possible.  */

  std::vector<const struct other_sections *> addrs_sorted
    = addrs_section_sort (*addrs);

  section_addr_info abfd_addrs = build_section_addr_info_from_bfd (abfd);
  std::vector<const struct other_sections *> abfd_addrs_sorted
    = addrs_section_sort (abfd_addrs);

  /* Now create ADDRS_TO_ABFD_ADDRS from ADDRS_SORTED and
     ABFD_ADDRS_SORTED.  */

  std::vector<const struct other_sections *>
    addrs_to_abfd_addrs (addrs->size (), nullptr);

  std::vector<const struct other_sections *>::iterator abfd_sorted_iter
    = abfd_addrs_sorted.begin ();
  for (const other_sections *sect : addrs_sorted)
    {
      const char *sect_name = addr_section_name (sect->name.c_str ());

      while (abfd_sorted_iter != abfd_addrs_sorted.end ()
	     && strcmp (addr_section_name ((*abfd_sorted_iter)->name.c_str ()),
			sect_name) < 0)
	abfd_sorted_iter++;

      if (abfd_sorted_iter != abfd_addrs_sorted.end ()
	  && strcmp (addr_section_name ((*abfd_sorted_iter)->name.c_str ()),
		     sect_name) == 0)
	{
	  int index_in_addrs;

	  /* Make the found item directly addressable from ADDRS.  */
	  index_in_addrs = sect - addrs->data ();
	  gdb_assert (addrs_to_abfd_addrs[index_in_addrs] == NULL);
	  addrs_to_abfd_addrs[index_in_addrs] = *abfd_sorted_iter;

	  /* Never use the same ABFD entry twice.  */
	  abfd_sorted_iter++;
	}
    }

  /* Calculate offsets for the loadable sections.
     FIXME! Sections must be in order of increasing loadable section
     so that contiguous sections can use the lower-offset!!!

     Adjust offsets if the segments are not contiguous.
     If the section is contiguous, its offset should be set to
     the offset of the highest loadable section lower than it
     (the loadable section directly below it in memory).
     this_offset = lower_offset = lower_addr - lower_orig_addr */

  for (i = 0; i < addrs->size (); i++)
    {
      const struct other_sections *sect = addrs_to_abfd_addrs[i];

      if (sect)
	{
	  /* This is the index used by BFD.  */
	  (*addrs)[i].sectindex = sect->sectindex;

	  if ((*addrs)[i].addr != 0)
	    {
	      (*addrs)[i].addr -= sect->addr;
	      lower_offset = (*addrs)[i].addr;
	    }
	  else
	    (*addrs)[i].addr = lower_offset;
	}
      else
	{
	  /* addr_section_name transformation is not used for SECT_NAME.  */
	  const std::string &sect_name = (*addrs)[i].name;

	  /* This section does not exist in ABFD, which is normally
	     unexpected and we want to issue a warning.

	     However, the ELF prelinker does create a few sections which are
	     marked in the main executable as loadable (they are loaded in
	     memory from the DYNAMIC segment) and yet are not present in
	     separate debug info files.  This is fine, and should not cause
	     a warning.  Shared libraries contain just the section
	     ".gnu.liblist" but it is not marked as loadable there.  There is
	     no other way to identify them than by their name as the sections
	     created by prelink have no special flags.

	     For the sections `.bss' and `.sbss' see addr_section_name.  */

	  if (!(sect_name == ".gnu.liblist"
		|| sect_name == ".gnu.conflict"
		|| (sect_name == ".bss"
		    && i > 0
		    && (*addrs)[i - 1].name == ".dynbss"
		    && addrs_to_abfd_addrs[i - 1] != NULL)
		|| (sect_name == ".sbss"
		    && i > 0
		    && (*addrs)[i - 1].name == ".sdynbss"
		    && addrs_to_abfd_addrs[i - 1] != NULL)))
	    warning (_("section %s not found in %s"), sect_name.c_str (),
		     bfd_get_filename (abfd));

	  (*addrs)[i].addr = 0;
	  (*addrs)[i].sectindex = -1;
	}
    }
}

/* Parse the user's idea of an offset for dynamic linking, into our idea
   of how to represent it for fast symbol reading.  This is the default
   version of the sym_fns.sym_offsets function for symbol readers that
   don't need to do anything special.  It allocates a section_offsets table
   for the objectfile OBJFILE and stuffs ADDR into all of the offsets.  */

void
default_symfile_offsets (struct objfile *objfile,
			 const section_addr_info &addrs)
{
  objfile->section_offsets.resize (gdb_bfd_count_sections (objfile->obfd));
  relative_addr_info_to_section_offsets (objfile->section_offsets, addrs);

  /* For relocatable files, all loadable sections will start at zero.
     The zero is meaningless, so try to pick arbitrary addresses such
     that no loadable sections overlap.  This algorithm is quadratic,
     but the number of sections in a single object file is generally
     small.  */
  if ((bfd_get_file_flags (objfile->obfd) & (EXEC_P | DYNAMIC)) == 0)
    {
      bfd *abfd = objfile->obfd;
      asection *cur_sec;

      for (cur_sec = abfd->sections; cur_sec != NULL; cur_sec = cur_sec->next)
	/* We do not expect this to happen; just skip this step if the
	   relocatable file has a section with an assigned VMA.  */
	if (bfd_section_vma (cur_sec) != 0)
	  break;

      if (cur_sec == NULL)
	{
	  section_offsets &offsets = objfile->section_offsets;

	  /* Pick non-overlapping offsets for sections the user did not
	     place explicitly.  */
	  CORE_ADDR lowest = 0;
	  for (asection *sect : gdb_bfd_sections (objfile->obfd))
	    place_section (objfile->obfd, sect, objfile->section_offsets,
			   lowest);

	  /* Correctly filling in the section offsets is not quite
	     enough.  Relocatable files have two properties that
	     (most) shared objects do not:

	     - Their debug information will contain relocations.  Some
	     shared libraries do also, but many do not, so this can not
	     be assumed.

	     - If there are multiple code sections they will be loaded
	     at different relative addresses in memory than they are
	     in the objfile, since all sections in the file will start
	     at address zero.

	     Because GDB has very limited ability to map from an
	     address in debug info to the correct code section,
	     it relies on adding SECT_OFF_TEXT to things which might be
	     code.  If we clear all the section offsets, and set the
	     section VMAs instead, then symfile_relocate_debug_section
	     will return meaningful debug information pointing at the
	     correct sections.

	     GDB has too many different data structures for section
	     addresses - a bfd, objfile, and so_list all have section
	     tables, as does exec_ops.  Some of these could probably
	     be eliminated.  */

	  for (cur_sec = abfd->sections; cur_sec != NULL;
	       cur_sec = cur_sec->next)
	    {
	      if ((bfd_section_flags (cur_sec) & SEC_ALLOC) == 0)
		continue;

	      bfd_set_section_vma (cur_sec, offsets[cur_sec->index]);
	      exec_set_section_address (bfd_get_filename (abfd),
					cur_sec->index,
					offsets[cur_sec->index]);
	      offsets[cur_sec->index] = 0;
	    }
	}
    }

  /* Remember the bfd indexes for the .text, .data, .bss and
     .rodata sections.  */
  init_objfile_sect_indices (objfile);
}

/* Divide the file into segments, which are individual relocatable units.
   This is the default version of the sym_fns.sym_segments function for
   symbol readers that do not have an explicit representation of segments.
   It assumes that object files do not have segments, and fully linked
   files have a single segment.  */

symfile_segment_data_up
default_symfile_segments (bfd *abfd)
{
  int num_sections, i;
  asection *sect;
  CORE_ADDR low, high;

  /* Relocatable files contain enough information to position each
     loadable section independently; they should not be relocated
     in segments.  */
  if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) == 0)
    return NULL;

  /* Make sure there is at least one loadable section in the file.  */
  for (sect = abfd->sections; sect != NULL; sect = sect->next)
    {
      if ((bfd_section_flags (sect) & SEC_ALLOC) == 0)
	continue;

      break;
    }
  if (sect == NULL)
    return NULL;

  low = bfd_section_vma (sect);
  high = low + bfd_section_size (sect);

  symfile_segment_data_up data (new symfile_segment_data);

  num_sections = bfd_count_sections (abfd);

  /* All elements are initialized to 0 (map to no segment).  */
  data->segment_info.resize (num_sections);

  for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
    {
      CORE_ADDR vma;

      if ((bfd_section_flags (sect) & SEC_ALLOC) == 0)
	continue;

      vma = bfd_section_vma (sect);
      if (vma < low)
	low = vma;
      if (vma + bfd_section_size (sect) > high)
	high = vma + bfd_section_size (sect);

      data->segment_info[i] = 1;
    }

  data->segments.emplace_back (low, high - low);

  return data;
}

/* This is a convenience function to call sym_read for OBJFILE and
   possibly force the partial symbols to be read.  */

static void
read_symbols (struct objfile *objfile, symfile_add_flags add_flags)
{
  (*objfile->sf->sym_read) (objfile, add_flags);
  objfile->per_bfd->minsyms_read = true;

  /* find_separate_debug_file_in_section should be called only if there is
     single binary with no existing separate debug info file.  */
  if (!objfile->has_partial_symbols ()
      && objfile->separate_debug_objfile == NULL
      && objfile->separate_debug_objfile_backlink == NULL)
    {
      gdb_bfd_ref_ptr abfd (find_separate_debug_file_in_section (objfile));

      if (abfd != NULL)
	{
	  /* find_separate_debug_file_in_section uses the same filename for the
	     virtual section-as-bfd like the bfd filename containing the
	     section.  Therefore use also non-canonical name form for the same
	     file containing the section.  */
	  symbol_file_add_separate (abfd.get (),
				    bfd_get_filename (abfd.get ()),
				    add_flags | SYMFILE_NOT_FILENAME, objfile);
	}
    }
  if ((add_flags & SYMFILE_NO_READ) == 0)
    objfile->require_partial_symbols (false);
}

/* Initialize entry point information for this objfile.  */

static void
init_entry_point_info (struct objfile *objfile)
{
  struct entry_info *ei = &objfile->per_bfd->ei;

  if (ei->initialized)
    return;
  ei->initialized = 1;

  /* Save startup file's range of PC addresses to help blockframe.c
     decide where the bottom of the stack is.  */

  if (bfd_get_file_flags (objfile->obfd) & EXEC_P)
    {
      /* Executable file -- record its entry point so we'll recognize
	 the startup file because it contains the entry point.  */
      ei->entry_point = bfd_get_start_address (objfile->obfd);
      ei->entry_point_p = 1;
    }
  else if (bfd_get_file_flags (objfile->obfd) & DYNAMIC
	   && bfd_get_start_address (objfile->obfd) != 0)
    {
      /* Some shared libraries may have entry points set and be
	 runnable.  There's no clear way to indicate this, so just check
	 for values other than zero.  */
      ei->entry_point = bfd_get_start_address (objfile->obfd);
      ei->entry_point_p = 1;
    }
  else
    {
      /* Examination of non-executable.o files.  Short-circuit this stuff.  */
      ei->entry_point_p = 0;
    }

  if (ei->entry_point_p)
    {
      struct obj_section *osect;
      CORE_ADDR entry_point =  ei->entry_point;
      int found;

      /* Make certain that the address points at real code, and not a
	 function descriptor.  */
      entry_point = gdbarch_convert_from_func_ptr_addr
	(objfile->arch (), entry_point, current_inferior ()->top_target ());

      /* Remove any ISA markers, so that this matches entries in the
	 symbol table.  */
      ei->entry_point
	= gdbarch_addr_bits_remove (objfile->arch (), entry_point);

      found = 0;
      ALL_OBJFILE_OSECTIONS (objfile, osect)
	{
	  struct bfd_section *sect = osect->the_bfd_section;

	  if (entry_point >= bfd_section_vma (sect)
	      && entry_point < (bfd_section_vma (sect)
				+ bfd_section_size (sect)))
	    {
	      ei->the_bfd_section_index
		= gdb_bfd_section_index (objfile->obfd, sect);
	      found = 1;
	      break;
	    }
	}

      if (!found)
	ei->the_bfd_section_index = SECT_OFF_TEXT (objfile);
    }
}

/* Process a symbol file, as either the main file or as a dynamically
   loaded file.

   This function does not set the OBJFILE's entry-point info.

   OBJFILE is where the symbols are to be read from.

   ADDRS is the list of section load addresses.  If the user has given
   an 'add-symbol-file' command, then this is the list of offsets and
   addresses he or she provided as arguments to the command; or, if
   we're handling a shared library, these are the actual addresses the
   sections are loaded at, according to the inferior's dynamic linker
   (as gleaned by GDB's shared library code).  We convert each address
   into an offset from the section VMA's as it appears in the object
   file, and then call the file's sym_offsets function to convert this
   into a format-specific offset table --- a `section_offsets'.
   The sectindex field is used to control the ordering of sections
   with the same name.  Upon return, it is updated to contain the
   corresponding BFD section index, or -1 if the section was not found.

   ADD_FLAGS encodes verbosity level, whether this is main symbol or
   an extra symbol file such as dynamically loaded code, and whether
   breakpoint reset should be deferred.  */

static void
syms_from_objfile_1 (struct objfile *objfile,
		     section_addr_info *addrs,
		     symfile_add_flags add_flags)
{
  section_addr_info local_addr;
  const int mainline = add_flags & SYMFILE_MAINLINE;

  objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd));
  objfile->qf.clear ();

  if (objfile->sf == NULL)
    {
      /* No symbols to load, but we still need to make sure
	 that the section_offsets table is allocated.  */
      int num_sections = gdb_bfd_count_sections (objfile->obfd);

      objfile->section_offsets.assign (num_sections, 0);
      return;
    }

  /* Make sure that partially constructed symbol tables will be cleaned up
     if an error occurs during symbol reading.  */
  gdb::optional<clear_symtab_users_cleanup> defer_clear_users;

  objfile_up objfile_holder (objfile);

  /* If ADDRS is NULL, put together a dummy address list.
     We now establish the convention that an addr of zero means
     no load address was specified.  */
  if (! addrs)
    addrs = &local_addr;

  if (mainline)
    {
      /* We will modify the main symbol table, make sure that all its users
	 will be cleaned up if an error occurs during symbol reading.  */
      defer_clear_users.emplace ((symfile_add_flag) 0);

      /* Since no error yet, throw away the old symbol table.  */

      if (current_program_space->symfile_object_file != NULL)
	{
	  current_program_space->symfile_object_file->unlink ();
	  gdb_assert (current_program_space->symfile_object_file == NULL);
	}

      /* Currently we keep symbols from the add-symbol-file command.
	 If the user wants to get rid of them, they should do "symbol-file"
	 without arguments first.  Not sure this is the best behavior
	 (PR 2207).  */

      (*objfile->sf->sym_new_init) (objfile);
    }

  /* Convert addr into an offset rather than an absolute address.
     We find the lowest address of a loaded segment in the objfile,
     and assume that <addr> is where that got loaded.

     We no longer warn if the lowest section is not a text segment (as
     happens for the PA64 port.  */
  if (addrs->size () > 0)
    addr_info_make_relative (addrs, objfile->obfd);

  /* Initialize symbol reading routines for this objfile, allow complaints to
     appear for this new file, and record how verbose to be, then do the
     initial symbol reading for this file.  */

  (*objfile->sf->sym_init) (objfile);
  clear_complaints ();

  (*objfile->sf->sym_offsets) (objfile, *addrs);

  read_symbols (objfile, add_flags);

  /* Discard cleanups as symbol reading was successful.  */

  objfile_holder.release ();
  if (defer_clear_users)
    defer_clear_users->release ();
}

/* Same as syms_from_objfile_1, but also initializes the objfile
   entry-point info.  */

static void
syms_from_objfile (struct objfile *objfile,
		   section_addr_info *addrs,
		   symfile_add_flags add_flags)
{
  syms_from_objfile_1 (objfile, addrs, add_flags);
  init_entry_point_info (objfile);
}

/* Perform required actions after either reading in the initial
   symbols for a new objfile, or mapping in the symbols from a reusable
   objfile.  ADD_FLAGS is a bitmask of enum symfile_add_flags.  */

static void
finish_new_objfile (struct objfile *objfile, symfile_add_flags add_flags)
{
  /* If this is the main symbol file we have to clean up all users of the
     old main symbol file.  Otherwise it is sufficient to fixup all the
     breakpoints that may have been redefined by this symbol file.  */
  if (add_flags & SYMFILE_MAINLINE)
    {
      /* OK, make it the "real" symbol file.  */
      current_program_space->symfile_object_file = objfile;

      clear_symtab_users (add_flags);
    }
  else if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
    {
      breakpoint_re_set ();
    }

  /* We're done reading the symbol file; finish off complaints.  */
  clear_complaints ();
}

/* Process a symbol file, as either the main file or as a dynamically
   loaded file.

   ABFD is a BFD already open on the file, as from symfile_bfd_open.
   A new reference is acquired by this function.

   For NAME description see the objfile constructor.

   ADD_FLAGS encodes verbosity, whether this is main symbol file or
   extra, such as dynamically loaded code, and what to do with breakpoints.

   ADDRS is as described for syms_from_objfile_1, above.
   ADDRS is ignored when SYMFILE_MAINLINE bit is set in ADD_FLAGS.

   PARENT is the original objfile if ABFD is a separate debug info file.
   Otherwise PARENT is NULL.

   Upon success, returns a pointer to the objfile that was added.
   Upon failure, jumps back to command level (never returns).  */

static struct objfile *
symbol_file_add_with_addrs (bfd *abfd, const char *name,
			    symfile_add_flags add_flags,
			    section_addr_info *addrs,
			    objfile_flags flags, struct objfile *parent)
{
  struct objfile *objfile;
  const int from_tty = add_flags & SYMFILE_VERBOSE;
  const int mainline = add_flags & SYMFILE_MAINLINE;
  const int always_confirm = add_flags & SYMFILE_ALWAYS_CONFIRM;
  const int should_print = (print_symbol_loading_p (from_tty, mainline, 1)
			    && (readnow_symbol_files
				|| (add_flags & SYMFILE_NO_READ) == 0));

  if (readnow_symbol_files)
    {
      flags |= OBJF_READNOW;
      add_flags &= ~SYMFILE_NO_READ;
    }
  else if (readnever_symbol_files
	   || (parent != NULL && (parent->flags & OBJF_READNEVER)))
    {
      flags |= OBJF_READNEVER;
      add_flags |= SYMFILE_NO_READ;
    }
  if ((add_flags & SYMFILE_NOT_FILENAME) != 0)
    flags |= OBJF_NOT_FILENAME;

  /* Give user a chance to burp if ALWAYS_CONFIRM or we'd be
     interactively wiping out any existing symbols.  */

  if (from_tty
      && (always_confirm
	  || ((have_full_symbols () || have_partial_symbols ())
	      && mainline))
      && !query (_("Load new symbol table from \"%s\"? "), name))
    error (_("Not confirmed."));

  if (mainline)
    flags |= OBJF_MAINLINE;
  objfile = objfile::make (abfd, name, flags, parent);

  /* We either created a new mapped symbol table, mapped an existing
     symbol table file which has not had initial symbol reading
     performed, or need to read an unmapped symbol table.  */
  if (should_print)
    {
      if (deprecated_pre_add_symbol_hook)
	deprecated_pre_add_symbol_hook (name);
      else
	printf_filtered (_("Reading symbols from %ps...\n"),
			 styled_string (file_name_style.style (), name));
    }
  syms_from_objfile (objfile, addrs, add_flags);

  /* We now have at least a partial symbol table.  Check to see if the
     user requested that all symbols be read on initial access via either
     the gdb startup command line or on a per symbol file basis.  Expand
     all partial symbol tables for this objfile if so.  */

  if ((flags & OBJF_READNOW))
    {
      if (should_print)
	printf_filtered (_("Expanding full symbols from %ps...\n"),
			 styled_string (file_name_style.style (), name));

      objfile->expand_all_symtabs ();
    }

  /* Note that we only print a message if we have no symbols and have
     no separate debug file.  If there is a separate debug file which
     does not have symbols, we'll have emitted this message for that
     file, and so printing it twice is just redundant.  */
  if (should_print && !objfile_has_symbols (objfile)
      && objfile->separate_debug_objfile == nullptr)
    printf_filtered (_("(No debugging symbols found in %ps)\n"),
		     styled_string (file_name_style.style (), name));

  if (should_print)
    {
      if (deprecated_post_add_symbol_hook)
	deprecated_post_add_symbol_hook ();
    }

  /* We print some messages regardless of whether 'from_tty ||
     info_verbose' is true, so make sure they go out at the right
     time.  */
  gdb_flush (gdb_stdout);

  if (objfile->sf == NULL)
    {
      gdb::observers::new_objfile.notify (objfile);
      return objfile;	/* No symbols.  */
    }

  finish_new_objfile (objfile, add_flags);

  gdb::observers::new_objfile.notify (objfile);

  bfd_cache_close_all ();
  return (objfile);
}

/* Add BFD as a separate debug file for OBJFILE.  For NAME description
   see the objfile constructor.  */

void
symbol_file_add_separate (bfd *bfd, const char *name,
			  symfile_add_flags symfile_flags,
			  struct objfile *objfile)
{
  /* Create section_addr_info.  We can't directly use offsets from OBJFILE
     because sections of BFD may not match sections of OBJFILE and because
     vma may have been modified by tools such as prelink.  */
  section_addr_info sap = build_section_addr_info_from_objfile (objfile);

  symbol_file_add_with_addrs
    (bfd, name, symfile_flags, &sap,
     objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW
		       | OBJF_USERLOADED | OBJF_MAINLINE),
     objfile);
}

/* Process the symbol file ABFD, as either the main file or as a
   dynamically loaded file.
   See symbol_file_add_with_addrs's comments for details.  */

struct objfile *
symbol_file_add_from_bfd (bfd *abfd, const char *name,
			  symfile_add_flags add_flags,
			  section_addr_info *addrs,
			  objfile_flags flags, struct objfile *parent)
{
  return symbol_file_add_with_addrs (abfd, name, add_flags, addrs, flags,
				     parent);
}

/* Process a symbol file, as either the main file or as a dynamically
   loaded file.  See symbol_file_add_with_addrs's comments for details.  */

struct objfile *
symbol_file_add (const char *name, symfile_add_flags add_flags,
		 section_addr_info *addrs, objfile_flags flags)
{
  gdb_bfd_ref_ptr bfd (symfile_bfd_open (name));

  return symbol_file_add_from_bfd (bfd.get (), name, add_flags, addrs,
				   flags, NULL);
}

/* Call symbol_file_add() with default values and update whatever is
   affected by the loading of a new main().
   Used when the file is supplied in the gdb command line
   and by some targets with special loading requirements.
   The auxiliary function, symbol_file_add_main_1(), has the flags
   argument for the switches that can only be specified in the symbol_file
   command itself.  */

void
symbol_file_add_main (const char *args, symfile_add_flags add_flags)
{
  symbol_file_add_main_1 (args, add_flags, 0, 0);
}

static void
symbol_file_add_main_1 (const char *args, symfile_add_flags add_flags,
			objfile_flags flags, CORE_ADDR reloff)
{
  add_flags |= current_inferior ()->symfile_flags | SYMFILE_MAINLINE;

  struct objfile *objfile = symbol_file_add (args, add_flags, NULL, flags);
  if (reloff != 0)
    objfile_rebase (objfile, reloff);

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

  if ((add_flags & SYMFILE_NO_READ) == 0)
    set_initial_language ();
}

void
symbol_file_clear (int from_tty)
{
  if ((have_full_symbols () || have_partial_symbols ())
      && from_tty
      && (current_program_space->symfile_object_file
	  ? !query (_("Discard symbol table from `%s'? "),
		    objfile_name (current_program_space->symfile_object_file))
	  : !query (_("Discard symbol table? "))))
    error (_("Not confirmed."));

  /* solib descriptors may have handles to objfiles.  Wipe them before their
     objfiles get stale by free_all_objfiles.  */
  no_shared_libraries (NULL, from_tty);

  current_program_space->free_all_objfiles ();

  clear_symtab_users (0);

  gdb_assert (current_program_space->symfile_object_file == NULL);
  if (from_tty)
    printf_filtered (_("No symbol file now.\n"));
}

/* See symfile.h.  */

bool separate_debug_file_debug = false;

static int
separate_debug_file_exists (const std::string &name, unsigned long crc,
			    struct objfile *parent_objfile)
{
  unsigned long file_crc;
  int file_crc_p;
  struct stat parent_stat, abfd_stat;
  int verified_as_different;

  /* Find a separate debug info file as if symbols would be present in
     PARENT_OBJFILE itself this function would not be called.  .gnu_debuglink
     section can contain just the basename of PARENT_OBJFILE without any
     ".debug" suffix as "/usr/lib/debug/path/to/file" is a separate tree where
     the separate debug infos with the same basename can exist.  */

  if (filename_cmp (name.c_str (), objfile_name (parent_objfile)) == 0)
    return 0;

  if (separate_debug_file_debug)
    {
      printf_filtered (_("  Trying %s..."), name.c_str ());
      gdb_flush (gdb_stdout);
    }

  gdb_bfd_ref_ptr abfd (gdb_bfd_open (name.c_str (), gnutarget));

  if (abfd == NULL)
    {
      if (separate_debug_file_debug)
	printf_filtered (_(" no, unable to open.\n"));

      return 0;
    }

  /* Verify symlinks were not the cause of filename_cmp name difference above.

     Some operating systems, e.g. Windows, do not provide a meaningful
     st_ino; they always set it to zero.  (Windows does provide a
     meaningful st_dev.)  Files accessed from gdbservers that do not
     support the vFile:fstat packet will also have st_ino set to zero.
     Do not indicate a duplicate library in either case.  While there
     is no guarantee that a system that provides meaningful inode
     numbers will never set st_ino to zero, this is merely an
     optimization, so we do not need to worry about false negatives.  */

  if (bfd_stat (abfd.get (), &abfd_stat) == 0
      && abfd_stat.st_ino != 0
      && bfd_stat (parent_objfile->obfd, &parent_stat) == 0)
    {
      if (abfd_stat.st_dev == parent_stat.st_dev
	  && abfd_stat.st_ino == parent_stat.st_ino)
	{
	  if (separate_debug_file_debug)
	    printf_filtered (_(" no, same file as the objfile.\n"));

	  return 0;
	}
      verified_as_different = 1;
    }
  else
    verified_as_different = 0;

  file_crc_p = gdb_bfd_crc (abfd.get (), &file_crc);

  if (!file_crc_p)
    {
      if (separate_debug_file_debug)
	printf_filtered (_(" no, error computing CRC.\n"));

      return 0;
    }

  if (crc != file_crc)
    {
      unsigned long parent_crc;

      /* If the files could not be verified as different with
	 bfd_stat then we need to calculate the parent's CRC
	 to verify whether the files are different or not.  */

      if (!verified_as_different)
	{
	  if (!gdb_bfd_crc (parent_objfile->obfd, &parent_crc))
	    {
	      if (separate_debug_file_debug)
		printf_filtered (_(" no, error computing CRC.\n"));

	      return 0;
	    }
	}

      if (verified_as_different || parent_crc != file_crc)
	warning (_("the debug information found in \"%s\""
		   " does not match \"%s\" (CRC mismatch).\n"),
		 name.c_str (), objfile_name (parent_objfile));

      if (separate_debug_file_debug)
	printf_filtered (_(" no, CRC doesn't match.\n"));

      return 0;
    }

  if (separate_debug_file_debug)
    printf_filtered (_(" yes!\n"));

  return 1;
}

char *debug_file_directory = NULL;
static void
show_debug_file_directory (struct ui_file *file, int from_tty,
			   struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("The directory where separate debug "
		      "symbols are searched for is \"%s\".\n"),
		    value);
}

#if ! defined (DEBUG_SUBDIRECTORY)
#define DEBUG_SUBDIRECTORY ".debug"
#endif

/* Find a separate debuginfo file for OBJFILE, using DIR as the directory
   where the original file resides (may not be the same as
   dirname(objfile->name) due to symlinks), and DEBUGLINK as the file we are
   looking for.  CANON_DIR is the "realpath" form of DIR.
   DIR must contain a trailing '/'.
   Returns the path of the file with separate debug info, or an empty
   string.  */

static std::string
find_separate_debug_file (const char *dir,
			  const char *canon_dir,
			  const char *debuglink,
			  unsigned long crc32, struct objfile *objfile)
{
  if (separate_debug_file_debug)
    printf_filtered (_("\nLooking for separate debug info (debug link) for "
		       "%s\n"), objfile_name (objfile));

  /* First try in the same directory as the original file.  */
  std::string debugfile = dir;
  debugfile += debuglink;

  if (separate_debug_file_exists (debugfile, crc32, objfile))
    return debugfile;

  /* Then try in the subdirectory named DEBUG_SUBDIRECTORY.  */
  debugfile = dir;
  debugfile += DEBUG_SUBDIRECTORY;
  debugfile += "/";
  debugfile += debuglink;

  if (separate_debug_file_exists (debugfile, crc32, objfile))
    return debugfile;

  /* Then try in the global debugfile directories.

     Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
     cause "/..." lookups.  */

  bool target_prefix = startswith (dir, "target:");
  const char *dir_notarget = target_prefix ? dir + strlen ("target:") : dir;
  std::vector<gdb::unique_xmalloc_ptr<char>> debugdir_vec
    = dirnames_to_char_ptr_vec (debug_file_directory);
  gdb::unique_xmalloc_ptr<char> canon_sysroot = gdb_realpath (gdb_sysroot);

 /* MS-Windows/MS-DOS don't allow colons in file names; we must
    convert the drive letter into a one-letter directory, so that the
    file name resulting from splicing below will be valid.

    FIXME: The below only works when GDB runs on MS-Windows/MS-DOS.
    There are various remote-debugging scenarios where such a
    transformation of the drive letter might be required when GDB runs
    on a Posix host, see

    https://sourceware.org/ml/gdb-patches/2019-04/msg00605.html

    If some of those scenarios need to be supported, we will need to
    use a different condition for HAS_DRIVE_SPEC and a different macro
    instead of STRIP_DRIVE_SPEC, which work on Posix systems as well.  */
  std::string drive;
  if (HAS_DRIVE_SPEC (dir_notarget))
    {
      drive = dir_notarget[0];
      dir_notarget = STRIP_DRIVE_SPEC (dir_notarget);
    }

  for (const gdb::unique_xmalloc_ptr<char> &debugdir : debugdir_vec)
    {
      debugfile = target_prefix ? "target:" : "";
      debugfile += debugdir.get ();
      debugfile += "/";
      debugfile += drive;
      debugfile += dir_notarget;
      debugfile += debuglink;

      if (separate_debug_file_exists (debugfile, crc32, objfile))
	return debugfile;

      const char *base_path = NULL;
      if (canon_dir != NULL)
	{
	  if (canon_sysroot.get () != NULL)
	    base_path = child_path (canon_sysroot.get (), canon_dir);
	  else
	    base_path = child_path (gdb_sysroot, canon_dir);
	}
      if (base_path != NULL)
	{
	  /* If the file is in the sysroot, try using its base path in
	     the global debugfile directory.  */
	  debugfile = target_prefix ? "target:" : "";
	  debugfile += debugdir.get ();
	  debugfile += "/";
	  debugfile += base_path;
	  debugfile += "/";
	  debugfile += debuglink;

	  if (separate_debug_file_exists (debugfile, crc32, objfile))
	    return debugfile;

	  /* If the file is in the sysroot, try using its base path in
	     the sysroot's global debugfile directory.  */
	  debugfile = target_prefix ? "target:" : "";
	  debugfile += gdb_sysroot;
	  debugfile += debugdir.get ();
	  debugfile += "/";
	  debugfile += base_path;
	  debugfile += "/";
	  debugfile += debuglink;

	  if (separate_debug_file_exists (debugfile, crc32, objfile))
	    return debugfile;
	}

    }

  return std::string ();
}

/* Modify PATH to contain only "[/]directory/" part of PATH.
   If there were no directory separators in PATH, PATH will be empty
   string on return.  */

static void
terminate_after_last_dir_separator (char *path)
{
  int i;

  /* Strip off the final filename part, leaving the directory name,
     followed by a slash.  The directory can be relative or absolute.  */
  for (i = strlen(path) - 1; i >= 0; i--)
    if (IS_DIR_SEPARATOR (path[i]))
      break;

  /* If I is -1 then no directory is present there and DIR will be "".  */
  path[i + 1] = '\0';
}

/* Find separate debuginfo for OBJFILE (using .gnu_debuglink section).
   Returns pathname, or an empty string.  */

std::string
find_separate_debug_file_by_debuglink (struct objfile *objfile)
{
  unsigned long crc32;

  gdb::unique_xmalloc_ptr<char> debuglink
    (bfd_get_debug_link_info (objfile->obfd, &crc32));

  if (debuglink == NULL)
    {
      /* There's no separate debug info, hence there's no way we could
	 load it => no warning.  */
      return std::string ();
    }

  std::string dir = objfile_name (objfile);
  terminate_after_last_dir_separator (&dir[0]);
  gdb::unique_xmalloc_ptr<char> canon_dir (lrealpath (dir.c_str ()));

  std::string debugfile
    = find_separate_debug_file (dir.c_str (), canon_dir.get (),
				debuglink.get (), crc32, objfile);

  if (debugfile.empty ())
    {
      /* For PR gdb/9538, try again with realpath (if different from the
	 original).  */

      struct stat st_buf;

      if (lstat (objfile_name (objfile), &st_buf) == 0
	  && S_ISLNK (st_buf.st_mode))
	{
	  gdb::unique_xmalloc_ptr<char> symlink_dir
	    (lrealpath (objfile_name (objfile)));
	  if (symlink_dir != NULL)
	    {
	      terminate_after_last_dir_separator (symlink_dir.get ());
	      if (dir != symlink_dir.get ())
		{
		  /* Different directory, so try using it.  */
		  debugfile = find_separate_debug_file (symlink_dir.get (),
							symlink_dir.get (),
							debuglink.get (),
							crc32,
							objfile);
		}
	    }
	}
    }

  return debugfile;
}

/* Make sure that OBJF_{READNOW,READNEVER} are not set
   simultaneously.  */

static void
validate_readnow_readnever (objfile_flags flags)
{
  if ((flags & OBJF_READNOW) && (flags & OBJF_READNEVER))
    error (_("-readnow and -readnever cannot be used simultaneously"));
}

/* This is the symbol-file command.  Read the file, analyze its
   symbols, and add a struct symtab to a symtab list.  The syntax of
   the command is rather bizarre:

   1. The function buildargv implements various quoting conventions
   which are undocumented and have little or nothing in common with
   the way things are quoted (or not quoted) elsewhere in GDB.

   2. Options are used, which are not generally used in GDB (perhaps
   "set mapped on", "set readnow on" would be better)

   3. The order of options matters, which is contrary to GNU
   conventions (because it is confusing and inconvenient).  */

void
symbol_file_command (const char *args, int from_tty)
{
  dont_repeat ();

  if (args == NULL)
    {
      symbol_file_clear (from_tty);
    }
  else
    {
      objfile_flags flags = OBJF_USERLOADED;
      symfile_add_flags add_flags = 0;
      char *name = NULL;
      bool stop_processing_options = false;
      CORE_ADDR offset = 0;
      int idx;
      char *arg;

      if (from_tty)
	add_flags |= SYMFILE_VERBOSE;

      gdb_argv built_argv (args);
      for (arg = built_argv[0], idx = 0; arg != NULL; arg = built_argv[++idx])
	{
	  if (stop_processing_options || *arg != '-')
	    {
	      if (name == NULL)
		name = arg;
	      else
		error (_("Unrecognized argument \"%s\""), arg);
	    }
	  else if (strcmp (arg, "-readnow") == 0)
	    flags |= OBJF_READNOW;
	  else if (strcmp (arg, "-readnever") == 0)
	    flags |= OBJF_READNEVER;
	  else if (strcmp (arg, "-o") == 0)
	    {
	      arg = built_argv[++idx];
	      if (arg == NULL)
		error (_("Missing argument to -o"));

	      offset = parse_and_eval_address (arg);
	    }
	  else if (strcmp (arg, "--") == 0)
	    stop_processing_options = true;
	  else
	    error (_("Unrecognized argument \"%s\""), arg);
	}

      if (name == NULL)
	error (_("no symbol file name was specified"));

      validate_readnow_readnever (flags);

      /* Set SYMFILE_DEFER_BP_RESET because the proper displacement for a PIE
	 (Position Independent Executable) main symbol file will only be
	 computed by the solib_create_inferior_hook below.  Without it,
	 breakpoint_re_set would fail to insert the breakpoints with the zero
	 displacement.  */
      add_flags |= SYMFILE_DEFER_BP_RESET;

      symbol_file_add_main_1 (name, add_flags, flags, offset);

      solib_create_inferior_hook (from_tty);

      /* Now it's safe to re-add the breakpoints.  */
      breakpoint_re_set ();
    }
}

/* Set the initial language.  */

void
set_initial_language (void)
{
  if (language_mode == language_mode_manual)
    return;
  enum language lang = main_language ();
  /* Make C the default language.  */
  enum language default_lang = language_c;

  if (lang == language_unknown)
    {
      const char *name = main_name ();
      struct symbol *sym
	= lookup_symbol_in_language (name, NULL, VAR_DOMAIN, default_lang,
				     NULL).symbol;

      if (sym != NULL)
	lang = sym->language ();
    }

  if (lang == language_unknown)
    {
      lang = default_lang;
    }

  set_language (lang);
  expected_language = current_language; /* Don't warn the user.  */
}

/* Open the file specified by NAME and hand it off to BFD for
   preliminary analysis.  Return a newly initialized bfd *, which
   includes a newly malloc'd` copy of NAME (tilde-expanded and made
   absolute).  In case of trouble, error() is called.  */

gdb_bfd_ref_ptr
symfile_bfd_open (const char *name)
{
  int desc = -1;

  gdb::unique_xmalloc_ptr<char> absolute_name;
  if (!is_target_filename (name))
    {
      gdb::unique_xmalloc_ptr<char> expanded_name (tilde_expand (name));

      /* Look down path for it, allocate 2nd new malloc'd copy.  */
      desc = openp (getenv ("PATH"),
		    OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH,
		    expanded_name.get (), O_RDONLY | O_BINARY, &absolute_name);
#if defined(__GO32__) || defined(_WIN32) || defined (__CYGWIN__)
      if (desc < 0)
	{
	  char *exename = (char *) alloca (strlen (expanded_name.get ()) + 5);

	  strcat (strcpy (exename, expanded_name.get ()), ".exe");
	  desc = openp (getenv ("PATH"),
			OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH,
			exename, O_RDONLY | O_BINARY, &absolute_name);
	}
#endif
      if (desc < 0)
	perror_with_name (expanded_name.get ());

      name = absolute_name.get ();
    }

  gdb_bfd_ref_ptr sym_bfd (gdb_bfd_open (name, gnutarget, desc));
  if (sym_bfd == NULL)
    error (_("`%s': can't open to read symbols: %s."), name,
	   bfd_errmsg (bfd_get_error ()));

  if (!gdb_bfd_has_target_filename (sym_bfd.get ()))
    bfd_set_cacheable (sym_bfd.get (), 1);

  if (!bfd_check_format (sym_bfd.get (), bfd_object))
    error (_("`%s': can't read symbols: %s."), name,
	   bfd_errmsg (bfd_get_error ()));

  return sym_bfd;
}

/* Return the section index for SECTION_NAME on OBJFILE.  Return -1 if
   the section was not found.  */

int
get_section_index (struct objfile *objfile, const char *section_name)
{
  asection *sect = bfd_get_section_by_name (objfile->obfd, section_name);

  if (sect)
    return sect->index;
  else
    return -1;
}

/* Link SF into the global symtab_fns list.
   FLAVOUR is the file format that SF handles.
   Called on startup by the _initialize routine in each object file format
   reader, to register information about each format the reader is prepared
   to handle.  */

void
add_symtab_fns (enum bfd_flavour flavour, const struct sym_fns *sf)
{
  symtab_fns.emplace_back (flavour, sf);
}

/* Initialize OBJFILE to read symbols from its associated BFD.  It
   either returns or calls error().  The result is an initialized
   struct sym_fns in the objfile structure, that contains cached
   information about the symbol file.  */

static const struct sym_fns *
find_sym_fns (bfd *abfd)
{
  enum bfd_flavour our_flavour = bfd_get_flavour (abfd);

  if (our_flavour == bfd_target_srec_flavour
      || our_flavour == bfd_target_ihex_flavour
      || our_flavour == bfd_target_tekhex_flavour)
    return NULL;	/* No symbols.  */

  for (const registered_sym_fns &rsf : symtab_fns)
    if (our_flavour == rsf.sym_flavour)
      return rsf.sym_fns;

  error (_("I'm sorry, Dave, I can't do that.  Symbol format `%s' unknown."),
	 bfd_get_target (abfd));
}


/* This function runs the load command of our current target.  */

static void
load_command (const char *arg, int from_tty)
{
  dont_repeat ();

  /* The user might be reloading because the binary has changed.  Take
     this opportunity to check.  */
  reopen_exec_file ();
  reread_symbols ();

  std::string temp;
  if (arg == NULL)
    {
      const char *parg, *prev;

      arg = get_exec_file (1);

      /* We may need to quote this string so buildargv can pull it
	 apart.  */
      prev = parg = arg;
      while ((parg = strpbrk (parg, "\\\"'\t ")))
	{
	  temp.append (prev, parg - prev);
	  prev = parg++;
	  temp.push_back ('\\');
	}
      /* If we have not copied anything yet, then we didn't see a
	 character to quote, and we can just leave ARG unchanged.  */
      if (!temp.empty ())
	{
	  temp.append (prev);
	  arg = temp.c_str ();
	}
    }

  target_load (arg, from_tty);

  /* After re-loading the executable, we don't really know which
     overlays are mapped any more.  */
  overlay_cache_invalid = 1;
}

/* This version of "load" should be usable for any target.  Currently
   it is just used for remote targets, not inftarg.c or core files,
   on the theory that only in that case is it useful.

   Avoiding xmodem and the like seems like a win (a) because we don't have
   to worry about finding it, and (b) On VMS, fork() is very slow and so
   we don't want to run a subprocess.  On the other hand, I'm not sure how
   performance compares.  */

static int validate_download = 0;

/* Opaque data for load_progress.  */
struct load_progress_data
{
  /* Cumulative data.  */
  unsigned long write_count = 0;
  unsigned long data_count = 0;
  bfd_size_type total_size = 0;
};

/* Opaque data for load_progress for a single section.  */
struct load_progress_section_data
{
  load_progress_section_data (load_progress_data *cumulative_,
			      const char *section_name_, ULONGEST section_size_,
			      CORE_ADDR lma_, gdb_byte *buffer_)
    : cumulative (cumulative_), section_name (section_name_),
      section_size (section_size_), lma (lma_), buffer (buffer_)
  {}

  struct load_progress_data *cumulative;

  /* Per-section data.  */
  const char *section_name;
  ULONGEST section_sent = 0;
  ULONGEST section_size;
  CORE_ADDR lma;
  gdb_byte *buffer;
};

/* Opaque data for load_section_callback.  */
struct load_section_data
{
  load_section_data (load_progress_data *progress_data_)
    : progress_data (progress_data_)
  {}

  ~load_section_data ()
  {
    for (auto &&request : requests)
      {
	xfree (request.data);
	delete ((load_progress_section_data *) request.baton);
      }
  }

  CORE_ADDR load_offset = 0;
  struct load_progress_data *progress_data;
  std::vector<struct memory_write_request> requests;
};

/* Target write callback routine for progress reporting.  */

static void
load_progress (ULONGEST bytes, void *untyped_arg)
{
  struct load_progress_section_data *args
    = (struct load_progress_section_data *) untyped_arg;
  struct load_progress_data *totals;

  if (args == NULL)
    /* Writing padding data.  No easy way to get at the cumulative
       stats, so just ignore this.  */
    return;

  totals = args->cumulative;

  if (bytes == 0 && args->section_sent == 0)
    {
      /* The write is just starting.  Let the user know we've started
	 this section.  */
      current_uiout->message ("Loading section %s, size %s lma %s\n",
			      args->section_name,
			      hex_string (args->section_size),
			      paddress (target_gdbarch (), args->lma));
      return;
    }

  if (validate_download)
    {
      /* Broken memories and broken monitors manifest themselves here
	 when bring new computers to life.  This doubles already slow
	 downloads.  */
      /* NOTE: cagney/1999-10-18: A more efficient implementation
	 might add a verify_memory() method to the target vector and
	 then use that.  remote.c could implement that method using
	 the ``qCRC'' packet.  */
      gdb::byte_vector check (bytes);

      if (target_read_memory (args->lma, check.data (), bytes) != 0)
	error (_("Download verify read failed at %s"),
	       paddress (target_gdbarch (), args->lma));
      if (memcmp (args->buffer, check.data (), bytes) != 0)
	error (_("Download verify compare failed at %s"),
	       paddress (target_gdbarch (), args->lma));
    }
  totals->data_count += bytes;
  args->lma += bytes;
  args->buffer += bytes;
  totals->write_count += 1;
  args->section_sent += bytes;
  if (check_quit_flag ()
      || (deprecated_ui_load_progress_hook != NULL
	  && deprecated_ui_load_progress_hook (args->section_name,
					       args->section_sent)))
    error (_("Canceled the download"));

  if (deprecated_show_load_progress != NULL)
    deprecated_show_load_progress (args->section_name,
				   args->section_sent,
				   args->section_size,
				   totals->data_count,
				   totals->total_size);
}

/* Service function for generic_load.  */

static void
load_one_section (bfd *abfd, asection *asec,
		  struct load_section_data *args)
{
  bfd_size_type size = bfd_section_size (asec);
  const char *sect_name = bfd_section_name (asec);

  if ((bfd_section_flags (asec) & SEC_LOAD) == 0)
    return;

  if (size == 0)
    return;

  ULONGEST begin = bfd_section_lma (asec) + args->load_offset;
  ULONGEST end = begin + size;
  gdb_byte *buffer = (gdb_byte *) xmalloc (size);
  bfd_get_section_contents (abfd, asec, buffer, 0, size);

  load_progress_section_data *section_data
    = new load_progress_section_data (args->progress_data, sect_name, size,
				      begin, buffer);

  args->requests.emplace_back (begin, end, buffer, section_data);
}

static void print_transfer_performance (struct ui_file *stream,
					unsigned long data_count,
					unsigned long write_count,
					std::chrono::steady_clock::duration d);

/* See symfile.h.  */

void
generic_load (const char *args, int from_tty)
{
  struct load_progress_data total_progress;
  struct load_section_data cbdata (&total_progress);
  struct ui_out *uiout = current_uiout;

  if (args == NULL)
    error_no_arg (_("file to load"));

  gdb_argv argv (args);

  gdb::unique_xmalloc_ptr<char> filename (tilde_expand (argv[0]));

  if (argv[1] != NULL)
    {
      const char *endptr;

      cbdata.load_offset = strtoulst (argv[1], &endptr, 0);

      /* If the last word was not a valid number then
	 treat it as a file name with spaces in.  */
      if (argv[1] == endptr)
	error (_("Invalid download offset:%s."), argv[1]);

      if (argv[2] != NULL)
	error (_("Too many parameters."));
    }

  /* Open the file for loading.  */
  gdb_bfd_ref_ptr loadfile_bfd (gdb_bfd_open (filename.get (), gnutarget));
  if (loadfile_bfd == NULL)
    perror_with_name (filename.get ());

  if (!bfd_check_format (loadfile_bfd.get (), bfd_object))
    {
      error (_("\"%s\" is not an object file: %s"), filename.get (),
	     bfd_errmsg (bfd_get_error ()));
    }

  for (asection *asec : gdb_bfd_sections (loadfile_bfd))
    total_progress.total_size += bfd_section_size (asec);

  for (asection *asec : gdb_bfd_sections (loadfile_bfd))
    load_one_section (loadfile_bfd.get (), asec, &cbdata);

  using namespace std::chrono;

  steady_clock::time_point start_time = steady_clock::now ();

  if (target_write_memory_blocks (cbdata.requests, flash_discard,
				  load_progress) != 0)
    error (_("Load failed"));

  steady_clock::time_point end_time = steady_clock::now ();

  CORE_ADDR entry = bfd_get_start_address (loadfile_bfd.get ());
  entry = gdbarch_addr_bits_remove (target_gdbarch (), entry);
  uiout->text ("Start address ");
  uiout->field_core_addr ("address", target_gdbarch (), entry);
  uiout->text (", load size ");
  uiout->field_unsigned ("load-size", total_progress.data_count);
  uiout->text ("\n");
  regcache_write_pc (get_current_regcache (), entry);

  /* Reset breakpoints, now that we have changed the load image.  For
     instance, breakpoints may have been set (or reset, by
     post_create_inferior) while connected to the target but before we
     loaded the program.  In that case, the prologue analyzer could
     have read instructions from the target to find the right
     breakpoint locations.  Loading has changed the contents of that
     memory.  */

  breakpoint_re_set ();

  print_transfer_performance (gdb_stdout, total_progress.data_count,
			      total_progress.write_count,
			      end_time - start_time);
}

/* Report on STREAM the performance of a memory transfer operation,
   such as 'load'.  DATA_COUNT is the number of bytes transferred.
   WRITE_COUNT is the number of separate write operations, or 0, if
   that information is not available.  TIME is how long the operation
   lasted.  */

static void
print_transfer_performance (struct ui_file *stream,
			    unsigned long data_count,
			    unsigned long write_count,
			    std::chrono::steady_clock::duration time)
{
  using namespace std::chrono;
  struct ui_out *uiout = current_uiout;

  milliseconds ms = duration_cast<milliseconds> (time);

  uiout->text ("Transfer rate: ");
  if (ms.count () > 0)
    {
      unsigned long rate = ((ULONGEST) data_count * 1000) / ms.count ();

      if (uiout->is_mi_like_p ())
	{
	  uiout->field_unsigned ("transfer-rate", rate * 8);
	  uiout->text (" bits/sec");
	}
      else if (rate < 1024)
	{
	  uiout->field_unsigned ("transfer-rate", rate);
	  uiout->text (" bytes/sec");
	}
      else
	{
	  uiout->field_unsigned ("transfer-rate", rate / 1024);
	  uiout->text (" KB/sec");
	}
    }
  else
    {
      uiout->field_unsigned ("transferred-bits", (data_count * 8));
      uiout->text (" bits in <1 sec");
    }
  if (write_count > 0)
    {
      uiout->text (", ");
      uiout->field_unsigned ("write-rate", data_count / write_count);
      uiout->text (" bytes/write");
    }
  uiout->text (".\n");
}

/* Add an OFFSET to the start address of each section in OBJF, except
   sections that were specified in ADDRS.  */

static void
set_objfile_default_section_offset (struct objfile *objf,
				    const section_addr_info &addrs,
				    CORE_ADDR offset)
{
  /* Add OFFSET to all sections by default.  */
  section_offsets offsets (objf->section_offsets.size (), offset);

  /* Create sorted lists of all sections in ADDRS as well as all
     sections in OBJF.  */

  std::vector<const struct other_sections *> addrs_sorted
    = addrs_section_sort (addrs);

  section_addr_info objf_addrs
    = build_section_addr_info_from_objfile (objf);
  std::vector<const struct other_sections *> objf_addrs_sorted
    = addrs_section_sort (objf_addrs);

  /* Walk the BFD section list, and if a matching section is found in
     ADDRS_SORTED_LIST, set its offset to zero to keep its address
     unchanged.

     Note that both lists may contain multiple sections with the same
     name, and then the sections from ADDRS are matched in BFD order
     (thanks to sectindex).  */

  std::vector<const struct other_sections *>::iterator addrs_sorted_iter
    = addrs_sorted.begin ();
  for (const other_sections *objf_sect : objf_addrs_sorted)
    {
      const char *objf_name = addr_section_name (objf_sect->name.c_str ());
      int cmp = -1;

      while (cmp < 0 && addrs_sorted_iter != addrs_sorted.end ())
	{
	  const struct other_sections *sect = *addrs_sorted_iter;
	  const char *sect_name = addr_section_name (sect->name.c_str ());
	  cmp = strcmp (sect_name, objf_name);
	  if (cmp <= 0)
	    ++addrs_sorted_iter;
	}

      if (cmp == 0)
	offsets[objf_sect->sectindex] = 0;
    }

  /* Apply the new section offsets.  */
  objfile_relocate (objf, offsets);
}

/* This function allows the addition of incrementally linked object files.
   It does not modify any state in the target, only in the debugger.  */

static void
add_symbol_file_command (const char *args, int from_tty)
{
  struct gdbarch *gdbarch = get_current_arch ();
  gdb::unique_xmalloc_ptr<char> filename;
  char *arg;
  int argcnt = 0;
  struct objfile *objf;
  objfile_flags flags = OBJF_USERLOADED | OBJF_SHARED;
  symfile_add_flags add_flags = 0;

  if (from_tty)
    add_flags |= SYMFILE_VERBOSE;

  struct sect_opt
  {
    const char *name;
    const char *value;
  };

  std::vector<sect_opt> sect_opts = { { ".text", NULL } };
  bool stop_processing_options = false;
  CORE_ADDR offset = 0;

  dont_repeat ();

  if (args == NULL)
    error (_("add-symbol-file takes a file name and an address"));

  bool seen_addr = false;
  bool seen_offset = false;
  gdb_argv argv (args);

  for (arg = argv[0], argcnt = 0; arg != NULL; arg = argv[++argcnt])
    {
      if (stop_processing_options || *arg != '-')
	{
	  if (filename == NULL)
	    {
	      /* First non-option argument is always the filename.  */
	      filename.reset (tilde_expand (arg));
	    }
	  else if (!seen_addr)
	    {
	      /* The second non-option argument is always the text
		 address at which to load the program.  */
	      sect_opts[0].value = arg;
	      seen_addr = true;
	    }
	  else
	    error (_("Unrecognized argument \"%s\""), arg);
	}
      else if (strcmp (arg, "-readnow") == 0)
	flags |= OBJF_READNOW;
      else if (strcmp (arg, "-readnever") == 0)
	flags |= OBJF_READNEVER;
      else if (strcmp (arg, "-s") == 0)
	{
	  if (argv[argcnt + 1] == NULL)
	    error (_("Missing section name after \"-s\""));
	  else if (argv[argcnt + 2] == NULL)
	    error (_("Missing section address after \"-s\""));

	  sect_opt sect = { argv[argcnt + 1], argv[argcnt + 2] };

	  sect_opts.push_back (sect);
	  argcnt += 2;
	}
      else if (strcmp (arg, "-o") == 0)
	{
	  arg = argv[++argcnt];
	  if (arg == NULL)
	    error (_("Missing argument to -o"));

	  offset = parse_and_eval_address (arg);
	  seen_offset = true;
	}
      else if (strcmp (arg, "--") == 0)
	stop_processing_options = true;
      else
	error (_("Unrecognized argument \"%s\""), arg);
    }

  if (filename == NULL)
    error (_("You must provide a filename to be loaded."));

  validate_readnow_readnever (flags);

  /* Print the prompt for the query below.  And save the arguments into
     a sect_addr_info structure to be passed around to other
     functions.  We have to split this up into separate print
     statements because hex_string returns a local static
     string.  */

  printf_unfiltered (_("add symbol table from file \"%s\""),
		     filename.get ());
  section_addr_info section_addrs;
  std::vector<sect_opt>::const_iterator it = sect_opts.begin ();
  if (!seen_addr)
    ++it;
  for (; it != sect_opts.end (); ++it)
    {
      CORE_ADDR addr;
      const char *val = it->value;
      const char *sec = it->name;

      if (section_addrs.empty ())
	printf_unfiltered (_(" at\n"));
      addr = parse_and_eval_address (val);

      /* Here we store the section offsets in the order they were
	 entered on the command line.  Every array element is
	 assigned an ascending section index to preserve the above
	 order over an unstable sorting algorithm.  This dummy
	 index is not used for any other purpose.
      */
      section_addrs.emplace_back (addr, sec, section_addrs.size ());
      printf_filtered ("\t%s_addr = %s\n", sec,
		       paddress (gdbarch, addr));

      /* The object's sections are initialized when a
	 call is made to build_objfile_section_table (objfile).
	 This happens in reread_symbols.
	 At this point, we don't know what file type this is,
	 so we can't determine what section names are valid.  */
    }
  if (seen_offset)
      printf_unfiltered (_("%s offset by %s\n"),
			 (section_addrs.empty ()
			  ? _(" with all sections")
			  : _("with other sections")),
			 paddress (gdbarch, offset));
  else if (section_addrs.empty ())
    printf_unfiltered ("\n");

  if (from_tty && (!query ("%s", "")))
    error (_("Not confirmed."));

  objf = symbol_file_add (filename.get (), add_flags, &section_addrs,
			  flags);
  if (!objfile_has_symbols (objf) && objf->per_bfd->minimal_symbol_count <= 0)
    warning (_("newly-added symbol file \"%s\" does not provide any symbols"),
	     filename.get ());

  if (seen_offset)
    set_objfile_default_section_offset (objf, section_addrs, offset);

  current_program_space->add_target_sections (objf);

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

/* This function removes a symbol file that was added via add-symbol-file.  */

static void
remove_symbol_file_command (const char *args, int from_tty)
{
  struct objfile *objf = NULL;
  struct program_space *pspace = current_program_space;

  dont_repeat ();

  if (args == NULL)
    error (_("remove-symbol-file: no symbol file provided"));

  gdb_argv argv (args);

  if (strcmp (argv[0], "-a") == 0)
    {
      /* Interpret the next argument as an address.  */
      CORE_ADDR addr;

      if (argv[1] == NULL)
	error (_("Missing address argument"));

      if (argv[2] != NULL)
	error (_("Junk after %s"), argv[1]);

      addr = parse_and_eval_address (argv[1]);

      for (objfile *objfile : current_program_space->objfiles ())
	{
	  if ((objfile->flags & OBJF_USERLOADED) != 0
	      && (objfile->flags & OBJF_SHARED) != 0
	      && objfile->pspace == pspace
	      && is_addr_in_objfile (addr, objfile))
	    {
	      objf = objfile;
	      break;
	    }
	}
    }
  else if (argv[0] != NULL)
    {
      /* Interpret the current argument as a file name.  */

      if (argv[1] != NULL)
	error (_("Junk after %s"), argv[0]);

      gdb::unique_xmalloc_ptr<char> filename (tilde_expand (argv[0]));

      for (objfile *objfile : current_program_space->objfiles ())
	{
	  if ((objfile->flags & OBJF_USERLOADED) != 0
	      && (objfile->flags & OBJF_SHARED) != 0
	      && objfile->pspace == pspace
	      && filename_cmp (filename.get (), objfile_name (objfile)) == 0)
	    {
	      objf = objfile;
	      break;
	    }
	}
    }

  if (objf == NULL)
    error (_("No symbol file found"));

  if (from_tty
      && !query (_("Remove symbol table from file \"%s\"? "),
		 objfile_name (objf)))
    error (_("Not confirmed."));

  objf->unlink ();
  clear_symtab_users (0);
}

/* Re-read symbols if a symbol-file has changed.  */

void
reread_symbols (void)
{
  long new_modtime;
  struct stat new_statbuf;
  int res;
  std::vector<struct objfile *> new_objfiles;

  for (objfile *objfile : current_program_space->objfiles ())
    {
      if (objfile->obfd == NULL)
	continue;

      /* Separate debug objfiles are handled in the main objfile.  */
      if (objfile->separate_debug_objfile_backlink)
	continue;

      /* If this object is from an archive (what you usually create with
	 `ar', often called a `static library' on most systems, though
	 a `shared library' on AIX is also an archive), then you should
	 stat on the archive name, not member name.  */
      if (objfile->obfd->my_archive)
	res = stat (bfd_get_filename (objfile->obfd->my_archive), &new_statbuf);
      else
	res = stat (objfile_name (objfile), &new_statbuf);
      if (res != 0)
	{
	  /* FIXME, should use print_sys_errmsg but it's not filtered.  */
	  printf_filtered (_("`%s' has disappeared; keeping its symbols.\n"),
			   objfile_name (objfile));
	  continue;
	}
      new_modtime = new_statbuf.st_mtime;
      if (new_modtime != objfile->mtime)
	{
	  printf_filtered (_("`%s' has changed; re-reading symbols.\n"),
			   objfile_name (objfile));

	  /* There are various functions like symbol_file_add,
	     symfile_bfd_open, syms_from_objfile, etc., which might
	     appear to do what we want.  But they have various other
	     effects which we *don't* want.  So we just do stuff
	     ourselves.  We don't worry about mapped files (for one thing,
	     any mapped file will be out of date).  */

	  /* If we get an error, blow away this objfile (not sure if
	     that is the correct response for things like shared
	     libraries).  */
	  objfile_up objfile_holder (objfile);

	  /* We need to do this whenever any symbols go away.  */
	  clear_symtab_users_cleanup defer_clear_users (0);

	  if (current_program_space->exec_bfd () != NULL
	      && filename_cmp (bfd_get_filename (objfile->obfd),
			       bfd_get_filename (current_program_space->exec_bfd ())) == 0)
	    {
	      /* Reload EXEC_BFD without asking anything.  */

	      exec_file_attach (bfd_get_filename (objfile->obfd), 0);
	    }

	  /* Keep the calls order approx. the same as in free_objfile.  */

	  /* Free the separate debug objfiles.  It will be
	     automatically recreated by sym_read.  */
	  free_objfile_separate_debug (objfile);

	  /* Clear the stale source cache.  */
	  forget_cached_source_info ();

	  /* Remove any references to this objfile in the global
	     value lists.  */
	  preserve_values (objfile);

	  /* Nuke all the state that we will re-read.  Much of the following
	     code which sets things to NULL really is necessary to tell
	     other parts of GDB that there is nothing currently there.

	     Try to keep the freeing order compatible with free_objfile.  */

	  if (objfile->sf != NULL)
	    {
	      (*objfile->sf->sym_finish) (objfile);
	    }

	  clear_objfile_data (objfile);

	  /* Clean up any state BFD has sitting around.  */
	  {
	    gdb_bfd_ref_ptr obfd (objfile->obfd);
	    const char *obfd_filename;

	    obfd_filename = bfd_get_filename (objfile->obfd);
	    /* Open the new BFD before freeing the old one, so that
	       the filename remains live.  */
	    gdb_bfd_ref_ptr temp (gdb_bfd_open (obfd_filename, gnutarget));
	    objfile->obfd = temp.release ();
	    if (objfile->obfd == NULL)
	      error (_("Can't open %s to read symbols."), obfd_filename);
	  }

	  std::string original_name = objfile->original_name;

	  /* bfd_openr sets cacheable to true, which is what we want.  */
	  if (!bfd_check_format (objfile->obfd, bfd_object))
	    error (_("Can't read symbols from %s: %s."), objfile_name (objfile),
		   bfd_errmsg (bfd_get_error ()));

	  /* NB: after this call to obstack_free, objfiles_changed
	     will need to be called (see discussion below).  */
	  obstack_free (&objfile->objfile_obstack, 0);
	  objfile->sections = NULL;
	  objfile->section_offsets.clear ();
	  objfile->sect_index_bss = -1;
	  objfile->sect_index_data = -1;
	  objfile->sect_index_rodata = -1;
	  objfile->sect_index_text = -1;
	  objfile->compunit_symtabs = NULL;
	  objfile->template_symbols = NULL;
	  objfile->static_links.reset (nullptr);

	  /* obstack_init also initializes the obstack so it is
	     empty.  We could use obstack_specify_allocation but
	     gdb_obstack.h specifies the alloc/dealloc functions.  */
	  obstack_init (&objfile->objfile_obstack);

	  /* set_objfile_per_bfd potentially allocates the per-bfd
	     data on the objfile's obstack (if sharing data across
	     multiple users is not possible), so it's important to
	     do it *after* the obstack has been initialized.  */
	  set_objfile_per_bfd (objfile);

	  objfile->original_name
	    = obstack_strdup (&objfile->objfile_obstack, original_name);

	  /* Reset the sym_fns pointer.  The ELF reader can change it
	     based on whether .gdb_index is present, and we need it to
	     start over.  PR symtab/15885  */
	  objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd));
	  objfile->qf.clear ();

	  build_objfile_section_table (objfile);

	  /* What the hell is sym_new_init for, anyway?  The concept of
	     distinguishing between the main file and additional files
	     in this way seems rather dubious.  */
	  if (objfile == current_program_space->symfile_object_file)
	    {
	      (*objfile->sf->sym_new_init) (objfile);
	    }

	  (*objfile->sf->sym_init) (objfile);
	  clear_complaints ();

	  objfile->flags &= ~OBJF_PSYMTABS_READ;

	  /* We are about to read new symbols and potentially also
	     DWARF information.  Some targets may want to pass addresses
	     read from DWARF DIE's through an adjustment function before
	     saving them, like MIPS, which may call into
	     "find_pc_section".  When called, that function will make
	     use of per-objfile program space data.

	     Since we discarded our section information above, we have
	     dangling pointers in the per-objfile program space data
	     structure.  Force GDB to update the section mapping
	     information by letting it know the objfile has changed,
	     making the dangling pointers point to correct data
	     again.  */

	  objfiles_changed ();

	  /* Recompute section offsets and section indices.  */
	  objfile->sf->sym_offsets (objfile, {});

	  read_symbols (objfile, 0);

	  if (!objfile_has_symbols (objfile))
	    {
	      wrap_here ("");
	      printf_filtered (_("(no debugging symbols found)\n"));
	      wrap_here ("");
	    }

	  /* We're done reading the symbol file; finish off complaints.  */
	  clear_complaints ();

	  /* Getting new symbols may change our opinion about what is
	     frameless.  */

	  reinit_frame_cache ();

	  /* Discard cleanups as symbol reading was successful.  */
	  objfile_holder.release ();
	  defer_clear_users.release ();

	  /* If the mtime has changed between the time we set new_modtime
	     and now, we *want* this to be out of date, so don't call stat
	     again now.  */
	  objfile->mtime = new_modtime;
	  init_entry_point_info (objfile);

	  new_objfiles.push_back (objfile);
	}
    }

  if (!new_objfiles.empty ())
    {
      clear_symtab_users (0);

      /* clear_objfile_data for each objfile was called before freeing it and
	 gdb::observers::new_objfile.notify (NULL) has been called by
	 clear_symtab_users above.  Notify the new files now.  */
      for (auto iter : new_objfiles)
	gdb::observers::new_objfile.notify (iter);

      /* At least one objfile has changed, so we can consider that
	 the executable we're debugging has changed too.  */
      gdb::observers::executable_changed.notify ();
    }
}


struct filename_language
{
  filename_language (const std::string &ext_, enum language lang_)
  : ext (ext_), lang (lang_)
  {}

  std::string ext;
  enum language lang;
};

static std::vector<filename_language> filename_language_table;

/* See symfile.h.  */

void
add_filename_language (const char *ext, enum language lang)
{
  gdb_assert (ext != nullptr);
  filename_language_table.emplace_back (ext, lang);
}

static char *ext_args;
static void
show_ext_args (struct ui_file *file, int from_tty,
	       struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("Mapping between filename extension "
		      "and source language is \"%s\".\n"),
		    value);
}

static void
set_ext_lang_command (const char *args,
		      int from_tty, struct cmd_list_element *e)
{
  char *cp = ext_args;
  enum language lang;

  /* First arg is filename extension, starting with '.'  */
  if (*cp != '.')
    error (_("'%s': Filename extension must begin with '.'"), ext_args);

  /* Find end of first arg.  */
  while (*cp && !isspace (*cp))
    cp++;

  if (*cp == '\0')
    error (_("'%s': two arguments required -- "
	     "filename extension and language"),
	   ext_args);

  /* Null-terminate first arg.  */
  *cp++ = '\0';

  /* Find beginning of second arg, which should be a source language.  */
  cp = skip_spaces (cp);

  if (*cp == '\0')
    error (_("'%s': two arguments required -- "
	     "filename extension and language"),
	   ext_args);

  /* Lookup the language from among those we know.  */
  lang = language_enum (cp);

  auto it = filename_language_table.begin ();
  /* Now lookup the filename extension: do we already know it?  */
  for (; it != filename_language_table.end (); it++)
    {
      if (it->ext == ext_args)
	break;
    }

  if (it == filename_language_table.end ())
    {
      /* New file extension.  */
      add_filename_language (ext_args, lang);
    }
  else
    {
      /* Redefining a previously known filename extension.  */

      /* if (from_tty) */
      /*   query ("Really make files of type %s '%s'?", */
      /*          ext_args, language_str (lang));           */

      it->lang = lang;
    }
}

static void
info_ext_lang_command (const char *args, int from_tty)
{
  printf_filtered (_("Filename extensions and the languages they represent:"));
  printf_filtered ("\n\n");
  for (const filename_language &entry : filename_language_table)
    printf_filtered ("\t%s\t- %s\n", entry.ext.c_str (),
		     language_str (entry.lang));
}

enum language
deduce_language_from_filename (const char *filename)
{
  const char *cp;

  if (filename != NULL)
    if ((cp = strrchr (filename, '.')) != NULL)
      {
	for (const filename_language &entry : filename_language_table)
	  if (entry.ext == cp)
	    return entry.lang;
      }

  return language_unknown;
}

/* Allocate and initialize a new symbol table.
   CUST is from the result of allocate_compunit_symtab.  */

struct symtab *
allocate_symtab (struct compunit_symtab *cust, const char *filename)
{
  struct objfile *objfile = cust->objfile;
  struct symtab *symtab
    = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symtab);

  symtab->filename = objfile->intern (filename);
  symtab->fullname = NULL;
  symtab->language = deduce_language_from_filename (filename);

  /* This can be very verbose with lots of headers.
     Only print at higher debug levels.  */
  if (symtab_create_debug >= 2)
    {
      /* Be a bit clever with debugging messages, and don't print objfile
	 every time, only when it changes.  */
      static std::string last_objfile_name;
      const char *this_objfile_name = objfile_name (objfile);

      if (last_objfile_name.empty () || last_objfile_name != this_objfile_name)
	{
	  last_objfile_name = this_objfile_name;
	  fprintf_filtered (gdb_stdlog,
			    "Creating one or more symtabs for objfile %s ...\n",
			    this_objfile_name);
	}
      fprintf_filtered (gdb_stdlog,
			"Created symtab %s for module %s.\n",
			host_address_to_string (symtab), filename);
    }

  /* Add it to CUST's list of symtabs.  */
  if (cust->filetabs == NULL)
    {
      cust->filetabs = symtab;
      cust->last_filetab = symtab;
    }
  else
    {
      cust->last_filetab->next = symtab;
      cust->last_filetab = symtab;
    }

  /* Backlink to the containing compunit symtab.  */
  symtab->compunit_symtab = cust;

  return symtab;
}

/* Allocate and initialize a new compunit.
   NAME is the name of the main source file, if there is one, or some
   descriptive text if there are no source files.  */

struct compunit_symtab *
allocate_compunit_symtab (struct objfile *objfile, const char *name)
{
  struct compunit_symtab *cu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
					       struct compunit_symtab);
  const char *saved_name;

  cu->objfile = objfile;

  /* The name we record here is only for display/debugging purposes.
     Just save the basename to avoid path issues (too long for display,
     relative vs absolute, etc.).  */
  saved_name = lbasename (name);
  cu->name = obstack_strdup (&objfile->objfile_obstack, saved_name);

  COMPUNIT_DEBUGFORMAT (cu) = "unknown";

  if (symtab_create_debug)
    {
      fprintf_filtered (gdb_stdlog,
			"Created compunit symtab %s for %s.\n",
			host_address_to_string (cu),
			cu->name);
    }

  return cu;
}

/* Hook CU to the objfile it comes from.  */

void
add_compunit_symtab_to_objfile (struct compunit_symtab *cu)
{
  cu->next = cu->objfile->compunit_symtabs;
  cu->objfile->compunit_symtabs = cu;
}


/* Reset all data structures in gdb which may contain references to
   symbol table data.  */

void
clear_symtab_users (symfile_add_flags add_flags)
{
  /* Someday, we should do better than this, by only blowing away
     the things that really need to be blown.  */

  /* Clear the "current" symtab first, because it is no longer valid.
     breakpoint_re_set may try to access the current symtab.  */
  clear_current_source_symtab_and_line ();

  clear_displays ();
  clear_last_displayed_sal ();
  clear_pc_function_cache ();
  gdb::observers::new_objfile.notify (NULL);

  /* Varobj may refer to old symbols, perform a cleanup.  */
  varobj_invalidate ();

  /* Now that the various caches have been cleared, we can re_set
     our breakpoints without risking it using stale data.  */
  if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
    breakpoint_re_set ();
}

/* OVERLAYS:
   The following code implements an abstraction for debugging overlay sections.

   The target model is as follows:
   1) The gnu linker will permit multiple sections to be mapped into the
   same VMA, each with its own unique LMA (or load address).
   2) It is assumed that some runtime mechanism exists for mapping the
   sections, one by one, from the load address into the VMA address.
   3) This code provides a mechanism for gdb to keep track of which
   sections should be considered to be mapped from the VMA to the LMA.
   This information is used for symbol lookup, and memory read/write.
   For instance, if a section has been mapped then its contents
   should be read from the VMA, otherwise from the LMA.

   Two levels of debugger support for overlays are available.  One is
   "manual", in which the debugger relies on the user to tell it which
   overlays are currently mapped.  This level of support is
   implemented entirely in the core debugger, and the information about
   whether a section is mapped is kept in the objfile->obj_section table.

   The second level of support is "automatic", and is only available if
   the target-specific code provides functionality to read the target's
   overlay mapping table, and translate its contents for the debugger
   (by updating the mapped state information in the obj_section tables).

   The interface is as follows:
   User commands:
   overlay map <name>   -- tell gdb to consider this section mapped
   overlay unmap <name> -- tell gdb to consider this section unmapped
   overlay list         -- list the sections that GDB thinks are mapped
   overlay read-target  -- get the target's state of what's mapped
   overlay off/manual/auto -- set overlay debugging state
   Functional interface:
   find_pc_mapped_section(pc):    if the pc is in the range of a mapped
   section, return that section.
   find_pc_overlay(pc):       find any overlay section that contains
   the pc, either in its VMA or its LMA
   section_is_mapped(sect):       true if overlay is marked as mapped
   section_is_overlay(sect):      true if section's VMA != LMA
   pc_in_mapped_range(pc,sec):    true if pc belongs to section's VMA
   pc_in_unmapped_range(...):     true if pc belongs to section's LMA
   sections_overlap(sec1, sec2):  true if mapped sec1 and sec2 ranges overlap
   overlay_mapped_address(...):   map an address from section's LMA to VMA
   overlay_unmapped_address(...): map an address from section's VMA to LMA
   symbol_overlayed_address(...): Return a "current" address for symbol:
   either in VMA or LMA depending on whether
   the symbol's section is currently mapped.  */

/* Overlay debugging state: */

enum overlay_debugging_state overlay_debugging = ovly_off;
int overlay_cache_invalid = 0;	/* True if need to refresh mapped state.  */

/* Function: section_is_overlay (SECTION)
   Returns true if SECTION has VMA not equal to LMA, ie.
   SECTION is loaded at an address different from where it will "run".  */

int
section_is_overlay (struct obj_section *section)
{
  if (overlay_debugging && section)
    {
      asection *bfd_section = section->the_bfd_section;

      if (bfd_section_lma (bfd_section) != 0
	  && bfd_section_lma (bfd_section) != bfd_section_vma (bfd_section))
	return 1;
    }

  return 0;
}

/* Function: overlay_invalidate_all (void)
   Invalidate the mapped state of all overlay sections (mark it as stale).  */

static void
overlay_invalidate_all (void)
{
  struct obj_section *sect;

  for (objfile *objfile : current_program_space->objfiles ())
    ALL_OBJFILE_OSECTIONS (objfile, sect)
      if (section_is_overlay (sect))
	sect->ovly_mapped = -1;
}

/* Function: section_is_mapped (SECTION)
   Returns true if section is an overlay, and is currently mapped.

   Access to the ovly_mapped flag is restricted to this function, so
   that we can do automatic update.  If the global flag
   OVERLAY_CACHE_INVALID is set (by wait_for_inferior), then call
   overlay_invalidate_all.  If the mapped state of the particular
   section is stale, then call TARGET_OVERLAY_UPDATE to refresh it.  */

int
section_is_mapped (struct obj_section *osect)
{
  struct gdbarch *gdbarch;

  if (osect == 0 || !section_is_overlay (osect))
    return 0;

  switch (overlay_debugging)
    {
    default:
    case ovly_off:
      return 0;			/* overlay debugging off */
    case ovly_auto:		/* overlay debugging automatic */
      /* Unles there is a gdbarch_overlay_update function,
	 there's really nothing useful to do here (can't really go auto).  */
      gdbarch = osect->objfile->arch ();
      if (gdbarch_overlay_update_p (gdbarch))
	{
	  if (overlay_cache_invalid)
	    {
	      overlay_invalidate_all ();
	      overlay_cache_invalid = 0;
	    }
	  if (osect->ovly_mapped == -1)
	    gdbarch_overlay_update (gdbarch, osect);
	}
      /* fall thru */
    case ovly_on:		/* overlay debugging manual */
      return osect->ovly_mapped == 1;
    }
}

/* Function: pc_in_unmapped_range
   If PC falls into the lma range of SECTION, return true, else false.  */

CORE_ADDR
pc_in_unmapped_range (CORE_ADDR pc, struct obj_section *section)
{
  if (section_is_overlay (section))
    {
      asection *bfd_section = section->the_bfd_section;

      /* We assume the LMA is relocated by the same offset as the VMA.  */
      bfd_vma size = bfd_section_size (bfd_section);
      CORE_ADDR offset = obj_section_offset (section);

      if (bfd_section_lma (bfd_section) + offset <= pc
	  && pc < bfd_section_lma (bfd_section) + offset + size)
	return 1;
    }

  return 0;
}

/* Function: pc_in_mapped_range
   If PC falls into the vma range of SECTION, return true, else false.  */

CORE_ADDR
pc_in_mapped_range (CORE_ADDR pc, struct obj_section *section)
{
  if (section_is_overlay (section))
    {
      if (obj_section_addr (section) <= pc
	  && pc < obj_section_endaddr (section))
	return 1;
    }

  return 0;
}

/* Return true if the mapped ranges of sections A and B overlap, false
   otherwise.  */

static int
sections_overlap (struct obj_section *a, struct obj_section *b)
{
  CORE_ADDR a_start = obj_section_addr (a);
  CORE_ADDR a_end = obj_section_endaddr (a);
  CORE_ADDR b_start = obj_section_addr (b);
  CORE_ADDR b_end = obj_section_endaddr (b);

  return (a_start < b_end && b_start < a_end);
}

/* Function: overlay_unmapped_address (PC, SECTION)
   Returns the address corresponding to PC in the unmapped (load) range.
   May be the same as PC.  */

CORE_ADDR
overlay_unmapped_address (CORE_ADDR pc, struct obj_section *section)
{
  if (section_is_overlay (section) && pc_in_mapped_range (pc, section))
    {
      asection *bfd_section = section->the_bfd_section;

      return (pc + bfd_section_lma (bfd_section)
	      - bfd_section_vma (bfd_section));
    }

  return pc;
}

/* Function: overlay_mapped_address (PC, SECTION)
   Returns the address corresponding to PC in the mapped (runtime) range.
   May be the same as PC.  */

CORE_ADDR
overlay_mapped_address (CORE_ADDR pc, struct obj_section *section)
{
  if (section_is_overlay (section) && pc_in_unmapped_range (pc, section))
    {
      asection *bfd_section = section->the_bfd_section;

      return (pc + bfd_section_vma (bfd_section)
	      - bfd_section_lma (bfd_section));
    }

  return pc;
}

/* Function: symbol_overlayed_address
   Return one of two addresses (relative to the VMA or to the LMA),
   depending on whether the section is mapped or not.  */

CORE_ADDR
symbol_overlayed_address (CORE_ADDR address, struct obj_section *section)
{
  if (overlay_debugging)
    {
      /* If the symbol has no section, just return its regular address.  */
      if (section == 0)
	return address;
      /* If the symbol's section is not an overlay, just return its
	 address.  */
      if (!section_is_overlay (section))
	return address;
      /* If the symbol's section is mapped, just return its address.  */
      if (section_is_mapped (section))
	return address;
      /*
       * HOWEVER: if the symbol is in an overlay section which is NOT mapped,
       * then return its LOADED address rather than its vma address!!
       */
      return overlay_unmapped_address (address, section);
    }
  return address;
}

/* Function: find_pc_overlay (PC)
   Return the best-match overlay section for PC:
   If PC matches a mapped overlay section's VMA, return that section.
   Else if PC matches an unmapped section's VMA, return that section.
   Else if PC matches an unmapped section's LMA, return that section.  */

struct obj_section *
find_pc_overlay (CORE_ADDR pc)
{
  struct obj_section *osect, *best_match = NULL;

  if (overlay_debugging)
    {
      for (objfile *objfile : current_program_space->objfiles ())
	ALL_OBJFILE_OSECTIONS (objfile, osect)
	  if (section_is_overlay (osect))
	    {
	      if (pc_in_mapped_range (pc, osect))
		{
		  if (section_is_mapped (osect))
		    return osect;
		  else
		    best_match = osect;
		}
	      else if (pc_in_unmapped_range (pc, osect))
		best_match = osect;
	    }
    }
  return best_match;
}

/* Function: find_pc_mapped_section (PC)
   If PC falls into the VMA address range of an overlay section that is
   currently marked as MAPPED, return that section.  Else return NULL.  */

struct obj_section *
find_pc_mapped_section (CORE_ADDR pc)
{
  struct obj_section *osect;

  if (overlay_debugging)
    {
      for (objfile *objfile : current_program_space->objfiles ())
	ALL_OBJFILE_OSECTIONS (objfile, osect)
	  if (pc_in_mapped_range (pc, osect) && section_is_mapped (osect))
	    return osect;
    }

  return NULL;
}

/* Function: list_overlays_command
   Print a list of mapped sections and their PC ranges.  */

static void
list_overlays_command (const char *args, int from_tty)
{
  int nmapped = 0;
  struct obj_section *osect;

  if (overlay_debugging)
    {
      for (objfile *objfile : current_program_space->objfiles ())
	ALL_OBJFILE_OSECTIONS (objfile, osect)
	  if (section_is_mapped (osect))
	    {
	      struct gdbarch *gdbarch = objfile->arch ();
	      const char *name;
	      bfd_vma lma, vma;
	      int size;

	      vma = bfd_section_vma (osect->the_bfd_section);
	      lma = bfd_section_lma (osect->the_bfd_section);
	      size = bfd_section_size (osect->the_bfd_section);
	      name = bfd_section_name (osect->the_bfd_section);

	      printf_filtered ("Section %s, loaded at ", name);
	      fputs_filtered (paddress (gdbarch, lma), gdb_stdout);
	      puts_filtered (" - ");
	      fputs_filtered (paddress (gdbarch, lma + size), gdb_stdout);
	      printf_filtered (", mapped at ");
	      fputs_filtered (paddress (gdbarch, vma), gdb_stdout);
	      puts_filtered (" - ");
	      fputs_filtered (paddress (gdbarch, vma + size), gdb_stdout);
	      puts_filtered ("\n");

	      nmapped++;
	    }
    }
  if (nmapped == 0)
    printf_filtered (_("No sections are mapped.\n"));
}

/* Function: map_overlay_command
   Mark the named section as mapped (ie. residing at its VMA address).  */

static void
map_overlay_command (const char *args, int from_tty)
{
  struct obj_section *sec, *sec2;

  if (!overlay_debugging)
    error (_("Overlay debugging not enabled.  Use "
	     "either the 'overlay auto' or\n"
	     "the 'overlay manual' command."));

  if (args == 0 || *args == 0)
    error (_("Argument required: name of an overlay section"));

  /* First, find a section matching the user supplied argument.  */
  for (objfile *obj_file : current_program_space->objfiles ())
    ALL_OBJFILE_OSECTIONS (obj_file, sec)
      if (!strcmp (bfd_section_name (sec->the_bfd_section), args))
	{
	  /* Now, check to see if the section is an overlay.  */
	  if (!section_is_overlay (sec))
	    continue;		/* not an overlay section */

	  /* Mark the overlay as "mapped".  */
	  sec->ovly_mapped = 1;

	  /* Next, make a pass and unmap any sections that are
	     overlapped by this new section: */
	  for (objfile *objfile2 : current_program_space->objfiles ())
	    ALL_OBJFILE_OSECTIONS (objfile2, sec2)
	      if (sec2->ovly_mapped && sec != sec2 && sections_overlap (sec,
									sec2))
		{
		  if (info_verbose)
		    printf_unfiltered (_("Note: section %s unmapped by overlap\n"),
				       bfd_section_name (sec2->the_bfd_section));
		  sec2->ovly_mapped = 0; /* sec2 overlaps sec: unmap sec2.  */
		}
	  return;
	}
  error (_("No overlay section called %s"), args);
}

/* Function: unmap_overlay_command
   Mark the overlay section as unmapped
   (ie. resident in its LMA address range, rather than the VMA range).  */

static void
unmap_overlay_command (const char *args, int from_tty)
{
  struct obj_section *sec = NULL;

  if (!overlay_debugging)
    error (_("Overlay debugging not enabled.  "
	     "Use either the 'overlay auto' or\n"
	     "the 'overlay manual' command."));

  if (args == 0 || *args == 0)
    error (_("Argument required: name of an overlay section"));

  /* First, find a section matching the user supplied argument.  */
  for (objfile *objfile : current_program_space->objfiles ())
    ALL_OBJFILE_OSECTIONS (objfile, sec)
      if (!strcmp (bfd_section_name (sec->the_bfd_section), args))
	{
	  if (!sec->ovly_mapped)
	    error (_("Section %s is not mapped"), args);
	  sec->ovly_mapped = 0;
	  return;
	}
  error (_("No overlay section called %s"), args);
}

/* Function: overlay_auto_command
   A utility command to turn on overlay debugging.
   Possibly this should be done via a set/show command.  */

static void
overlay_auto_command (const char *args, int from_tty)
{
  overlay_debugging = ovly_auto;
  enable_overlay_breakpoints ();
  if (info_verbose)
    printf_unfiltered (_("Automatic overlay debugging enabled."));
}

/* Function: overlay_manual_command
   A utility command to turn on overlay debugging.
   Possibly this should be done via a set/show command.  */

static void
overlay_manual_command (const char *args, int from_tty)
{
  overlay_debugging = ovly_on;
  disable_overlay_breakpoints ();
  if (info_verbose)
    printf_unfiltered (_("Overlay debugging enabled."));
}

/* Function: overlay_off_command
   A utility command to turn on overlay debugging.
   Possibly this should be done via a set/show command.  */

static void
overlay_off_command (const char *args, int from_tty)
{
  overlay_debugging = ovly_off;
  disable_overlay_breakpoints ();
  if (info_verbose)
    printf_unfiltered (_("Overlay debugging disabled."));
}

static void
overlay_load_command (const char *args, int from_tty)
{
  struct gdbarch *gdbarch = get_current_arch ();

  if (gdbarch_overlay_update_p (gdbarch))
    gdbarch_overlay_update (gdbarch, NULL);
  else
    error (_("This target does not know how to read its overlay state."));
}

/* Command list chain containing all defined "overlay" subcommands.  */
static struct cmd_list_element *overlaylist;

/* Target Overlays for the "Simplest" overlay manager:

   This is GDB's default target overlay layer.  It works with the
   minimal overlay manager supplied as an example by Cygnus.  The
   entry point is via a function pointer "gdbarch_overlay_update",
   so targets that use a different runtime overlay manager can
   substitute their own overlay_update function and take over the
   function pointer.

   The overlay_update function pokes around in the target's data structures
   to see what overlays are mapped, and updates GDB's overlay mapping with
   this information.

   In this simple implementation, the target data structures are as follows:
   unsigned _novlys;            /# number of overlay sections #/
   unsigned _ovly_table[_novlys][4] = {
   {VMA, OSIZE, LMA, MAPPED},    /# one entry per overlay section #/
   {..., ...,  ..., ...},
   }
   unsigned _novly_regions;     /# number of overlay regions #/
   unsigned _ovly_region_table[_novly_regions][3] = {
   {VMA, OSIZE, MAPPED_TO_LMA},  /# one entry per overlay region #/
   {..., ...,  ...},
   }
   These functions will attempt to update GDB's mappedness state in the
   symbol section table, based on the target's mappedness state.

   To do this, we keep a cached copy of the target's _ovly_table, and
   attempt to detect when the cached copy is invalidated.  The main
   entry point is "simple_overlay_update(SECT), which looks up SECT in
   the cached table and re-reads only the entry for that section from
   the target (whenever possible).  */

/* Cached, dynamically allocated copies of the target data structures: */
static unsigned (*cache_ovly_table)[4] = 0;
static unsigned cache_novlys = 0;
static CORE_ADDR cache_ovly_table_base = 0;
enum ovly_index
  {
    VMA, OSIZE, LMA, MAPPED
  };

/* Throw away the cached copy of _ovly_table.  */

static void
simple_free_overlay_table (void)
{
  xfree (cache_ovly_table);
  cache_novlys = 0;
  cache_ovly_table = NULL;
  cache_ovly_table_base = 0;
}

/* Read an array of ints of size SIZE from the target into a local buffer.
   Convert to host order.  int LEN is number of ints.  */

static void
read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr,
			int len, int size, enum bfd_endian byte_order)
{
  /* FIXME (alloca): Not safe if array is very large.  */
  gdb_byte *buf = (gdb_byte *) alloca (len * size);
  int i;

  read_memory (memaddr, buf, len * size);
  for (i = 0; i < len; i++)
    myaddr[i] = extract_unsigned_integer (size * i + buf, size, byte_order);
}

/* Find and grab a copy of the target _ovly_table
   (and _novlys, which is needed for the table's size).  */

static int
simple_read_overlay_table (void)
{
  struct bound_minimal_symbol novlys_msym;
  struct bound_minimal_symbol ovly_table_msym;
  struct gdbarch *gdbarch;
  int word_size;
  enum bfd_endian byte_order;

  simple_free_overlay_table ();
  novlys_msym = lookup_minimal_symbol ("_novlys", NULL, NULL);
  if (! novlys_msym.minsym)
    {
      error (_("Error reading inferior's overlay table: "
	     "couldn't find `_novlys' variable\n"
	     "in inferior.  Use `overlay manual' mode."));
      return 0;
    }

  ovly_table_msym = lookup_bound_minimal_symbol ("_ovly_table");
  if (! ovly_table_msym.minsym)
    {
      error (_("Error reading inferior's overlay table: couldn't find "
	     "`_ovly_table' array\n"
	     "in inferior.  Use `overlay manual' mode."));
      return 0;
    }

  gdbarch = ovly_table_msym.objfile->arch ();
  word_size = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
  byte_order = gdbarch_byte_order (gdbarch);

  cache_novlys = read_memory_integer (BMSYMBOL_VALUE_ADDRESS (novlys_msym),
				      4, byte_order);
  cache_ovly_table
    = (unsigned int (*)[4]) xmalloc (cache_novlys * sizeof (*cache_ovly_table));
  cache_ovly_table_base = BMSYMBOL_VALUE_ADDRESS (ovly_table_msym);
  read_target_long_array (cache_ovly_table_base,
			  (unsigned int *) cache_ovly_table,
			  cache_novlys * 4, word_size, byte_order);

  return 1;			/* SUCCESS */
}

/* Function: simple_overlay_update_1
   A helper function for simple_overlay_update.  Assuming a cached copy
   of _ovly_table exists, look through it to find an entry whose vma,
   lma and size match those of OSECT.  Re-read the entry and make sure
   it still matches OSECT (else the table may no longer be valid).
   Set OSECT's mapped state to match the entry.  Return: 1 for
   success, 0 for failure.  */

static int
simple_overlay_update_1 (struct obj_section *osect)
{
  int i;
  asection *bsect = osect->the_bfd_section;
  struct gdbarch *gdbarch = osect->objfile->arch ();
  int word_size = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  for (i = 0; i < cache_novlys; i++)
    if (cache_ovly_table[i][VMA] == bfd_section_vma (bsect)
	&& cache_ovly_table[i][LMA] == bfd_section_lma (bsect))
      {
	read_target_long_array (cache_ovly_table_base + i * word_size,
				(unsigned int *) cache_ovly_table[i],
				4, word_size, byte_order);
	if (cache_ovly_table[i][VMA] == bfd_section_vma (bsect)
	    && cache_ovly_table[i][LMA] == bfd_section_lma (bsect))
	  {
	    osect->ovly_mapped = cache_ovly_table[i][MAPPED];
	    return 1;
	  }
	else	/* Warning!  Warning!  Target's ovly table has changed!  */
	  return 0;
      }
  return 0;
}

/* Function: simple_overlay_update
   If OSECT is NULL, then update all sections' mapped state
   (after re-reading the entire target _ovly_table).
   If OSECT is non-NULL, then try to find a matching entry in the
   cached ovly_table and update only OSECT's mapped state.
   If a cached entry can't be found or the cache isn't valid, then
   re-read the entire cache, and go ahead and update all sections.  */

void
simple_overlay_update (struct obj_section *osect)
{
  /* Were we given an osect to look up?  NULL means do all of them.  */
  if (osect)
    /* Have we got a cached copy of the target's overlay table?  */
    if (cache_ovly_table != NULL)
      {
	/* Does its cached location match what's currently in the
	   symtab?  */
	struct bound_minimal_symbol minsym
	  = lookup_minimal_symbol ("_ovly_table", NULL, NULL);

	if (minsym.minsym == NULL)
	  error (_("Error reading inferior's overlay table: couldn't "
		   "find `_ovly_table' array\n"
		   "in inferior.  Use `overlay manual' mode."));
	
	if (cache_ovly_table_base == BMSYMBOL_VALUE_ADDRESS (minsym))
	  /* Then go ahead and try to look up this single section in
	     the cache.  */
	  if (simple_overlay_update_1 (osect))
	    /* Found it!  We're done.  */
	    return;
      }

  /* Cached table no good: need to read the entire table anew.
     Or else we want all the sections, in which case it's actually
     more efficient to read the whole table in one block anyway.  */

  if (! simple_read_overlay_table ())
    return;

  /* Now may as well update all sections, even if only one was requested.  */
  for (objfile *objfile : current_program_space->objfiles ())
    ALL_OBJFILE_OSECTIONS (objfile, osect)
      if (section_is_overlay (osect))
	{
	  int i;
	  asection *bsect = osect->the_bfd_section;

	  for (i = 0; i < cache_novlys; i++)
	    if (cache_ovly_table[i][VMA] == bfd_section_vma (bsect)
		&& cache_ovly_table[i][LMA] == bfd_section_lma (bsect))
	      { /* obj_section matches i'th entry in ovly_table.  */
		osect->ovly_mapped = cache_ovly_table[i][MAPPED];
		break;		/* finished with inner for loop: break out.  */
	      }
	}
}

/* Default implementation for sym_relocate.  */

bfd_byte *
default_symfile_relocate (struct objfile *objfile, asection *sectp,
			  bfd_byte *buf)
{
  /* Use sectp->owner instead of objfile->obfd.  sectp may point to a
     DWO file.  */
  bfd *abfd = sectp->owner;

  /* We're only interested in sections with relocation
     information.  */
  if ((sectp->flags & SEC_RELOC) == 0)
    return NULL;

  /* We will handle section offsets properly elsewhere, so relocate as if
     all sections begin at 0.  */
  for (asection *sect : gdb_bfd_sections (abfd))
    {
      sect->output_section = sect;
      sect->output_offset = 0;
    }

  return bfd_simple_get_relocated_section_contents (abfd, sectp, buf, NULL);
}

/* Relocate the contents of a debug section SECTP in ABFD.  The
   contents are stored in BUF if it is non-NULL, or returned in a
   malloc'd buffer otherwise.

   For some platforms and debug info formats, shared libraries contain
   relocations against the debug sections (particularly for DWARF-2;
   one affected platform is PowerPC GNU/Linux, although it depends on
   the version of the linker in use).  Also, ELF object files naturally
   have unresolved relocations for their debug sections.  We need to apply
   the relocations in order to get the locations of symbols correct.
   Another example that may require relocation processing, is the
   DWARF-2 .eh_frame section in .o files, although it isn't strictly a
   debug section.  */

bfd_byte *
symfile_relocate_debug_section (struct objfile *objfile,
				asection *sectp, bfd_byte *buf)
{
  gdb_assert (objfile->sf->sym_relocate);

  return (*objfile->sf->sym_relocate) (objfile, sectp, buf);
}

symfile_segment_data_up
get_symfile_segment_data (bfd *abfd)
{
  const struct sym_fns *sf = find_sym_fns (abfd);

  if (sf == NULL)
    return NULL;

  return sf->sym_segments (abfd);
}

/* Given:
   - DATA, containing segment addresses from the object file ABFD, and
     the mapping from ABFD's sections onto the segments that own them,
     and
   - SEGMENT_BASES[0 .. NUM_SEGMENT_BASES - 1], holding the actual
     segment addresses reported by the target,
   store the appropriate offsets for each section in OFFSETS.

   If there are fewer entries in SEGMENT_BASES than there are segments
   in DATA, then apply SEGMENT_BASES' last entry to all the segments.

   If there are more entries, then ignore the extra.  The target may
   not be able to distinguish between an empty data segment and a
   missing data segment; a missing text segment is less plausible.  */

int
symfile_map_offsets_to_segments (bfd *abfd,
				 const struct symfile_segment_data *data,
				 section_offsets &offsets,
				 int num_segment_bases,
				 const CORE_ADDR *segment_bases)
{
  int i;
  asection *sect;

  /* It doesn't make sense to call this function unless you have some
     segment base addresses.  */
  gdb_assert (num_segment_bases > 0);

  /* If we do not have segment mappings for the object file, we
     can not relocate it by segments.  */
  gdb_assert (data != NULL);
  gdb_assert (data->segments.size () > 0);

  for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
    {
      int which = data->segment_info[i];

      gdb_assert (0 <= which && which <= data->segments.size ());

      /* Don't bother computing offsets for sections that aren't
	 loaded as part of any segment.  */
      if (! which)
	continue;

      /* Use the last SEGMENT_BASES entry as the address of any extra
	 segments mentioned in DATA->segment_info.  */
      if (which > num_segment_bases)
	which = num_segment_bases;

      offsets[i] = segment_bases[which - 1] - data->segments[which - 1].base;
    }

  return 1;
}

static void
symfile_find_segment_sections (struct objfile *objfile)
{
  bfd *abfd = objfile->obfd;
  int i;
  asection *sect;

  symfile_segment_data_up data
    = get_symfile_segment_data (objfile->obfd);
  if (data == NULL)
    return;

  if (data->segments.size () != 1 && data->segments.size () != 2)
    return;

  for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
    {
      int which = data->segment_info[i];

      if (which == 1)
	{
	  if (objfile->sect_index_text == -1)
	    objfile->sect_index_text = sect->index;

	  if (objfile->sect_index_rodata == -1)
	    objfile->sect_index_rodata = sect->index;
	}
      else if (which == 2)
	{
	  if (objfile->sect_index_data == -1)
	    objfile->sect_index_data = sect->index;

	  if (objfile->sect_index_bss == -1)
	    objfile->sect_index_bss = sect->index;
	}
    }
}

/* Listen for free_objfile events.  */

static void
symfile_free_objfile (struct objfile *objfile)
{
  /* Remove the target sections owned by this objfile.  */
  if (objfile != NULL)
    current_program_space->remove_target_sections ((void *) objfile);
}

/* Wrapper around the quick_symbol_functions expand_symtabs_matching "method".
   Expand all symtabs that match the specified criteria.
   See quick_symbol_functions.expand_symtabs_matching for details.  */

bool
expand_symtabs_matching
  (gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
   const lookup_name_info &lookup_name,
   gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
   gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
   block_search_flags search_flags,
   enum search_domain kind)
{
  for (objfile *objfile : current_program_space->objfiles ())
    if (!objfile->expand_symtabs_matching (file_matcher,
					   &lookup_name,
					   symbol_matcher,
					   expansion_notify,
					   search_flags,
					   UNDEF_DOMAIN,
					   kind))
      return false;
  return true;
}

/* Wrapper around the quick_symbol_functions map_symbol_filenames "method".
   Map function FUN over every file.
   See quick_symbol_functions.map_symbol_filenames for details.  */

void
map_symbol_filenames (gdb::function_view<symbol_filename_ftype> fun,
		      bool need_fullname)
{
  for (objfile *objfile : current_program_space->objfiles ())
    objfile->map_symbol_filenames (fun, need_fullname);
}

#if GDB_SELF_TEST

namespace selftests {
namespace filename_language {

static void test_filename_language ()
{
  /* This test messes up the filename_language_table global.  */
  scoped_restore restore_flt = make_scoped_restore (&filename_language_table);

  /* Test deducing an unknown extension.  */
  language lang = deduce_language_from_filename ("myfile.blah");
  SELF_CHECK (lang == language_unknown);

  /* Test deducing a known extension.  */
  lang = deduce_language_from_filename ("myfile.c");
  SELF_CHECK (lang == language_c);

  /* Test adding a new extension using the internal API.  */
  add_filename_language (".blah", language_pascal);
  lang = deduce_language_from_filename ("myfile.blah");
  SELF_CHECK (lang == language_pascal);
}

static void
test_set_ext_lang_command ()
{
  /* This test messes up the filename_language_table global.  */
  scoped_restore restore_flt = make_scoped_restore (&filename_language_table);

  /* Confirm that the .hello extension is not known.  */
  language lang = deduce_language_from_filename ("cake.hello");
  SELF_CHECK (lang == language_unknown);

  /* Test adding a new extension using the CLI command.  */
  auto args_holder = make_unique_xstrdup (".hello rust");
  ext_args = args_holder.get ();
  set_ext_lang_command (NULL, 1, NULL);

  lang = deduce_language_from_filename ("cake.hello");
  SELF_CHECK (lang == language_rust);

  /* Test overriding an existing extension using the CLI command.  */
  int size_before = filename_language_table.size ();
  args_holder.reset (xstrdup (".hello pascal"));
  ext_args = args_holder.get ();
  set_ext_lang_command (NULL, 1, NULL);
  int size_after = filename_language_table.size ();

  lang = deduce_language_from_filename ("cake.hello");
  SELF_CHECK (lang == language_pascal);
  SELF_CHECK (size_before == size_after);
}

} /* namespace filename_language */
} /* namespace selftests */

#endif /* GDB_SELF_TEST */

void _initialize_symfile ();
void
_initialize_symfile ()
{
  struct cmd_list_element *c;

  gdb::observers::free_objfile.attach (symfile_free_objfile, "symfile");

#define READNOW_READNEVER_HELP \
  "The '-readnow' option will cause GDB to read the entire symbol file\n\
immediately.  This makes the command slower, but may make future operations\n\
faster.\n\
The '-readnever' option will prevent GDB from reading the symbol file's\n\
symbolic debug information."

  c = add_cmd ("symbol-file", class_files, symbol_file_command, _("\
Load symbol table from executable file FILE.\n\
Usage: symbol-file [-readnow | -readnever] [-o OFF] FILE\n\
OFF is an optional offset which is added to each section address.\n\
The `file' command can also load symbol tables, as well as setting the file\n\
to execute.\n" READNOW_READNEVER_HELP), &cmdlist);
  set_cmd_completer (c, filename_completer);

  c = add_cmd ("add-symbol-file", class_files, add_symbol_file_command, _("\
Load symbols from FILE, assuming FILE has been dynamically loaded.\n\
Usage: add-symbol-file FILE [-readnow | -readnever] [-o OFF] [ADDR] \
[-s SECT-NAME SECT-ADDR]...\n\
ADDR is the starting address of the file's text.\n\
Each '-s' argument provides a section name and address, and\n\
should be specified if the data and bss segments are not contiguous\n\
with the text.  SECT-NAME is a section name to be loaded at SECT-ADDR.\n\
OFF is an optional offset which is added to the default load addresses\n\
of all sections for which no other address was specified.\n"
READNOW_READNEVER_HELP),
	       &cmdlist);
  set_cmd_completer (c, filename_completer);

  c = add_cmd ("remove-symbol-file", class_files,
	       remove_symbol_file_command, _("\
Remove a symbol file added via the add-symbol-file command.\n\
Usage: remove-symbol-file FILENAME\n\
       remove-symbol-file -a ADDRESS\n\
The file to remove can be identified by its filename or by an address\n\
that lies within the boundaries of this symbol file in memory."),
	       &cmdlist);

  c = add_cmd ("load", class_files, load_command, _("\
Dynamically load FILE into the running program.\n\
FILE symbols are recorded for access from GDB.\n\
Usage: load [FILE] [OFFSET]\n\
An optional load OFFSET may also be given as a literal address.\n\
When OFFSET is provided, FILE must also be provided.  FILE can be provided\n\
on its own."), &cmdlist);
  set_cmd_completer (c, filename_completer);

  cmd_list_element *overlay_cmd
    = add_basic_prefix_cmd ("overlay", class_support,
			    _("Commands for debugging overlays."), &overlaylist,
			    0, &cmdlist);

  add_com_alias ("ovly", overlay_cmd, class_support, 1);
  add_com_alias ("ov", overlay_cmd, class_support, 1);

  add_cmd ("map-overlay", class_support, map_overlay_command,
	   _("Assert that an overlay section is mapped."), &overlaylist);

  add_cmd ("unmap-overlay", class_support, unmap_overlay_command,
	   _("Assert that an overlay section is unmapped."), &overlaylist);

  add_cmd ("list-overlays", class_support, list_overlays_command,
	   _("List mappings of overlay sections."), &overlaylist);

  add_cmd ("manual", class_support, overlay_manual_command,
	   _("Enable overlay debugging."), &overlaylist);
  add_cmd ("off", class_support, overlay_off_command,
	   _("Disable overlay debugging."), &overlaylist);
  add_cmd ("auto", class_support, overlay_auto_command,
	   _("Enable automatic overlay debugging."), &overlaylist);
  add_cmd ("load-target", class_support, overlay_load_command,
	   _("Read the overlay mapping state from the target."), &overlaylist);

  /* Filename extension to source language lookup table: */
  add_setshow_string_noescape_cmd ("extension-language", class_files,
				   &ext_args, _("\
Set mapping between filename extension and source language."), _("\
Show mapping between filename extension and source language."), _("\
Usage: set extension-language .foo bar"),
				   set_ext_lang_command,
				   show_ext_args,
				   &setlist, &showlist);

  add_info ("extensions", info_ext_lang_command,
	    _("All filename extensions associated with a source language."));

  add_setshow_optional_filename_cmd ("debug-file-directory", class_support,
				     &debug_file_directory, _("\
Set the directories where separate debug symbols are searched for."), _("\
Show the directories where separate debug symbols are searched for."), _("\
Separate debug symbols are first searched for in the same\n\
directory as the binary, then in the `" DEBUG_SUBDIRECTORY "' subdirectory,\n\
and lastly at the path of the directory of the binary with\n\
each global debug-file-directory component prepended."),
				     NULL,
				     show_debug_file_directory,
				     &setlist, &showlist);

  add_setshow_enum_cmd ("symbol-loading", no_class,
			print_symbol_loading_enums, &print_symbol_loading,
			_("\
Set printing of symbol loading messages."), _("\
Show printing of symbol loading messages."), _("\
off   == turn all messages off\n\
brief == print messages for the executable,\n\
	 and brief messages for shared libraries\n\
full  == print messages for the executable,\n\
	 and messages for each shared library."),
			NULL,
			NULL,
			&setprintlist, &showprintlist);

  add_setshow_boolean_cmd ("separate-debug-file", no_class,
			   &separate_debug_file_debug, _("\
Set printing of separate debug info file search debug."), _("\
Show printing of separate debug info file search debug."), _("\
When on, GDB prints the searched locations while looking for separate debug \
info files."), NULL, NULL, &setdebuglist, &showdebuglist);

#if GDB_SELF_TEST
  selftests::register_test
    ("filename_language", selftests::filename_language::test_filename_language);
  selftests::register_test
    ("set_ext_lang_command",
     selftests::filename_language::test_set_ext_lang_command);
#endif
}
