OSDN Git Service

Merge branch 'master' of git://github.com/monaka/binutils
[pf3gnuchains/pf3gnuchains3x.git] / gdb / symfile.c
index d9aff2f..cee84db 100644 (file)
@@ -1,7 +1,7 @@
 /* Generic symbol file reading for the GNU debugger, GDB.
 
    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    Contributed by Cygnus Support, using pieces from other GDB modules.
@@ -22,6 +22,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "arch-utils.h"
 #include "bfdlink.h"
 #include "symtab.h"
 #include "gdbtypes.h"
@@ -37,7 +38,8 @@
 #include "language.h"
 #include "complaints.h"
 #include "demangle.h"
-#include "inferior.h"          /* for write_pc */
+#include "inferior.h"
+#include "regcache.h"
 #include "filenames.h"         /* for DOSish file names */
 #include "gdb-stabs.h"
 #include "gdb_obstack.h"
@@ -95,10 +97,6 @@ static void symbol_file_add_main_1 (char *args, int from_tty, int flags);
 
 static void add_symbol_file_command (char *, int);
 
-static void add_shared_symbol_files_command (char *, int);
-
-static void reread_separate_symbols (struct objfile *objfile);
-
 static void cashier_psymtab (struct partial_symtab *);
 
 bfd *symfile_bfd_open (char *);
@@ -129,7 +127,8 @@ static void overlay_command (char *, int);
 
 static void simple_free_overlay_table (void);
 
-static void read_target_long_array (CORE_ADDR, unsigned int *, int);
+static void read_target_long_array (CORE_ADDR, unsigned int *, int, int,
+                                   enum bfd_endian);
 
 static int simple_read_overlay_table (void);
 
@@ -139,8 +138,6 @@ static void add_filename_language (char *ext, enum language lang);
 
 static void info_ext_lang_command (char *args, int from_tty);
 
-static char *find_separate_debug_file (struct objfile *objfile);
-
 static void init_filename_language_table (void);
 
 static void symfile_find_segment_sections (struct objfile *objfile);
@@ -170,13 +167,6 @@ Dynamic symbol table reloading multiple times in one run is %s.\n"),
                    value);
 }
 
-/* If non-zero, gdb will notify the user when it is loading symbols
-   from a file.  This is almost always what users will want to have happen;
-   but for programs with lots of dynamically linked libraries, the output
-   can be more noise than signal.  */
-
-int print_symbol_loading = 1;
-
 /* 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
@@ -368,11 +358,11 @@ copy_section_addr_info (struct section_addr_info *addrs)
    an existing section table. */
 
 extern struct section_addr_info *
-build_section_addr_info_from_section_table (const struct section_table *start,
-                                            const struct section_table *end)
+build_section_addr_info_from_section_table (const struct target_section *start,
+                                            const struct target_section *end)
 {
   struct section_addr_info *sap;
-  const struct section_table *stp;
+  const struct target_section *stp;
   int oidx;
 
   sap = alloc_section_addr_info (end - start);
@@ -394,6 +384,29 @@ build_section_addr_info_from_section_table (const struct section_table *start,
   return sap;
 }
 
+/* Create a section_addr_info from section offsets in OBJFILE.  */
+
+static struct section_addr_info *
+build_section_addr_info_from_objfile (const struct objfile *objfile)
+{
+  struct section_addr_info *sap;
+  int i;
+  struct bfd_section *sec;
+
+  sap = alloc_section_addr_info (objfile->num_sections);
+  for (i = 0, sec = objfile->obfd->sections;
+       i < objfile->num_sections;
+       i++, sec = sec->next)
+    {
+      gdb_assert (sec != NULL);
+      sap->other[i].addr = (bfd_get_section_vma (objfile->obfd, sec)
+                            + objfile->section_offsets->offsets[i]);
+      sap->other[i].name = xstrdup (bfd_get_section_name (objfile->obfd, sec));
+      sap->other[i].sectindex = sec->index;
+    }
+  return sap;
+}
+
 
 /* Free all memory allocated by build_section_addr_info_from_section_table. */
 
@@ -480,7 +493,7 @@ struct place_section_arg
 /* Find a unique offset to use for loadable section SECT if
    the user did not provide an offset.  */
 
-void
+static void
 place_section (bfd *abfd, asection *sect, void *obj)
 {
   struct place_section_arg *arg = obj;
@@ -741,22 +754,20 @@ default_symfile_segments (bfd *abfd)
    list any more; all we have is the section offset table.)  If
    OFFSETS is non-zero, ADDRS must be zero.
 
-   MAINLINE is nonzero if this is the main symbol file, or zero if
-   it's an extra symbol file such as dynamically loaded code.
-
-   VERBO is nonzero if the caller has printed a verbose message about
-   the symbol reading (and complaints can be more terse about it).  */
+   ADD_FLAGS encodes verbosity level, whether this is main symbol or
+   an extra symbol file such as dynamically loaded code, and wether
+   breakpoint reset should be deferred.  */
 
 void
 syms_from_objfile (struct objfile *objfile,
                    struct section_addr_info *addrs,
                    struct section_offsets *offsets,
                    int num_offsets,
-                  int mainline,
-                   int verbo)
+                  int add_flags)
 {
   struct section_addr_info *local_addr = NULL;
   struct cleanup *old_chain;
+  const int mainline = add_flags & SYMFILE_MAINLINE;
 
   gdb_assert (! (addrs && offsets));
 
@@ -794,7 +805,7 @@ syms_from_objfile (struct objfile *objfile,
       if (symfile_objfile != NULL)
        {
          free_objfile (symfile_objfile);
-         symfile_objfile = NULL;
+         gdb_assert (symfile_objfile == NULL);
        }
 
       /* Currently we keep symbols from the add-symbol-file command.
@@ -811,7 +822,7 @@ syms_from_objfile (struct objfile *objfile,
 
      We no longer warn if the lowest section is not a text segment (as
      happens for the PA64 port.  */
-  if (!mainline && addrs && addrs->other[0].name)
+  if (addrs && addrs->other[0].name)
     {
       asection *lower_sect;
       asection *sect;
@@ -876,7 +887,7 @@ syms_from_objfile (struct objfile *objfile,
      initial symbol reading for this file. */
 
   (*objfile->sf->sym_init) (objfile);
-  clear_complaints (&symfile_complaints, 1, verbo);
+  clear_complaints (&symfile_complaints, 1, add_flags & SYMFILE_VERBOSE);
 
   if (addrs)
     (*objfile->sf->sym_offsets) (objfile, addrs);
@@ -894,11 +905,12 @@ syms_from_objfile (struct objfile *objfile,
       init_objfile_sect_indices (objfile);
     }
 
-  (*objfile->sf->sym_read) (objfile, mainline);
+  (*objfile->sf->sym_read) (objfile, add_flags);
 
   /* Discard cleanups as symbol reading was successful.  */
 
   discard_cleanups (old_chain);
+  xfree (local_addr);
 }
 
 /* Perform required actions after either reading in the initial
@@ -906,26 +918,26 @@ syms_from_objfile (struct objfile *objfile,
    objfile. */
 
 void
-new_symfile_objfile (struct objfile *objfile, int mainline, int verbo)
+new_symfile_objfile (struct objfile *objfile, int add_flags)
 {
 
   /* If this is the main symbol file we have to clean up all users of the
      old main symbol file. Otherwise it is sufficient to fixup all the
      breakpoints that may have been redefined by this symbol file.  */
-  if (mainline)
+  if (add_flags & SYMFILE_MAINLINE)
     {
       /* OK, make it the "real" symbol file.  */
       symfile_objfile = objfile;
 
       clear_symtab_users ();
     }
-  else
+  else if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
     {
       breakpoint_re_set ();
     }
 
   /* We're done reading the symbol file; finish off complaints.  */
-  clear_complaints (&symfile_complaints, 0, verbo);
+  clear_complaints (&symfile_complaints, 0, add_flags & SYMFILE_VERBOSE);
 }
 
 /* Process a symbol file, as either the main file or as a dynamically
@@ -934,30 +946,29 @@ new_symfile_objfile (struct objfile *objfile, int mainline, int verbo)
    ABFD is a BFD already open on the file, as from symfile_bfd_open.
    This BFD will be closed on error, and is always consumed by this function.
 
-   FROM_TTY says how verbose to be.
-
-   MAINLINE specifies whether this is the main symbol file, or whether
-   it's an extra symbol file such as dynamically loaded code.
+   ADD_FLAGS encodes verbosity, whether this is main symbol file or
+   extra, such as dynamically loaded code, and what to do with breakpoins.
 
    ADDRS, OFFSETS, and NUM_OFFSETS are as described for
-   syms_from_objfile, above.  ADDRS is ignored when MAINLINE is
-   non-zero.
+   syms_from_objfile, above.
+   ADDRS is ignored when SYMFILE_MAINLINE bit is set in ADD_FLAGS.
 
    Upon success, returns a pointer to the objfile that was added.
    Upon failure, jumps back to command level (never returns). */
+
 static struct objfile *
-symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty,
+symbol_file_add_with_addrs_or_offsets (bfd *abfd,
+                                       int add_flags,
                                        struct section_addr_info *addrs,
                                        struct section_offsets *offsets,
                                        int num_offsets,
-                                       int mainline, int flags)
+                                       int flags)
 {
   struct objfile *objfile;
   struct partial_symtab *psymtab;
-  char *debugfile = NULL;
-  struct section_addr_info *orig_addrs = NULL;
   struct cleanup *my_cleanups;
   const char *name = bfd_get_filename (abfd);
+  const int from_tty = add_flags & SYMFILE_VERBOSE;
 
   my_cleanups = make_cleanup_bfd_close (abfd);
 
@@ -965,20 +976,14 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty,
      interactively wiping out any existing symbols.  */
 
   if ((have_full_symbols () || have_partial_symbols ())
-      && mainline
+      && (add_flags & SYMFILE_MAINLINE)
       && from_tty
-      && !query ("Load new symbol table from \"%s\"? ", name))
+      && !query (_("Load new symbol table from \"%s\"? "), name))
     error (_("Not confirmed."));
 
   objfile = allocate_objfile (abfd, flags);
   discard_cleanups (my_cleanups);
 
-  if (addrs)
-    {
-      orig_addrs = copy_section_addr_info (addrs);
-      make_cleanup_free_section_addr_info (orig_addrs);
-    }
-
   /* We either created a new mapped symbol table, mapped an existing
      symbol table file which has not had initial symbol reading
      performed, or need to read an unmapped symbol table. */
@@ -988,16 +993,13 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty,
        deprecated_pre_add_symbol_hook (name);
       else
        {
-          if (print_symbol_loading)
-           {
-             printf_unfiltered (_("Reading symbols from %s..."), name);
-             wrap_here ("");
-             gdb_flush (gdb_stdout);
-           }
+         printf_unfiltered (_("Reading symbols from %s..."), name);
+         wrap_here ("");
+         gdb_flush (gdb_stdout);
        }
     }
   syms_from_objfile (objfile, addrs, offsets, num_offsets,
-                    mainline, from_tty);
+                    add_flags);
 
   /* We now have at least a partial symbol table.  Check to see if the
      user requested that all symbols be read on initial access via either
@@ -1006,7 +1008,7 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty,
 
   if ((flags & OBJF_READNOW) || readnow_symbol_files)
     {
-      if ((from_tty || info_verbose) && print_symbol_loading)
+      if (from_tty || info_verbose)
        {
          printf_unfiltered (_("expanding to full symbols..."));
          wrap_here ("");
@@ -1021,42 +1023,11 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty,
        }
     }
 
-  /* If the file has its own symbol tables it has no separate debug info.
-     `.dynsym'/`.symtab' go to MSYMBOLS, `.debug_info' goes to SYMTABS/PSYMTABS.
-     `.gnu_debuglink' may no longer be present with `.note.gnu.build-id'.  */
-  if (objfile->psymtabs == NULL)
-    debugfile = find_separate_debug_file (objfile);
-  if (debugfile)
-    {
-      if (addrs != NULL)
-       {
-         objfile->separate_debug_objfile
-            = symbol_file_add (debugfile, from_tty, orig_addrs, 0, flags);
-       }
-      else
-       {
-         objfile->separate_debug_objfile
-            = symbol_file_add (debugfile, from_tty, NULL, 0, flags);
-       }
-      objfile->separate_debug_objfile->separate_debug_objfile_backlink
-        = objfile;
-
-      /* Put the separate debug object before the normal one, this is so that
-         usage of the ALL_OBJFILES_SAFE macro will stay safe. */
-      put_objfile_before (objfile->separate_debug_objfile, objfile);
-
-      xfree (debugfile);
-    }
-
-  if (!have_partial_symbols () && !have_full_symbols ()
-      && print_symbol_loading)
+  if ((from_tty || info_verbose)
+      && !objfile_has_symbols (objfile))
     {
       wrap_here ("");
-      printf_unfiltered (_("(no debugging symbols found)"));
-      if (from_tty || info_verbose)
-        printf_unfiltered ("...");
-      else
-        printf_unfiltered ("\n");
+      printf_unfiltered (_("(no debugging symbols found)..."));
       wrap_here ("");
     }
 
