* symfile.c (symfile_bfd_open): Don't copy name. Call
authorTom Tromey <tromey@redhat.com>
Wed, 18 Jul 2012 19:34:57 +0000 (19:34 +0000)
committerTom Tromey <tromey@redhat.com>
Wed, 18 Jul 2012 19:34:57 +0000 (19:34 +0000)
gdb_bfd_stash_filename.
(load_command): Open the new BFD before freeing the old.
(bfd_open_maybe_remote): Call gdb_bfd_stash_filename.
* symfile-mem.c (symbol_file_add_from_memory): Don't copy name.
Call gdb_bfd_stash_filename.
* spu-linux-nat.c (spu_bfd_open): Don't copy name.
* solib-spu.c (spu_bfd_fopen): Don't copy name.  Call
gdb_bfd_stash_filename.
* solib-darwin.c (darwin_solib_get_all_image_info_addr_at_init):
Free found_pathname.
* rs6000-nat.c (add_vmap): Don't copy filename.  Call
gdb_bfd_stash_filename.
* remote.c (remote_bfd_open): Call gdb_bfd_stash_filename.
* machoread.c (macho_add_oso_symfile): Call
gdb_bfd_stash_filename.
(macho_symfile_read_all_oso): Arrange to free archive_name.  Call
gdb_bfd_stash_filename.
(macho_check_dsym): Don't copy filename.  Call
gdb_bfd_stash_filename.
* jit.c (bfd_open_from_target_memory): Don't copy the filename.
* gdb_bfd.c (gdb_bfd_stash_filename): New function.
* gdb_bfd.h (gdb_bfd_stash_filename): Declare.
* gcore.c (create_gcore_bfd): Call gdb_bfd_stash_filename.
* exec.c (exec_close): Don't free the BFD's filename.
(exec_file_attach): Don't copy the filename.  Call
gdb_bfd_stash_filename.
* corelow.c (core_close): Don't free the BFD's filename.
(core_open): Call gdb_bfd_stash_filename.
* corefile.c (reopen_exec_file): Remove #if 0 code.
* solib.c (solib_bfd_fopen): Call gdb_bfd_stash_filename.  Free
pathname.
* dwarf2read.c (try_open_dwo_file): Call gdb_bfd_stash_filename.

17 files changed:
gdb/ChangeLog
gdb/corelow.c
gdb/dwarf2read.c
gdb/exec.c
gdb/gcore.c
gdb/gdb_bfd.c
gdb/gdb_bfd.h
gdb/jit.c
gdb/machoread.c
gdb/remote.c
gdb/rs6000-nat.c
gdb/solib-darwin.c
gdb/solib-spu.c
gdb/solib.c
gdb/spu-linux-nat.c
gdb/symfile-mem.c
gdb/symfile.c

index 5bdabe1..e07597e 100644 (file)
@@ -1,5 +1,41 @@
 2012-07-18  Tom Tromey  <tromey@redhat.com>
 
+       * symfile.c (symfile_bfd_open): Don't copy name.  Call
+       gdb_bfd_stash_filename.
+       (load_command): Open the new BFD before freeing the old.
+       (bfd_open_maybe_remote): Call gdb_bfd_stash_filename.
+       * symfile-mem.c (symbol_file_add_from_memory): Don't copy name.
+       Call gdb_bfd_stash_filename.
+       * spu-linux-nat.c (spu_bfd_open): Don't copy name.
+       * solib-spu.c (spu_bfd_fopen): Don't copy name.  Call
+       gdb_bfd_stash_filename.
+       * solib-darwin.c (darwin_solib_get_all_image_info_addr_at_init):
+       Free found_pathname.
+       * rs6000-nat.c (add_vmap): Don't copy filename.  Call
+       gdb_bfd_stash_filename.
+       * remote.c (remote_bfd_open): Call gdb_bfd_stash_filename.
+       * machoread.c (macho_add_oso_symfile): Call
+       gdb_bfd_stash_filename.
+       (macho_symfile_read_all_oso): Arrange to free archive_name.  Call
+       gdb_bfd_stash_filename.
+       (macho_check_dsym): Don't copy filename.  Call
+       gdb_bfd_stash_filename.
+       * jit.c (bfd_open_from_target_memory): Don't copy the filename.
+       * gdb_bfd.c (gdb_bfd_stash_filename): New function.
+       * gdb_bfd.h (gdb_bfd_stash_filename): Declare.
+       * gcore.c (create_gcore_bfd): Call gdb_bfd_stash_filename.
+       * exec.c (exec_close): Don't free the BFD's filename.
+       (exec_file_attach): Don't copy the filename.  Call
+       gdb_bfd_stash_filename.
+       * corelow.c (core_close): Don't free the BFD's filename.
+       (core_open): Call gdb_bfd_stash_filename.
+       * corefile.c (reopen_exec_file): Remove #if 0 code.
+       * solib.c (solib_bfd_fopen): Call gdb_bfd_stash_filename.  Free
+       pathname.
+       * dwarf2read.c (try_open_dwo_file): Call gdb_bfd_stash_filename.
+
+2012-07-18  Tom Tromey  <tromey@redhat.com>
+
        * dwarf2read.c (try_open_dwo_file): Use gdb_bfd_ref and
        gdb_bfd_unref.
        (free_dwo_file): Use gdb_bfd_unref.
