Make add_separate_debug_objfile static
[deliverable/binutils-gdb.git] / gdb / symfile.c
index 4bbe0b5a622d1a02aa6f3d8c83e8588e689656fb..8e3cf7f23e57b8740edbd54dc6e22eb9d23c5abf 100644 (file)
@@ -1,6 +1,6 @@
 /* Generic symbol file reading for the GNU debugger, GDB.
 
-   Copyright (C) 1990-2017 Free Software Foundation, Inc.
+   Copyright (C) 1990-2019 Free Software Foundation, Inc.
 
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
@@ -44,9 +44,9 @@
 #include "completer.h"
 #include "bcache.h"
 #include "hashtab.h"
-#include "readline/readline.h"
+#include "readline/tilde.h"
 #include "block.h"
-#include "observer.h"
+#include "observable.h"
 #include "exec.h"
 #include "parser-defs.h"
 #include "varobj.h"
 #include "stack.h"
 #include "gdb_bfd.h"
 #include "cli/cli-utils.h"
-#include "common/byte-vector.h"
-#include "selftest.h"
+#include "gdbsupport/byte-vector.h"
+#include "gdbsupport/pathstuff.h"
+#include "gdbsupport/selftest.h"
+#include "cli/cli-style.h"
+#include "gdbsupport/forward-scope-exit.h"
 
 #include <sys/types.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <ctype.h>
 #include <chrono>
+#include <algorithm>
 
 #include "psymtab.h"
 
@@ -77,15 +81,17 @@ void (*deprecated_show_load_progress) (const char *section,
 void (*deprecated_pre_add_symbol_hook) (const char *);
 void (*deprecated_post_add_symbol_hook) (void);
 
-static void clear_symtab_users_cleanup (void *ignore);
+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);
+                                   objfile_flags flags, CORE_ADDR reloff);
 
 static const struct sym_fns *find_sym_fns (bfd *);
 
@@ -135,17 +141,9 @@ static const char *print_symbol_loading_enums[] =
 };
 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;
+/* See symfile.h.  */
+
+bool auto_solib_add = true;
 \f
 
 /* Return non-zero if symbol-loading messages should be printed.
@@ -202,126 +200,80 @@ 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)))
+  if (0 == (bfd_section_flags (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))
+  else if (bfd_section_vma (*lowest) > bfd_section_vma (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)))
+  else if (bfd_section_vma (*lowest) == bfd_section_vma (sect)
+          && (bfd_section_size (*lowest) <= bfd_section_size (sect)))
     *lowest = sect;
 }
 
-/* Create a new section_addr_info, with room for NUM_SECTIONS.  The
-   new object's 'num_sections' field is set to 0; it must be updated
-   by the caller.  */
-
-struct section_addr_info *
-alloc_section_addr_info (size_t num_sections)
-{
-  struct section_addr_info *sap;
-  size_t size;
-
-  size = (sizeof (struct section_addr_info)
-         +  sizeof (struct other_sections) * (num_sections - 1));
-  sap = (struct section_addr_info *) xmalloc (size);
-  memset (sap, 0, size);
-
-  return sap;
-}
-
 /* Build (allocate and populate) a section_addr_info struct from
    an existing section table.  */
 
-extern struct section_addr_info *
+section_addr_info
 build_section_addr_info_from_section_table (const struct target_section *start,
                                             const struct target_section *end)
 {
-  struct section_addr_info *sap;
   const struct target_section *stp;
-  int oidx;
 
-  sap = alloc_section_addr_info (end - start);
+  section_addr_info sap;
 
-  for (stp = start, oidx = 0; stp != end; stp++)
+  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)
-         && oidx < end - start)
-       {
-         sap->other[oidx].addr = stp->addr;
-         sap->other[oidx].name = xstrdup (bfd_section_name (abfd, asect));
-         sap->other[oidx].sectindex = gdb_bfd_section_index (abfd, asect);
-         oidx++;
-       }
+      if (bfd_section_flags (asect) & (SEC_ALLOC | SEC_LOAD)
+         && sap.size () < end - start)
+       sap.emplace_back (stp->addr,
+                         bfd_section_name (asect),
+                         gdb_bfd_section_index (abfd, asect));
     }
 
-  sap->num_sections = oidx;
-
   return sap;
 }
 
 /* Create a section_addr_info from section offsets in ABFD.  */
 
-static struct section_addr_info *
+static section_addr_info
 build_section_addr_info_from_bfd (bfd *abfd)
 {
-  struct section_addr_info *sap;
-  int i;
   struct bfd_section *sec;
 
-  sap = alloc_section_addr_info (bfd_count_sections (abfd));
-  for (i = 0, sec = abfd->sections; sec != NULL; sec = sec->next)
-    if (bfd_get_section_flags (abfd, sec) & (SEC_ALLOC | SEC_LOAD))
-      {
-       sap->other[i].addr = bfd_get_section_vma (abfd, sec);
-       sap->other[i].name = xstrdup (bfd_get_section_name (abfd, sec));
-       sap->other[i].sectindex = gdb_bfd_section_index (abfd, sec);
-       i++;
-      }
-
-  sap->num_sections = i;
+  section_addr_info sap;
+  for (sec = abfd->sections; sec != NULL; sec = sec->next)
+    if (bfd_section_flags (sec) & (SEC_ALLOC | SEC_LOAD))
+      sap.emplace_back (bfd_section_vma (sec),
+                       bfd_section_name (sec),
+                       gdb_bfd_section_index (abfd, sec));
 
   return sap;
 }
 
 /* Create a section_addr_info from section offsets in OBJFILE.  */
 
-struct section_addr_info *
+section_addr_info
 build_section_addr_info_from_objfile (const struct objfile *objfile)
 {
-  struct section_addr_info *sap;
   int i;
 
   /* Before reread_symbols gets rewritten it is not safe to call:
      gdb_assert (objfile->num_sections == bfd_count_sections (objfile->obfd));
      */
-  sap = build_section_addr_info_from_bfd (objfile->obfd);
-  for (i = 0; i < sap->num_sections; i++)
+  section_addr_info sap = build_section_addr_info_from_bfd (objfile->obfd);
+  for (i = 0; i < sap.size (); i++)
     {
-      int sectindex = sap->other[i].sectindex;
+      int sectindex = sap[i].sectindex;
 
-      sap->other[i].addr += objfile->section_offsets->offsets[sectindex];
+      sap[i].addr += objfile->section_offsets->offsets[sectindex];
     }
   return sap;
 }
 
-/* Free all memory allocated by build_section_addr_info_from_section_table.  */
-
-extern void
-free_section_addr_info (struct section_addr_info *sap)
-{
-  int idx;
-
-  for (idx = 0; idx < sap->num_sections; idx++)
-    xfree (sap->other[idx].name);
-  xfree (sap);
-}
-
 /* Initialize OBJFILE's sect_index_* members.  */
 
 static void
@@ -400,10 +352,10 @@ 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);
+  ULONGEST align = ((ULONGEST) 1) << bfd_section_alignment (sect);
 
   /* We are only interested in allocated sections.  */
-  if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0)
+  if ((bfd_section_flags (sect) & SEC_ALLOC) == 0)
     return;
 
   /* If the user specified an offset, honor it.  */
@@ -427,7 +379,7 @@ place_section (bfd *abfd, asection *sect, void *obj)
          continue;
 
        /* We can only conflict with allocated sections.  */
-       if ((bfd_get_section_flags (abfd, cur_sec) & SEC_ALLOC) == 0)
+       if ((bfd_section_flags (cur_sec) & SEC_ALLOC) == 0)
          continue;
 
        /* If the section offset is 0, either the section has not been placed
@@ -437,10 +389,10 @@ place_section (bfd *abfd, asection *sect, void *obj)
          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))
+       if (start_addr + bfd_section_size (sect) > offsets[indx]
+           && start_addr < offsets[indx] + bfd_section_size (cur_sec))
          {
-           start_addr = offsets[indx] + bfd_get_section_size (cur_sec);
+           start_addr = offsets[indx] + bfd_section_size (cur_sec);
            start_addr = (start_addr + align - 1) & -align;
            done = 0;
            break;
@@ -452,28 +404,28 @@ place_section (bfd *abfd, asection *sect, void *obj)
   while (!done);
 
   offsets[gdb_bfd_section_index (abfd, sect)] = start_addr;
-  arg->lowest = start_addr + bfd_get_section_size (sect);
+  arg->lowest = start_addr + bfd_section_size (sect);
 }
 
-/* Store struct section_addr_info as prepared (made relative and with SECTINDEX
+/* 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 struct section_addr_info *addrs)
+                                      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->num_sections; i++)
+  for (i = 0; i < addrs.size (); i++)
     {
       const struct other_sections *osp;
 
-      osp = &addrs->other[i];
+      osp = &addrs[i];
       if (osp->sectindex == -1)
        continue;
 
@@ -501,39 +453,36 @@ addr_section_name (const char *s)
   return s;
 }
 
-/* qsort comparator for addrs_section_sort.  Sort entries in ascending order by
-   their (name, sectindex) pair.  sectindex makes the sort by name stable.  */
+/* 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 int
-addrs_section_compar (const void *ap, const void *bp)
+static bool
+addrs_section_compar (const struct other_sections *a,
+                     const struct other_sections *b)
 {
-  const struct other_sections *a = *((struct other_sections **) ap);
-  const struct other_sections *b = *((struct other_sections **) bp);
   int retval;
 
-  retval = strcmp (addr_section_name (a->name), addr_section_name (b->name));
-  if (retval)
-    return 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;
+  return a->sectindex < b->sectindex;
 }
 
-/* Provide sorted array of pointers to sections of ADDRS.  The array is
-   terminated by NULL.  Caller is responsible to call xfree for it.  */
+/* Provide sorted array of pointers to sections of ADDRS.  */
 