@@ -1065,10 +1036,7 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty,
       if (deprecated_post_add_symbol_hook)
        deprecated_post_add_symbol_hook ();
       else
-       {
-         if (print_symbol_loading)
-           printf_unfiltered (_("done.\n"));
-       }
+       printf_unfiltered (_("done.\n"));
     }
 
   /* We print some messages regardless of whether 'from_tty ||
@@ -1079,9 +1047,12 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty,
   do_cleanups (my_cleanups);
 
   if (objfile->sf == NULL)
-    return objfile;    /* No symbols. */
+    {
+      observer_notify_new_objfile (objfile);
+      return objfile;  /* No symbols. */
+    }
 
-  new_symfile_objfile (objfile, mainline, from_tty);
+  new_symfile_objfile (objfile, add_flags);
 
   observer_notify_new_objfile (objfile);
 
@@ -1089,6 +1060,31 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty,
   return (objfile);
 }
 
+/* Add BFD as a separate debug file for OBJFILE.  */
+
+void
+symbol_file_add_separate (bfd *bfd, int symfile_flags, struct objfile *objfile)
+{
+  struct objfile *new_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);
+
+  new_objfile = symbol_file_add_with_addrs_or_offsets
+    (bfd, symfile_flags,
+     sap, NULL, 0,
+     objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW
+                      | OBJF_USERLOADED));
+
+  do_cleanups (my_cleanup);
+
+  add_separate_debug_objfile (new_objfile, objfile);
+}
 
 /* Process the symbol file ABFD, as either the main file or as a
    dynamically loaded file.
@@ -1096,13 +1092,12 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty,
    See symbol_file_add_with_addrs_or_offsets's comments for
    details.  */
 struct objfile *
-symbol_file_add_from_bfd (bfd *abfd, int from_tty,
+symbol_file_add_from_bfd (bfd *abfd, int add_flags,
                           struct section_addr_info *addrs,
-                          int mainline, int flags)
+                          int flags)
 {
-  return symbol_file_add_with_addrs_or_offsets (abfd,
-                                               from_tty, addrs, 0, 0,
-                                                mainline, flags);
+  return symbol_file_add_with_addrs_or_offsets (abfd, add_flags, addrs, 0, 0,
+                                                flags);
 }
 
 
@@ -1110,11 +1105,11 @@ symbol_file_add_from_bfd (bfd *abfd, int from_tty,
    loaded file.  See symbol_file_add_with_addrs_or_offsets's comments
    for details.  */
 struct objfile *
-symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
-                int mainline, int flags)
+symbol_file_add (char *name, int add_flags, struct section_addr_info *addrs,
+                int flags)
 {
-  return symbol_file_add_from_bfd (symfile_bfd_open (name), from_tty,
-                                   addrs, mainline, flags);
+  return symbol_file_add_from_bfd (symfile_bfd_open (name), add_flags, addrs,
+                                   flags);
 }
 
 
@@ -1135,7 +1130,8 @@ symbol_file_add_main (char *args, int from_tty)
 static void
 symbol_file_add_main_1 (char *args, int from_tty, int flags)
 {
-  symbol_file_add (args, from_tty, NULL, 1, flags);
+  const int add_flags = SYMFILE_MAINLINE | (from_tty ? SYMFILE_VERBOSE : 0);
+  symbol_file_add (args, add_flags, NULL, flags);
 
   /* Getting new symbols may change our opinion about
      what is frameless.  */
@@ -1154,114 +1150,17 @@ symbol_file_clear (int from_tty)
                    symfile_objfile->name)
          : !query (_("Discard symbol table? "))))
     error (_("Not confirmed."));
