Use gdb::unique_xmalloc_ptr when calling tilde_expand
[deliverable/binutils-gdb.git] / gdb / symfile.c
index 84858dcf07b21fe865ee9c34f8104943b36ac545..3e2df9bda43d3c126d39d305bd60739a16792ad3 100644 (file)
@@ -1,6 +1,6 @@
 /* Generic symbol file reading for the GNU debugger, GDB.
 
-   Copyright (C) 1990-2014 Free Software Foundation, Inc.
+   Copyright (C) 1990-2017 Free Software Foundation, Inc.
 
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
@@ -45,7 +45,6 @@
 #include "bcache.h"
 #include "hashtab.h"
 #include "readline/readline.h"
-#include "gdb_assert.h"
 #include "block.h"
 #include "observer.h"
 #include "exec.h"
 
 #include <sys/types.h>
 #include <fcntl.h>
-#include <string.h>
 #include <sys/stat.h>
 #include <ctype.h>
-#include <time.h>
-#include <sys/time.h>
+#include <chrono>
 
 #include "psymtab.h"
 
@@ -87,14 +84,13 @@ int readnow_symbol_files;   /* Read full symbols immediately.  */
 
 static void load_command (char *, int);
 
-static void symbol_file_add_main_1 (const char *args, int from_tty, int flags);
+static void symbol_file_add_main_1 (const char *args, symfile_add_flags add_flags,
+                                   objfile_flags flags);
 
 static void add_symbol_file_command (char *, int);
 
 static const struct sym_fns *find_sym_fns (bfd *);
 
-static void decrement_reading_symtab (void *);
-
 static void overlay_invalidate_all (void);
 
 static void overlay_auto_command (char *, int);
@@ -116,12 +112,8 @@ static int simple_read_overlay_table (void);
 
 static int simple_overlay_update_1 (struct obj_section *);
 
-static void add_filename_language (char *ext, enum language lang);
-
 static void info_ext_lang_command (char *args, int from_tty);
 
-static void init_filename_language_table (void);
-
 static void symfile_find_segment_sections (struct objfile *objfile);
 
 void _initialize_symfile (void);
@@ -199,22 +191,15 @@ print_symbol_loading_p (int from_tty, int exec, int full)
 
 int currently_reading_symtab = 0;
 
-static void
-decrement_reading_symtab (void *dummy)
-{
-  currently_reading_symtab--;
-  gdb_assert (currently_reading_symtab >= 0);
-}
-
 /* Increment currently_reading_symtab and return a cleanup that can be
    used to decrement it.  */
 
-struct cleanup *
+scoped_restore_tmpl<int>
 increment_reading_symtab (void)
 {
-  ++currently_reading_symtab;
-  gdb_assert (currently_reading_symtab > 0);
-  return make_cleanup (decrement_reading_symtab, NULL);
+  gdb_assert (currently_reading_symtab >= 0);
+  return make_scoped_restore (&currently_reading_symtab,
+                             currently_reading_symtab + 1);
 }
 
 /* Remember the lowest-addressed loadable section we've seen.
@@ -426,7 +411,7 @@ struct place_section_arg
 static void
 place_section (bfd *abfd, asection *sect, void *obj)
 {
-  struct place_section_arg *arg = 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);
@@ -557,7 +542,7 @@ addrs_section_sort (struct section_addr_info *addrs)
   int i;
 
   /* `+ 1' for the NULL terminator.  */
-  array = xmalloc (sizeof (*array) * (addrs->num_sections + 1));
+  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;
@@ -616,8 +601,7 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
   /* Now create ADDRS_TO_ABFD_ADDRS from ADDRS_SORTED and
      ABFD_ADDRS_SORTED.  */
 
-  addrs_to_abfd_addrs = xzalloc (sizeof (*addrs_to_abfd_addrs)
-                                * addrs->num_sections);
+  addrs_to_abfd_addrs = XCNEWVEC (struct other_sections *, addrs->num_sections);
   make_cleanup (xfree, addrs_to_abfd_addrs);
 
   while (*addrs_sorted)
@@ -872,10 +856,10 @@ default_symfile_segments (bfd *abfd)
    possibly force the partial symbols to be read.  */
 
 static void
-read_symbols (struct objfile *objfile, int add_flags)
+read_symbols (struct objfile *objfile, symfile_add_flags add_flags)
 {
   (*objfile->sf->sym_read) (objfile, add_flags);
-  objfile->per_bfd->minsyms_read = 1;
+  objfile->per_bfd->minsyms_read = true;
 
   /* find_separate_debug_file_in_section should be called only if there is
      single binary with no existing separate debug info file.  */
@@ -883,8 +867,7 @@ read_symbols (struct objfile *objfile, int add_flags)
       && objfile->separate_debug_objfile == NULL
       && objfile->separate_debug_objfile_backlink == NULL)
     {
-      bfd *abfd = find_separate_debug_file_in_section (objfile);
-      struct cleanup *cleanup = make_cleanup_bfd_unref (abfd);
+      gdb_bfd_ref_ptr abfd (find_separate_debug_file_in_section (objfile));
 
       if (abfd != NULL)
        {
@@ -892,11 +875,9 @@ read_symbols (struct objfile *objfile, int 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, objfile->original_name, add_flags,
-                                   objfile);
+         symbol_file_add_separate (abfd.get (), objfile->original_name,
+                                   add_flags, objfile);
        }
-
-      do_cleanups (cleanup);
     }
   if ((add_flags & SYMFILE_NO_READ) == 0)
     require_partial_symbols (objfile, 0);