index 3dfa2f4..1fd60e4 100644 (file)
@@ -216,9 +216,7 @@ core_close (int quitting)
          core_data = NULL;
        }
 
-      name = bfd_get_filename (core_bfd);
       gdb_bfd_unref (core_bfd);
-      xfree (name);
       core_bfd = NULL;
     }
   core_vec = NULL;
@@ -326,6 +324,8 @@ core_open (char *filename, int from_tty)
   if (temp_bfd == NULL)
     perror_with_name (filename);
 
+  gdb_bfd_stash_filename (temp_bfd);
+
   if (!bfd_check_format (temp_bfd, bfd_core)
       && !gdb_check_format (temp_bfd))
     {
@@ -341,7 +341,7 @@ core_open (char *filename, int from_tty)
   /* Looks semi-reasonable.  Toss the old core file and work on the
      new.  */
 
-  discard_cleanups (old_chain);        /* Don't free filename any more */
+  do_cleanups (old_chain);
   unpush_target (&core_ops);
   core_bfd = temp_bfd;
   old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/);
index 4c976f3..6667c05 100644 (file)
@@ -8121,11 +8121,12 @@ try_open_dwo_file (const char *file_name)
       xfree (absolute_name);
       return NULL;
     }
+  gdb_bfd_stash_filename (sym_bfd);
+  xfree (absolute_name);
   bfd_set_cacheable (sym_bfd, 1);
 
   if (!bfd_check_format (sym_bfd, bfd_object))
     {
-      xfree (absolute_name);
       gdb_bfd_unref (sym_bfd); /* This also closes desc.  */
       return NULL;
     }
index 3d26bcc..540c271 100644 (file)
@@ -99,10 +99,8 @@ exec_close (void)
   if (exec_bfd)
     {
       bfd *abfd = exec_bfd;
-      char *name = bfd_get_filename (abfd);
 
       gdb_bfd_unref (abfd);
-      xfree (name);
 
       /* Removing target sections may close the exec_ops target.
         Clear exec_bfd before doing so to prevent recursion.  */
@@ -230,6 +228,9 @@ exec_file_attach (char *filename, int from_tty)
             &scratch_pathname);
        }
 #endif
+
+      cleanups = make_cleanup (xfree, scratch_pathname);
+
       if (scratch_chan < 0)
        perror_with_name (filename);
       exec_bfd = gdb_bfd_ref (bfd_fopen (scratch_pathname, gnutarget,
@@ -242,13 +243,6 @@ exec_file_attach (char *filename, int from_tty)
                 scratch_pathname, bfd_errmsg (bfd_get_error ()));
        }
 