-    free_all_objfiles ();
-
-    /* solib descriptors may have handles to objfiles.  Since their
-       storage has just been released, we'd better wipe the solib
-       descriptors as well.
-     */
-    no_shared_libraries (NULL, from_tty);
-
-    symfile_objfile = NULL;
-    if (from_tty)
-      printf_unfiltered (_("No symbol file now.\n"));
-}
-
-struct build_id
-  {
-    size_t size;
-    gdb_byte data[1];
-  };
 
-/* Locate NT_GNU_BUILD_ID from ABFD and return its content.  */
+  free_all_objfiles ();
 
-static struct build_id *
-build_id_bfd_get (bfd *abfd)
-{
-  struct build_id *retval;
+  /* solib descriptors may have handles to objfiles.  Since their
+     storage has just been released, we'd better wipe the solib
+     descriptors as well.  */
+  no_shared_libraries (NULL, from_tty);
 
-  if (!bfd_check_format (abfd, bfd_object)
-      || bfd_get_flavour (abfd) != bfd_target_elf_flavour
-      || elf_tdata (abfd)->build_id == NULL)
-    return NULL;
-
-  retval = xmalloc (sizeof *retval - 1 + elf_tdata (abfd)->build_id_size);
-  retval->size = elf_tdata (abfd)->build_id_size;
-  memcpy (retval->data, elf_tdata (abfd)->build_id, retval->size);
-
-  return retval;
-}
-
-/* Return if FILENAME has NT_GNU_BUILD_ID matching the CHECK value.  */
-
-static int
-build_id_verify (const char *filename, struct build_id *check)
-{
-  bfd *abfd;
-  struct build_id *found = NULL;
-  int retval = 0;
-
-  /* We expect to be silent on the non-existing files.  */
-  if (remote_filename_p (filename))
-    abfd = remote_bfd_open (filename, gnutarget);
-  else
-    abfd = bfd_openr (filename, gnutarget);
-  if (abfd == NULL)
-    return 0;
-
-  found = build_id_bfd_get (abfd);
-
-  if (found == NULL)
-    warning (_("File \"%s\" has no build-id, file skipped"), filename);
-  else if (found->size != check->size
-           || memcmp (found->data, check->data, found->size) != 0)
-    warning (_("File \"%s\" has a different build-id, file skipped"), filename);
-  else
-    retval = 1;
-
-  if (!bfd_close (abfd))
-    warning (_("cannot close \"%s\": %s"), filename,
-            bfd_errmsg (bfd_get_error ()));
-
-  xfree (found);
-
-  return retval;
-}
-
-static char *
-build_id_to_debug_filename (struct build_id *build_id)
-{
-  char *link, *s, *retval = NULL;
-  gdb_byte *data = build_id->data;
-  size_t size = build_id->size;
-
-  /* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */
-  link = xmalloc (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1
-                 + 2 * size + (sizeof ".debug" - 1) + 1);
-  s = link + sprintf (link, "%s/.build-id/", debug_file_directory);
-  if (size > 0)
-    {
-      size--;
-      s += sprintf (s, "%02x", (unsigned) *data++);
-    }
-  if (size > 0)
-    *s++ = '/';
-  while (size-- > 0)
-    s += sprintf (s, "%02x", (unsigned) *data++);
-  strcpy (s, ".debug");
-
-  /* lrealpath() is expensive even for the usually non-existent files.  */
-  if (access (link, F_OK) == 0)
-    retval = lrealpath (link);
-  xfree (link);
-
-  if (retval != NULL && !build_id_verify (retval, build_id))
-    {
-      xfree (retval);
-      retval = NULL;
-    }
-
-  return retval;
+  gdb_assert (symfile_objfile == NULL);
+  if (from_tty)
+    printf_unfiltered (_("No symbol file now.\n"));
 }
 
 static char *
@@ -1296,27 +1195,63 @@ get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out)
 }
 
 static int
-separate_debug_file_exists (const char *name, unsigned long crc)
+separate_debug_file_exists (const char *name, unsigned long crc,
+                           struct objfile *parent_objfile)
 {
   unsigned long file_crc = 0;
   bfd *abfd;
   gdb_byte buffer[8*1024];
   int count;
+  struct stat parent_stat, abfd_stat;
 
-  if (remote_filename_p (name))
-    abfd = remote_bfd_open (name, gnutarget);
-  else
-    abfd = bfd_openr (name, gnutarget);
+  /* Find a separate debug info file as if symbols would be present in
+     PARENT_OBJFILE itself this function would not be called.  .gnu_debuglink
+     section can contain just the basename of PARENT_OBJFILE without any
+     ".debug" suffix as "/usr/lib/debug/path/to/file" is a separate tree where
+     the separate debug infos with the same basename can exist. */
+
+  if (strcmp (name, parent_objfile->name) == 0)
+    return 0;
+
+  abfd = bfd_open_maybe_remote (name);
 
   if (!abfd)
     return 0;
 
+  /* Verify symlinks were not the cause of strcmp 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
+      && bfd_stat (parent_objfile->obfd, &parent_stat) == 0
+      && abfd_stat.st_dev == parent_stat.st_dev
+      && abfd_stat.st_ino == parent_stat.st_ino
+      && abfd_stat.st_ino != 0)
+    {
+      bfd_close (abfd);
+      return 0;
+    }
+
   while ((count = bfd_bread (buffer, sizeof (buffer), abfd)) > 0)
     file_crc = gnu_debuglink_crc32 (file_crc, buffer, count);
 
   bfd_close (abfd);
 
-  return crc == file_crc;
+  if (crc != file_crc)
+    {
+      warning (_("the debug information found in \"%s\""
+                " does not match \"%s\" (CRC mismatch).\n"),
+              name, parent_objfile->name);
+      return 0;
+    }
+
+  return 1;
 }
 
 char *debug_file_directory = NULL;
@@ -1333,42 +1268,24 @@ The directory where separate debug symbols are searched for is \"%s\".\n"),
 #define DEBUG_SUBDIRECTORY ".debug"
 #endif
 
-static char *
-find_separate_debug_file (struct objfile *objfile)
+char *
+find_separate_debug_file_by_debuglink (struct objfile *objfile)
 {
   asection *sect;
-  char *basename;
-  char *dir;
-  char *debugfile;
-  char *name_copy;
-  char *canon_name;
+  char *basename, *name_copy, *debugdir;
+  char *dir = NULL;
+  char *debugfile = NULL;
+  char *canon_name = NULL;
   bfd_size_type debuglink_size;
   unsigned long crc32;
   int i;
-  struct build_id *build_id;
-
-  build_id = build_id_bfd_get (objfile->obfd);
-  if (build_id != NULL)
-    {
-      char *build_id_name;
-
-      build_id_name = build_id_to_debug_filename (build_id);
-      xfree (build_id);
-      /* Prevent looping on a stripped .debug file.  */
-      if (build_id_name != NULL && strcmp (build_id_name, objfile->name) == 0)
-        {
-         warning (_("\"%s\": separate debug info file has no debug info"),
-                  build_id_name);
-         xfree (build_id_name);
-       }
-      else if (build_id_name != NULL)
-        return build_id_name;
-    }
 
   basename = get_debug_link_info (objfile, &crc32);
 
   if (basename == NULL)
-    return NULL;
+    /* There's no separate debug info, hence there's no way we could
+       load it => no warning.  */
+    goto cleanup_return_debugfile;
 
   dir = xstrdup (objfile->name);
 
@@ -1384,23 +1301,25 @@ find_separate_debug_file (struct objfile *objfile)
   gdb_assert (i >= 0 && IS_DIR_SEPARATOR (dir[i]));
   dir[i+1] = '\0';
 
-  debugfile = alloca (strlen (debug_file_directory) + 1
-                      + strlen (dir)
-                      + strlen (DEBUG_SUBDIRECTORY)
-                      + strlen ("/")
-                      + strlen (basename)
-                      + 1);
+  /* Set I to max (strlen (canon_name), strlen (dir)). */
+  canon_name = lrealpath (dir);
+  i = strlen (dir);
+  if (canon_name && strlen (canon_name) > i)
+    i = strlen (canon_name);
+
+  debugfile = xmalloc (strlen (debug_file_directory) + 1
+                      + i
+                      + strlen (DEBUG_SUBDIRECTORY)
+                      + strlen ("/")
+                      + strlen (basename)
+                      + 1);
 
   /* First try in the same directory as the original file.  */
   strcpy (debugfile, dir);
   strcat (debugfile, basename);
 