@@ -1001,7 +982,7 @@ init_entry_point_info (struct objfile *objfile)
 static void
 syms_from_objfile_1 (struct objfile *objfile,
                     struct section_addr_info *addrs,
-                    int add_flags)
+                    symfile_add_flags add_flags)
 {
   struct section_addr_info *local_addr = NULL;
   struct cleanup *old_chain;
@@ -1018,7 +999,8 @@ syms_from_objfile_1 (struct objfile *objfile,
 
       objfile->num_sections = num_sections;
       objfile->section_offsets
-        = obstack_alloc (&objfile->objfile_obstack, size);
+       = (struct section_offsets *) obstack_alloc (&objfile->objfile_obstack,
+                                                   size);
       memset (objfile->section_offsets, 0, size);
       return;
     }
@@ -1091,7 +1073,7 @@ syms_from_objfile_1 (struct objfile *objfile,
 static void
 syms_from_objfile (struct objfile *objfile,
                   struct section_addr_info *addrs,
-                  int add_flags)
+                  symfile_add_flags add_flags)
 {
   syms_from_objfile_1 (objfile, addrs, add_flags);
   init_entry_point_info (objfile);
@@ -1101,8 +1083,8 @@ syms_from_objfile (struct objfile *objfile,
    symbols for a new objfile, or mapping in the symbols from a reusable
    objfile.  ADD_FLAGS is a bitmask of enum symfile_add_flags.  */
 
-void
-new_symfile_objfile (struct objfile *objfile, int add_flags)
+static void
+finish_new_objfile (struct objfile *objfile, symfile_add_flags add_flags)
 {
   /* If this is the main symbol file we have to clean up all users of the
      old main symbol file.  Otherwise it is sufficient to fixup all the
@@ -1144,9 +1126,10 @@ new_symfile_objfile (struct objfile *objfile, int add_flags)
    Upon failure, jumps back to command level (never returns).  */
 
 static struct objfile *
-symbol_file_add_with_addrs (bfd *abfd, const char *name, int add_flags,
+symbol_file_add_with_addrs (bfd *abfd, const char *name,
+                           symfile_add_flags add_flags,
                            struct section_addr_info *addrs,
-                           int flags, struct objfile *parent)
+                           objfile_flags flags, struct objfile *parent)
 {
   struct objfile *objfile;
   const int from_tty = add_flags & SYMFILE_VERBOSE;
@@ -1170,8 +1153,9 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name, int add_flags,
       && !query (_("Load new symbol table from \"%s\"? "), name))
     error (_("Not confirmed."));
 
-  objfile = allocate_objfile (abfd, name,
-                             flags | (mainline ? OBJF_MAINLINE : 0));
+  if (mainline)
+    flags |= OBJF_MAINLINE;
+  objfile = allocate_objfile (abfd, name, flags);
 
   if (parent)
     add_separate_debug_objfile (objfile, parent);
@@ -1236,7 +1220,7 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name, int add_flags,
       return objfile;  /* No symbols.  */
     }
 
-  new_symfile_objfile (objfile, add_flags);
+  finish_new_objfile (objfile, add_flags);
 
   observer_notify_new_objfile (objfile);
 
@@ -1248,10 +1232,10 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name, int add_flags,
    see allocate_objfile's definition.  */
 
 void
-symbol_file_add_separate (bfd *bfd, const char *name, int symfile_flags,
+symbol_file_add_separate (bfd *bfd, const char *name,
+                         symfile_add_flags symfile_flags,
                          struct objfile *objfile)
 {
-  struct objfile *new_objfile;
   struct section_addr_info *sap;
   struct cleanup *my_cleanup;
 
@@ -1261,7 +1245,7 @@ symbol_file_add_separate (bfd *bfd, const char *name, int symfile_flags,
   sap = build_section_addr_info_from_objfile (objfile);
   my_cleanup = make_cleanup_free_section_addr_info (sap);
 
-  new_objfile = symbol_file_add_with_addrs
+  symbol_file_add_with_addrs
     (bfd, name, symfile_flags, sap,
      objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW
                       | OBJF_USERLOADED),
@@ -1275,9 +1259,10 @@ symbol_file_add_separate (bfd *bfd, const char *name, int symfile_flags,
    See symbol_file_add_with_addrs's comments for details.  */
 
 struct objfile *
-symbol_file_add_from_bfd (bfd *abfd, const char *name, int add_flags,
+symbol_file_add_from_bfd (bfd *abfd, const char *name,
+                         symfile_add_flags add_flags,
                           struct section_addr_info *addrs,
-                          int flags, struct objfile *parent)
+                          objfile_flags flags, struct objfile *parent)
 {
   return symbol_file_add_with_addrs (abfd, name, add_flags, addrs, flags,
                                     parent);
@@ -1287,16 +1272,13 @@ symbol_file_add_from_bfd (bfd *abfd, const char *name, int add_flags,
    loaded file.  See symbol_file_add_with_addrs's comments for details.  */
 
 struct objfile *
-symbol_file_add (const char *name, int add_flags,
-                struct section_addr_info *addrs, int flags)
+symbol_file_add (const char *name, symfile_add_flags add_flags,
+                struct section_addr_info *addrs, objfile_flags flags)
 {
-  bfd *bfd = symfile_bfd_open (name);
-  struct cleanup *cleanup = make_cleanup_bfd_unref (bfd);
-  struct objfile *objf;
+  gdb_bfd_ref_ptr bfd (symfile_bfd_open (name));
 
-  objf = symbol_file_add_from_bfd (bfd, name, add_flags, addrs, flags, NULL);
-  do_cleanups (cleanup);
-  return objf;
+  return symbol_file_add_from_bfd (bfd.get (), name, add_flags, addrs,
+                                  flags, NULL);
 }
 
 /* Call symbol_file_add() with default values and update whatever is
@@ -1308,16 +1290,16 @@ symbol_file_add (const char *name, int add_flags,
    command itself.  */
 
 void
-symbol_file_add_main (const char *args, int from_tty)
+symbol_file_add_main (const char *args, symfile_add_flags add_flags)
 {
-  symbol_file_add_main_1 (args, from_tty, 0);
+  symbol_file_add_main_1 (args, add_flags, 0);
 }
 
 static void
-symbol_file_add_main_1 (const char *args, int from_tty, int flags)
+symbol_file_add_main_1 (const char *args, symfile_add_flags add_flags,
+                       objfile_flags flags)
 {
-  const int add_flags = (current_inferior ()->symfile_flags
-                        | SYMFILE_MAINLINE | (from_tty ? SYMFILE_VERBOSE : 0));
+  add_flags |= current_inferior ()->symfile_flags | SYMFILE_MAINLINE;
 
   symbol_file_add (args, add_flags, NULL, flags);
 
@@ -1325,7 +1307,7 @@ symbol_file_add_main_1 (const char *args, int from_tty, int flags)
      what is frameless.  */
   reinit_frame_cache ();
 
-  if ((flags & SYMFILE_NO_READ) == 0)
+  if ((add_flags & SYMFILE_NO_READ) == 0)
     set_initial_language ();
 }
 
@@ -1351,13 +1333,16 @@ symbol_file_clear (int from_tty)
     printf_unfiltered (_("No symbol file now.\n"));
 }
 
+/* See symfile.h.  */
+
+int separate_debug_file_debug = 0;
+
 static int
 separate_debug_file_exists (const char *name, unsigned long crc,
                            struct objfile *parent_objfile)
 {
   unsigned long file_crc;
   int file_crc_p;
-  bfd *abfd;
   struct stat parent_stat, abfd_stat;
   int verified_as_different;
 
@@ -1370,39 +1355,38 @@ separate_debug_file_exists (const char *name, unsigned long crc,
   if (filename_cmp (name, objfile_name (parent_objfile)) == 0)
     return 0;
 
-  abfd = gdb_bfd_open_maybe_remote (name);
+  if (separate_debug_file_debug)
+    printf_unfiltered (_("  Trying %s\n"), name);
+
+  gdb_bfd_ref_ptr abfd (gdb_bfd_open (name, gnutarget, -1));
 
-  if (!abfd)
+  if (abfd == NULL)
     return 0;
 
   /* Verify symlinks were not the cause of filename_cmp name difference above.
 
      Some operating systems, e.g. Windows, do not provide a meaningful
      st_ino; they always set it to zero.  (Windows does provide a
-     meaningful st_dev.)  Do not indicate a duplicate library in that
-     case.  While there is no guarantee that a system that provides
-     meaningful inode numbers will never set st_ino to zero, this is
-     merely an optimization, so we do not need to worry about false
-     negatives.  */
-
-  if (bfd_stat (abfd, &abfd_stat) == 0
+     meaningful st_dev.)  Files accessed from gdbservers that do not
+     support the vFile:fstat packet will also have st_ino set to zero.
+     Do not indicate a duplicate library in either case.  While there
+     is no guarantee that a system that provides meaningful inode
+     numbers will never set st_ino to zero, this is merely an
+     optimization, so we do not need to worry about false negatives.  */
+
+  if (bfd_stat (abfd.get (), &abfd_stat) == 0
       && abfd_stat.st_ino != 0
       && bfd_stat (parent_objfile->obfd, &parent_stat) == 0)
     {
       if (abfd_stat.st_dev == parent_stat.st_dev
          && abfd_stat.st_ino == parent_stat.st_ino)
-       {
-         gdb_bfd_unref (abfd);
-         return 0;
-       }
+       return 0;
       verified_as_different = 1;
     }
   else
     verified_as_different = 0;
 
-  file_crc_p = gdb_bfd_crc (abfd, &file_crc);
-
-  gdb_bfd_unref (abfd);
+  file_crc_p = gdb_bfd_crc (abfd.get (), &file_crc);
 
   if (!file_crc_p)
     return 0;
@@ -1411,9 +1395,9 @@ separate_debug_file_exists (const char *name, unsigned long crc,
     {
       unsigned long parent_crc;
 
-      /* If one (or both) the files are accessed for example the via "remote:"
-        gdbserver way it does not support the bfd_stat operation.  Verify
-        whether those two files are not the same manually.  */
+      /* If the files could not be verified as different with
+        bfd_stat then we need to calculate the parent's CRC
+        to verify whether the files are different or not.  */
 
       if (!verified_as_different)
        {
@@ -1467,17 +1451,22 @@ find_separate_debug_file (const char *dir,
   struct cleanup *back_to;
   int ix;
 
-  /* Set I to max (strlen (canon_dir), strlen (dir)).  */
+  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 = xmalloc (strlen (debug_file_directory) + 1
-                      + i
-                      + strlen (DEBUG_SUBDIRECTORY)
-                      + strlen ("/")
-                      + strlen (debuglink)
-                      + 1);
+  debugfile
+    = (char *) xmalloc (strlen (debug_file_directory) + 1
+                       + i
+                       + strlen (DEBUG_SUBDIRECTORY)
+                       + strlen ("/")
+                       + strlen (debuglink)
+                       + 1);
 
   /* First try in the same directory as the original file.  */
   strcpy (debugfile, dir);
@@ -1593,7 +1582,6 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile)
 
   if (debugfile == NULL)
     {
-#ifdef HAVE_LSTAT
       /* For PR gdb/9538, try again with realpath (if different from the
         original).  */
 
@@ -1620,7 +1608,6 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile)
                }
            }
        }
-#endif  /* HAVE_LSTAT  */
     }
 
   do_cleanups (cleanups);
@@ -1652,31 +1639,30 @@ symbol_file_command (char *args, int from_tty)
     }
   else
     {
-      char **argv = gdb_buildargv (args);
-      int flags = OBJF_USERLOADED;
+      objfile_flags flags = OBJF_USERLOADED;
+      symfile_add_flags add_flags = 0;
       struct cleanup *cleanups;
       char *name = NULL;
 
-      cleanups = make_cleanup_freeargv (argv);
-      while (*argv != NULL)
+      if (from_tty)
+       add_flags |= SYMFILE_VERBOSE;
+
+      gdb_argv built_argv (args);
+      for (char *arg : built_argv)
        {
-         if (strcmp (*argv, "-readnow") == 0)
+         if (strcmp (arg, "-readnow") == 0)
            flags |= OBJF_READNOW;
-         else if (**argv == '-')
-           error (_("unknown option `%s'"), *argv);
+         else if (*arg == '-')
+           error (_("unknown option `%s'"), arg);
          else
            {
-             symbol_file_add_main_1 (*argv, from_tty, flags);
-             name = *argv;
+             symbol_file_add_main_1 (arg, add_flags, flags);
+             name = arg;
            }
-
-         argv++;
        }
 
       if (name == NULL)
        error (_("no symbol file name was specified"));
-
-      do_cleanups (cleanups);
     }
 }
 
@@ -1699,7 +1685,7 @@ set_initial_language (void)
   if (lang == language_unknown)
     {
       char *name = main_name ();
-      struct symbol *sym = lookup_symbol (name, NULL, VAR_DOMAIN, NULL);
+      struct symbol *sym = lookup_symbol (name, NULL, VAR_DOMAIN, NULL).symbol;
 
       if (sym != NULL)
        lang = SYMBOL_LANGUAGE (sym);
@@ -1715,90 +1701,56 @@ set_initial_language (void)
   expected_language = current_language; /* Don't warn the user.  */
 }
 
-/* If NAME is a remote name open the file using remote protocol, otherwise
-   open it normally.  Returns a new reference to the BFD.  On error,
-   returns NULL with the BFD error set.  */
-
-bfd *
-gdb_bfd_open_maybe_remote (const char *name)
-{
-  bfd *result;
-
-  if (remote_filename_p (name))
-    result = remote_bfd_open (name, gnutarget);
-  else
-    result = gdb_bfd_open (name, gnutarget, -1);
-
-  return result;
-}
-
 /* Open the file specified by NAME and hand it off to BFD for
    preliminary analysis.  Return a newly initialized bfd *, which
    includes a newly malloc'd` copy of NAME (tilde-expanded and made
    absolute).  In case of trouble, error() is called.  */
 
-bfd *
-symfile_bfd_open (const char *cname)
+gdb_bfd_ref_ptr
+symfile_bfd_open (const char *name)
 {
-  bfd *sym_bfd;
-  int desc;
-  char *name, *absolute_name;
-  struct cleanup *back_to;
+  int desc = -1;
+  struct cleanup *back_to = make_cleanup (null_cleanup, 0);
 
-  if (remote_filename_p (cname))
+  if (!is_target_filename (name))
     {
-      sym_bfd = remote_bfd_open (cname, gnutarget);
-      if (!sym_bfd)
-       error (_("`%s': can't open to read symbols: %s."), cname,
-              bfd_errmsg (bfd_get_error ()));
-
-      if (!bfd_check_format (sym_bfd, bfd_object))
-       {
-         make_cleanup_bfd_unref (sym_bfd);
-         error (_("`%s': can't read symbols: %s."), cname,
-                bfd_errmsg (bfd_get_error ()));
-       }
+      char *absolute_name;
 
-      return sym_bfd;
-    }
+      gdb::unique_xmalloc_ptr<char> expanded_name (tilde_expand (name));
 
-  name = tilde_expand (cname); /* Returns 1st new malloc'd copy.  */
-
-  /* Look down path for it, allocate 2nd new malloc'd copy.  */
-  desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, name,
-               O_RDONLY | O_BINARY, &absolute_name);
+      /* Look down path for it, allocate 2nd new malloc'd copy.  */
+      desc = openp (getenv ("PATH"),
+                   OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH,
+                   expanded_name.get (), O_RDONLY | O_BINARY, &absolute_name);
 #if defined(__GO32__) || defined(_WIN32) || defined (__CYGWIN__)
-  if (desc < 0)
-    {
-      char *exename = alloca (strlen (name) + 5);
+      if (desc < 0)
+       {
+         char *exename = (char *) alloca (strlen (expanded_name.get ()) + 5);
 
-      strcat (strcpy (exename, name), ".exe");
-      desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH,
-                   exename, O_RDONLY | O_BINARY, &absolute_name);
-    }
+         strcat (strcpy (exename, expanded_name.get ()), ".exe");
+         desc = openp (getenv ("PATH"),
+                       OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH,
+                       exename, O_RDONLY | O_BINARY, &absolute_name);
+       }
 #endif
-  if (desc < 0)
-    {
-      make_cleanup (xfree, name);
-      perror_with_name (name);
-    }
+      if (desc < 0)
+       perror_with_name (expanded_name.get ());
 
-  xfree (name);
-  name = absolute_name;
-  back_to = make_cleanup (xfree, name);
+      make_cleanup (xfree, absolute_name);
+      name = absolute_name;
+    }
 
-  sym_bfd = gdb_bfd_open (name, gnutarget, desc);
-  if (!sym_bfd)
+  gdb_bfd_ref_ptr sym_bfd (gdb_bfd_open (name, gnutarget, desc));
+  if (sym_bfd == NULL)
     error (_("`%s': can't open to read symbols: %s."), name,
           bfd_errmsg (bfd_get_error ()));
-  bfd_set_cacheable (sym_bfd, 1);
 
-  if (!bfd_check_format (sym_bfd, bfd_object))
-    {
-      make_cleanup_bfd_unref (sym_bfd);
-      error (_("`%s': can't read symbols: %s."), name,
-            bfd_errmsg (bfd_get_error ()));
-    }
+  if (!gdb_bfd_has_target_filename (sym_bfd.get ()))
+    bfd_set_cacheable (sym_bfd.get (), 1);
+
+  if (!bfd_check_format (sym_bfd.get (), bfd_object))
+    error (_("`%s': can't read symbols: %s."), name,
+          bfd_errmsg (bfd_get_error ()));
 
   do_cleanups (back_to);
 
@@ -1809,7 +1761,7 @@ symfile_bfd_open (const char *cname)
    the section was not found.  */
 
 int
-get_section_index (struct objfile *objfile, char *section_name)
+get_section_index (struct objfile *objfile, const char *section_name)
 {
   asection *sect = bfd_get_section_by_name (objfile->obfd, section_name);
 
@@ -1890,7 +1842,7 @@ load_command (char *arg, int from_tty)
       if (count)
        {
          /* We need to quote this string so buildargv can pull it apart.  */
-         char *temp = xmalloc (strlen (arg) + count + 1 );
+         char *temp = (char *) xmalloc (strlen (arg) + count + 1 );
          char *ptemp = temp;
          char *prev;
 
@@ -1935,7 +1887,7 @@ static int validate_download = 0;
 static void
 add_section_size_callback (bfd *abfd, asection *asec, void *data)
 {
-  bfd_size_type *sum = data;
+  bfd_size_type *sum = (bfd_size_type *) data;
 
   *sum += bfd_get_section_size (asec);
 }
@@ -1972,7 +1924,8 @@ struct load_progress_section_data {
 static void
 load_progress (ULONGEST bytes, void *untyped_arg)
 {
-  struct load_progress_section_data *args = untyped_arg;
+  struct load_progress_section_data *args
+    = (struct load_progress_section_data *) untyped_arg;
   struct load_progress_data *totals;
 
   if (args == NULL)
@@ -1986,9 +1939,10 @@ load_progress (ULONGEST bytes, void *untyped_arg)
     {
       /* The write is just starting.  Let the user know we've started
         this section.  */
-      ui_out_message (current_uiout, 0, "Loading section %s, size %s lma %s\n",
-                     args->section_name, hex_string (args->section_size),
-                     paddress (target_gdbarch (), args->lma));
+      current_uiout->message ("Loading section %s, size %s lma %s\n",
+                             args->section_name,
+                             hex_string (args->section_size),
+                             paddress (target_gdbarch (), args->lma));
       return;
     }
 
@@ -2001,7 +1955,7 @@ load_progress (ULONGEST bytes, void *untyped_arg)
         might add a verify_memory() method to the target vector and
         then use that.  remote.c could implement that method using
         the ``qCRC'' packet.  */
-      gdb_byte *check = xmalloc (bytes);
+      gdb_byte *check = (gdb_byte *) xmalloc (bytes);
       struct cleanup *verify_cleanups = make_cleanup (xfree, check);
 
       if (target_read_memory (args->lma, check, bytes) != 0)
@@ -2037,7 +1991,7 @@ static void
 load_section_callback (bfd *abfd, asection *asec, void *data)
 {
   struct memory_write_request *new_request;
-  struct load_section_data *args = data;
+  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;
@@ -2052,11 +2006,11 @@ load_section_callback (bfd *abfd, asection *asec, void *data)
   new_request = VEC_safe_push (memory_write_request_s,
                               args->requests, NULL);
   memset (new_request, 0, sizeof (struct memory_write_request));
-  section_data = xcalloc (1, sizeof (struct load_progress_section_data));
+  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 = xmalloc (size);
+  new_request->data = (gdb_byte *) xmalloc (size);
   new_request->baton = section_data;
 
   buffer = new_request->data;
@@ -2076,7 +2030,7 @@ load_section_callback (bfd *abfd, asection *asec, void *data)
 static void
 clear_memory_write_data (void *arg)
 {
-  VEC(memory_write_request_s) **vec_p = 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;
@@ -2089,34 +2043,33 @@ clear_memory_write_data (void *arg)
   VEC_free (memory_write_request_s, vec);
 }
 
+static void print_transfer_performance (struct ui_file *stream,
+                                       unsigned long data_count,
+                                       unsigned long write_count,
+                                       std::chrono::steady_clock::duration d);
+
 void
-generic_load (char *args, int from_tty)
+generic_load (const char *args, int from_tty)
 {
-  bfd *loadfile_bfd;
-  struct timeval start_time, end_time;
-  char *filename;
-  struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0);
+  struct cleanup *old_cleanups;
   struct load_section_data cbdata;
   struct load_progress_data total_progress;
   struct ui_out *uiout = current_uiout;
 
   CORE_ADDR entry;
-  char **argv;
 
   memset (&cbdata, 0, sizeof (cbdata));
   memset (&total_progress, 0, sizeof (total_progress));
   cbdata.progress_data = &total_progress;
 
-  make_cleanup (clear_memory_write_data, &cbdata.requests);
+  old_cleanups = make_cleanup (clear_memory_write_data, &cbdata.requests);
 
   if (args == NULL)
     error_no_arg (_("file to load"));
 
-  argv = gdb_buildargv (args);
-  make_cleanup_freeargv (argv);
+  gdb_argv argv (args);
 
-  filename = tilde_expand (argv[0]);
-  make_cleanup (xfree, filename);
+  gdb::unique_xmalloc_ptr<char> filename (tilde_expand (argv[0]));
 
   if (argv[1] != NULL)
     {
@@ -2134,43 +2087,38 @@ generic_load (char *args, int from_tty)
     }
 
   /* Open the file for loading.  */
-  loadfile_bfd = gdb_bfd_open (filename, gnutarget, -1);
+  gdb_bfd_ref_ptr loadfile_bfd (gdb_bfd_open (filename.get (), gnutarget, -1));
   if (loadfile_bfd == NULL)
-    {
-      perror_with_name (filename);
-      return;
-    }
-
-  make_cleanup_bfd_unref (loadfile_bfd);
+    perror_with_name (filename.get ());
 
-  if (!bfd_check_format (loadfile_bfd, bfd_object))
+  if (!bfd_check_format (loadfile_bfd.get (), bfd_object))
     {
-      error (_("\"%s\" is not an object file: %s"), filename,
+      error (_("\"%s\" is not an object file: %s"), filename.get (),
             bfd_errmsg (bfd_get_error ()));
     }
 
-  bfd_map_over_sections (loadfile_bfd, add_section_size_callback,
+  bfd_map_over_sections (loadfile_bfd.get (), add_section_size_callback,
                         (void *) &total_progress.total_size);
 
-  bfd_map_over_sections (loadfile_bfd, load_section_callback, &cbdata);
+  bfd_map_over_sections (loadfile_bfd.get (), load_section_callback, &cbdata);
+
+  using namespace std::chrono;
 
-  gettimeofday (&start_time, NULL);
+  steady_clock::time_point start_time = steady_clock::now ();
 
   if (target_write_memory_blocks (cbdata.requests, flash_discard,
                                  load_progress) != 0)
     error (_("Load failed"));
 
-  gettimeofday (&end_time, NULL);
+  steady_clock::time_point end_time = steady_clock::now ();
 
-  entry = bfd_get_start_address (loadfile_bfd);
+  entry = bfd_get_start_address (loadfile_bfd.get ());
   entry = gdbarch_addr_bits_remove (target_gdbarch (), entry);
-  ui_out_text (uiout, "Start address ");
-  ui_out_field_fmt (uiout, "address", "%s", paddress (target_gdbarch (), entry));
-  ui_out_text (uiout, ", load size ");
-  ui_out_field_fmt (uiout, "load-size", "%lu", total_progress.data_count);
-  ui_out_text (uiout, "\n");
-  /* We were doing this in remote-mips.c, I suspect it is right
-     for other targets too.  */
+  uiout->text ("Start address ");
+  uiout->field_fmt ("address", "%s", paddress (target_gdbarch (), entry));
+  uiout->text (", load size ");
+  uiout->field_fmt ("load-size", "%lu", total_progress.data_count);
+  uiout->text ("\n");
   regcache_write_pc (get_current_regcache (), entry);
 
   /* Reset breakpoints, now that we have changed the load image.  For
@@ -2183,69 +2131,63 @@ generic_load (char *args, int from_tty)
 
   breakpoint_re_set ();
 
-  /* FIXME: are we supposed to call symbol_file_add or not?  According
-     to a comment from remote-mips.c (where a call to symbol_file_add
-     was commented out), making the call confuses GDB if more than one
-     file is loaded in.  Some targets do (e.g., remote-vx.c) but
-     others don't (or didn't - perhaps they have all been deleted).  */
-
   print_transfer_performance (gdb_stdout, total_progress.data_count,
                              total_progress.write_count,
-                             &start_time, &end_time);
+                             end_time - start_time);
 
   do_cleanups (old_cleanups);
 }
 
-/* Report how fast the transfer went.  */
+/* Report on STREAM the performance of a memory transfer operation,
+   such as 'load'.  DATA_COUNT is the number of bytes transferred.
+   WRITE_COUNT is the number of separate write operations, or 0, if
+   that information is not available.  TIME is how long the operation
+   lasted.  */
 
-void
+static void
 print_transfer_performance (struct ui_file *stream,
                            unsigned long data_count,
                            unsigned long write_count,
-                           const struct timeval *start_time,
-                           const struct timeval *end_time)
+                           std::chrono::steady_clock::duration time)
 {
-  ULONGEST time_count;
+  using namespace std::chrono;
   struct ui_out *uiout = current_uiout;
 
-  /* Compute the elapsed time in milliseconds, as a tradeoff between
-     accuracy and overflow.  */
-  time_count = (end_time->tv_sec - start_time->tv_sec) * 1000;
-  time_count += (end_time->tv_usec - start_time->tv_usec) / 1000;
+  milliseconds ms = duration_cast<milliseconds> (time);
 
-  ui_out_text (uiout, "Transfer rate: ");
-  if (time_count > 0)
+  uiout->text ("Transfer rate: ");
+  if (ms.count () > 0)
     {
-      unsigned long rate = ((ULONGEST) data_count * 1000) / time_count;
+      unsigned long rate = ((ULONGEST) data_count * 1000) / ms.count ();
 
-      if (ui_out_is_mi_like_p (uiout))
+      if (uiout->is_mi_like_p ())
        {
-         ui_out_field_fmt (uiout, "transfer-rate", "%lu", rate * 8);
-         ui_out_text (uiout, " bits/sec");
+         uiout->field_fmt ("transfer-rate", "%lu", rate * 8);
+         uiout->text (" bits/sec");
        }
       else if (rate < 1024)
        {
-         ui_out_field_fmt (uiout, "transfer-rate", "%lu", rate);
-         ui_out_text (uiout, " bytes/sec");
+         uiout->field_fmt ("transfer-rate", "%lu", rate);
+         uiout->text (" bytes/sec");
        }
       else
        {
-         ui_out_field_fmt (uiout, "transfer-rate", "%lu", rate / 1024);
-         ui_out_text (uiout, " KB/sec");
+         uiout->field_fmt ("transfer-rate", "%lu", rate / 1024);
+         uiout->text (" KB/sec");
        }
     }
   else
     {
-      ui_out_field_fmt (uiout, "transferred-bits", "%lu", (data_count * 8));
-      ui_out_text (uiout, " bits in <1 sec");
+      uiout->field_fmt ("transferred-bits", "%lu", (data_count * 8));
+      uiout->text (" bits in <1 sec");
     }
   if (write_count > 0)
     {
-      ui_out_text (uiout, ", ");
-      ui_out_field_fmt (uiout, "write-rate", "%lu", data_count / write_count);
-      ui_out_text (uiout, " bytes/write");
+      uiout->text (", ");
+      uiout->field_fmt ("write-rate", "%lu", data_count / write_count);
+      uiout->text (" bytes/write");
     }
-  ui_out_text (uiout, ".\n");
+  uiout->text (".\n");
 }
 
 /* This function allows the addition of incrementally linked object files.
@@ -2261,8 +2203,7 @@ static void
 add_symbol_file_command (char *args, int from_tty)
 {
   struct gdbarch *gdbarch = get_current_arch ();
-  char *filename = NULL;
-  int flags = OBJF_USERLOADED | OBJF_SHARED;
+  gdb::unique_xmalloc_ptr<char> filename;
   char *arg;
   int section_index = 0;
   int argcnt = 0;
@@ -2270,13 +2211,17 @@ add_symbol_file_command (char *args, int from_tty)
   int i;
   int expecting_sec_name = 0;
   int expecting_sec_addr = 0;
-  char **argv;
   struct objfile *objf;
+  objfile_flags flags = OBJF_USERLOADED | OBJF_SHARED;
+  symfile_add_flags add_flags = 0;
+
+  if (from_tty)
+    add_flags |= SYMFILE_VERBOSE;
 
   struct sect_opt
   {
-    char *name;
-    char *value;
+    const char *name;
+    const char *value;
   };
 
   struct section_addr_info *section_addrs;
@@ -2285,16 +2230,14 @@ add_symbol_file_command (char *args, int from_tty)
   struct cleanup *my_cleanups = make_cleanup (null_cleanup, NULL);
 
   num_sect_opts = 16;
-  sect_opts = (struct sect_opt *) xmalloc (num_sect_opts
-                                          * sizeof (struct sect_opt));
+  sect_opts = XNEWVEC (struct sect_opt, num_sect_opts);
 
   dont_repeat ();
 
   if (args == NULL)
     error (_("add-symbol-file takes a file name and an address"));
 
-  argv = gdb_buildargv (args);
-  make_cleanup_freeargv (argv);
+  gdb_argv argv (args);
 
   for (arg = argv[0], argcnt = 0; arg != NULL; arg = argv[++argcnt])
     {
@@ -2302,8 +2245,7 @@ add_symbol_file_command (char *args, int from_tty)
       if (argcnt == 0)
        {
          /* The first argument is the file name.  */
-         filename = tilde_expand (arg);
-         make_cleanup (xfree, filename);
+         filename.reset (tilde_expand (arg));
        }
       else if (argcnt == 1)
        {
@@ -2360,7 +2302,8 @@ add_symbol_file_command (char *args, int from_tty)
      loaded.  Abort now if this address hasn't been provided by the
      user.  */
   if (section_index < 1)
-    error (_("The address where %s has been loaded is missing"), filename);
+    error (_("The address where %s has been loaded is missing"),
+          filename.get ());
 
   /* Print the prompt for the query below.  And save the arguments into
      a sect_addr_info structure to be passed around to other
@@ -2368,20 +2311,21 @@ add_symbol_file_command (char *args, int from_tty)
      statements because hex_string returns a local static
      string.  */
 
-  printf_unfiltered (_("add symbol table from file \"%s\" at\n"), filename);
+  printf_unfiltered (_("add symbol table from file \"%s\" at\n"),
+                    filename.get ());
   section_addrs = alloc_section_addr_info (section_index);
   make_cleanup (xfree, section_addrs);
   for (i = 0; i < section_index; i++)
     {
       CORE_ADDR addr;
-      char *val = sect_opts[i].value;
-      char *sec = sect_opts[i].name;
+      const char *val = sect_opts[i].value;
+      const char *sec = sect_opts[i].name;
 
       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 = sec;
+      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));
@@ -2398,8 +2342,7 @@ add_symbol_file_command (char *args, int from_tty)
   if (from_tty && (!query ("%s", "")))
     error (_("Not confirmed."));
 
-  objf = symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0,
-                         section_addrs, flags);
+  objf = symbol_file_add (filename.get (), add_flags, section_addrs, flags);
 
   add_target_sections_of_objfile (objf);
 
@@ -2415,20 +2358,15 @@ add_symbol_file_command (char *args, int from_tty)
 static void
 remove_symbol_file_command (char *args, int from_tty)
 {
-  char **argv;
   struct objfile *objf = NULL;
-  struct cleanup *my_cleanups;
   struct program_space *pspace = current_program_space;
-  struct gdbarch *gdbarch = get_current_arch ();
 
   dont_repeat ();
 
   if (args == NULL)
     error (_("remove-symbol-file: no symbol file provided"));
 
-  my_cleanups = make_cleanup (null_cleanup, NULL);
-
-  argv = gdb_buildargv (args);
+  gdb_argv argv (args);
 
   if (strcmp (argv[0], "-a") == 0)
     {
@@ -2454,20 +2392,18 @@ remove_symbol_file_command (char *args, int from_tty)
   else if (argv[0] != NULL)
     {
       /* Interpret the current argument as a file name.  */
-      char *filename;
 
       if (argv[1] != NULL)
        error (_("Junk after %s"), argv[0]);
 
-      filename = tilde_expand (argv[0]);
-      make_cleanup (xfree, filename);
+      gdb::unique_xmalloc_ptr<char> filename (tilde_expand (argv[0]));
 
       ALL_OBJFILES (objf)
        {
          if ((objf->flags & OBJF_USERLOADED) != 0
              && (objf->flags & OBJF_SHARED) != 0
              && objf->pspace == pspace
-             && filename_cmp (filename, objfile_name (objf)) == 0)
+             && filename_cmp (filename.get (), objfile_name (objf)) == 0)
            break;
        }
     }
@@ -2482,14 +2418,8 @@ remove_symbol_file_command (char *args, int from_tty)
 
   free_objfile (objf);
   clear_symtab_users (0);
-
-  do_cleanups (my_cleanups);
 }
 
-typedef struct objfile *objfilep;
-
-DEF_VEC_P (objfilep);
-
 /* Re-read symbols if a symbol-file has changed.  */
 
 void
@@ -2499,10 +2429,7 @@ reread_symbols (void)
   long new_modtime;
   struct stat new_statbuf;
   int res;
-  VEC (objfilep) *new_objfiles = NULL;
-  struct cleanup *all_cleanups;
-
-  all_cleanups = make_cleanup (VEC_cleanup (objfilep), &new_objfiles);
+  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
@@ -2593,22 +2520,16 @@ reread_symbols (void)
 
          /* Clean up any state BFD has sitting around.  */
          {
-           struct bfd *obfd = objfile->obfd;
+           gdb_bfd_ref_ptr obfd (objfile->obfd);
            char *obfd_filename;
 
            obfd_filename = bfd_get_filename (objfile->obfd);
            /* Open the new BFD before freeing the old one, so that
               the filename remains live.  */
-           objfile->obfd = gdb_bfd_open_maybe_remote (obfd_filename);
+           gdb_bfd_ref_ptr temp (gdb_bfd_open (obfd_filename, gnutarget, -1));
+           objfile->obfd = temp.release ();
            if (objfile->obfd == NULL)
-             {
-               /* We have to make a cleanup and error here, rather
-                  than erroring later, because once we unref OBFD,
-                  OBFD_FILENAME will be freed.  */
-               make_cleanup_bfd_unref (obfd);
-               error (_("Can't open %s to read symbols."), obfd_filename);
-             }
-           gdb_bfd_unref (obfd);
+             error (_("Can't open %s to read symbols."), obfd_filename);
          }
 
          original_name = xstrdup (objfile->original_name);
@@ -2641,9 +2562,12 @@ reread_symbols (void)
          /* Free the obstacks for non-reusable objfiles.  */
          psymbol_bcache_free (objfile->psymbol_cache);
          objfile->psymbol_cache = psymbol_bcache_init ();
+
+         /* 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->symtabs = NULL;
+         objfile->compunit_symtabs = NULL;
          objfile->psymtabs = NULL;
          objfile->psymtabs_addrmap = NULL;
          objfile->free_psymtabs = NULL;
@@ -2660,9 +2584,9 @@ reread_symbols (void)
             do it *after* the obstack has been initialized.  */
          set_objfile_per_bfd (objfile);
 
-         objfile->original_name = obstack_copy0 (&objfile->objfile_obstack,
-                                                 original_name,
-                                                 strlen (original_name));
+         objfile->original_name
+           = (char *) obstack_copy0 (&objfile->objfile_obstack, original_name,
+                                     strlen (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
@@ -2693,6 +2617,23 @@ reread_symbols (void)
          clear_complaints (&symfile_complaints, 1, 1);
 
          objfile->flags &= ~OBJF_PSYMTABS_READ;
+
+         /* We are about to read new symbols and potentially also
+            DWARF information.  Some targets may want to pass addresses
+            read from DWARF DIE's through an adjustment function before
+            saving them, like MIPS, which may call into
+            "find_pc_section".  When called, that function will make
+            use of per-objfile program space data.
+
+            Since we discarded our section information above, we have
+            dangling pointers in the per-objfile program space data
+            structure.  Force GDB to update the section mapping
+            information by letting it know the objfile has changed,
+            making the dangling pointers point to correct data
+            again.  */
+
+         objfiles_changed ();
+
          read_symbols (objfile, 0);
 
          if (!objfile_has_symbols (objfile))
@@ -2719,31 +2660,24 @@ reread_symbols (void)
          objfile->mtime = new_modtime;
          init_entry_point_info (objfile);
 
-         VEC_safe_push (objfilep, new_objfiles, objfile);
+         new_objfiles.push_back (objfile);
        }
     }
 
-  if (new_objfiles)
+  if (!new_objfiles.empty ())
     {
-      int ix;
-
-      /* Notify objfiles that we've modified objfile sections.  */
-      objfiles_changed ();
-
       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
         clear_symtab_users above.  Notify the new files now.  */
-      for (ix = 0; VEC_iterate (objfilep, new_objfiles, ix, objfile); ix++)
-       observer_notify_new_objfile (objfile);
+      for (auto iter : new_objfiles)
+       observer_notify_new_objfile (iter);
 
       /* At least one objfile has changed, so we can consider that
          the executable we're debugging has changed too.  */
       observer_notify_executable_changed ();
     }
-
-  do_cleanups (all_cleanups);
 }
 \f
 
@@ -2751,26 +2685,23 @@ typedef struct
 {
   char *ext;
   enum language lang;
-}
-filename_language;
+} filename_language;
 
-static filename_language *filename_language_table;
-static int fl_table_size, fl_table_next;
+DEF_VEC_O (filename_language);
 
-static void
-add_filename_language (char *ext, enum language lang)
+static VEC (filename_language) *filename_language_table;
+
+/* See symfile.h.  */
+
+void
+add_filename_language (const char *ext, enum language lang)
 {
-  if (fl_table_next >= fl_table_size)
-    {
-      fl_table_size += 10;
-      filename_language_table =
-       xrealloc (filename_language_table,
-                 fl_table_size * sizeof (*filename_language_table));
-    }
+  filename_language entry;
+
+  entry.ext = xstrdup (ext);
+  entry.lang = lang;
 
-  filename_language_table[fl_table_next].ext = xstrdup (ext);
-  filename_language_table[fl_table_next].lang = lang;
-  fl_table_next++;
+  VEC_safe_push (filename_language, filename_language_table, &entry);
 }
 
 static char *ext_args;
@@ -2790,6 +2721,7 @@ set_ext_lang_command (char *args, int from_tty, struct cmd_list_element *e)
   int i;
   char *cp = ext_args;
   enum language lang;
+  filename_language *entry;
 
   /* First arg is filename extension, starting with '.'  */
   if (*cp != '.')
@@ -2819,11 +2751,15 @@ set_ext_lang_command (char *args, int from_tty, struct cmd_list_element *e)
   lang = language_enum (cp);
 
   /* Now lookup the filename extension: do we already know it?  */
-  for (i = 0; i < fl_table_next; i++)
-    if (0 == strcmp (ext_args, filename_language_table[i].ext))
-      break;
+  for (i = 0;
+       VEC_iterate (filename_language, filename_language_table, i, entry);
+       ++i)
+    {
+      if (0 == strcmp (ext_args, entry->ext))
+       break;
+    }
 
-  if (i >= fl_table_next)
+  if (entry == NULL)
     {
       /* New file extension.  */
       add_filename_language (ext_args, lang);
@@ -2836,9 +2772,9 @@ set_ext_lang_command (char *args, int from_tty, struct cmd_list_element *e)
       /*   query ("Really make files of type %s '%s'?", */
       /*          ext_args, language_str (lang));           */
 
-      xfree (filename_language_table[i].ext);
-      filename_language_table[i].ext = xstrdup (ext_args);
-      filename_language_table[i].lang = lang;
+      xfree (entry->ext);
+      entry->ext = xstrdup (ext_args);
+      entry->lang = lang;
     }
 }
 
@@ -2846,112 +2782,52 @@ static void
 info_ext_lang_command (char *args, int from_tty)
 {
   int i;
+  filename_language *entry;
 
   printf_filtered (_("Filename extensions and the languages they represent:"));
   printf_filtered ("\n\n");
-  for (i = 0; i < fl_table_next; i++)
-    printf_filtered ("\t%s\t- %s\n",
-                    filename_language_table[i].ext,
-                    language_str (filename_language_table[i].lang));
-}
-
-static void
-init_filename_language_table (void)
-{
-  if (fl_table_size == 0)      /* Protect against repetition.  */
-    {
-      fl_table_size = 20;
-      fl_table_next = 0;
-      filename_language_table =
-       xmalloc (fl_table_size * sizeof (*filename_language_table));
-      add_filename_language (".c", language_c);
-      add_filename_language (".d", language_d);
-      add_filename_language (".C", language_cplus);
-      add_filename_language (".cc", language_cplus);
-      add_filename_language (".cp", language_cplus);
-      add_filename_language (".cpp", language_cplus);
-      add_filename_language (".cxx", language_cplus);
-      add_filename_language (".c++", language_cplus);
-      add_filename_language (".java", language_java);
-      add_filename_language (".class", language_java);
-      add_filename_language (".m", language_objc);
-      add_filename_language (".f", language_fortran);
-      add_filename_language (".F", language_fortran);
-      add_filename_language (".for", language_fortran);
-      add_filename_language (".FOR", language_fortran);
-      add_filename_language (".ftn", language_fortran);
-      add_filename_language (".FTN", language_fortran);
-      add_filename_language (".fpp", language_fortran);
-      add_filename_language (".FPP", language_fortran);
-      add_filename_language (".f90", language_fortran);
-      add_filename_language (".F90", language_fortran);
-      add_filename_language (".f95", language_fortran);
-      add_filename_language (".F95", language_fortran);
-      add_filename_language (".f03", language_fortran);
-      add_filename_language (".F03", language_fortran);
-      add_filename_language (".f08", language_fortran);
-      add_filename_language (".F08", language_fortran);
-      add_filename_language (".s", language_asm);
-      add_filename_language (".sx", language_asm);
-      add_filename_language (".S", language_asm);
-      add_filename_language (".pas", language_pascal);
-      add_filename_language (".p", language_pascal);
-      add_filename_language (".pp", language_pascal);
-      add_filename_language (".adb", language_ada);
-      add_filename_language (".ads", language_ada);
-      add_filename_language (".a", language_ada);
-      add_filename_language (".ada", language_ada);
-      add_filename_language (".dg", language_ada);
-    }
+  for (i = 0;
+       VEC_iterate (filename_language, filename_language_table, i, entry);
+       ++i)
+    printf_filtered ("\t%s\t- %s\n", entry->ext, language_str (entry->lang));
 }
 
 enum language
 deduce_language_from_filename (const char *filename)
 {
   int i;
-  char *cp;
+  const char *cp;
 
   if (filename != NULL)
     if ((cp = strrchr (filename, '.')) != NULL)
-      for (i = 0; i < fl_table_next; i++)
-       if (strcmp (cp, filename_language_table[i].ext) == 0)
-         return filename_language_table[i].lang;
+      {
+       filename_language *entry;
+
+       for (i = 0;
+            VEC_iterate (filename_language, filename_language_table, i, entry);
+            ++i)
+         if (strcmp (cp, entry->ext) == 0)
+           return entry->lang;
+      }
 
   return language_unknown;
 }
 \f
-/* allocate_symtab:
-
-   Allocate and partly initialize a new symbol table.  Return a pointer
-   to it.  error() if no space.
-
-   Caller must set these fields:
-   LINETABLE(symtab)
-   symtab->blockvector
-   symtab->dirname
-   symtab->free_code
-   symtab->free_ptr
- */
+/* Allocate and initialize a new symbol table.
+   CUST is from the result of allocate_compunit_symtab.  */
 
 struct symtab *
-allocate_symtab (const char *filename, struct objfile *objfile)
+allocate_symtab (struct compunit_symtab *cust, const char *filename)
 {
-  struct symtab *symtab;
+  struct objfile *objfile = cust->objfile;
+  struct symtab *symtab
+    = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symtab);
 
-  symtab = (struct symtab *)
-    obstack_alloc (&objfile->objfile_obstack, sizeof (struct symtab));
-  memset (symtab, 0, sizeof (*symtab));
-  symtab->filename = bcache (filename, strlen (filename) + 1,
+  symtab->filename
+    = (const char *) bcache (filename, strlen (filename) + 1,
                             objfile->per_bfd->filename_cache);
   symtab->fullname = NULL;
   symtab->language = deduce_language_from_filename (filename);
-  symtab->debugformat = "unknown";
-
-  /* Hook it to the objfile it comes from.  */
-
-  symtab->objfile = objfile;
-  symtab->next = objfile->symtabs;
-  objfile->symtabs = symtab;
 
   /* This can be very verbose with lots of headers.
      Only print at higher debug levels.  */
@@ -2975,15 +2851,73 @@ allocate_symtab (const char *filename, struct objfile *objfile)
                          host_address_to_string (symtab), filename);
     }
 
-  return (symtab);
+  /* Add it to CUST's list of symtabs.  */
+  if (cust->filetabs == NULL)
+    {
+      cust->filetabs = symtab;
+      cust->last_filetab = symtab;
+    }
+  else
+    {
+      cust->last_filetab->next = symtab;
+      cust->last_filetab = symtab;
+    }
+
+  /* Backlink to the containing compunit symtab.  */
+  symtab->compunit_symtab = cust;
+
+  return symtab;
+}
+
+/* Allocate and initialize a new compunit.
+   NAME is the name of the main source file, if there is one, or some
+   descriptive text if there are no source files.  */
+
+struct compunit_symtab *
+allocate_compunit_symtab (struct objfile *objfile, const char *name)
+{
+  struct compunit_symtab *cu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+                                              struct compunit_symtab);
+  const char *saved_name;
+
+  cu->objfile = objfile;
+
+  /* The name we record here is only for display/debugging purposes.
+     Just save the basename to avoid path issues (too long for display,
+     relative vs absolute, etc.).  */
+  saved_name = lbasename (name);
+  cu->name
+    = (const char *) obstack_copy0 (&objfile->objfile_obstack, saved_name,
+                                   strlen (saved_name));
+
+  COMPUNIT_DEBUGFORMAT (cu) = "unknown";
+
+  if (symtab_create_debug)
+    {
+      fprintf_unfiltered (gdb_stdlog,
+                         "Created compunit symtab %s for %s.\n",
+                         host_address_to_string (cu),
+                         cu->name);
+    }
+
+  return cu;
+}
+
+/* Hook CU to the objfile it comes from.  */
+
+void
+add_compunit_symtab_to_objfile (struct compunit_symtab *cu)
+{
+  cu->next = cu->objfile->compunit_symtabs;
+  cu->objfile->compunit_symtabs = cu;
 }
 \f
 
-/* Reset all data structures in gdb which may contain references to symbol
-   table data.  ADD_FLAGS is a bitmask of enum symfile_add_flags.  */
+/* Reset all data structures in gdb which may contain references to
+   symbol table data.  */
 
 void
-clear_symtab_users (int add_flags)
+clear_symtab_users (symfile_add_flags add_flags)
 {
   /* Someday, we should do better than this, by only blowing away
      the things that really need to be blown.  */
@@ -2993,8 +2927,6 @@ clear_symtab_users (int add_flags)
   clear_current_source_symtab_and_line ();
 
   clear_displays ();
-  if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
-    breakpoint_re_set ();
   clear_last_displayed_sal ();
   clear_pc_function_cache ();
   observer_notify_new_objfile (NULL);
@@ -3008,6 +2940,10 @@ clear_symtab_users (int add_flags)
   /* Varobj may refer to old symbols, perform a cleanup.  */
   varobj_invalidate ();
 
+  /* Now that the various caches have been cleared, we can re_set
+     our breakpoints without risking it using stale data.  */
+  if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
+    breakpoint_re_set ();
 }
 
 static void
@@ -3278,19 +3214,21 @@ find_pc_overlay (CORE_ADDR pc)
   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))