-      /* At this point, scratch_pathname and exec_bfd->name both point to the
-         same malloc'd string.  However exec_close() will attempt to free it
-         via the exec_bfd->name pointer, so we need to make another copy and
-         leave exec_bfd as the new owner of the original copy.  */
-      scratch_pathname = xstrdup (scratch_pathname);
-      cleanups = make_cleanup (xfree, scratch_pathname);
-
       if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching))
        {
          /* Make sure to close exec_bfd, or else "run" might try to use
@@ -259,6 +253,8 @@ exec_file_attach (char *filename, int from_tty)
                 gdb_bfd_errmsg (bfd_get_error (), matching));
        }
 
+      gdb_bfd_stash_filename (exec_bfd);
+
       /* FIXME - This should only be run for RS6000, but the ifdef is a poor
          way to accomplish.  */
 #ifdef DEPRECATED_IBM6000_TARGET
index 486ea5f..f9a1389 100644 (file)
@@ -55,6 +55,7 @@ create_gcore_bfd (char *filename)
 
   if (!obfd)
     error (_("Failed to open '%s' for output."), filename);
+  gdb_bfd_stash_filename (obfd);
   bfd_set_format (obfd, bfd_core);
   bfd_set_arch_mach (obfd, default_gcore_arch (), default_gcore_mach ());
   return obfd;
index 160e9e6..8f40d74 100644 (file)
 #include "defs.h"
 #include "gdb_bfd.h"
 #include "gdb_assert.h"
+#include "gdb_string.h"
+
+/* See gdb_bfd.h.  */
+
+void
+gdb_bfd_stash_filename (struct bfd *abfd)
+{
+  char *name = bfd_get_filename (abfd);
+  char *data;
+
+  data = bfd_alloc (abfd, strlen (name) + 1);
+  strcpy (data, name);
+
+  /* Unwarranted chumminess with BFD.  */
+  abfd->filename = data;
+}
 
 /* Close ABFD, and warn if that fails.  */
 
index c6d94a0..a1d5b03 100644 (file)
 #ifndef GDB_BFD_H
 #define GDB_BFD_H
 
+/* Make a copy ABFD's filename using bfd_alloc, and reassign it to the
+   BFD.  This ensures that the BFD's filename has the same lifetime as
+   the BFD itself.  */
+
+void gdb_bfd_stash_filename (struct bfd *abfd);
+
 /* Acquire a new reference to ABFD.  Returns ABFD for convenience.
    It is fine for ABFD to be NULL; in this case the function does
    nothing and returns NULL.  */
index 6a1425c..6478397 100644 (file)
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -133,12 +133,11 @@ mem_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
 static struct bfd *
 bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size, char *target)
 {
-  const char *filename = xstrdup ("<in-memory>");
   struct target_buffer *buffer = xmalloc (sizeof (struct target_buffer));
 
   buffer->base = addr;
   buffer->size = size;
-  return bfd_openr_iovec (filename, target,
+  return bfd_openr_iovec ("<in-memory>", target,
                           mem_bfd_iovec_open,
                           buffer,
                           mem_bfd_iovec_pread,
index eb56f14..6d309bb 100644 (file)
@@ -629,10 +629,10 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd,
 
   bfd_hash_table_free (&table);
 
-  /* Make sure that the filename was malloc'ed.  The current filename comes
-     either from an OSO symbol name or from an archive name.  Memory for both
-     is not managed by gdb.  */
-  abfd->filename = xstrdup (abfd->filename);
+  /* Make sure that the filename has the correct lifetime.  The
+     current filename comes either from an OSO symbol name or from an
+     archive name.  Memory for both is not managed by gdb.  */
+  gdb_bfd_stash_filename (abfd);
 
   /* We need to clear SYMFILE_MAINLINE to avoid interractive question
      from symfile.c:symbol_file_add_with_addrs_or_offsets.  */
@@ -651,6 +651,7 @@ macho_symfile_read_all_oso (struct objfile *main_objfile, int symfile_flags)
   int ix;
   VEC (oso_el) *vec;
   oso_el *oso;
+  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
 
   vec = oso_vector;
   oso_vector = NULL;
@@ -677,6 +678,8 @@ macho_symfile_read_all_oso (struct objfile *main_objfile, int symfile_flags)
          memcpy (archive_name, oso->name, pfx_len);
          archive_name[pfx_len] = '\0';
 
+         make_cleanup (xfree, archive_name);
+
           /* Compute number of oso for this archive.  */
           for (last_ix = ix;
                VEC_iterate (oso_el, vec, last_ix, oso2); last_ix++)
@@ -702,6 +705,9 @@ macho_symfile_read_all_oso (struct objfile *main_objfile, int symfile_flags)
               ix = last_ix;
              continue;
            }
+
+         gdb_bfd_stash_filename (archive_bfd);
+
          member_bfd = gdb_bfd_ref (bfd_openr_next_archived_file (archive_bfd,
                                                                  NULL));
 
@@ -773,6 +779,7 @@ macho_symfile_read_all_oso (struct objfile *main_objfile, int symfile_flags)
     }
 
   VEC_free (oso_el, vec);
+  do_cleanups (cleanup);
 }
 
 /* DSYM (debug symbols) files contain the debug info of an executable.
@@ -810,20 +817,18 @@ macho_check_dsym (struct objfile *objfile)
       warning (_("can't find UUID in %s"), objfile->name);
       return NULL;
     }
-  dsym_filename = xstrdup (dsym_filename);
   dsym_bfd = gdb_bfd_ref (bfd_openr (dsym_filename, gnutarget));
   if (dsym_bfd == NULL)
     {
       warning (_("can't open dsym file %s"), dsym_filename);
-      xfree (dsym_filename);
       return NULL;
     }
+  gdb_bfd_stash_filename (dsym_filename);
 
   if (!bfd_check_format (dsym_bfd, bfd_object))
     {
       gdb_bfd_unref (dsym_bfd);
       warning (_("bad dsym file format: %s"), bfd_errmsg (bfd_get_error ()));
-      xfree (dsym_filename);
       return NULL;
     }
 
@@ -832,7 +837,6 @@ macho_check_dsym (struct objfile *objfile)
     {
       warning (_("can't find UUID in %s"), dsym_filename);
       gdb_bfd_unref (dsym_bfd);
-      xfree (dsym_filename);
       return NULL;
     }
   if (memcmp (dsym_uuid->command.uuid.uuid, main_uuid->command.uuid.uuid,
@@ -840,7 +844,6 @@ macho_check_dsym (struct objfile *objfile)
     {
       warning (_("dsym file UUID doesn't match the one in %s"), objfile->name);
       gdb_bfd_unref (dsym_bfd);
-      xfree (dsym_filename);
       return NULL;
     }
   return dsym_bfd;
index 1c9367d..6ccab54 100644 (file)
@@ -42,6 +42,7 @@
 #include "cli/cli-decode.h"
 #include "cli/cli-setshow.h"
 #include "target-descriptions.h"
+#include "gdb_bfd.h"
 
 #include <ctype.h>
 #include <sys/time.h>
@@ -9823,11 +9824,15 @@ remote_filename_p (const char *filename)
 bfd *
 remote_bfd_open (const char *remote_file, const char *target)
 {
-  return bfd_openr_iovec (remote_file, target,
-                         remote_bfd_iovec_open, NULL,
-                         remote_bfd_iovec_pread,
-                         remote_bfd_iovec_close,
-                         remote_bfd_iovec_stat);
+  bfd *abfd = bfd_openr_iovec (remote_file, target,
+                              remote_bfd_iovec_open, NULL,
+                              remote_bfd_iovec_pread,
+                              remote_bfd_iovec_close,
+                              remote_bfd_iovec_stat);
+
+  if (abfd != NULL)
+    gdb_bfd_stash_filename (abfd);
+  return abfd;
 }
 
 void
index 1aa4a17..017e997 100644 (file)
@@ -730,7 +730,7 @@ static struct vmap *
 add_vmap (LdInfo *ldi)
 {
   bfd *abfd, *last;
-  char *mem, *objname, *filename;
+  char *mem, *filename;
   struct objfile *obj;
   struct vmap *vp;
   int fd;
@@ -743,22 +743,22 @@ add_vmap (LdInfo *ldi)
   filename = LDI_FILENAME (ldi, arch64);
   mem = filename + strlen (filename) + 1;
   mem = xstrdup (mem);
-  objname = xstrdup (filename);
 
   fd = LDI_FD (ldi, arch64);
   if (fd < 0)
     /* Note that this opens it once for every member; a possible
        enhancement would be to only open it once for every object.  */