-  if (separate_debug_file_exists (debugfile, crc32))
-    {
-      xfree (basename);
-      xfree (dir);
-      return xstrdup (debugfile);
-    }
+  if (separate_debug_file_exists (debugfile, crc32, objfile))
+    goto cleanup_return_debugfile;
 
   /* Then try in the subdirectory named DEBUG_SUBDIRECTORY.  */
   strcpy (debugfile, dir);
@@ -1408,53 +1327,63 @@ find_separate_debug_file (struct objfile *objfile)
   strcat (debugfile, "/");
   strcat (debugfile, basename);
 
-  if (separate_debug_file_exists (debugfile, crc32))
-    {
-      xfree (basename);
-      xfree (dir);
-      return xstrdup (debugfile);
-    }
+  if (separate_debug_file_exists (debugfile, crc32, objfile))
+    goto cleanup_return_debugfile;
 
-  /* Then try in the global debugfile directory.  */
-  strcpy (debugfile, debug_file_directory);
-  strcat (debugfile, "/");
-  strcat (debugfile, dir);
-  strcat (debugfile, basename);
+  /* Then try in the global debugfile directories.
+     Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
+     cause "/..." lookups.  */
 
-  if (separate_debug_file_exists (debugfile, crc32))
+  debugdir = debug_file_directory;
+  do
     {
-      xfree (basename);
-      xfree (dir);
-      return xstrdup (debugfile);
-    }
+      char *debugdir_end;
 
-  /* If the file is in the sysroot, try using its base path in the
-     global debugfile directory.  */
-  canon_name = lrealpath (dir);
-  if (canon_name
-      && strncmp (canon_name, gdb_sysroot, strlen (gdb_sysroot)) == 0
-      && IS_DIR_SEPARATOR (canon_name[strlen (gdb_sysroot)]))
-    {
-      strcpy (debugfile, debug_file_directory);
-      strcat (debugfile, canon_name + strlen (gdb_sysroot));
+      while (*debugdir == DIRNAME_SEPARATOR)
+       debugdir++;
+
+      debugdir_end = strchr (debugdir, DIRNAME_SEPARATOR);
+      if (debugdir_end == NULL)
+       debugdir_end = &debugdir[strlen (debugdir)];
+
+      memcpy (debugfile, debugdir, debugdir_end - debugdir);
+      debugfile[debugdir_end - debugdir] = 0;
       strcat (debugfile, "/");
+      strcat (debugfile, dir);
       strcat (debugfile, basename);
 
-      if (separate_debug_file_exists (debugfile, crc32))
+      if (separate_debug_file_exists (debugfile, crc32, objfile))
+       goto cleanup_return_debugfile;
+
+      /* If the file is in the sysroot, try using its base path in the
+        global debugfile directory.  */
+      if (canon_name
+         && strncmp (canon_name, gdb_sysroot, strlen (gdb_sysroot)) == 0
+         && IS_DIR_SEPARATOR (canon_name[strlen (gdb_sysroot)]))
        {
-         xfree (canon_name);
-         xfree (basename);
-         xfree (dir);
-         return xstrdup (debugfile);
+         memcpy (debugfile, debugdir, debugdir_end - debugdir);
+         debugfile[debugdir_end - debugdir] = 0;
+         strcat (debugfile, canon_name + strlen (gdb_sysroot));
+         strcat (debugfile, "/");
+         strcat (debugfile, basename);
+
+         if (separate_debug_file_exists (debugfile, crc32, objfile))
+           goto cleanup_return_debugfile;
        }
+
+      debugdir = debugdir_end;
     }
+  while (*debugdir != 0);
   
-  if (canon_name)
-    xfree (canon_name);
+  xfree (debugfile);
+  debugfile = NULL;
 
+cleanup_return_debugfile:
+  xfree (canon_name);
   xfree (basename);
   xfree (dir);
-  return NULL;
+  return debugfile;
 }
 
 
@@ -1545,6 +1474,19 @@ set_initial_language (void)
     }
 }
 
+/* If NAME is a remote name open the file using remote protocol, otherwise
+   open it normally.  */
+
+bfd *
+bfd_open_maybe_remote (const char *name)
+{
+  if (remote_filename_p (name))
+    return remote_bfd_open (name, gnutarget);
+  else
+    return bfd_openr (name, gnutarget);
+}
+
+
 /* 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
@@ -1583,14 +1525,14 @@ symfile_bfd_open (char *name)
 
   /* Look down path for it, allocate 2nd new malloc'd copy.  */
   desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, name,
-               O_RDONLY | O_BINARY, 0, &absolute_name);
+               O_RDONLY | O_BINARY, &absolute_name);
 #if defined(__GO32__) || defined(_WIN32) || defined (__CYGWIN__)
   if (desc < 0)
     {
       char *exename = alloca (strlen (name) + 5);
       strcat (strcpy (exename, name), ".exe");
       desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, exename,
-                   O_RDONLY | O_BINARY, 0, &absolute_name);
+                   O_RDONLY | O_BINARY, &absolute_name);
     }
 #endif
   if (desc < 0)
@@ -1625,6 +1567,9 @@ symfile_bfd_open (char *name)
             bfd_errmsg (bfd_get_error ()));
     }
 
+  /* bfd_usrdata exists for applications and libbfd must not touch it.  */
+  gdb_assert (bfd_usrdata (sym_bfd) == NULL);
+
   return sym_bfd;
 }
 
@@ -1800,9 +1745,9 @@ load_progress (ULONGEST bytes, void *untyped_arg)
     {
       /* The write is just starting.  Let the user know we've started
         this section.  */
-      ui_out_message (uiout, 0, "Loading section %s, size 0x%s lma 0x%s\n",
-                     args->section_name, paddr_nz (args->section_size),
-                     paddr_nz (args->lma));
+      ui_out_message (uiout, 0, "Loading section %s, size %s lma %s\n",
+                     args->section_name, hex_string (args->section_size),
+                     paddress (target_gdbarch, args->lma));
       return;
     }
 
@@ -1819,11 +1764,11 @@ load_progress (ULONGEST bytes, void *untyped_arg)
       struct cleanup *verify_cleanups = make_cleanup (xfree, check);
 
       if (target_read_memory (args->lma, check, bytes) != 0)
-       error (_("Download verify read failed at 0x%s"),
-              paddr (args->lma));
+       error (_("Download verify read failed at %s"),
+              paddress (target_gdbarch, args->lma));
       if (memcmp (args->buffer, check, bytes) != 0)
-       error (_("Download verify compare failed at 0x%s"),
-              paddr (args->lma));
+       error (_("Download verify compare failed at %s"),
+              paddress (target_gdbarch, args->lma));
       do_cleanups (verify_cleanups);
     }
   totals->data_count += bytes;
@@ -1979,13 +1924,13 @@ generic_load (char *args, int from_tty)
 
   entry = bfd_get_start_address (loadfile_bfd);
   ui_out_text (uiout, "Start address ");
-  ui_out_field_fmt (uiout, "address", "0x%s", paddr_nz (entry));
+  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.  */
-  write_pc (entry);
+  regcache_write_pc (get_current_regcache (), entry);
 
   /* 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
@@ -2081,6 +2026,7 @@ print_transfer_performance (struct ui_file *stream,
 static void
 add_symbol_file_command (char *args, int from_tty)
 {
+  struct gdbarch *gdbarch = get_current_arch ();
   char *filename = NULL;
   int flags = OBJF_USERLOADED;
   char *arg;
@@ -2211,7 +2157,8 @@ add_symbol_file_command (char *args, int from_tty)
          entered on the command line. */
       section_addrs->other[sec_num].name = sec;
       section_addrs->other[sec_num].addr = addr;
-      printf_unfiltered ("\t%s_addr = %s\n", sec, paddress (addr));
+      printf_unfiltered ("\t%s_addr = %s\n", sec,
+                        paddress (gdbarch, addr));
       sec_num++;
 
       /* The object's sections are initialized when a
@@ -2224,7 +2171,8 @@ add_symbol_file_command (char *args, int from_tty)
   if (from_tty && (!query ("%s", "")))
     error (_("Not confirmed."));
 
-  symbol_file_add (filename, from_tty, section_addrs, 0, flags);
+  symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0,
+                   section_addrs, flags);
 
   /* Getting new symbols may change our opinion about what is
      frameless.  */
@@ -2232,16 +2180,7 @@ add_symbol_file_command (char *args, int from_tty)
   do_cleanups (my_cleanups);
 }
 \f