+    {
+      ALL_OBJSECTIONS (objfile, osect)
+       if (section_is_overlay (osect))
          {
-           if (section_is_mapped (osect))
-             return osect;
-           else
+           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;
          }
-       else if (pc_in_unmapped_range (pc, osect))
-         best_match = osect;
-      }
+    }
   return best_match;
 }
 
@@ -3305,9 +3243,11 @@ find_pc_mapped_section (CORE_ADDR pc)
   struct obj_section *osect;
 
   if (overlay_debugging)
-    ALL_OBJSECTIONS (objfile, osect)
-      if (pc_in_mapped_range (pc, osect) && section_is_mapped (osect))
-       return osect;
+    {
+      ALL_OBJSECTIONS (objfile, osect)
+       if (pc_in_mapped_range (pc, osect) && section_is_mapped (osect))
+         return osect;
+    }
 
   return NULL;
 }
@@ -3323,31 +3263,33 @@ list_overlays_command (char *args, int from_tty)
   struct obj_section *osect;
 
   if (overlay_debugging)
-    ALL_OBJSECTIONS (objfile, osect)
+    {
+      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++;
-      }
+       {
+         struct gdbarch *gdbarch = get_objfile_arch (objfile);
+         const char *name;
+         bfd_vma lma, vma;
+         int size;
+
+         vma = bfd_section_vma (objfile->obfd, osect->the_bfd_section);
+         lma = bfd_section_lma (objfile->obfd, osect->the_bfd_section);
+         size = bfd_get_section_size (osect->the_bfd_section);
+         name = bfd_section_name (objfile->obfd, osect->the_bfd_section);
+
+         printf_filtered ("Section %s, loaded at ", name);
+         fputs_filtered (paddress (gdbarch, lma), gdb_stdout);
+         puts_filtered (" - ");
+         fputs_filtered (paddress (gdbarch, lma + size), gdb_stdout);
+         printf_filtered (", mapped at ");
+         fputs_filtered (paddress (gdbarch, vma), gdb_stdout);
+         puts_filtered (" - ");
+         fputs_filtered (paddress (gdbarch, vma + size), gdb_stdout);
+         puts_filtered ("\n");
+
+         nmapped++;
+       }
+    }
   if (nmapped == 0)
     printf_filtered (_("No sections are mapped.\n"));
 }
