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

   Copyright (C) 1990-2019 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/readline.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 "common/byte-vector.h"
#include "common/pathstuff.h"
#include "common/selftest.h"
#include "cli/cli-style.h"
#include "common/forward-scope-exit.h"

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

#include "psymtab.h"

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.  */
int readnow_symbol_files;	/* Read full symbols immediately.  */
int readnever_symbol_files;	/* Never read full symbols.  */

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

/* If non-zero, shared library symbols will be added automatically
   when the inferior is created, new libraries are loaded, or when
   attaching to the inferior.  This is almost always what users will
   want to have happen; but for very large programs, the startup time
   will be excessive, and so if this is a problem, the user can clear
   this flag and then add the shared library symbols as needed.  Note
   that there is a potential for confusion, since if the shared
   library symbols are not loaded, commands like "info fun" will *not*
   report all the functions that are actually present.  */

int auto_solib_add = 1;


/* 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.
   This function is called via bfd_map_over_sections.

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

void
find_lowest_section (bfd *abfd, asection *sect, void *obj)
{
  asection **lowest = (asection **) obj;

  if (0 == (bfd_get_section_flags (abfd, sect) & (SEC_ALLOC | SEC_LOAD)))
    return;
  if (!*lowest)
    *lowest = sect;		/* First loadable section */
  else if (bfd_section_vma (abfd, *lowest) > bfd_section_vma (abfd, sect))
    *lowest = sect;		/* A lower loadable section */
  else if (bfd_section_vma (abfd, *lowest) == bfd_section_vma (abfd, sect)
	   && (bfd_section_size (abfd, (*lowest))
	       <= bfd_section_size (abfd, 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 struct target_section *start,
                                            const struct target_section *end)
{
  const struct target_section *stp;

  section_addr_info sap;

  for (stp = start; stp != end; stp++)
    {
      struct bfd_section *asect = stp->the_bfd_section;
      bfd *abfd = asect->owner;

      if (bfd_get_section_flags (abfd, asect) & (SEC_ALLOC | SEC_LOAD)
	  && sap.size () < end - start)
	sap.emplace_back (stp->addr,
			  bfd_section_name (abfd, 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_get_section_flags (abfd, sec) & (SEC_ALLOC | SEC_LOAD))
      sap.emplace_back (bfd_get_section_vma (abfd, sec),
			bfd_get_section_name (abfd, 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->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->num_sections; i++)
    {
      if (ANOFFSET (objfile->section_offsets, i) != 0)
	{
	  break;
	}
    }
  if (i == objfile->num_sections)
    {
      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;
    }
}

/* The arguments to place_section.  */

struct place_section_arg
{
  struct section_offsets *offsets;
  CORE_ADDR lowest;
};

/* 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, void *obj)
{
  struct place_section_arg *arg = (struct place_section_arg *) obj;
  CORE_ADDR *offsets = arg->offsets->offsets, start_addr;
  int done;
  ULONGEST align = ((ULONGEST) 1) << bfd_get_section_alignment (abfd, sect);

  /* We are only interested in allocated sections.  */
  if ((bfd_get_section_flags (abfd, 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 = (arg->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_get_section_flags (abfd, 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_get_section_size (sect) > offsets[indx]
	    && start_addr < offsets[indx] + bfd_get_section_size (cur_sec))
	  {
	    start_addr = offsets[indx] + bfd_get_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;
  arg->lowest = start_addr + bfd_get_section_size (sect);
}

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

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

  memset (section_offsets, 0, SIZEOF_N_SECTION_OFFSETS (num_sections));

  /* 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->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
     continguous sections.  */
  lower_sect = NULL;
  bfd_map_over_sections (abfd, find_lowest_section, &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 (bfd_get_filename (abfd), 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->num_sections = gdb_bfd_count_sections (objfile->obfd);
  objfile->section_offsets = (struct section_offsets *)
    obstack_alloc (&objfile->objfile_obstack,
		   SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
  relative_addr_info_to_section_offsets (objfile->section_offsets,
					 objfile->num_sections, 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)
    {
      struct place_section_arg arg;
      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 (abfd, cur_sec) != 0)
	  break;

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

	  /* Pick non-overlapping offsets for sections the user did not
	     place explicitly.  */
	  arg.offsets = objfile->section_offsets;
	  arg.lowest = 0;
	  bfd_map_over_sections (objfile->obfd, place_section, &arg);

	  /* 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_get_section_flags (abfd, cur_sec) & SEC_ALLOC) == 0)
		continue;

	      bfd_set_section_vma (abfd, 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.  */

struct symfile_segment_data *
default_symfile_segments (bfd *abfd)
{
  int num_sections, i;
  asection *sect;
  struct symfile_segment_data *data;
  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_get_section_flags (abfd, sect) & SEC_ALLOC) == 0)
	continue;

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

  low = bfd_get_section_vma (abfd, sect);
  high = low + bfd_get_section_size (sect);

  data = XCNEW (struct symfile_segment_data);
  data->num_segments = 1;
  data->segment_bases = XCNEW (CORE_ADDR);
  data->segment_sizes = XCNEW (CORE_ADDR);

  num_sections = bfd_count_sections (abfd);
  data->segment_info = XCNEWVEC (int, num_sections);

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

      if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0)
	continue;

      vma = bfd_get_section_vma (abfd, sect);
      if (vma < low)
	low = vma;
      if (vma + bfd_get_section_size (sect) > high)
	high = vma + bfd_get_section_size (sect);

      data->segment_info[i] = 1;
    }

  data->segment_bases[0] = low;
  data->segment_sizes[0] = 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)
      && 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)
    require_partial_symbols (objfile, 0);
}

/* 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 (get_objfile_arch (objfile),
					      entry_point,
					      current_top_target ());

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

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

	  if (entry_point >= bfd_get_section_vma (objfile->obfd, sect)
	      && entry_point < (bfd_get_section_vma (objfile->obfd, sect)
				+ bfd_get_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 `struct 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
   correspondig 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 wether
   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));

  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);
      size_t size = SIZEOF_N_SECTION_OFFSETS (num_sections);

      objfile->num_sections = num_sections;
      objfile->section_offsets
	= (struct section_offsets *) obstack_alloc (&objfile->objfile_obstack,
						    size);
      memset (objfile->section_offsets, 0, size);
      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;

  std::unique_ptr<struct objfile> 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 (symfile_objfile != NULL)
	{
	  delete symfile_objfile;
	  gdb_assert (symfile_objfile == 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.  */
      symfile_objfile = 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 breakpoins.

   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 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 we'd be
     interactively wiping out any existing symbols.  */

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

  if (mainline)
    flags |= OBJF_MAINLINE;
  objfile = new struct objfile (abfd, name, flags);

  if (parent)
    add_separate_debug_objfile (objfile, 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
	{
	  puts_filtered (_("Reading symbols from "));
	  fputs_styled (name, file_name_style.style (), gdb_stdout);
	  puts_filtered ("...\n");
	}
    }
  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 %s...\n"), name);

      if (objfile->sf)
	objfile->sf->qf->expand_all_symtabs (objfile);
    }

  /* 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 %s)\n"), 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),
     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
      && (symfile_objfile
	  ? !query (_("Discard symbol table from `%s'? "),
		    objfile_name (symfile_objfile))
	  : !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);

  free_all_objfiles ();

  gdb_assert (symfile_objfile == NULL);
  if (from_tty)
    printf_filtered (_("No symbol file now.\n"));
}

/* See symfile.h.  */

int separate_debug_file_debug = 0;

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, -1));

  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 scenarions 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);

      symbol_file_add_main_1 (name, add_flags, flags, offset);
    }
}