-static void
-add_shared_symbol_files_command (char *args, int from_tty)
-{
-#ifdef ADD_SHARED_SYMBOL_FILES
-  ADD_SHARED_SYMBOL_FILES (args, from_tty);
-#else
-  error (_("This command is not available in this configuration of GDB."));
-#endif
-}
-\f
+
 /* Re-read symbols if a symbol-file has changed.  */
 void
 reread_symbols (void)
@@ -2260,274 +2199,222 @@ reread_symbols (void)
 
   for (objfile = object_files; objfile; objfile = objfile->next)
     {
-      if (objfile->obfd)
-       {
+      /* solib-sunos.c creates one objfile with obfd.  */
+      if (objfile->obfd == NULL)
+       continue;
+
+      /* Separate debug objfiles are handled in the main objfile.  */
+      if (objfile->separate_debug_objfile_backlink)
+       continue;
+
 #ifdef DEPRECATED_IBM6000_TARGET
-         /* If this object is from a shared library, then you should
-            stat on the library name, not member name. */
+      /* If this object is from a shared library, then you should
+        stat on the library name, not member name. */
 
-         if (objfile->obfd->my_archive)
-           res = stat (objfile->obfd->my_archive->filename, &new_statbuf);
-         else
+      if (objfile->obfd->my_archive)
+       res = stat (objfile->obfd->my_archive->filename, &new_statbuf);
+      else
 #endif
-           res = stat (objfile->name, &new_statbuf);
-         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);
-             continue;
-           }
-         new_modtime = new_statbuf.st_mtime;
-         if (new_modtime != objfile->mtime)
+       res = stat (objfile->name, &new_statbuf);
+      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);
+         continue;
+       }
+      new_modtime = new_statbuf.st_mtime;
+      if (new_modtime != objfile->mtime)
+       {
+         struct cleanup *old_cleanups;
+         struct section_offsets *offsets;
+         int num_offsets;
+         char *obfd_filename;
+
+         printf_unfiltered (_("`%s' has changed; re-reading symbols.\n"),
+                            objfile->name);
+
+         /* There are various functions like symbol_file_add,
+            symfile_bfd_open, syms_from_objfile, etc., which might
+            appear to do what we want.  But they have various other
+            effects which we *don't* want.  So we just do stuff
+            ourselves.  We don't worry about mapped files (for one thing,
+            any mapped file will be out of date).  */
+
+         /* If we get an error, blow away this objfile (not sure if
+            that is the correct response for things like shared
+            libraries).  */
+         old_cleanups = make_cleanup_free_objfile (objfile);
+         /* We need to do this whenever any symbols go away.  */
+         make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/);
+
+         if (exec_bfd != NULL && strcmp (bfd_get_filename (objfile->obfd),
+                                         bfd_get_filename (exec_bfd)) == 0)
            {
-             struct cleanup *old_cleanups;
-             struct section_offsets *offsets;
-             int num_offsets;
-             char *obfd_filename;
-
-             printf_unfiltered (_("`%s' has changed; re-reading symbols.\n"),
-                              objfile->name);
-
-             /* There are various functions like symbol_file_add,
-                symfile_bfd_open, syms_from_objfile, etc., which might
-                appear to do what we want.  But they have various other
-                effects which we *don't* want.  So we just do stuff
-                ourselves.  We don't worry about mapped files (for one thing,
-                any mapped file will be out of date).  */
-
-             /* If we get an error, blow away this objfile (not sure if
-                that is the correct response for things like shared
-                libraries).  */
-             old_cleanups = make_cleanup_free_objfile (objfile);
-             /* We need to do this whenever any symbols go away.  */
-             make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/);
-
-             if (exec_bfd != NULL && strcmp (bfd_get_filename (objfile->obfd),
-                                             bfd_get_filename (exec_bfd)) == 0)
-               {
-                 /* Reload EXEC_BFD without asking anything.  */
+             /* Reload EXEC_BFD without asking anything.  */
 
-                 exec_file_attach (bfd_get_filename (objfile->obfd), 0);
-               }
+             exec_file_attach (bfd_get_filename (objfile->obfd), 0);
+           }
 
-             /* Clean up any state BFD has sitting around.  We don't need
-                to close the descriptor but BFD lacks a way of closing the
-                BFD without closing the descriptor.  */
-             obfd_filename = bfd_get_filename (objfile->obfd);
-             if (!bfd_close (objfile->obfd))
-               error (_("Can't close BFD for %s: %s"), objfile->name,
-                      bfd_errmsg (bfd_get_error ()));
-             if (remote_filename_p (obfd_filename))
-               objfile->obfd = remote_bfd_open (obfd_filename, gnutarget);
-             else
-               objfile->obfd = bfd_openr (obfd_filename, gnutarget);
-             if (objfile->obfd == NULL)
-               error (_("Can't open %s to read symbols."), objfile->name);
-             /* bfd_openr sets cacheable to true, which is what we want.  */
-             if (!bfd_check_format (objfile->obfd, bfd_object))
-               error (_("Can't read symbols from %s: %s."), objfile->name,
-                      bfd_errmsg (bfd_get_error ()));
-
-             /* Save the offsets, we will nuke them with the rest of the
-                objfile_obstack.  */
-             num_offsets = objfile->num_sections;
-             offsets = ((struct section_offsets *)
-                        alloca (SIZEOF_N_SECTION_OFFSETS (num_offsets)));
-             memcpy (offsets, objfile->section_offsets,
-                     SIZEOF_N_SECTION_OFFSETS (num_offsets));
-
-             /* Remove any references to this objfile in the global
-                value lists.  */
-             preserve_values (objfile);
-
-             /* Nuke all the state that we will re-read.  Much of the following
-                code which sets things to NULL really is necessary to tell
-                other parts of GDB that there is nothing currently there.  */
-
-             /* FIXME: Do we have to free a whole linked list, or is this
-                enough?  */
-             if (objfile->global_psymbols.list)
-               xfree (objfile->global_psymbols.list);
-             memset (&objfile->global_psymbols, 0,
-                     sizeof (objfile->global_psymbols));
-             if (objfile->static_psymbols.list)
-               xfree (objfile->static_psymbols.list);
-             memset (&objfile->static_psymbols, 0,
-                     sizeof (objfile->static_psymbols));
-
-             /* Free the obstacks for non-reusable objfiles */
-             bcache_xfree (objfile->psymbol_cache);
-             objfile->psymbol_cache = bcache_xmalloc ();
-             bcache_xfree (objfile->macro_cache);
-             objfile->macro_cache = bcache_xmalloc ();
-             if (objfile->demangled_names_hash != NULL)
-               {
-                 htab_delete (objfile->demangled_names_hash);
-                 objfile->demangled_names_hash = NULL;
-               }
-             obstack_free (&objfile->objfile_obstack, 0);
-             objfile->sections = NULL;
-             objfile->symtabs = NULL;
-             objfile->psymtabs = NULL;
-             objfile->free_psymtabs = NULL;
-             objfile->cp_namespace_symtab = NULL;
-             objfile->msymbols = NULL;
-             objfile->deprecated_sym_private = NULL;
-             objfile->minimal_symbol_count = 0;
-             memset (&objfile->msymbol_hash, 0,
-                     sizeof (objfile->msymbol_hash));
-             memset (&objfile->msymbol_demangled_hash, 0,
-                     sizeof (objfile->msymbol_demangled_hash));
-             clear_objfile_data (objfile);
-             if (objfile->sf != NULL)
-               {
-                 (*objfile->sf->sym_finish) (objfile);
-               }
+         /* Clean up any state BFD has sitting around.  We don't need
+            to close the descriptor but BFD lacks a way of closing the
+            BFD without closing the descriptor.  */
+         obfd_filename = bfd_get_filename (objfile->obfd);
+         if (!bfd_close (objfile->obfd))
+           error (_("Can't close BFD for %s: %s"), objfile->name,
+                  bfd_errmsg (bfd_get_error ()));
+         objfile->obfd = bfd_open_maybe_remote (obfd_filename);
+         if (objfile->obfd == NULL)
+           error (_("Can't open %s to read symbols."), objfile->name);
+         else
+           objfile->obfd = gdb_bfd_ref (objfile->obfd);
+         /* bfd_openr sets cacheable to true, which is what we want.  */
+         if (!bfd_check_format (objfile->obfd, bfd_object))
+           error (_("Can't read symbols from %s: %s."), objfile->name,
+                  bfd_errmsg (bfd_get_error ()));
+
+         /* Save the offsets, we will nuke them with the rest of the
+            objfile_obstack.  */
+         num_offsets = objfile->num_sections;
+         offsets = ((struct section_offsets *)
+                    alloca (SIZEOF_N_SECTION_OFFSETS (num_offsets)));
+         memcpy (offsets, objfile->section_offsets,
+                 SIZEOF_N_SECTION_OFFSETS (num_offsets));
+
+         /* Remove any references to this objfile in the global
+            value lists.  */
+         preserve_values (objfile);
+
+         /* Nuke all the state that we will re-read.  Much of the following
+            code which sets things to NULL really is necessary to tell
+            other parts of GDB that there is nothing currently there.
+
+            Try to keep the freeing order compatible with free_objfile.  */
+
+         if (objfile->sf != NULL)
+           {
+             (*objfile->sf->sym_finish) (objfile);
+           }
 