-    abfd = bfd_openr (objname, gnutarget);
+    abfd = bfd_openr (filename, gnutarget);
   else
-    abfd = bfd_fdopenr (objname, gnutarget, fd);
+    abfd = bfd_fdopenr (filename, gnutarget, fd);
   abfd = gdb_bfd_ref (abfd);
   if (!abfd)
     {
       warning (_("Could not open `%s' as an executable file: %s"),
-              objname, bfd_errmsg (bfd_get_error ()));
+              filename, bfd_errmsg (bfd_get_error ()));
       return NULL;
     }
+  gdb_bfd_stash_filename (abfd);
 
   /* Make sure we have an object file.  */
 
@@ -775,7 +775,7 @@ add_vmap (LdInfo *ldi)
 
       if (!last)
        {
-         warning (_("\"%s\": member \"%s\" missing."), objname, mem);
+         warning (_("\"%s\": member \"%s\" missing."), filename, mem);
          gdb_bfd_unref (abfd);
          return NULL;
        }
@@ -783,7 +783,7 @@ add_vmap (LdInfo *ldi)
       if (!bfd_check_format (last, bfd_object))
        {
          warning (_("\"%s\": member \"%s\" not in executable format: %s."),
-                  objname, mem, bfd_errmsg (bfd_get_error ()));
+                  filename, mem, bfd_errmsg (bfd_get_error ()));
          gdb_bfd_unref (last);
          gdb_bfd_unref (abfd);
          return NULL;