-static struct other_sections **
-addrs_section_sort (struct section_addr_info *addrs)
+static std::vector<const struct other_sections *>
+addrs_section_sort (const section_addr_info &addrs)
 {
-  struct other_sections **array;
   int i;
 
-  /* `+ 1' for the NULL terminator.  */
-  array = XNEWVEC (struct other_sections *, addrs->num_sections + 1);
-  for (i = 0; i < addrs->num_sections; i++)
-    array[i] = &addrs->other[i];
-  array[i] = NULL;
+  std::vector<const struct other_sections *> array (addrs.size ());
+  for (i = 0; i < addrs.size (); i++)
+    array[i] = &addrs[i];
 
-  qsort (array, i, sizeof (*array), addrs_section_compar);
+  std::sort (array.begin (), array.end (), addrs_section_compar);
 
   return array;
 }
@@ -543,18 +492,14 @@ addrs_section_sort (struct section_addr_info *addrs)
    rebase ADDRS to start referencing different BFD than before.  */
 
 void
-addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
+addr_info_make_relative (section_addr_info *addrs, bfd *abfd)
 {
   asection *lower_sect;
   CORE_ADDR lower_offset;
   int i;
-  struct cleanup *my_cleanup;
-  struct section_addr_info *abfd_addrs;
-  struct other_sections **addrs_sorted, **abfd_addrs_sorted;
-  struct other_sections **addrs_to_abfd_addrs;
 
   /* Find lowest loadable section to be used as starting point for
-     continguous sections.  */
+     contiguous sections.  */
   lower_sect = NULL;
   bfd_map_over_sections (abfd, find_lowest_section, &lower_sect);
   if (lower_sect == NULL)
@@ -564,7 +509,7 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
       lower_offset = 0;
     }
   else
-    lower_offset = bfd_section_vma (bfd_get_filename (abfd), lower_sect);
+    lower_offset = bfd_section_vma (lower_sect);
 
   /* Create ADDRS_TO_ABFD_ADDRS array to map the sections in ADDRS to sections
      in ABFD.  Section names are not unique - there can be multiple sections of
@@ -576,45 +521,44 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
      Use stable sort by name for the sections in both files.  Then linearly
      scan both lists matching as most of the entries as possible.  */
 
-  addrs_sorted = addrs_section_sort (addrs);
-  my_cleanup = make_cleanup (xfree, addrs_sorted);
+  std::vector<const struct other_sections *> addrs_sorted
+    = addrs_section_sort (*addrs);
 
-  abfd_addrs = build_section_addr_info_from_bfd (abfd);
-  make_cleanup_free_section_addr_info (abfd_addrs);
-  abfd_addrs_sorted = addrs_section_sort (abfd_addrs);
-  make_cleanup (xfree, abfd_addrs_sorted);
+  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.  */
 
-  addrs_to_abfd_addrs = XCNEWVEC (struct other_sections *, addrs->num_sections);
-  make_cleanup (xfree, addrs_to_abfd_addrs);
+  std::vector<const struct other_sections *>
+    addrs_to_abfd_addrs (addrs->size (), nullptr);
 
-  while (*addrs_sorted)
+  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 ((*addrs_sorted)->name);
+      const char *sect_name = addr_section_name (sect->name.c_str ());
 