-             objfile->psymbol_cache = bcache_xmalloc ();
-             objfile->macro_cache = bcache_xmalloc ();
-             /* obstack_init also initializes the obstack so it is
-                empty.  We could use obstack_specify_allocation but
-                gdb_obstack.h specifies the alloc/dealloc
-                functions.  */
-             obstack_init (&objfile->objfile_obstack);
-             if (build_objfile_section_table (objfile))
-               {
-                 error (_("Can't find the file sections in `%s': %s"),
-                        objfile->name, bfd_errmsg (bfd_get_error ()));
-               }
-              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.  */
-             objfile->section_offsets = (struct section_offsets *)
-               obstack_alloc (&objfile->objfile_obstack,
-                              SIZEOF_N_SECTION_OFFSETS (num_offsets));
-             memcpy (objfile->section_offsets, offsets,
-                     SIZEOF_N_SECTION_OFFSETS (num_offsets));
-             objfile->num_sections = num_offsets;
-
-             /* What the hell is sym_new_init for, anyway?  The concept of
-                distinguishing between the main file and additional files
-                in this way seems rather dubious.  */
-             if (objfile == symfile_objfile)
-               {
-                 (*objfile->sf->sym_new_init) (objfile);
-               }
+         clear_objfile_data (objfile);
+
+         /* Free the separate debug objfiles.  It will be
+            automatically recreated by sym_read.  */
+          free_objfile_separate_debug (objfile);
+
+         /* FIXME: Do we have to free a whole linked list, or is this
+            enough?  */
+         if (objfile->global_psymbols.list)
+           xfree (objfile->global_psymbols.list);
+         memset (&objfile->global_psymbols, 0,
+                 sizeof (objfile->global_psymbols));
+         if (objfile->static_psymbols.list)
+           xfree (objfile->static_psymbols.list);
+         memset (&objfile->static_psymbols, 0,
+                 sizeof (objfile->static_psymbols));
+
+         /* Free the obstacks for non-reusable objfiles */
+         bcache_xfree (objfile->psymbol_cache);
+         objfile->psymbol_cache = bcache_xmalloc ();
+         bcache_xfree (objfile->macro_cache);
+         objfile->macro_cache = bcache_xmalloc ();
+         bcache_xfree (objfile->filename_cache);
+         objfile->filename_cache = bcache_xmalloc ();
+         if (objfile->demangled_names_hash != NULL)
+           {
+             htab_delete (objfile->demangled_names_hash);
+             objfile->demangled_names_hash = NULL;
+           }
+         obstack_free (&objfile->objfile_obstack, 0);
+         objfile->sections = NULL;
+         objfile->symtabs = NULL;
+         objfile->psymtabs = NULL;
+         objfile->psymtabs_addrmap = NULL;
+         objfile->free_psymtabs = NULL;
+         objfile->cp_namespace_symtab = NULL;
+         objfile->msymbols = NULL;
+         objfile->deprecated_sym_private = NULL;
+         objfile->minimal_symbol_count = 0;
+         memset (&objfile->msymbol_hash, 0,
+                 sizeof (objfile->msymbol_hash));
+         memset (&objfile->msymbol_demangled_hash, 0,
+                 sizeof (objfile->msymbol_demangled_hash));
+
+         objfile->psymbol_cache = bcache_xmalloc ();
+         objfile->macro_cache = bcache_xmalloc ();
+         objfile->filename_cache = bcache_xmalloc ();
+         /* obstack_init also initializes the obstack so it is
+            empty.  We could use obstack_specify_allocation but
+            gdb_obstack.h specifies the alloc/dealloc
+            functions.  */
+         obstack_init (&objfile->objfile_obstack);
+         if (build_objfile_section_table (objfile))
+           {
+             error (_("Can't find the file sections in `%s': %s"),
+                    objfile->name, bfd_errmsg (bfd_get_error ()));
+           }
+         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.  */
+         objfile->section_offsets = (struct section_offsets *)
+           obstack_alloc (&objfile->objfile_obstack,
+                          SIZEOF_N_SECTION_OFFSETS (num_offsets));
+         memcpy (objfile->section_offsets, offsets,
+                 SIZEOF_N_SECTION_OFFSETS (num_offsets));
+         objfile->num_sections = num_offsets;
+
+         /* What the hell is sym_new_init for, anyway?  The concept of
+            distinguishing between the main file and additional files
+            in this way seems rather dubious.  */
+         if (objfile == symfile_objfile)
+           {
+             (*objfile->sf->sym_new_init) (objfile);
+           }
 
-             (*objfile->sf->sym_init) (objfile);
-             clear_complaints (&symfile_complaints, 1, 1);
-             /* The "mainline" parameter is a hideous hack; I think leaving it
-                zero is OK since dbxread.c also does what it needs to do if
-                objfile->global_psymbols.size is 0.  */
-             (*objfile->sf->sym_read) (objfile, 0);
-             if (!have_partial_symbols () && !have_full_symbols ())
-               {
-                 wrap_here ("");
-                 printf_unfiltered (_("(no debugging symbols found)\n"));
-                 wrap_here ("");
-               }
+         (*objfile->sf->sym_init) (objfile);
+         clear_complaints (&symfile_complaints, 1, 1);
+         /* Do not set flags as this is safe and we don't want to be
+             verbose.  */
+         (*objfile->sf->sym_read) (objfile, 0);
+         if (!objfile_has_symbols (objfile))
+           {
+             wrap_here ("");
+             printf_unfiltered (_("(no debugging symbols found)\n"));
+             wrap_here ("");
+           }
 
-             /* We're done reading the symbol file; finish off complaints.  */
-             clear_complaints (&symfile_complaints, 0, 1);
+         /* We're done reading the symbol file; finish off complaints.  */
+         clear_complaints (&symfile_complaints, 0, 1);
 
-             /* Getting new symbols may change our opinion about what is
-                frameless.  */
+         /* Getting new symbols may change our opinion about what is
+            frameless.  */
 
-             reinit_frame_cache ();
+         reinit_frame_cache ();
 
-             /* Discard cleanups as symbol reading was successful.  */
-             discard_cleanups (old_cleanups);
+         /* Discard cleanups as symbol reading was successful.  */
+         discard_cleanups (old_cleanups);
 
-             /* If the mtime has changed between the time we set new_modtime
-                and now, we *want* this to be out of date, so don't call stat
-                again now.  */
-             objfile->mtime = new_modtime;
-             reread_one = 1;
-              reread_separate_symbols (objfile);
-             init_entry_point_info (objfile);
-           }
+         /* If the mtime has changed between the time we set new_modtime
+            and now, we *want* this to be out of date, so don't call stat
+            again now.  */
+         objfile->mtime = new_modtime;
+         reread_one = 1;
+         init_entry_point_info (objfile);
        }
     }
 
   if (reread_one)
     {
+      /* Notify objfiles that we've modified objfile sections.  */
+      objfiles_changed ();
+
       clear_symtab_users ();
       /* At least one objfile has changed, so we can consider that
          the executable we're debugging has changed too.  */
       observer_notify_executable_changed ();
     }
-      
 }