@@ -794,7 +794,7 @@ add_vmap (LdInfo *ldi)
   else
     {
       warning (_("\"%s\": not in executable format: %s."),
-              objname, bfd_errmsg (bfd_get_error ()));
+              filename, bfd_errmsg (bfd_get_error ()));
       gdb_bfd_unref (abfd);
       return NULL;
     }
index bc2cd79..242f8cc 100644 (file)
@@ -510,17 +510,10 @@ darwin_bfd_open (char *pathname)
                                gdbarch_bfd_arch_info (target_gdbarch));
   if (!res)
     {
-      gdb_bfd_unref (abfd);
-      make_cleanup (xfree, found_pathname);
+      make_cleanup_bfd_close (abfd);
       error (_("`%s': not a shared-library: %s"),
-            found_pathname, bfd_errmsg (bfd_get_error ()));
+            bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
     }
-
-  /* Make sure that the filename is malloc'ed.  The current filename
-     for fat-binaries BFDs is a name that was generated by BFD, usually
-     a static string containing the name of the architecture.  */
-  res->filename = xstrdup (pathname);
-
   return res;
 }
 
index 5f03a42..5eeae62 100644 (file)
@@ -326,7 +326,7 @@ spu_bfd_fopen (char *name, CORE_ADDR addr)
   CORE_ADDR *open_closure = xmalloc (sizeof (CORE_ADDR));
   *open_closure = addr;
 
-  nbfd = gdb_bfd_ref (bfd_openr_iovec (xstrdup (name), "elf32-spu",
+  nbfd = gdb_bfd_ref (bfd_openr_iovec (name, "elf32-spu",
                                       spu_bfd_iovec_open, open_closure,
                                       spu_bfd_iovec_pread, spu_bfd_iovec_close,
                                       spu_bfd_iovec_stat));
@@ -339,6 +339,7 @@ spu_bfd_fopen (char *name, CORE_ADDR addr)
       return NULL;
     }
 
+  gdb_bfd_stash_filename (nbfd);
   return nbfd;
 }
 
index 7b9f473..4ddf91a 100644 (file)
@@ -361,9 +361,9 @@ solib_find (char *in_pathname, int *fd)
    it is used as file handle to open the file.  Throws an error if the file
    could not be opened.  Handles both local and remote file access.
 
-   PATHNAME must be malloc'ed by the caller.  If successful, the new BFD's
-   name will point to it.  If unsuccessful, PATHNAME will be freed and the
-   FD will be closed (unless FD was -1).  */
+   PATHNAME must be malloc'ed by the caller.  It will be freed by this
+   function.  If unsuccessful, the FD will be closed (unless FD was
+   -1).  */
 
 bfd *
 solib_bfd_fopen (char *pathname, int fd)
@@ -390,6 +390,9 @@ solib_bfd_fopen (char *pathname, int fd)
             pathname, bfd_errmsg (bfd_get_error ()));
     }
 
+  gdb_bfd_stash_filename (abfd);
+  xfree (pathname);
+
   return gdb_bfd_ref (abfd);
 }
 
@@ -421,17 +424,16 @@ solib_bfd_open (char *pathname)
   /* Check bfd format.  */
   if (!bfd_check_format (abfd, bfd_object))
     {
-      gdb_bfd_unref (abfd);
-      make_cleanup (xfree, found_pathname);
+      make_cleanup_bfd_close (abfd);
       error (_("`%s': not in executable format: %s"),
-            found_pathname, bfd_errmsg (bfd_get_error ()));
+            bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
     }
 
   /* Check bfd arch.  */
   b = gdbarch_bfd_arch_info (target_gdbarch);
   if (!b->compatible (b, bfd_get_arch_info (abfd)))
     warning (_("`%s': Shared library architecture %s is not compatible "
-               "with target architecture %s."), found_pathname,
+               "with target architecture %s."), bfd_get_filename (abfd),
              bfd_get_arch_info (abfd)->printable_name, b->printable_name);
 
   return abfd;