/* Set the initial language.

   FIXME: A better solution would be to record the language in the
   psymtab when reading partial symbols, and then use it (if known) to
   set the language.  This would be a win for formats that encode the
   language in an easily discoverable place, such as DWARF.  For
   stabs, we can jump through hoops looking for specially named
   symbols or try to intuit the language from the specific type of
   stabs we find, but we can't do that until later when we read in
   full symbols.  */

void
set_initial_language (void)
{
  enum language lang = main_language ();

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

      if (sym != NULL)
	lang = SYMBOL_LANGUAGE (sym);
    }

  if (lang == language_unknown)
    {
      /* Make C the default language */
      lang = language_c;
    }

  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;

/* Callback service function for generic_load (bfd_map_over_sections).  */

static void
add_section_size_callback (bfd *abfd, asection *asec, void *data)
{
  bfd_size_type *sum = (bfd_size_type *) data;

  *sum += bfd_get_section_size (asec);
}

/* 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);
}

/* Callback service function for generic_load (bfd_map_over_sections).  */

static void
load_section_callback (bfd *abfd, asection *asec, void *data)
{
  struct load_section_data *args = (struct load_section_data *) data;
  bfd_size_type size = bfd_get_section_size (asec);
  const char *sect_name = bfd_get_section_name (abfd, asec);

  if ((bfd_get_section_flags (abfd, asec) & SEC_LOAD) == 0)
    return;

  if (size == 0)
    return;

  ULONGEST begin = bfd_section_lma (abfd, 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);

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, -1));
  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 ()));
    }

  bfd_map_over_sections (loadfile_bfd.get (), add_section_size_callback,
			 (void *) &total_progress.total_size);

  bfd_map_over_sections (loadfile_bfd.get (), load_section_callback, &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_fmt ("address", "%s", paddress (target_gdbarch (), entry));
  uiout->text (", load size ");
  uiout->field_fmt ("load-size", "%lu", 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_fmt ("transfer-rate", "%lu", rate * 8);
	  uiout->text (" bits/sec");
	}
      else if (rate < 1024)
	{
	  uiout->field_fmt ("transfer-rate", "%lu", rate);
	  uiout->text (" bytes/sec");
	}
      else
	{
	  uiout->field_fmt ("transfer-rate", "%lu", rate / 1024);
	  uiout->text (" KB/sec");
	}
    }
  else
    {
      uiout->field_fmt ("transferred-bits", "%lu", (data_count * 8));
      uiout->text (" bits in <1 sec");
    }
  if (write_count > 0)
    {
      uiout->text (", ");
      uiout->field_fmt ("write-rate", "%lu", 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.  */
  std::vector<struct section_offsets> offsets (objf->num_sections,
					       { { 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].offsets[0] = 0;
    }

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

/* 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);

  add_target_sections_of_objfile (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."));

  delete objf;
  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 (objfile->obfd->my_archive->filename, &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)
	{
	  struct section_offsets *offsets;
	  int num_offsets;

	  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).  */
	  std::unique_ptr<struct objfile> objfile_holder (objfile);

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

	  if (exec_bfd != NULL
	      && filename_cmp (bfd_get_filename (objfile->obfd),
			       bfd_get_filename (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);

	  /* 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);
	    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, -1));
	    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 ()));

	  /* Save the offsets, we will nuke them with the rest of the
	     objfile_obstack.  */
	  num_offsets = objfile->num_sections;
	  offsets = ((struct section_offsets *)
		     alloca (SIZEOF_N_SECTION_OFFSETS (num_offsets)));
	  memcpy (offsets, objfile->section_offsets,
		  SIZEOF_N_SECTION_OFFSETS (num_offsets));

	  objfile->reset_psymtabs ();

	  /* 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->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
	    = (char *) obstack_copy0 (&objfile->objfile_obstack,
				      original_name.c_str (),
				      original_name.size ());

	  /* 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));

	  build_objfile_section_table (objfile);

	  /* We use the same section offsets as from last time.  I'm not
	     sure whether that is always correct for shared libraries.  */
	  objfile->section_offsets = (struct section_offsets *)
	    obstack_alloc (&objfile->objfile_obstack,
			   SIZEOF_N_SECTION_OFFSETS (num_offsets));
	  memcpy (objfile->section_offsets, offsets,
		  SIZEOF_N_SECTION_OFFSETS (num_offsets));
	  objfile->num_sections = num_offsets;

	  /* 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 == symfile_objfile)
	    {
	      (*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 ();

	  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)
{
  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
    = ((const char *) objfile->per_bfd->filename_cache.insert
       (filename, strlen (filename) + 1));
  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 char *last_objfile_name = NULL;

      if (last_objfile_name == NULL
	  || strcmp (last_objfile_name, objfile_name (objfile)) != 0)
	{
	  xfree (last_objfile_name);
	  last_objfile_name = xstrdup (objfile_name (objfile));
	  fprintf_filtered (gdb_stdlog,
			    "Creating one or more symtabs for objfile %s ...\n",
			    last_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
    = (const char *) obstack_copy0 (&objfile->objfile_obstack, saved_name,
				    strlen (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 (abfd, bfd_section) != 0
	  && bfd_section_lma (abfd, bfd_section)
	     != bfd_section_vma (abfd, 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 = get_objfile_arch (osect->objfile);
      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))
    {
      bfd *abfd = section->objfile->obfd;
      asection *bfd_section = section->the_bfd_section;

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

      if (bfd_get_section_lma (abfd, bfd_section) + offset <= pc
	  && pc < bfd_get_section_lma (abfd, 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 (abfd, bfd_section)
		- bfd_section_vma (abfd, 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 (abfd, bfd_section)
		- bfd_section_lma (abfd, 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 = get_objfile_arch (objfile);
	      const char *name;
	      bfd_vma lma, vma;
	      int size;

	      vma = bfd_section_vma (objfile->obfd, osect->the_bfd_section);
	      lma = bfd_section_lma (objfile->obfd, osect->the_bfd_section);
	      size = bfd_get_section_size (osect->the_bfd_section);
	      name = bfd_section_name (objfile->obfd, 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 (obj_file->obfd, 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 (obj_file->obfd,
							 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 (objfile->obfd, 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."));
}

/* Function: overlay_command
   A place-holder for a mis-typed command.  */

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

static void
overlay_command (const char *args, int from_tty)
{
  printf_unfiltered
    ("\"overlay\" must be followed by the name of an overlay command.\n");
  help_list (overlaylist, "overlay ", all_commands, gdb_stdout);
}

/* 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)
{
  if (cache_ovly_table)
    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 = get_objfile_arch (ovly_table_msym.objfile);
  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 = get_objfile_arch (osect->objfile);
  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 (obfd, bsect)
	&& cache_ovly_table[i][LMA] == bfd_section_lma (obfd, 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 (obfd, bsect)
	    && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, 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 (obfd, bsect)
		&& cache_ovly_table[i][LMA] == bfd_section_lma (obfd, 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.  */
	      }
	}
}

/* Set the output sections and output offsets for section SECTP in
   ABFD.  The relocation code in BFD will read these offsets, so we
   need to be sure they're initialized.  We map each section to itself,
   with no offset; this means that SECTP->vma will be honored.  */

static void
symfile_dummy_outputs (bfd *abfd, asection *sectp, void *dummy)
{
  sectp->output_section = sectp;
  sectp->output_offset = 0;
}

/* 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.  */
  bfd_map_over_sections (abfd, symfile_dummy_outputs, NULL);

  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);
}