-
-
-/* Handle separate debug info for OBJFILE, which has just been
-   re-read:
-   - If we had separate debug info before, but now we don't, get rid
-     of the separated objfile.
-   - If we didn't have separated debug info before, but now we do,
-     read in the new separated debug info file.
-   - If the debug link points to a different file, toss the old one
-     and read the new one.
-   This function does *not* handle the case where objfile is still
-   using the same separate debug info file, but that file's timestamp
-   has changed.  That case should be handled by the loop in
-   reread_symbols already.  */
-static void
-reread_separate_symbols (struct objfile *objfile)
-{
-  char *debug_file;
-  unsigned long crc32;
-
-  /* Does the updated objfile's debug info live in a
-     separate file?  */
-  debug_file = find_separate_debug_file (objfile);
-
-  if (objfile->separate_debug_objfile)
-    {
-      /* There are two cases where we need to get rid of
-         the old separated debug info objfile:
-         - if the new primary objfile doesn't have
-         separated debug info, or
-         - if the new primary objfile has separate debug
-         info, but it's under a different filename.
-
-         If the old and new objfiles both have separate
-         debug info, under the same filename, then we're
-         okay --- if the separated file's contents have
-         changed, we will have caught that when we
-         visited it in this function's outermost
-         loop.  */
-      if (! debug_file
-          || strcmp (debug_file, objfile->separate_debug_objfile->name) != 0)
-        free_objfile (objfile->separate_debug_objfile);
-    }
-
-  /* If the new objfile has separate debug info, and we
-     haven't loaded it already, do so now.  */
-  if (debug_file
-      && ! objfile->separate_debug_objfile)
-    {
-      /* Use the same section offset table as objfile itself.
-         Preserve the flags from objfile that make sense.  */
-      objfile->separate_debug_objfile
-        = (symbol_file_add_with_addrs_or_offsets
-           (symfile_bfd_open (debug_file),
-            info_verbose, /* from_tty: Don't override the default. */
-            0, /* No addr table.  */
-            objfile->section_offsets, objfile->num_sections,
-            0, /* Not mainline.  See comments about this above.  */
-            objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW
-                              | OBJF_USERLOADED)));
-      objfile->separate_debug_objfile->separate_debug_objfile_backlink
-        = objfile;
-    }
-  if (debug_file)
-    xfree (debug_file);
-}
-
-
 \f
 
 
@@ -2708,12 +2595,11 @@ allocate_symtab (char *filename, struct objfile *objfile)
   symtab = (struct symtab *)
     obstack_alloc (&objfile->objfile_obstack, sizeof (struct symtab));
   memset (symtab, 0, sizeof (*symtab));
-  symtab->filename = obsavestring (filename, strlen (filename),
-                                  &objfile->objfile_obstack);
+  symtab->filename = (char *) bcache (filename, strlen (filename) + 1,
+                                     objfile->filename_cache);
   symtab->fullname = NULL;
   symtab->language = deduce_language_from_filename (filename);
-  symtab->debugformat = obsavestring ("unknown", 7,
-                                     &objfile->objfile_obstack);
+  symtab->debugformat = "unknown";
 
   /* Hook it to the objfile it comes from */
 
@@ -2725,7 +2611,7 @@ allocate_symtab (char *filename, struct objfile *objfile)
 }
 
 struct partial_symtab *
-allocate_psymtab (char *filename, struct objfile *objfile)
+allocate_psymtab (const char *filename, struct objfile *objfile)
 {
   struct partial_symtab *psymtab;
 
@@ -2740,8 +2626,8 @@ allocate_psymtab (char *filename, struct objfile *objfile)
                     sizeof (struct partial_symtab));
 
   memset (psymtab, 0, sizeof (struct partial_symtab));
-  psymtab->filename = obsavestring (filename, strlen (filename),
-                                   &objfile->objfile_obstack);
+  psymtab->filename = (char *) bcache (filename, strlen (filename) + 1,
+                                      objfile->filename_cache);
   psymtab->symtab = NULL;
 
   /* Prepend it to the psymtab list for the objfile it belongs to.
@@ -2807,7 +2693,7 @@ clear_symtab_users (void)
 
   clear_displays ();
   breakpoint_re_set ();
-  set_default_breakpoint (0, 0, 0, 0);
+  set_default_breakpoint (0, NULL, 0, 0, 0);
   clear_pc_function_cache ();
   observer_notify_new_objfile (NULL);
 
@@ -3039,7 +2925,8 @@ again2:
 
 struct partial_symtab *
 start_psymtab_common (struct objfile *objfile,
-                     struct section_offsets *section_offsets, char *filename,
+                     struct section_offsets *section_offsets,
+                     const char *filename,
                      CORE_ADDR textlow, struct partial_symbol **global_syms,
                      struct partial_symbol **static_syms)
 {
@@ -3061,26 +2948,23 @@ start_psymtab_common (struct objfile *objfile,
    different domain (or address) is possible and correct.  */
 
 static const struct partial_symbol *