index aeb7242..12f8211 100644 (file)
@@ -315,7 +315,7 @@ spu_bfd_open (ULONGEST addr)
   ULONGEST *open_closure = xmalloc (sizeof (ULONGEST));
   *open_closure = addr;
 
-  nbfd = bfd_openr_iovec (xstrdup ("<in-memory>"), "elf32-spu",
+  nbfd = bfd_openr_iovec ("<in-memory>", "elf32-spu",
                          spu_bfd_iovec_open, open_closure,
                          spu_bfd_iovec_pread, spu_bfd_iovec_close,
                          spu_bfd_iovec_stat);
index 1c306fa..0470d97 100644 (file)
@@ -103,9 +103,13 @@ symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name,
 
   gdb_bfd_ref (nbfd);
   if (name == NULL)
-    nbfd->filename = xstrdup ("shared object read from target memory");
+    nbfd->filename = "shared object read from target memory";
   else
-    nbfd->filename = name;
+    {
+      nbfd->filename = name;
+      gdb_bfd_stash_filename (nbfd);
+      xfree (name);
+    }
 
   if (!bfd_check_format (nbfd, bfd_object))
     {
index 2ad72c5..99427ae 100644 (file)
@@ -1700,7 +1700,13 @@ bfd_open_maybe_remote (const char *name)
   if (remote_filename_p (name))
     return gdb_bfd_ref (remote_bfd_open (name, gnutarget));
   else
-    return gdb_bfd_ref (bfd_openr (name, gnutarget));
+    {
+      bfd *result = gdb_bfd_ref (bfd_openr (name, gnutarget));
+
+      if (result != NULL)
+       gdb_bfd_stash_filename (result);
+      return result;
+    }
 }
 
 
@@ -1718,19 +1724,14 @@ symfile_bfd_open (char *name)
 
   if (remote_filename_p (name))
     {
-      name = xstrdup (name);
       sym_bfd = gdb_bfd_ref (remote_bfd_open (name, gnutarget));
       if (!sym_bfd)
-       {
-         make_cleanup (xfree, name);
-         error (_("`%s': can't open to read symbols: %s."), name,
-                bfd_errmsg (bfd_get_error ()));
-       }
+       error (_("`%s': can't open to read symbols: %s."), name,
+              bfd_errmsg (bfd_get_error ()));
 
       if (!bfd_check_format (sym_bfd, bfd_object))
        {
-         gdb_bfd_unref (sym_bfd);
-         make_cleanup (xfree, name);
+         make_cleanup_bfd_close (sym_bfd);
          error (_("`%s': can't read symbols: %s."), name,
                 bfd_errmsg (bfd_get_error ()));
        }
@@ -1759,10 +1760,9 @@ symfile_bfd_open (char *name)
       perror_with_name (name);
     }
 
-  /* Free 1st new malloc'd copy, but keep the 2nd malloc'd copy in
-     bfd.  It'll be freed in free_objfile().  */
   xfree (name);
   name = absolute_name;
+  make_cleanup (xfree, name);
 
   sym_bfd = gdb_bfd_ref (bfd_fopen (name, gnutarget, FOPEN_RB, desc));
   if (!sym_bfd)
@@ -1776,11 +1776,12 @@ symfile_bfd_open (char *name)
   if (!bfd_check_format (sym_bfd, bfd_object))
     {
       make_cleanup_bfd_close (sym_bfd);
-      make_cleanup (xfree, name);
       error (_("`%s': can't read symbols: %s."), name,
             bfd_errmsg (bfd_get_error ()));
     }
 
+  gdb_bfd_stash_filename (sym_bfd);
+
   return sym_bfd;
 }
 
@@ -2511,9 +2512,16 @@ reread_symbols (void)
          /* 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);
-         gdb_bfd_unref (objfile->obfd);
-         objfile->obfd = bfd_open_maybe_remote (obfd_filename);
+         {
+           struct bfd *obfd = objfile->obfd;
+
+           obfd_filename = bfd_get_filename (objfile->obfd);
+           /* Open the new BFD before freeing the old one, so that
+              the filename remains live.  */
+           objfile->obfd = bfd_open_maybe_remote (obfd_filename);
+           gdb_bfd_unref (obfd);
+         }
+
          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.  */