-      while (*abfd_addrs_sorted
-            && strcmp (addr_section_name ((*abfd_addrs_sorted)->name),
+      while (abfd_sorted_iter != abfd_addrs_sorted.end ()
+            && strcmp (addr_section_name ((*abfd_sorted_iter)->name.c_str ()),
                        sect_name) < 0)
-       abfd_addrs_sorted++;
+       abfd_sorted_iter++;
 
-      if (*abfd_addrs_sorted
-         && strcmp (addr_section_name ((*abfd_addrs_sorted)->name),
+      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 = *addrs_sorted - addrs->other;
+         index_in_addrs = sect - addrs->data ();
          gdb_assert (addrs_to_abfd_addrs[index_in_addrs] == NULL);
-         addrs_to_abfd_addrs[index_in_addrs] = *abfd_addrs_sorted;
+         addrs_to_abfd_addrs[index_in_addrs] = *abfd_sorted_iter;
 
          /* Never use the same ABFD entry twice.  */
-         abfd_addrs_sorted++;
+         abfd_sorted_iter++;
        }
-
-      addrs_sorted++;
     }
 
   /* Calculate offsets for the loadable sections.
@@ -627,27 +571,27 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
      (the loadable section directly below it in memory).
      this_offset = lower_offset = lower_addr - lower_orig_addr */
 
-  for (i = 0; i < addrs->num_sections; i++)
+  for (i = 0; i < addrs->size (); i++)
     {
-      struct other_sections *sect = addrs_to_abfd_addrs[i];
+      const struct other_sections *sect = addrs_to_abfd_addrs[i];
 
       if (sect)
        {
          /* This is the index used by BFD.  */
-         addrs->other[i].sectindex = sect->sectindex;
+         (*addrs)[i].sectindex = sect->sectindex;
 
-         if (addrs->other[i].addr != 0)
+         if ((*addrs)[i].addr != 0)
            {
-             addrs->other[i].addr -= sect->addr;
-             lower_offset = addrs->other[i].addr;
+             (*addrs)[i].addr -= sect->addr;
+             lower_offset = (*addrs)[i].addr;
            }
          else
-           addrs->other[i].addr = lower_offset;
+           (*addrs)[i].addr = lower_offset;
        }
       else
        {
          /* addr_section_name transformation is not used for SECT_NAME.  */
-         const char *sect_name = addrs->other[i].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.
@@ -663,25 +607,23 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
 
             For the sections `.bss' and `.sbss' see addr_section_name.  */
 
-         if (!(strcmp (sect_name, ".gnu.liblist") == 0
-               || strcmp (sect_name, ".gnu.conflict") == 0
-               || (strcmp (sect_name, ".bss") == 0
+         if (!(sect_name == ".gnu.liblist"
+               || sect_name == ".gnu.conflict"
+               || (sect_name == ".bss"
                    && i > 0
-                   && strcmp (addrs->other[i - 1].name, ".dynbss") == 0
+                   && (*addrs)[i - 1].name == ".dynbss"
                    && addrs_to_abfd_addrs[i - 1] != NULL)
-               || (strcmp (sect_name, ".sbss") == 0
+               || (sect_name == ".sbss"
                    && i > 0
-                   && strcmp (addrs->other[i - 1].name, ".sdynbss") == 0
+                   && (*addrs)[i - 1].name == ".sdynbss"
                    && addrs_to_abfd_addrs[i - 1] != NULL)))
-           warning (_("section %s not found in %s"), sect_name,
+           warning (_("section %s not found in %s"), sect_name.c_str (),
                     bfd_get_filename (abfd));
 
-         addrs->other[i].addr = 0;
-         addrs->other[i].sectindex = -1;
+         (*addrs)[i].addr = 0;
+         (*addrs)[i].sectindex = -1;
        }
     }
-
-  do_cleanups (my_cleanup);
 }
 
 /* Parse the user's idea of an offset for dynamic linking, into our idea
@@ -692,7 +634,7 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
 
 void
 default_symfile_offsets (struct objfile *objfile,
-                        const struct section_addr_info *addrs)
+                        const section_addr_info &addrs)
 {
   objfile->num_sections = gdb_bfd_count_sections (objfile->obfd);
   objfile->section_offsets = (struct section_offsets *)
@@ -715,7 +657,7 @@ default_symfile_offsets (struct objfile *objfile,
       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)
+       if (bfd_section_vma (cur_sec) != 0)
          break;
 
       if (cur_sec == NULL)
@@ -757,10 +699,10 @@ default_symfile_offsets (struct objfile *objfile,
          for (cur_sec = abfd->sections; cur_sec != NULL;
               cur_sec = cur_sec->next)
            {
-             if ((bfd_get_section_flags (abfd, cur_sec) & SEC_ALLOC) == 0)
+             if ((bfd_section_flags (cur_sec) & SEC_ALLOC) == 0)
                continue;
 
-             bfd_set_section_vma (abfd, cur_sec, offsets[cur_sec->index]);
+             bfd_set_section_vma (cur_sec, offsets[cur_sec->index]);
              exec_set_section_address (bfd_get_filename (abfd),
                                        cur_sec->index,
                                        offsets[cur_sec->index]);
@@ -797,7 +739,7 @@ default_symfile_segments (bfd *abfd)
   /* 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)
+      if ((bfd_section_flags (sect) & SEC_ALLOC) == 0)
        continue;
 
       break;
@@ -805,8 +747,8 @@ default_symfile_segments (bfd *abfd)
   if (sect == NULL)
     return NULL;
 
-  low = bfd_get_section_vma (abfd, sect);
-  high = low + bfd_get_section_size (sect);
+  low = bfd_section_vma (sect);
+  high = low + bfd_section_size (sect);
 
   data = XCNEW (struct symfile_segment_data);
   data->num_segments = 1;
@@ -820,14 +762,14 @@ default_symfile_segments (bfd *abfd)
     {
       CORE_ADDR vma;
 
-      if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0)
+      if ((bfd_section_flags (sect) & SEC_ALLOC) == 0)
        continue;
 
-      vma = bfd_get_section_vma (abfd, sect);
+      vma = bfd_section_vma (sect);
       if (vma < low)
        low = vma;
-      if (vma + bfd_get_section_size (sect) > high)
-       high = vma + bfd_get_section_size (sect);
+      if (vma + bfd_section_size (sect) > high)
+       high = vma + bfd_section_size (sect);
 
       data->segment_info[i] = 1;
     }
@@ -861,12 +803,13 @@ read_symbols (struct objfile *objfile, symfile_add_flags add_flags)
             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 (), objfile->original_name,
-                                   add_flags, objfile);
+         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);
+    require_partial_symbols (objfile, false);
 }
 
 /* Initialize entry point information for this objfile.  */
@@ -916,7 +859,7 @@ init_entry_point_info (struct objfile *objfile)
       entry_point
        = gdbarch_convert_from_func_ptr_addr (get_objfile_arch (objfile),
                                              entry_point,
-                                             &current_target);
+                                             current_top_target ());
 
       /* Remove any ISA markers, so that this matches entries in the
         symbol table.  */
@@ -928,9 +871,9 @@ init_entry_point_info (struct objfile *objfile)
        {
          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)))
+         if (entry_point >= bfd_section_vma (sect)
+             && entry_point < (bfd_section_vma (sect)
+                               + bfd_section_size (sect)))
            {
              ei->the_bfd_section_index
                = gdb_bfd_section_index (objfile->obfd, sect);
@@ -960,18 +903,20 @@ init_entry_point_info (struct objfile *objfile)
    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
+   corresponding BFD section index, or -1 if the section was not found.
 
    ADD_FLAGS encodes verbosity level, whether this is main symbol or
-   an extra symbol file such as dynamically loaded code, and wether
+   an extra symbol file such as dynamically loaded code, and whether
    breakpoint reset should be deferred.  */
 
 static void
 syms_from_objfile_1 (struct objfile *objfile,
-                    struct section_addr_info *addrs,
+                    section_addr_info *addrs,
                     symfile_add_flags add_flags)
 {
-  struct section_addr_info *local_addr = NULL;
-  struct cleanup *old_chain;
+  section_addr_info local_addr;
   const int mainline = add_flags & SYMFILE_MAINLINE;
 
   objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd));
@@ -993,24 +938,21 @@ syms_from_objfile_1 (struct objfile *objfile,
 
   /* Make sure that partially constructed symbol tables will be cleaned up
      if an error occurs during symbol reading.  */
-  old_chain = make_cleanup (null_cleanup, NULL);
+  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)
-    {
-      local_addr = alloc_section_addr_info (1);
-      make_cleanup (xfree, local_addr);
-      addrs = local_addr;
-    }
+    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.  */
-      make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/);
+      defer_clear_users.emplace ((symfile_add_flag) 0);
 
       /* Since no error yet, throw away the old symbol table.  */
 
@@ -1034,7 +976,7 @@ syms_from_objfile_1 (struct objfile *objfile,
 
      We no longer warn if the lowest section is not a text segment (as
      happens for the PA64 port.  */
-  if (addrs->num_sections > 0)
+  if (addrs->size () > 0)
     addr_info_make_relative (addrs, objfile->obfd);
 
   /* Initialize symbol reading routines for this objfile, allow complaints to
@@ -1042,17 +984,17 @@ syms_from_objfile_1 (struct objfile *objfile,
      initial symbol reading for this file.  */
 
   (*objfile->sf->sym_init) (objfile);
-  clear_complaints (&symfile_complaints, 1, add_flags & SYMFILE_VERBOSE);
+  clear_complaints ();
 
-  (*objfile->sf->sym_offsets) (objfile, addrs);
+  (*objfile->sf->sym_offsets) (objfile, *addrs);
 
   read_symbols (objfile, add_flags);
 
   /* Discard cleanups as symbol reading was successful.  */
 
   objfile_holder.release ();
-  discard_cleanups (old_chain);
-  xfree (local_addr);
+  if (defer_clear_users)
+    defer_clear_users->release ();
 }
 
 /* Same as syms_from_objfile_1, but also initializes the objfile
@@ -1060,7 +1002,7 @@ syms_from_objfile_1 (struct objfile *objfile,
 
 static void
 syms_from_objfile (struct objfile *objfile,
-                  struct section_addr_info *addrs,
+                  section_addr_info *addrs,
                   symfile_add_flags add_flags)
 {
   syms_from_objfile_1 (objfile, addrs, add_flags);
@@ -1090,7 +1032,7 @@ finish_new_objfile (struct objfile *objfile, symfile_add_flags add_flags)
     }
 
   /* We're done reading the symbol file; finish off complaints.  */
-  clear_complaints (&symfile_complaints, 0, add_flags & SYMFILE_VERBOSE);
+  clear_complaints ();
 }
 
 /* Process a symbol file, as either the main file or as a dynamically
@@ -1102,7 +1044,7 @@ finish_new_objfile (struct objfile *objfile, symfile_add_flags add_flags)
    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.
+   extra, such as dynamically loaded code, and what to do with breakpoints.
 
    ADDRS is as described for syms_from_objfile_1, above.
    ADDRS is ignored when SYMFILE_MAINLINE bit is set in ADD_FLAGS.
@@ -1116,7 +1058,7 @@ finish_new_objfile (struct objfile *objfile, symfile_add_flags add_flags)
 static struct objfile *
 symbol_file_add_with_addrs (bfd *abfd, const char *name,
                            symfile_add_flags add_flags,
-                           struct section_addr_info *addrs,
+                           section_addr_info *addrs,
                            objfile_flags flags, struct objfile *parent)
 {
   struct objfile *objfile;
@@ -1131,6 +1073,14 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name,
       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.  */
@@ -1143,10 +1093,7 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name,
 
   if (mainline)
     flags |= OBJF_MAINLINE;
-  objfile = new struct objfile (abfd, name, flags);
-
-  if (parent)
-    add_separate_debug_objfile (objfile, parent);
+  objfile = objfile::make (abfd, name, flags, parent);
 
   /* We either created a new mapped symbol table, mapped an existing
      symbol table file which has not had initial symbol reading
@@ -1156,11 +1103,8 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name,
       if (deprecated_pre_add_symbol_hook)
        deprecated_pre_add_symbol_hook (name);
       else
-       {
-         printf_unfiltered (_("Reading symbols from %s..."), name);
-         wrap_here ("");
-         gdb_flush (gdb_stdout);
-       }
+       printf_filtered (_("Reading symbols from %ps...\n"),
+                        styled_string (file_name_style.style (), name));
     }
   syms_from_objfile (objfile, addrs, add_flags);
 
@@ -1172,29 +1116,26 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name,
   if ((flags & OBJF_READNOW))
     {
       if (should_print)
-       {
-         printf_unfiltered (_("expanding to full symbols..."));
-         wrap_here ("");
-         gdb_flush (gdb_stdout);
-       }
+       printf_filtered (_("Expanding full symbols from %ps...\n"),
+                        styled_string (file_name_style.style (), name));
 
       if (objfile->sf)
        objfile->sf->qf->expand_all_symtabs (objfile);
     }
 
-  if (should_print && !objfile_has_symbols (objfile))
-    {
-      wrap_here ("");
-      printf_unfiltered (_("(no debugging symbols found)..."));
-      wrap_here ("");
-    }
+  /* Note that we only print a message if we have no symbols and have
+     no separate debug file.  If there is a separate debug file which
+     does not have symbols, we'll have emitted this message for that
+     file, and so printing it twice is just redundant.  */
+  if (should_print && !objfile_has_symbols (objfile)
+      && objfile->separate_debug_objfile == nullptr)
+    printf_filtered (_("(No debugging symbols found in %ps)\n"),
+                    styled_string (file_name_style.style (), name));
 
   if (should_print)
     {
       if (deprecated_post_add_symbol_hook)
        deprecated_post_add_symbol_hook ();
-      else
-       printf_unfiltered (_("done.\n"));
     }
 
   /* We print some messages regardless of whether 'from_tty ||
@@ -1204,13 +1145,13 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name,
 
   if (objfile->sf == NULL)
     {
-      observer_notify_new_objfile (objfile);
+      gdb::observers::new_objfile.notify (objfile);
       return objfile;  /* No symbols.  */
     }
 
   finish_new_objfile (objfile, add_flags);
 
-  observer_notify_new_objfile (objfile);
+  gdb::observers::new_objfile.notify (objfile);
 
   bfd_cache_close_all ();
   return (objfile);
@@ -1224,22 +1165,16 @@ symbol_file_add_separate (bfd *bfd, const char *name,
                          symfile_add_flags symfile_flags,
                          struct objfile *objfile)
 {
-  struct section_addr_info *sap;
-  struct cleanup *my_cleanup;
-
   /* 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.  */
-  sap = build_section_addr_info_from_objfile (objfile);
-  my_cleanup = make_cleanup_free_section_addr_info (sap);
+  section_addr_info sap = build_section_addr_info_from_objfile (objfile);
 
   symbol_file_add_with_addrs
-    (bfd, name, symfile_flags, sap,
+    (bfd, name, symfile_flags, &sap,
      objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW
                       | OBJF_USERLOADED),
      objfile);
-
-  do_cleanups (my_cleanup);
 }
 
 /* Process the symbol file ABFD, as either the main file or as a
@@ -1249,7 +1184,7 @@ symbol_file_add_separate (bfd *bfd, const char *name,
 struct objfile *
 symbol_file_add_from_bfd (bfd *abfd, const char *name,
                          symfile_add_flags add_flags,
-                          struct section_addr_info *addrs,
+                         section_addr_info *addrs,
                           objfile_flags flags, struct objfile *parent)
 {
   return symbol_file_add_with_addrs (abfd, name, add_flags, addrs, flags,
@@ -1261,7 +1196,7 @@ symbol_file_add_from_bfd (bfd *abfd, const char *name,
 
 struct objfile *
 symbol_file_add (const char *name, symfile_add_flags add_flags,
-                struct section_addr_info *addrs, objfile_flags flags)
+                section_addr_info *addrs, objfile_flags flags)
 {
   gdb_bfd_ref_ptr bfd (symfile_bfd_open (name));
 
@@ -1280,16 +1215,18 @@ symbol_file_add (const char *name, symfile_add_flags add_flags,
 void
 symbol_file_add_main (const char *args, symfile_add_flags add_flags)
 {
-  symbol_file_add_main_1 (args, add_flags, 0);
+  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)
+                       objfile_flags flags, CORE_ADDR reloff)
 {
   add_flags |= current_inferior ()->symfile_flags | SYMFILE_MAINLINE;
 
-  symbol_file_add (args, add_flags, NULL, flags);
+  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.  */
@@ -1318,15 +1255,15 @@ symbol_file_clear (int from_tty)
 
   gdb_assert (symfile_objfile == NULL);
   if (from_tty)
-    printf_unfiltered (_("No symbol file now.\n"));
+    printf_filtered (_("No symbol file now.\n"));
 }
 
 /* See symfile.h.  */
 