-add_psymbol_to_bcache (char *name, int namelength, domain_enum domain,
+add_psymbol_to_bcache (char *name, int namelength, int copy_name,
+                      domain_enum domain,
                       enum address_class class,
                       long val,        /* Value as a long */
                       CORE_ADDR coreaddr,      /* Value as a CORE_ADDR */
                       enum language language, struct objfile *objfile,
                       int *added)
 {
-  char *buf = name;  
   /* psymbol is static so that there will be no uninitialized gaps in the
      structure which might contain random data, causing cache misses in
      bcache. */
   static struct partial_symbol psymbol;
-  
-  if (name[namelength] != '\0')
-    {
-      buf = alloca (namelength + 1);
-      /* Create local copy of the partial symbol */
-      memcpy (buf, name, namelength);
-      buf[namelength] = '\0';
-    }
+
+  /* However, we must ensure that the entire 'value' field has been
+     zeroed before assigning to it, because an assignment may not
+     write the entire field.  */
+  memset (&psymbol.ginfo.value, 0, sizeof (psymbol.ginfo.value));
   /* val and coreaddr are mutually exclusive, one of them *will* be zero */
   if (val != 0)
     {
@@ -3095,7 +2979,7 @@ add_psymbol_to_bcache (char *name, int namelength, domain_enum domain,
   PSYMBOL_DOMAIN (&psymbol) = domain;
   PSYMBOL_CLASS (&psymbol) = class;
 
-  SYMBOL_SET_NAMES (&psymbol, buf, namelength, objfile);
+  SYMBOL_SET_NAMES (&psymbol, name, namelength, copy_name, objfile);
 
   /* Stash the partial symbol away in the cache */
   return bcache_full (&psymbol, sizeof (struct partial_symbol),
@@ -3132,7 +3016,8 @@ append_psymbol_to_list (struct psymbol_allocation_list *list,
    cache.  */
 
 const struct partial_symbol *
-add_psymbol_to_list (char *name, int namelength, domain_enum domain,
+add_psymbol_to_list (char *name, int namelength, int copy_name,
+                    domain_enum domain,
                     enum address_class class,
                     struct psymbol_allocation_list *list, 
                     long val,  /* Value as a long */
@@ -3144,7 +3029,7 @@ add_psymbol_to_list (char *name, int namelength, domain_enum domain,
   int added;
 
   /* Stash the partial symbol away in the cache */
-  psym = add_psymbol_to_bcache (name, namelength, domain, class,
+  psym = add_psymbol_to_bcache (name, namelength, copy_name, domain, class,
                                val, coreaddr, language, objfile, &added);
 
   /* Do not duplicate global partial symbols.  */
@@ -3297,6 +3182,8 @@ overlay_invalidate_all (void)
 int
 section_is_mapped (struct obj_section *osect)
 {
+  struct gdbarch *gdbarch;
+
   if (osect == 0 || !section_is_overlay (osect))
     return 0;
 
@@ -3308,7 +3195,8 @@ section_is_mapped (struct obj_section *osect)
     case ovly_auto:            /* overlay debugging automatic */
       /* Unles there is a gdbarch_overlay_update function,
          there's really nothing useful to do here (can't really go auto)  */
-      if (gdbarch_overlay_update_p (current_gdbarch))
+      gdbarch = get_objfile_arch (osect->objfile);
+      if (gdbarch_overlay_update_p (gdbarch))
        {
          if (overlay_cache_invalid)
            {
@@ -3316,7 +3204,7 @@ section_is_mapped (struct obj_section *osect)
              overlay_cache_invalid = 0;
            }
          if (osect->ovly_mapped == -1)
-           gdbarch_overlay_update (current_gdbarch, osect);
+           gdbarch_overlay_update (gdbarch, osect);
        }
       /* fall thru to manual case */
     case ovly_on:              /* overlay debugging manual */
@@ -3504,6 +3392,7 @@ list_overlays_command (char *args, int from_tty)
     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;
@@ -3514,13 +3403,13 @@ list_overlays_command (char *args, int from_tty)
        name = bfd_section_name (objfile->obfd, osect->the_bfd_section);
 
        printf_filtered ("Section %s, loaded at ", name);
-       fputs_filtered (paddress (lma), gdb_stdout);
+       fputs_filtered (paddress (gdbarch, lma), gdb_stdout);
        puts_filtered (" - ");
-       fputs_filtered (paddress (lma + size), gdb_stdout);
+       fputs_filtered (paddress (gdbarch, lma + size), gdb_stdout);
        printf_filtered (", mapped at ");
-       fputs_filtered (paddress (vma), gdb_stdout);
+       fputs_filtered (paddress (gdbarch, vma), gdb_stdout);
        puts_filtered (" - ");
-       fputs_filtered (paddress (vma + size), gdb_stdout);
+       fputs_filtered (paddress (gdbarch, vma + size), gdb_stdout);
        puts_filtered ("\n");
 
        nmapped++;
@@ -3645,8 +3534,10 @@ overlay_off_command (char *args, int from_tty)
 static void
 overlay_load_command (char *args, int from_tty)
 {
-  if (gdbarch_overlay_update_p (current_gdbarch))
-    gdbarch_overlay_update (current_gdbarch, NULL);
+  struct gdbarch *gdbarch = get_current_arch ();
+
+  if (gdbarch_overlay_update_p (gdbarch))
+    gdbarch_overlay_update (gdbarch, NULL);
   else
     error (_("This target does not know how to read its overlay state."));
 }
@@ -3717,8 +3608,6 @@ enum ovly_index
   {
     VMA, SIZE, LMA, MAPPED
   };
-#define TARGET_LONG_BYTES (gdbarch_long_bit (current_gdbarch) \
-                           / TARGET_CHAR_BIT)
 
 /* Throw away the cached copy of _ovly_table */
 static void
@@ -3744,19 +3633,19 @@ simple_free_overlay_region_table (void)
 }
 #endif
 
-/* Read an array of ints from the target into a local buffer.
+/* Read an array of ints of size SIZE from the target into a local buffer.
    Convert to host order.  int LEN is number of ints  */
 static void
-read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr, int len)
+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 * TARGET_LONG_BYTES);
+  gdb_byte *buf = alloca (len * size);
   int i;
 
-  read_memory (memaddr, buf, len * TARGET_LONG_BYTES);
+  read_memory (memaddr, buf, len * size);
   for (i = 0; i < len; i++)
-    myaddr[i] = extract_unsigned_integer (TARGET_LONG_BYTES * i + buf,
-                                         TARGET_LONG_BYTES);
+    myaddr[i] = extract_unsigned_integer (size * i + buf, size, byte_order);
 }
 
 /* Find and grab a copy of the target _ovly_table
@@ -3765,6 +3654,9 @@ static int
 simple_read_overlay_table (void)
 {
   struct minimal_symbol *novlys_msym, *ovly_table_msym;
+  struct gdbarch *gdbarch;
+  int word_size;
+  enum bfd_endian byte_order;
 
   simple_free_overlay_table ();
   novlys_msym = lookup_minimal_symbol ("_novlys", NULL, NULL);
@@ -3785,13 +3677,18 @@ simple_read_overlay_table (void)
       return 0;
     }
 
-  cache_novlys = read_memory_integer (SYMBOL_VALUE_ADDRESS (novlys_msym), 4);
+  gdbarch = get_objfile_arch (msymbol_objfile (ovly_table_msym));
+  word_size = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
+  byte_order = gdbarch_byte_order (gdbarch);
+
+  cache_novlys = read_memory_integer (SYMBOL_VALUE_ADDRESS (novlys_msym),
+                                     4, byte_order);
   cache_ovly_table
     = (void *) xmalloc (cache_novlys * sizeof (*cache_ovly_table));
   cache_ovly_table_base = SYMBOL_VALUE_ADDRESS (ovly_table_msym);
   read_target_long_array (cache_ovly_table_base,
                           (unsigned int *) cache_ovly_table,
-                          cache_novlys * 4);
+                          cache_novlys * 4, word_size, byte_order);
 
   return 1;                    /* SUCCESS */
 }
@@ -3803,13 +3700,22 @@ static int
 simple_read_overlay_region_table (void)
 {
   struct minimal_symbol *msym;
+  struct gdbarch *gdbarch;
+  int word_size;
+  enum bfd_endian byte_order;
 
   simple_free_overlay_region_table ();
   msym = lookup_minimal_symbol ("_novly_regions", NULL, NULL);
-  if (msym != NULL)
-    cache_novly_regions = read_memory_integer (SYMBOL_VALUE_ADDRESS (msym), 4);
-  else
+  if (msym == NULL)
     return 0;                  /* failure */
+
+  gdbarch = get_objfile_arch (msymbol_objfile (msym));
+  word_size = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
+  byte_order = gdbarch_byte_order (gdbarch);
+
+  cache_novly_regions = read_memory_integer (SYMBOL_VALUE_ADDRESS (msym),
+                                            4, byte_order);
+
   cache_ovly_region_table = (void *) xmalloc (cache_novly_regions * 12);
   if (cache_ovly_region_table != NULL)
     {
@@ -3819,7 +3725,8 @@ simple_read_overlay_region_table (void)
          cache_ovly_region_table_base = SYMBOL_VALUE_ADDRESS (msym);
          read_target_long_array (cache_ovly_region_table_base,
                                  (unsigned int *) cache_ovly_region_table,
-                                 cache_novly_regions * 3);
+                                 cache_novly_regions * 3,
+                                 word_size, byte_order);
        }
       else
        return 0;               /* failure */
@@ -3844,6 +3751,9 @@ simple_overlay_update_1 (struct obj_section *osect)
   int i, size;
   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++)
@@ -3851,8 +3761,9 @@ simple_overlay_update_1 (struct obj_section *osect)
        && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect)
        /* && cache_ovly_table[i][SIZE] == size */ )
       {
-       read_target_long_array (cache_ovly_table_base + i * TARGET_LONG_BYTES,
-                               (unsigned int *) cache_ovly_table[i], 4);
+       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 */ )
@@ -3939,17 +3850,18 @@ symfile_dummy_outputs (bfd *abfd, asection *sectp, void *dummy)
    one affected platform is PowerPC GNU/Linux, although it depends on
    the version of the linker in use).  Also, ELF object files naturally
    have unresolved relocations for their debug sections.  We need to apply
-   the relocations in order to get the locations of symbols correct.  */
+   the relocations in order to get the locations of symbols correct.
+   Another example that may require relocation processing, is the
+   DWARF-2 .eh_frame section in .o files, although it isn't strictly a
+   debug section.  */
 
 bfd_byte *
 symfile_relocate_debug_section (bfd *abfd, asection *sectp, bfd_byte *buf)
 {
-  /* We're only interested in debugging sections with relocation
+  /* We're only interested in sections with relocation
      information.  */
   if ((sectp->flags & SEC_RELOC) == 0)
     return NULL;
-  if ((sectp->flags & SEC_DEBUGGING) == 0)
-    return NULL;
 
   /* We will handle section offsets properly elsewhere, so relocate as if
      all sections begin at 0.  */
@@ -4099,13 +4011,6 @@ with the text.  SECT is a section name to be loaded at SECT_ADDR."),
               &cmdlist);
   set_cmd_completer (c, filename_completer);
 
-  c = add_cmd ("add-shared-symbol-files", class_files,
-              add_shared_symbol_files_command, _("\
-Load the symbols from shared objects in the dynamic linker's link map."),
-              &cmdlist);
-  c = add_alias_cmd ("assf", "add-shared-symbol-files", class_files, 1,
-                    &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\
@@ -4161,21 +4066,13 @@ Usage: set extension-language .foo bar"),
 
   add_setshow_optional_filename_cmd ("debug-file-directory", class_support,
                                     &debug_file_directory, _("\
-Set the directory where separate debug symbols are searched for."), _("\
-Show the directory where separate debug symbols are searched for."), _("\
+Set the directories where separate debug symbols are searched for."), _("\
+Show the directories where separate debug symbols are searched for."), _("\
 Separate debug symbols are first searched for in the same\n\
 directory as the binary, then in the `" DEBUG_SUBDIRECTORY "' subdirectory,\n\
 and lastly at the path of the directory of the binary with\n\
-the global debug-file directory prepended."),
+each global debug-file-directory component prepended."),
                                     NULL,
                                     show_debug_file_directory,
                                     &setlist, &showlist);
-
-  add_setshow_boolean_cmd ("symbol-loading", no_class,
-                           &print_symbol_loading, _("\
-Set printing of symbol loading messages."), _("\
-Show printing of symbol loading messages."), NULL,
-                           NULL,
-                           NULL,
-                           &setprintlist, &showprintlist);
 }