@@ -3404,7 +3346,7 @@ static void
 unmap_overlay_command (char *args, int from_tty)
 {
   struct objfile *objfile;
-  struct obj_section *sec;
+  struct obj_section *sec = NULL;
 
   if (!overlay_debugging)
     error (_("Overlay debugging not enabled.  "
@@ -3506,12 +3448,12 @@ overlay_command (char *args, int from_tty)
    In this simple implementation, the target data structures are as follows:
    unsigned _novlys;            /# number of overlay sections #/
    unsigned _ovly_table[_novlys][4] = {
-   {VMA, SIZE, LMA, MAPPED},    /# one entry per overlay section #/
+   {VMA, OSIZE, LMA, MAPPED},    /# one entry per overlay section #/
    {..., ...,  ..., ...},
    }
    unsigned _novly_regions;     /# number of overlay regions #/
    unsigned _ovly_region_table[_novly_regions][3] = {
-   {VMA, SIZE, MAPPED_TO_LMA},  /# one entry per overlay region #/
+   {VMA, OSIZE, MAPPED_TO_LMA},  /# one entry per overlay region #/
    {..., ...,  ...},
    }
    These functions will attempt to update GDB's mappedness state in the
@@ -3529,7 +3471,7 @@ static unsigned cache_novlys = 0;
 static CORE_ADDR cache_ovly_table_base = 0;
 enum ovly_index
   {
-    VMA, SIZE, LMA, MAPPED
+    VMA, OSIZE, LMA, MAPPED
   };
 
 /* Throw away the cached copy of _ovly_table.  */
@@ -3552,7 +3494,7 @@ read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr,
                        int len, int size, enum bfd_endian byte_order)
 {
   /* FIXME (alloca): Not safe if array is very large.  */
-  gdb_byte *buf = alloca (len * size);
+  gdb_byte *buf = (gdb_byte *) alloca (len * size);
   int i;
 
   read_memory (memaddr, buf, len * size);
@@ -3598,7 +3540,7 @@ simple_read_overlay_table (void)
   cache_novlys = read_memory_integer (BMSYMBOL_VALUE_ADDRESS (novlys_msym),
                                      4, byte_order);
   cache_ovly_table
-    = (void *) xmalloc (cache_novlys * sizeof (*cache_ovly_table));
+    = (unsigned int (*)[4]) xmalloc (cache_novlys * sizeof (*cache_ovly_table));
   cache_ovly_table_base = BMSYMBOL_VALUE_ADDRESS (ovly_table_msym);
   read_target_long_array (cache_ovly_table_base,
                           (unsigned int *) cache_ovly_table,
@@ -3618,25 +3560,22 @@ simple_read_overlay_table (void)
 static int
 simple_overlay_update_1 (struct obj_section *osect)
 {
-  int i, size;
+  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);
 
-  size = bfd_get_section_size (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)
-       /* && cache_ovly_table[i][SIZE] == size */ )
+       && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect))
       {
        read_target_long_array (cache_ovly_table_base + i * word_size,
                                (unsigned int *) cache_ovly_table[i],
                                4, word_size, byte_order);
        if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect)
-           && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect)
-           /* && cache_ovly_table[i][SIZE] == size */ )
+           && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect))
          {
            osect->ovly_mapped = cache_ovly_table[i][MAPPED];
            return 1;
@@ -3694,15 +3633,13 @@ simple_overlay_update (struct obj_section *osect)
   ALL_OBJSECTIONS (objfile, osect)
     if (section_is_overlay (osect))
     {
-      int i, size;
+      int i;
       bfd *obfd = osect->objfile->obfd;
       asection *bsect = osect->the_bfd_section;
 
-      size = bfd_get_section_size (bsect);
       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)
-           /* && cache_ovly_table[i][SIZE] == size */ )
+           && 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.  */
@@ -3902,10 +3839,11 @@ symfile_free_objfile (struct objfile *objfile)
    See quick_symbol_functions.expand_symtabs_matching for details.  */
 
 void