-int separate_debug_file_debug = 0;
+bool separate_debug_file_debug = false;
 
 static int
-separate_debug_file_exists (const char *name, unsigned long crc,
+separate_debug_file_exists (const std::string &name, unsigned long crc,
                            struct objfile *parent_objfile)
 {
   unsigned long file_crc;
@@ -1340,16 +1277,24 @@ separate_debug_file_exists (const char *name, unsigned long crc,
      ".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, objfile_name (parent_objfile)) == 0)
+  if (filename_cmp (name.c_str (), objfile_name (parent_objfile)) == 0)
     return 0;
 
   if (separate_debug_file_debug)
-    printf_unfiltered (_("  Trying %s\n"), name);
+    {
+      printf_filtered (_("  Trying %s..."), name.c_str ());
+      gdb_flush (gdb_stdout);
+    }
 
-  gdb_bfd_ref_ptr abfd (gdb_bfd_open (name, gnutarget, -1));
+  gdb_bfd_ref_ptr abfd (gdb_bfd_open (name.c_str (), gnutarget, -1));
 
   if (abfd == NULL)
-    return 0;
+    {
+      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.
 
@@ -1368,7 +1313,12 @@ separate_debug_file_exists (const char *name, unsigned long crc,
     {
       if (abfd_stat.st_dev == parent_stat.st_dev
          && abfd_stat.st_ino == parent_stat.st_ino)
-       return 0;
+       {
+         if (separate_debug_file_debug)
+           printf_filtered (_(" no, same file as the objfile.\n"));
+
+         return 0;
+       }
       verified_as_different = 1;
     }
   else
@@ -1377,7 +1327,12 @@ separate_debug_file_exists (const char *name, unsigned long crc,
   file_crc_p = gdb_bfd_crc (abfd.get (), &file_crc);
 
   if (!file_crc_p)
-    return 0;
+    {
+      if (separate_debug_file_debug)
+       printf_filtered (_(" no, error computing CRC.\n"));
+
+      return 0;
+    }
 
   if (crc != file_crc)
     {
@@ -1390,17 +1345,28 @@ separate_debug_file_exists (const char *name, unsigned long crc,
       if (!verified_as_different)
        {
          if (!gdb_bfd_crc (parent_objfile->obfd, &parent_crc))
-           return 0;
+           {
+             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, objfile_name (parent_objfile));
+                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;
 }
 
@@ -1424,50 +1390,31 @@ show_debug_file_directory (struct ui_file *file, int from_tty,
    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, of NULL.  */
+   Returns the path of the file with separate debug info, or an empty
+   string.  */
 
-static char *
+static std::string
 find_separate_debug_file (const char *dir,
                          const char *canon_dir,
                          const char *debuglink,
                          unsigned long crc32, struct objfile *objfile)
 {
-  char *debugdir;
-  char *debugfile;
-  int i;
-  VEC (char_ptr) *debugdir_vec;
-  struct cleanup *back_to;
-  int ix;
-
   if (separate_debug_file_debug)
-    printf_unfiltered (_("\nLooking for separate debug info (debug link) for "
-                        "%s\n"), objfile_name (objfile));
-
-  /* Set I to std::max (strlen (canon_dir), strlen (dir)).  */
-  i = strlen (dir);
-  if (canon_dir != NULL && strlen (canon_dir) > i)
-    i = strlen (canon_dir);
-
-  debugfile
-    = (char *) xmalloc (strlen (debug_file_directory) + 1
-                       + i
-                       + strlen (DEBUG_SUBDIRECTORY)
-                       + strlen ("/")
-                       + strlen (debuglink)
-                       + 1);
+    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.  */
-  strcpy (debugfile, dir);
-  strcat (debugfile, debuglink);
+  std::string debugfile = dir;
+  debugfile += debuglink;
 
   if (separate_debug_file_exists (debugfile, crc32, objfile))
     return debugfile;
 
   /* Then try in the subdirectory named DEBUG_SUBDIRECTORY.  */
-  strcpy (debugfile, dir);
-  strcat (debugfile, DEBUG_SUBDIRECTORY);
-  strcat (debugfile, "/");
-  strcat (debugfile, debuglink);
+  debugfile = dir;
+  debugfile += DEBUG_SUBDIRECTORY;
+  debugfile += "/";
+  debugfile += debuglink;
 
   if (separate_debug_file_exists (debugfile, crc32, objfile))
     return debugfile;
@@ -1477,45 +1424,84 @@ find_separate_debug_file (const char *dir,
      Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
      cause "/..." lookups.  */
 
-  debugdir_vec = dirnames_to_char_ptr_vec (debug_file_directory);
-  back_to = make_cleanup_free_char_ptr_vec (debugdir_vec);
+  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);
 
-  for (ix = 0; VEC_iterate (char_ptr, debugdir_vec, ix, debugdir); ++ix)
+ /* MS-Windows/MS-DOS don't allow colons in file names; we must
+    convert the drive letter into a one-letter directory, so that the
+    file name resulting from splicing below will be valid.
+
+    FIXME: The below only works when GDB runs on MS-Windows/MS-DOS.
+    There are various remote-debugging scenarios where such a
+    transformation of the drive letter might be required when GDB runs
+    on a Posix host, see
+
+    https://sourceware.org/ml/gdb-patches/2019-04/msg00605.html
+
+    If some of those scenarios need to be supported, we will need to
+    use a different condition for HAS_DRIVE_SPEC and a different macro
+    instead of STRIP_DRIVE_SPEC, which work on Posix systems as well.  */
+  std::string drive;
+  if (HAS_DRIVE_SPEC (dir_notarget))
+    {
+      drive = dir_notarget[0];
+      dir_notarget = STRIP_DRIVE_SPEC (dir_notarget);
+    }
+
+  for (const gdb::unique_xmalloc_ptr<char> &debugdir : debugdir_vec)
     {
-      strcpy (debugfile, debugdir);
-      strcat (debugfile, "/");
-      strcat (debugfile, dir);
-      strcat (debugfile, debuglink);
+      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)
        {
-         do_cleanups (back_to);
-         return debugfile;
+         if (canon_sysroot.get () != NULL)
+           base_path = child_path (canon_sysroot.get (), canon_dir);
+         else
+           base_path = child_path (gdb_sysroot, canon_dir);
        }
-
-      /* If the file is in the sysroot, try using its base path in the
-        global debugfile directory.  */
-      if (canon_dir != NULL
-         && filename_ncmp (canon_dir, gdb_sysroot,
-                           strlen (gdb_sysroot)) == 0
-         && IS_DIR_SEPARATOR (canon_dir[strlen (gdb_sysroot)]))
+      if (base_path != NULL)
        {
-         strcpy (debugfile, debugdir);
-         strcat (debugfile, canon_dir + strlen (gdb_sysroot));
-         strcat (debugfile, "/");
-         strcat (debugfile, debuglink);
+         /* 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))
-           {
-             do_cleanups (back_to);
-             return debugfile;
-           }
+           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;
        }
+
     }
 
-  do_cleanups (back_to);
-  xfree (debugfile);
-  return NULL;
+  return std::string ();
 }
 
 /* Modify PATH to contain only "[/]directory/" part of PATH.
@@ -1538,12 +1524,11 @@ terminate_after_last_dir_separator (char *path)
 }
 
 /* Find separate debuginfo for OBJFILE (using .gnu_debuglink section).
-   Returns pathname, or NULL.  */
+   Returns pathname, or an empty string.  */
 
-char *
+std::string
 find_separate_debug_file_by_debuglink (struct objfile *objfile)
 {
-  char *debugfile;
   unsigned long crc32;
 
   gdb::unique_xmalloc_ptr<char> debuglink
@@ -1553,17 +1538,18 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile)
     {
       /* There's no separate debug info, hence there's no way we could
         load it => no warning.  */
-      return NULL;
+      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 ()));
 
-  debugfile = find_separate_debug_file (dir.c_str (), canon_dir.get (),
-                                       debuglink.get (), crc32, objfile);
+  std::string debugfile
+    = find_separate_debug_file (dir.c_str (), canon_dir.get (),
+                               debuglink.get (), crc32, objfile);
 
-  if (debugfile == NULL)
+  if (debugfile.empty ())
     {
       /* For PR gdb/9538, try again with realpath (if different from the
         original).  */
@@ -1594,6 +1580,16 @@ find_separate_debug_file_by_debuglink (struct objfile *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:
@@ -1622,26 +1618,60 @@ symbol_file_command (const char *args, int from_tty)
       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 (char *arg : built_argv)
+      for (arg = built_argv[0], idx = 0; arg != NULL; arg = built_argv[++idx])
        {
-         if (strcmp (arg, "-readnow") == 0)
+         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 (*arg == '-')
-           error (_("unknown option `%s'"), arg);
-         else
+         else if (strcmp (arg, "-readnever") == 0)
+           flags |= OBJF_READNEVER;
+         else if (strcmp (arg, "-o") == 0)
            {
-             symbol_file_add_main_1 (arg, add_flags, flags);
-             name = arg;
+             arg = built_argv[++idx];
+             if (arg == NULL)
+               error (_("Missing argument to -o"));
+
+             offset = parse_and_eval_address (arg);
            }
+         else if (strcmp (arg, "--") == 0)
+           stop_processing_options = true;
+         else
+           error (_("Unrecognized argument \"%s\""), arg);
        }
 
       if (name == NULL)
        error (_("no symbol file name was specified"));
+
+      validate_readnow_readnever (flags);
+
+      /* Set SYMFILE_DEFER_BP_RESET because the proper displacement for a PIE
+        (Position Independent Executable) main symbol file will only be
+        computed by the solib_create_inferior_hook below.  Without it,
+        breakpoint_re_set would fail to insert the breakpoints with the zero
+        displacement.  */
+      add_flags |= SYMFILE_DEFER_BP_RESET;
+
+      symbol_file_add_main_1 (name, add_flags, flags, offset);
+
+      solib_create_inferior_hook (from_tty);
+
+      /* Now it's safe to re-add the breakpoints.  */
+      breakpoint_re_set ();
     }
 }
 
@@ -1663,7 +1693,7 @@ set_initial_language (void)
 
   if (lang == language_unknown)
     {
-      char *name = main_name ();
+      const char *name = main_name ();
       struct symbol *sym = lookup_symbol (name, NULL, VAR_DOMAIN, NULL).symbol;
 
       if (sym != NULL)
@@ -1689,12 +1719,10 @@ gdb_bfd_ref_ptr
 symfile_bfd_open (const char *name)
 {
   int desc = -1;
-  struct cleanup *back_to = make_cleanup (null_cleanup, 0);
 
+  gdb::unique_xmalloc_ptr<char> absolute_name;
   if (!is_target_filename (name))
     {
-      char *absolute_name;
-
       gdb::unique_xmalloc_ptr<char> expanded_name (tilde_expand (name));
 
       /* Look down path for it, allocate 2nd new malloc'd copy.  */
@@ -1715,8 +1743,7 @@ symfile_bfd_open (const char *name)
       if (desc < 0)
        perror_with_name (expanded_name.get ());
 
-      make_cleanup (xfree, absolute_name);
-      name = absolute_name;
+      name = absolute_name.get ();
     }
 
   gdb_bfd_ref_ptr sym_bfd (gdb_bfd_open (name, gnutarget, desc));
@@ -1731,8 +1758,6 @@ symfile_bfd_open (const char *name)
     error (_("`%s': can't read symbols: %s."), name,
           bfd_errmsg (bfd_get_error ()));
 
-  do_cleanups (back_to);
-
   return sym_bfd;
 }
 
@@ -1791,8 +1816,6 @@ find_sym_fns (bfd *abfd)
 static void
 load_command (const char *arg, int from_tty)
 {
-  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
-
   dont_repeat ();
 
   /* The user might be reloading because the binary has changed.  Take
@@ -1800,40 +1823,28 @@ load_command (const char *arg, int from_tty)
   reopen_exec_file ();
   reread_symbols ();
 
+  std::string temp;
   if (arg == NULL)
     {
-      const char *parg;
-      int count = 0;
+      const char *parg, *prev;
 
-      parg = arg = get_exec_file (1);
+      arg = get_exec_file (1);
 
-      /* Count how many \ " ' tab space there are in the name.  */
+      /* We may need to quote this string so buildargv can pull it
+        apart.  */
+      prev = parg = arg;
       while ((parg = strpbrk (parg, "\\\"'\t ")))
        {
-         parg++;
-         count++;
+         temp.append (prev, parg - prev);
+         prev = parg++;
+         temp.push_back ('\\');
        }
-
-      if (count)
+      /* 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 ())
        {
-         /* We need to quote this string so buildargv can pull it apart.  */
-         char *temp = (char *) xmalloc (strlen (arg) + count + 1 );
-         char *ptemp = temp;
-         const char *prev;
-
-         make_cleanup (xfree, temp);
-
-         prev = parg = arg;
-         while ((parg = strpbrk (parg, "\\\"'\t ")))
-           {
-             strncpy (ptemp, prev, parg - prev);
-             ptemp += parg - prev;
-             prev = parg++;
-             *ptemp++ = '\\';
-           }
-         strcpy (ptemp, prev);
-
-         arg = temp;
+         temp.append (prev);
+         arg = temp.c_str ();
        }
     }
 
@@ -1842,8 +1853,6 @@ load_command (const char *arg, int from_tty)
   /* After re-loading the executable, we don't really know which
      overlays are mapped any more.  */
   overlay_cache_invalid = 1;
-
-  do_cleanups (cleanup);
 }
 
 /* This version of "load" should be usable for any target.  Currently
@@ -1864,36 +1873,59 @@ add_section_size_callback (bfd *abfd, asection *asec, void *data)
 {
   bfd_size_type *sum = (bfd_size_type *) data;
 
-  *sum += bfd_get_section_size (asec);
+  *sum += bfd_section_size (asec);
 }
 
-/* Opaque data for load_section_callback.  */
-struct load_section_data {
-  CORE_ADDR load_offset;
-  struct load_progress_data *progress_data;
-  VEC(memory_write_request_s) *requests;
-};
-
 /* Opaque data for load_progress.  */
-struct load_progress_data {
+struct load_progress_data
+{
   /* Cumulative data.  */
-  unsigned long write_count;
-  unsigned long data_count;
-  bfd_size_type total_size;
+  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 {
+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;
+  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
@@ -1963,57 +1995,26 @@ load_progress (ULONGEST bytes, void *untyped_arg)
 static void
 load_section_callback (bfd *abfd, asection *asec, void *data)
 {
-  struct memory_write_request *new_request;
   struct load_section_data *args = (struct load_section_data *) data;
-  struct load_progress_section_data *section_data;
-  bfd_size_type size = bfd_get_section_size (asec);
-  gdb_byte *buffer;
-  const char *sect_name = bfd_get_section_name (abfd, asec);
+  bfd_size_type size = bfd_section_size (asec);
+  const char *sect_name = bfd_section_name (asec);
 
-  if ((bfd_get_section_flags (abfd, asec) & SEC_LOAD) == 0)
+  if ((bfd_section_flags (asec) & SEC_LOAD) == 0)
     return;
 
   if (size == 0)
     return;
 
-  new_request = VEC_safe_push (memory_write_request_s,
-                              args->requests, NULL);
-  memset (new_request, 0, sizeof (struct memory_write_request));
-  section_data = XCNEW (struct load_progress_section_data);
-  new_request->begin = bfd_section_lma (abfd, asec) + args->load_offset;
-  new_request->end = new_request->begin + size; /* FIXME Should size
-                                                  be in instead?  */
-  new_request->data = (gdb_byte *) xmalloc (size);
-  new_request->baton = section_data;
-
-  buffer = new_request->data;
-
-  section_data->cumulative = args->progress_data;
-  section_data->section_name = sect_name;
-  section_data->section_size = size;
-  section_data->lma = new_request->begin;
-  section_data->buffer = buffer;
-
+  ULONGEST begin = bfd_section_lma (asec) + args->load_offset;
+  ULONGEST end = begin + size;
+  gdb_byte *buffer = (gdb_byte *) xmalloc (size);
   bfd_get_section_contents (abfd, asec, buffer, 0, size);
-}
-
-/* Clean up an entire memory request vector, including load
-   data and progress records.  */
 
-static void
-clear_memory_write_data (void *arg)
-{
-  VEC(memory_write_request_s) **vec_p = (VEC(memory_write_request_s) **) arg;
-  VEC(memory_write_request_s) *vec = *vec_p;
-  int i;
-  struct memory_write_request *mr;
+  load_progress_section_data *section_data
+    = new load_progress_section_data (args->progress_data, sect_name, size,
+                                     begin, buffer);
 
-  for (i = 0; VEC_iterate (memory_write_request_s, vec, i, mr); ++i)
-    {
-      xfree (mr->data);
-      xfree (mr->baton);
-    }
-  VEC_free (memory_write_request_s, vec);
+  args->requests.emplace_back (begin, end, buffer, section_data);
 }
 
 static void print_transfer_performance (struct ui_file *stream,
@@ -2021,22 +2022,15 @@ static void print_transfer_performance (struct ui_file *stream,
                                        unsigned long write_count,
                                        std::chrono::steady_clock::duration d);
 
+/* See symfile.h.  */
+
 void
 generic_load (const char *args, int from_tty)
 {
-  struct cleanup *old_cleanups;
-  struct load_section_data cbdata;
   struct load_progress_data total_progress;
+  struct load_section_data cbdata (&total_progress);
   struct ui_out *uiout = current_uiout;
 
-  CORE_ADDR entry;
-
-  memset (&cbdata, 0, sizeof (cbdata));
-  memset (&total_progress, 0, sizeof (total_progress));
-  cbdata.progress_data = &total_progress;
-
-  old_cleanups = make_cleanup (clear_memory_write_data, &cbdata.requests);
-
   if (args == NULL)
     error_no_arg (_("file to load"));
 
@@ -2085,12 +2079,12 @@ generic_load (const char *args, int from_tty)
 
   steady_clock::time_point end_time = steady_clock::now ();
 
-  entry = bfd_get_start_address (loadfile_bfd.get ());
+  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->field_core_addr ("address", target_gdbarch (), entry);
   uiout->text (", load size ");
-  uiout->field_fmt ("load-size", "%lu", total_progress.data_count);
+  uiout->field_unsigned ("load-size", total_progress.data_count);
   uiout->text ("\n");
   regcache_write_pc (get_current_regcache (), entry);
 
@@ -2107,8 +2101,6 @@ generic_load (const char *args, int from_tty)
   print_transfer_performance (gdb_stdout, total_progress.data_count,
                              total_progress.write_count,
                              end_time - start_time);
-
-  do_cleanups (old_cleanups);
 }
 
 /* Report on STREAM the performance of a memory transfer operation,
@@ -2135,42 +2127,91 @@ print_transfer_performance (struct ui_file *stream,
 
       if (uiout->is_mi_like_p ())
        {
-         uiout->field_fmt ("transfer-rate", "%lu", rate * 8);
+         uiout->field_unsigned ("transfer-rate", rate * 8);
          uiout->text (" bits/sec");
        }
       else if (rate < 1024)
        {
-         uiout->field_fmt ("transfer-rate", "%lu", rate);
+         uiout->field_unsigned ("transfer-rate", rate);
          uiout->text (" bytes/sec");
        }
       else
        {
-         uiout->field_fmt ("transfer-rate", "%lu", rate / 1024);
+         uiout->field_unsigned ("transfer-rate", rate / 1024);
          uiout->text (" KB/sec");
        }
     }
   else
     {
-      uiout->field_fmt ("transferred-bits", "%lu", (data_count * 8));
+      uiout->field_unsigned ("transferred-bits", (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->field_unsigned ("write-rate", data_count / write_count);
       uiout->text (" bytes/write");
     }
   uiout->text (".\n");
 }
 
+/* Add an OFFSET to the start address of each section in OBJF, except
+   sections that were specified in ADDRS.  */
+
+static void
+set_objfile_default_section_offset (struct objfile *objf,
+                                   const section_addr_info &addrs,
+                                   CORE_ADDR offset)
+{
+  /* Add OFFSET to all sections by default.  */
+  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.  */
-/* Note: ezannoni 2000-04-13 This function/command used to have a
-   special case syntax for the rombug target (Rombug is the boot
-   monitor for Microware's OS-9 / OS-9000, see remote-os9k.c). In the
-   rombug case, the user doesn't need to supply a text address,
-   instead a call to target_link() (in target.c) would supply the
-   value to use.  We are now discontinuing this type of ad hoc syntax.  */
 
 static void
 add_symbol_file_command (const char *args, int from_tty)
@@ -2179,9 +2220,6 @@ add_symbol_file_command (const char *args, int from_tty)
   gdb::unique_xmalloc_ptr<char> filename;
   char *arg;
   int argcnt = 0;
-  int sec_num = 0;
-  int expecting_sec_name = 0;
-  int expecting_sec_addr = 0;
   struct objfile *objf;
   objfile_flags flags = OBJF_USERLOADED | OBJF_SHARED;
   symfile_add_flags add_flags = 0;
@@ -2195,71 +2233,73 @@ add_symbol_file_command (const char *args, int from_tty)
     const char *value;
   };
 
-  struct section_addr_info *section_addrs;
-  std::vector<sect_opt> sect_opts;
-  struct cleanup *my_cleanups = make_cleanup (null_cleanup, NULL);
+  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])
     {
-      /* Process the argument.  */
-      if (argcnt == 0)
-       {
-         /* The first argument is the file name.  */
-         filename.reset (tilde_expand (arg));
-       }
-      else if (argcnt == 1)
-       {
-         /* The second argument is always the text address at which
-            to load the program.  */
-         sect_opt sect = { ".text", arg };
-         sect_opts.push_back (sect);
-       }
-      else
+      if (stop_processing_options || *arg != '-')
        {
-         /* It's an option (starting with '-') or it's an argument
-            to an option.  */
-         if (expecting_sec_name)
-           {
-             sect_opt sect = { arg, NULL };
-             sect_opts.push_back (sect);
-             expecting_sec_name = 0;
-           }
-         else if (expecting_sec_addr)
+         if (filename == NULL)
            {
-             sect_opts.back ().value = arg;
-             expecting_sec_addr = 0;
+             /* First non-option argument is always the filename.  */
+             filename.reset (tilde_expand (arg));
            }
-         else if (strcmp (arg, "-readnow") == 0)
-           flags |= OBJF_READNOW;
-         else if (strcmp (arg, "-s") == 0)
+         else if (!seen_addr)
            {
-             expecting_sec_name = 1;
-             expecting_sec_addr = 1;
+             /* 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);
     }
 
-  /* This command takes at least two arguments.  The first one is a
-     filename, and the second is the address where this file has been
-     loaded.  Abort now if this address hasn't been provided by the
-     user.  */
-  if (sect_opts.empty ())
-    error (_("The address where %s has been loaded is missing"),
-          filename.get ());
+  if (filename == NULL)
+    error (_("You must provide a filename to be loaded."));
 
-  if (expecting_sec_name)
-    error (_("Missing section name after \"-s\""));
-  else if (expecting_sec_addr)
-    error (_("Missing section address after \"-s\""));
+  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
@@ -2267,25 +2307,31 @@ add_symbol_file_command (const char *args, int from_tty)
      statements because hex_string returns a local static
      string.  */
 
-  printf_unfiltered (_("add symbol table from file \"%s\" at\n"),
+  printf_unfiltered (_("add symbol table from file \"%s\""),
                     filename.get ());
-  section_addrs = alloc_section_addr_info (sect_opts.size ());
-  make_cleanup (xfree, section_addrs);
-  for (sect_opt &sect : sect_opts)
+  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 = sect.value;
-      const char *sec = sect.name;
+      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.  */
-      section_addrs->other[sec_num].name = (char *) sec;
-      section_addrs->other[sec_num].addr = addr;
-      printf_unfiltered ("\t%s_addr = %s\n", sec,
-                        paddress (gdbarch, addr));
-      sec_num++;
+         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).
@@ -2293,19 +2339,32 @@ add_symbol_file_command (const char *args, int from_tty)
         At this point, we don't know what file type this is,
         so we can't determine what section names are valid.  */
     }
-  section_addrs->num_sections = sec_num;
+  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);
+  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 ();
-  do_cleanups (my_cleanups);
 }
 \f
 
@@ -2337,12 +2396,16 @@ remove_symbol_file_command (const char *args, int from_tty)
 
       addr = parse_and_eval_address (argv[1]);
 
-      ALL_OBJFILES (objf)
+      for (objfile *objfile : current_program_space->objfiles ())
        {
-         if ((objf->flags & OBJF_USERLOADED) != 0
-             && (objf->flags & OBJF_SHARED) != 0
-             && objf->pspace == pspace && is_addr_in_objfile (addr, objf))
-           break;
+         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)
@@ -2354,13 +2417,16 @@ remove_symbol_file_command (const char *args, int from_tty)
 
       gdb::unique_xmalloc_ptr<char> filename (tilde_expand (argv[0]));
 
-      ALL_OBJFILES (objf)
+      for (objfile *objfile : current_program_space->objfiles ())
        {
-         if ((objf->flags & OBJF_USERLOADED) != 0
-             && (objf->flags & OBJF_SHARED) != 0
-             && objf->pspace == pspace
-             && filename_cmp (filename.get (), objfile_name (objf)) == 0)
-           break;
+         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;
+           }
        }
     }
 
@@ -2381,19 +2447,12 @@ remove_symbol_file_command (const char *args, int from_tty)
 void
 reread_symbols (void)
 {
-  struct objfile *objfile;
   long new_modtime;
   struct stat new_statbuf;
   int res;
   std::vector<struct objfile *> new_objfiles;
 
-  /* With the addition of shared libraries, this should be modified,
-     the load time should be saved in the partial symbol tables, since
-     different tables may come from different source files.  FIXME.
-     This routine should then walk down each partial symbol table
-     and see if the symbol table that it originates from has been changed.  */
-
-  for (objfile = object_files; objfile; objfile = objfile->next)
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       if (objfile->obfd == NULL)
        continue;
@@ -2413,20 +2472,18 @@ reread_symbols (void)
       if (res != 0)
        {
          /* FIXME, should use print_sys_errmsg but it's not filtered.  */
-         printf_unfiltered (_("`%s' has disappeared; keeping its symbols.\n"),
-                            objfile_name (objfile));
+         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 cleanup *old_cleanups;
          struct section_offsets *offsets;
          int num_offsets;
-         char *original_name;
 
-         printf_unfiltered (_("`%s' has changed; re-reading symbols.\n"),
-                            objfile_name (objfile));
+         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
@@ -2441,7 +2498,7 @@ reread_symbols (void)
          std::unique_ptr<struct objfile> objfile_holder (objfile);
 
          /* We need to do this whenever any symbols go away.  */
-         old_cleanups = make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/);
+         clear_symtab_users_cleanup defer_clear_users (0);
 
          if (exec_bfd != NULL
              && filename_cmp (bfd_get_filename (objfile->obfd),
@@ -2458,6 +2515,9 @@ reread_symbols (void)
             automatically recreated by sym_read.  */
          free_objfile_separate_debug (objfile);
 
+         /* Clear the stale source cache.  */
+         forget_cached_source_info ();
+
          /* Remove any references to this objfile in the global
             value lists.  */
          preserve_values (objfile);
@@ -2478,7 +2538,7 @@ reread_symbols (void)
          /* Clean up any state BFD has sitting around.  */
          {
            gdb_bfd_ref_ptr obfd (objfile->obfd);
-           char *obfd_filename;
+           const char *obfd_filename;
 
            obfd_filename = bfd_get_filename (objfile->obfd);
            /* Open the new BFD before freeing the old one, so that
@@ -2489,8 +2549,7 @@ reread_symbols (void)
              error (_("Can't open %s to read symbols."), obfd_filename);
          }
 
-         original_name = xstrdup (objfile->original_name);
-         make_cleanup (xfree, original_name);
+         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))
@@ -2505,24 +2564,15 @@ reread_symbols (void)
          memcpy (offsets, objfile->section_offsets,
                  SIZEOF_N_SECTION_OFFSETS (num_offsets));
 
-         /* FIXME: Do we have to free a whole linked list, or is this
-            enough?  */
-         objfile->global_psymbols.clear ();
-         objfile->static_psymbols.clear ();
-
-         /* Free the obstacks for non-reusable objfiles.  */
-         psymbol_bcache_free (objfile->psymbol_cache);
-         objfile->psymbol_cache = psymbol_bcache_init ();
+         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->psymtabs = NULL;
-         objfile->psymtabs_addrmap = NULL;
-         objfile->free_psymtabs = 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
@@ -2536,8 +2586,7 @@ reread_symbols (void)
          set_objfile_per_bfd (objfile);
 
          objfile->original_name
-           = (char *) obstack_copy0 (&objfile->objfile_obstack, original_name,
-                                     strlen (original_name));
+           = obstack_strdup (&objfile->objfile_obstack, original_name);
 
          /* Reset the sym_fns pointer.  The ELF reader can change it
             based on whether .gdb_index is present, and we need it to
@@ -2545,7 +2594,6 @@ reread_symbols (void)
          objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd));
 
          build_objfile_section_table (objfile);
-         terminate_minimal_symbol_table (objfile);
 
          /* We use the same section offsets as from last time.  I'm not
             sure whether that is always correct for shared libraries.  */
@@ -2565,7 +2613,7 @@ reread_symbols (void)
            }
 
          (*objfile->sf->sym_init) (objfile);
-         clear_complaints (&symfile_complaints, 1, 1);
+         clear_complaints ();
 
          objfile->flags &= ~OBJF_PSYMTABS_READ;
 
@@ -2590,12 +2638,12 @@ reread_symbols (void)
          if (!objfile_has_symbols (objfile))
            {
              wrap_here ("");
-             printf_unfiltered (_("(no debugging symbols found)\n"));
+             printf_filtered (_("(no debugging symbols found)\n"));
              wrap_here ("");
            }
 
          /* We're done reading the symbol file; finish off complaints.  */
-         clear_complaints (&symfile_complaints, 0, 1);
+         clear_complaints ();
 
          /* Getting new symbols may change our opinion about what is
             frameless.  */
@@ -2604,7 +2652,7 @@ reread_symbols (void)
 
          /* Discard cleanups as symbol reading was successful.  */
          objfile_holder.release ();
-         discard_cleanups (old_cleanups);
+         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
@@ -2621,14 +2669,14 @@ reread_symbols (void)
       clear_symtab_users (0);
 
       /* clear_objfile_data for each objfile was called before freeing it and
-        observer_notify_new_objfile (NULL) has been called by
+        gdb::observers::new_objfile.notify (NULL) has been called by
         clear_symtab_users above.  Notify the new files now.  */
       for (auto iter : new_objfiles)
-       observer_notify_new_objfile (iter);
+       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.  */
-      observer_notify_executable_changed ();
+      gdb::observers::executable_changed.notify ();
     }
 }
 \f
@@ -2760,8 +2808,8 @@ allocate_symtab (struct compunit_symtab *cust, const char *filename)
     = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symtab);
 
   symtab->filename
-    = (const char *) bcache (filename, strlen (filename) + 1,
-                            objfile->per_bfd->filename_cache);
+    = ((const char *) objfile->per_bfd->filename_cache.insert
+       (filename, strlen (filename) + 1));
   symtab->fullname = NULL;
   symtab->language = deduce_language_from_filename (filename);
 
@@ -2778,13 +2826,13 @@ allocate_symtab (struct compunit_symtab *cust, const char *filename)
        {
          xfree (last_objfile_name);
          last_objfile_name = xstrdup (objfile_name (objfile));
-         fprintf_unfiltered (gdb_stdlog,
-                             "Creating one or more symtabs for objfile %s ...\n",
-                             last_objfile_name);
+         fprintf_filtered (gdb_stdlog,
+                           "Creating one or more symtabs for objfile %s ...\n",
+                           last_objfile_name);
        }
-      fprintf_unfiltered (gdb_stdlog,
-                         "Created symtab %s for module %s.\n",
-                         host_address_to_string (symtab), filename);
+      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.  */
@@ -2822,18 +2870,16 @@ allocate_compunit_symtab (struct objfile *objfile, const char *name)
      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));
+  cu->name = obstack_strdup (&objfile->objfile_obstack, saved_name);
 
   COMPUNIT_DEBUGFORMAT (cu) = "unknown";
 
   if (symtab_create_debug)
     {
-      fprintf_unfiltered (gdb_stdlog,
-                         "Created compunit symtab %s for %s.\n",
-                         host_address_to_string (cu),
-                         cu->name);
+      fprintf_filtered (gdb_stdlog,
+                       "Created compunit symtab %s for %s.\n",
+                       host_address_to_string (cu),
+                       cu->name);
     }
 
   return cu;
@@ -2865,13 +2911,7 @@ clear_symtab_users (symfile_add_flags add_flags)
   clear_displays ();
   clear_last_displayed_sal ();
   clear_pc_function_cache ();
-  observer_notify_new_objfile (NULL);
-
-  /* Clear globals which might have pointed into a removed objfile.
-     FIXME: It's not clear which of these are supposed to persist
-     between expressions and which ought to be reset each time.  */
-  expression_context_block = NULL;
-  innermost_block = NULL;
+  gdb::observers::new_objfile.notify (NULL);
 
   /* Varobj may refer to old symbols, perform a cleanup.  */
   varobj_invalidate ();
@@ -2881,12 +2921,6 @@ clear_symtab_users (symfile_add_flags add_flags)
   if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
     breakpoint_re_set ();
 }
-
-static void
-clear_symtab_users_cleanup (void *ignore)
-{
-  clear_symtab_users (0);
-}
 \f
 /* OVERLAYS:
    The following code implements an abstraction for debugging overlay sections.
@@ -2950,12 +2984,10 @@ section_is_overlay (struct obj_section *section)
 {
   if (overlay_debugging && section)
     {
-      bfd *abfd = section->objfile->obfd;
       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))
+      if (bfd_section_lma (bfd_section) != 0
+         && bfd_section_lma (bfd_section) != bfd_section_vma (bfd_section))
        return 1;
     }
 
@@ -2968,12 +3000,12 @@ section_is_overlay (struct obj_section *section)
 static void
 overlay_invalidate_all (void)
 {
-  struct objfile *objfile;
   struct obj_section *sect;
 
-  ALL_OBJSECTIONS (objfile, sect)
-    if (section_is_overlay (sect))
-      sect->ovly_mapped = -1;
+  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)
@@ -3012,7 +3044,7 @@ section_is_mapped (struct obj_section *osect)
          if (osect->ovly_mapped == -1)
            gdbarch_overlay_update (gdbarch, osect);
        }
-      /* fall thru to manual case */
+      /* fall thru */
     case ovly_on:              /* overlay debugging manual */
       return osect->ovly_mapped == 1;
     }
@@ -3026,15 +3058,14 @@ 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);
+      bfd_vma size = bfd_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)
+      if (bfd_section_lma (bfd_section) + offset <= pc
+         && pc < bfd_section_lma (bfd_section) + offset + size)
        return 1;
     }
 
@@ -3080,11 +3111,10 @@ overlay_unmapped_address (CORE_ADDR pc, struct obj_section *section)
 {
   if (section_is_overlay (section) && pc_in_mapped_range (pc, section))
     {
-      bfd *abfd = section->objfile->obfd;
       asection *bfd_section = section->the_bfd_section;
 
-      return pc + bfd_section_lma (abfd, bfd_section)
-               - bfd_section_vma (abfd, bfd_section);
+      return (pc + bfd_section_lma (bfd_section)
+             - bfd_section_vma (bfd_section));
     }
 
   return pc;
@@ -3099,11 +3129,10 @@ overlay_mapped_address (CORE_ADDR pc, struct obj_section *section)
 {
   if (section_is_overlay (section) && pc_in_unmapped_range (pc, section))
     {
-      bfd *abfd = section->objfile->obfd;
       asection *bfd_section = section->the_bfd_section;
 
-      return pc + bfd_section_vma (abfd, bfd_section)
-               - bfd_section_lma (abfd, bfd_section);
+      return (pc + bfd_section_vma (bfd_section)
+             - bfd_section_lma (bfd_section));
     }
 
   return pc;
@@ -3146,24 +3175,24 @@ symbol_overlayed_address (CORE_ADDR address, struct obj_section *section)
 struct obj_section *
 find_pc_overlay (CORE_ADDR pc)
 {
-  struct objfile *objfile;
   struct obj_section *osect, *best_match = NULL;
 
   if (overlay_debugging)
     {
-      ALL_OBJSECTIONS (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;
-         }
+      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;
 }
@@ -3175,14 +3204,14 @@ find_pc_overlay (CORE_ADDR pc)
 struct obj_section *
 find_pc_mapped_section (CORE_ADDR pc)
 {
-  struct objfile *objfile;
   struct obj_section *osect;
 
   if (overlay_debugging)
     {
-      ALL_OBJSECTIONS (objfile, osect)
-       if (pc_in_mapped_range (pc, osect) && section_is_mapped (osect))
-         return osect;
+      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;
@@ -3195,36 +3224,36 @@ static void
 list_overlays_command (const char *args, int from_tty)
 {
   int nmapped = 0;
-  struct objfile *objfile;
   struct obj_section *osect;
 
   if (overlay_debugging)
     {
-      ALL_OBJSECTIONS (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++;
-       }
+      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 (osect->the_bfd_section);
+             lma = bfd_section_lma (osect->the_bfd_section);
+             size = bfd_section_size (osect->the_bfd_section);
+             name = bfd_section_name (osect->the_bfd_section);
+
+             printf_filtered ("Section %s, loaded at ", name);
+             fputs_filtered (paddress (gdbarch, lma), gdb_stdout);
+             puts_filtered (" - ");
+             fputs_filtered (paddress (gdbarch, lma + size), gdb_stdout);
+             printf_filtered (", mapped at ");
+             fputs_filtered (paddress (gdbarch, vma), gdb_stdout);
+             puts_filtered (" - ");
+             fputs_filtered (paddress (gdbarch, vma + size), gdb_stdout);
+             puts_filtered ("\n");
+
+             nmapped++;
+           }
     }
   if (nmapped == 0)
     printf_filtered (_("No sections are mapped.\n"));
@@ -3236,7 +3265,6 @@ list_overlays_command (const char *args, int from_tty)
 static void
 map_overlay_command (const char *args, int from_tty)
 {
-  struct objfile *objfile, *objfile2;
   struct obj_section *sec, *sec2;
 
   if (!overlay_debugging)
@@ -3248,29 +3276,31 @@ map_overlay_command (const char *args, int from_tty)
     error (_("Argument required: name of an overlay section"));
 
   /* First, find a section matching the user supplied argument.  */
-  ALL_OBJSECTIONS (objfile, sec)
-    if (!strcmp (bfd_section_name (objfile->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: */
-      ALL_OBJSECTIONS (objfile2, sec2)
-       if (sec2->ovly_mapped && sec != sec2 && sections_overlap (sec, sec2))
+  for (objfile *obj_file : current_program_space->objfiles ())
+    ALL_OBJFILE_OSECTIONS (obj_file, sec)
+      if (!strcmp (bfd_section_name (sec->the_bfd_section), args))
        {
-         if (info_verbose)
-           printf_unfiltered (_("Note: section %s unmapped by overlap\n"),
-                            bfd_section_name (objfile->obfd,
-                                              sec2->the_bfd_section));
-         sec2->ovly_mapped = 0;        /* sec2 overlaps sec: unmap sec2.  */
+         /* Now, check to see if the section is an overlay.  */
+         if (!section_is_overlay (sec))
+           continue;           /* not an overlay section */
+
+         /* Mark the overlay as "mapped".  */
+         sec->ovly_mapped = 1;
+
+         /* Next, make a pass and unmap any sections that are
+            overlapped by this new section: */
+         for (objfile *objfile2 : current_program_space->objfiles ())
+           ALL_OBJFILE_OSECTIONS (objfile2, sec2)
+             if (sec2->ovly_mapped && sec != sec2 && sections_overlap (sec,
+                                                                       sec2))
+               {
+                 if (info_verbose)
+                   printf_unfiltered (_("Note: section %s unmapped by overlap\n"),
+                                      bfd_section_name (sec2->the_bfd_section));
+                 sec2->ovly_mapped = 0; /* sec2 overlaps sec: unmap sec2.  */
+               }
+         return;
        }
-      return;
-    }
   error (_("No overlay section called %s"), args);
 }
 
@@ -3281,7 +3311,6 @@ map_overlay_command (const char *args, int from_tty)
 static void
 unmap_overlay_command (const char *args, int from_tty)
 {
-  struct objfile *objfile;
   struct obj_section *sec = NULL;
 
   if (!overlay_debugging)
@@ -3293,14 +3322,15 @@ unmap_overlay_command (const char *args, int from_tty)
     error (_("Argument required: name of an overlay section"));
 
   /* First, find a section matching the user supplied argument.  */
-  ALL_OBJSECTIONS (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;
-    }
+  for (objfile *objfile : current_program_space->objfiles ())
+    ALL_OBJFILE_OSECTIONS (objfile, sec)
+      if (!strcmp (bfd_section_name (sec->the_bfd_section), args))
+       {
+         if (!sec->ovly_mapped)
+           error (_("Section %s is not mapped"), args);
+         sec->ovly_mapped = 0;
+         return;
+       }
   error (_("No overlay section called %s"), args);
 }
 
@@ -3497,21 +3527,20 @@ static int
 simple_overlay_update_1 (struct obj_section *osect)
 {
   int i;
-  bfd *obfd = osect->objfile->obfd;
   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))
+    if (cache_ovly_table[i][VMA] == bfd_section_vma (bsect)
+       && cache_ovly_table[i][LMA] == bfd_section_lma (bsect))
       {
        read_target_long_array (cache_ovly_table_base + i * word_size,
                                (unsigned int *) cache_ovly_table[i],
                                4, word_size, byte_order);
-       if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect)
-           && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect))
+       if (cache_ovly_table[i][VMA] == bfd_section_vma (bsect)
+           && cache_ovly_table[i][LMA] == bfd_section_lma (bsect))
          {
            osect->ovly_mapped = cache_ovly_table[i][MAPPED];
            return 1;
@@ -3533,8 +3562,6 @@ simple_overlay_update_1 (struct obj_section *osect)
 void
 simple_overlay_update (struct obj_section *osect)
 {
-  struct objfile *objfile;
-
   /* 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?  */
@@ -3566,21 +3593,21 @@ simple_overlay_update (struct obj_section *osect)
     return;
 
   /* Now may as well update all sections, even if only one was requested.  */
-  ALL_OBJSECTIONS (objfile, osect)
-    if (section_is_overlay (osect))
-    {
-      int i;
-      bfd *obfd = osect->objfile->obfd;
-      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.  */
-         }
-    }
+  for (objfile *objfile : current_program_space->objfiles ())
+    ALL_OBJFILE_OSECTIONS (objfile, osect)
+      if (section_is_overlay (osect))
+       {
+         int i;
+         asection *bsect = osect->the_bfd_section;
+
+         for (i = 0; i < cache_novlys; i++)
+           if (cache_ovly_table[i][VMA] == bfd_section_vma (bsect)
+               && cache_ovly_table[i][LMA] == bfd_section_lma (bsect))
+             { /* obj_section matches i'th entry in ovly_table.  */
+               osect->ovly_mapped = cache_ovly_table[i][MAPPED];
+               break;          /* finished with inner for loop: break out.  */
+             }
+       }
 }
 
 /* Set the output sections and output offsets for section SECTP in
@@ -3782,16 +3809,14 @@ expand_symtabs_matching
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain kind)
 {
-  struct objfile *objfile;
-
-  ALL_OBJFILES (objfile)
-  {
-    if (objfile->sf)
-      objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher,
-                                               lookup_name,
-                                               symbol_matcher,
-                                               expansion_notify, 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".
@@ -3802,14 +3827,12 @@ void
 map_symbol_filenames (symbol_filename_ftype *fun, void *data,
                      int need_fullname)
 {
-  struct objfile *objfile;
-
-  ALL_OBJFILES (objfile)
-  {
-    if (objfile->sf)
-      objfile->sf->qf->map_symbol_filenames (objfile, fun, data,
-                                            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
@@ -3847,7 +3870,7 @@ test_set_ext_lang_command ()
   SELF_CHECK (lang == language_unknown);
 
   /* Test adding a new extension using the CLI command.  */
-  gdb::unique_xmalloc_ptr<char> args_holder (xstrdup (".hello rust"));
+  auto args_holder = make_unique_xstrdup (".hello rust");
   ext_args = args_holder.get ();
   set_ext_lang_command (NULL, 1, NULL);
 
@@ -3876,28 +3899,34 @@ _initialize_symfile (void)
 {
   struct cmd_list_element *c;
 
-  observer_attach_free_objfile (symfile_free_objfile);
+  gdb::observers::free_objfile.attach (symfile_free_objfile);
 
-#define READNOW_HELP \
+#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."
+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] 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_HELP), &cmdlist);
+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 ADDR [-readnow | -s SECT-NAME SECT-ADDR]...\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"
-READNOW_HELP),
+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);
 
@@ -3911,8 +3940,8 @@ 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\
+Dynamically load FILE into the running program.\n\
+FILE symbols are recorded for access from GDB.\n\
 Usage: load [FILE] [OFFSET]\n\
 An optional load OFFSET may also be given as a literal address.\n\
 When OFFSET is provided, FILE must also be provided.  FILE can be provided\n\
This page took 0.057916 seconds and 4 git commands to generate.