struct symfile_segment_data *
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);
}

void
free_symfile_segment_data (struct symfile_segment_data *data)
{
  xfree (data->segment_bases);
  xfree (data->segment_sizes);
  xfree (data->segment_info);
  xfree (data);
}

/* 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,
				 struct 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->num_segments > 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->num_segments);

      /* 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->offsets[i] = (segment_bases[which - 1]
                             - data->segment_bases[which - 1]);
    }

  return 1;
}

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

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

  if (data->num_segments != 1 && data->num_segments != 2)
    {
      free_symfile_segment_data (data);
      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;
	}
    }

  free_symfile_segment_data (data);
}

/* Listen for free_objfile events.  */

static void
symfile_free_objfile (struct objfile *objfile)
{
  /* Remove the target sections owned by this objfile.  */
  if (objfile != NULL)
    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.  */

void
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,
   enum search_domain kind)
{
  for (objfile *objfile : current_program_space->objfiles ())
    {
      if (objfile->sf)
	objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher,
						  lookup_name,
						  symbol_matcher,
						  expansion_notify, kind);
    }
}

/* 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 (symbol_filename_ftype *fun, void *data,
		      int need_fullname)
{
  for (objfile *objfile : current_program_space->objfiles ())
    {
      if (objfile->sf)
	objfile->sf->qf->map_symbol_filenames (objfile, fun, data,
					       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)
{
  struct cmd_list_element *c;

  gdb::observers::free_objfile.attach (symfile_free_objfile);

#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, and record its symbols\n\
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);

  add_prefix_cmd ("overlay", class_support, overlay_command,
		  _("Commands for debugging overlays."), &overlaylist,
		  "overlay ", 0, &cmdlist);

  add_com_alias ("ovly", "overlay", class_alias, 1);
  add_com_alias ("ov", "overlay", class_alias, 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
}