-expand_symtabs_matching (expand_symtabs_file_matcher_ftype *file_matcher,
-                        expand_symtabs_symbol_matcher_ftype *symbol_matcher,
-                        enum search_domain kind,
-                        void *data)
+expand_symtabs_matching
+  (gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+   gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
+   gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+   enum search_domain kind)
 {
   struct objfile *objfile;
 
@@ -3913,8 +3851,8 @@ expand_symtabs_matching (expand_symtabs_file_matcher_ftype *file_matcher,
   {
     if (objfile->sf)
       objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher,
-                                               symbol_matcher, kind,
-                                               data);
+                                               symbol_matcher,
+                                               expansion_notify, kind);
   }
 }
 
@@ -3971,7 +3909,10 @@ that lies within the boundaries of this symbol file in memory."),
   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\
-A load OFFSET may also be given."), &cmdlist);
+An optional load OFFSET may also be given as a literal address.\n\
+When OFFSET is provided, FILE must also be provided.  FILE can be provided\n\
+on its own.\n\
+Usage: load [FILE] [OFFSET]"), &cmdlist);
   set_cmd_completer (c, filename_completer);
 
   add_prefix_cmd ("overlay", class_support, overlay_command,
@@ -4000,7 +3941,6 @@ A load OFFSET may also be given."), &cmdlist);
           _("Read the overlay mapping state from the target."), &overlaylist);
 
   /* Filename extension to source language lookup table: */
-  init_filename_language_table ();
   add_setshow_string_noescape_cmd ("extension-language", class_files,
                                   &ext_args, _("\
 Set mapping between filename extension and source language."), _("\
@@ -4038,4 +3978,11 @@ full  == print messages for the executable,\n\
                        NULL,
                        NULL,
                        &setprintlist, &showprintlist);
+
+  add_setshow_boolean_cmd ("separate-debug-file", no_class,
+                          &separate_debug_file_debug, _("\
+Set printing of separate debug info file search debug."), _("\
+Show printing of separate debug info file search debug."), _("\
+When on, GDB prints the searched locations while looking for separate debug \
+info files."), NULL, NULL, &setdebuglist, &showdebuglist);
 }
This page took 0.080811 seconds and 4 git commands to generate.