PR gdb/14290:
authorTom Tromey <tromey@redhat.com>
Wed, 28 Nov 2012 18:48:38 +0000 (18:48 +0000)
committerTom Tromey <tromey@redhat.com>
Wed, 28 Nov 2012 18:48:38 +0000 (18:48 +0000)
* solib-darwin.c (gdb_bfd_mach_o_fat_extract): New function.
(darwin_solib_get_all_image_info_addr_at_init, darwin_bfd_open):
Use it.
* gdb_bfd.h (gdb_bfd_mark_parent): Declare.
* gdb_bfd.c (gdb_bfd_mark_parent): New function.
(gdb_bfd_openr_next_archived_file): Use it.

gdb/ChangeLog
gdb/gdb_bfd.c
gdb/gdb_bfd.h
gdb/solib-darwin.c

index 41b687ae1e7391d6c73893fbd39ff8efcc02c98a..632f6cf99fbac4eaa07230e3f21205285ffc9b97 100644 (file)
@@ -1,3 +1,13 @@
+2012-11-28  Tom Tromey  <tromey@redhat.com>
+
+       PR gdb/14290:
+       * solib-darwin.c (gdb_bfd_mach_o_fat_extract): New function.
+       (darwin_solib_get_all_image_info_addr_at_init, darwin_bfd_open):
+       Use it.
+       * gdb_bfd.h (gdb_bfd_mark_parent): Declare.
+       * gdb_bfd.c (gdb_bfd_mark_parent): New function.
+       (gdb_bfd_openr_next_archived_file): Use it.
+
 2012-11-28  Markus Metzger <markus.t.metzger@intel.com>
 
        * configure.ac: Check for linux/perf_event.h.
index 2bcc4b42b1cb4d2ceb7621834231a90747d23821..f0e349b6e3af4e494d4cb39e1b7cfdbb70bf4348 100644 (file)
@@ -499,24 +499,34 @@ gdb_bfd_openr_iovec (const char *filename, const char *target,
 
 /* See gdb_bfd.h.  */
 
+void
+gdb_bfd_mark_parent (bfd *child, bfd *parent)
+{
+  struct gdb_bfd_data *gdata;
+
+  gdb_bfd_ref (child);
+  /* No need to stash the filename here, because we also keep a
+     reference on the parent archive.  */
+
+  gdata = bfd_usrdata (child);
+  if (gdata->archive_bfd == NULL)
+    {
+      gdata->archive_bfd = parent;
+      gdb_bfd_ref (parent);
+    }
+  else
+    gdb_assert (gdata->archive_bfd == parent);
+}
+
+/* See gdb_bfd.h.  */
+
 bfd *
 gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous)
 {
   bfd *result = bfd_openr_next_archived_file (archive, previous);
 
   if (result)
-    {
-      struct gdb_bfd_data *gdata;
-
-      gdb_bfd_ref (result);
-      /* No need to stash the filename here, because we also keep a
-        reference on the parent archive.  */
-
-      gdata = bfd_usrdata (result);
-      gdb_assert (gdata->archive_bfd == NULL || gdata->archive_bfd == archive);
-      gdata->archive_bfd = archive;
-      gdb_bfd_ref (archive);
-    }
+    gdb_bfd_mark_parent (result, archive);
 
   return result;
 }
index 5fd361cf8994de61a76aad5c351ed20b55ea6b07..bb70b2767a8f74226934b84e68d356d402396834 100644 (file)
@@ -50,6 +50,15 @@ void gdb_bfd_ref (struct bfd *abfd);
 
 void gdb_bfd_unref (struct bfd *abfd);
 
+/* Mark the CHILD BFD as being a member of PARENT.  Also, increment
+   the reference count of CHILD.  Calling this function ensures that
+   as along as CHILD remains alive, PARENT will as well.  Both CHILD
+   and PARENT must be non-NULL.  This can be called more than once
+   with the same arguments; but it is not allowed to call it for a
+   single CHILD with different values for PARENT.  */
+
+void gdb_bfd_mark_parent (bfd *child, bfd *parent);
+
 /* Try to read or map the contents of the section SECT.  If
    successful, the section data is returned and *SIZE is set to the
    size of the section data; this may not be the same as the size
index 4ea07223117a060d0b17085fcab1af71e91379ca..735d1c3addae9146d261a90f896ea3bbbf980ebb 100644 (file)
@@ -348,6 +348,27 @@ darwin_special_symbol_handling (void)
 {
 }
 
+/* A wrapper for bfd_mach_o_fat_extract that handles reference
+   counting properly.  This will either return NULL, or return a new
+   reference to a BFD.  */
+
+static bfd *
+gdb_bfd_mach_o_fat_extract (bfd *abfd, bfd_format format,
+                           const bfd_arch_info_type *arch)
+{
+  bfd *result = bfd_mach_o_fat_extract (abfd, format, arch);
+
+  if (result == NULL)
+    return NULL;
+
+  if (result == abfd)
+    gdb_bfd_ref (result);
+  else
+    gdb_bfd_mark_parent (result, abfd);
+
+  return result;
+}
+
 /* Extract dyld_all_image_addr when the process was just created, assuming the
    current PC is at the entry of the dynamic linker.  */
 
@@ -377,12 +398,11 @@ darwin_solib_get_all_image_info_addr_at_init (struct darwin_info *info)
       bfd *sub;
 
       make_cleanup_bfd_unref (dyld_bfd);
-      sub = bfd_mach_o_fat_extract (dyld_bfd, bfd_object,
-                                   gdbarch_bfd_arch_info (target_gdbarch ()));
+      sub = gdb_bfd_mach_o_fat_extract (dyld_bfd, bfd_object,
+                                       gdbarch_bfd_arch_info (target_gdbarch ()));
       if (sub)
        {
          dyld_bfd = sub;
-         gdb_bfd_ref (sub);
          make_cleanup_bfd_unref (sub);
        }
       else
@@ -514,14 +534,16 @@ darwin_bfd_open (char *pathname)
   /* Open bfd for shared library.  */
   abfd = solib_bfd_fopen (found_pathname, found_file);
 
-  res = bfd_mach_o_fat_extract (abfd, bfd_object,
-                               gdbarch_bfd_arch_info (target_gdbarch ()));
+  res = gdb_bfd_mach_o_fat_extract (abfd, bfd_object,
+                                   gdbarch_bfd_arch_info (target_gdbarch ()));
   if (!res)
     {
       make_cleanup_bfd_unref (abfd);
       error (_("`%s': not a shared-library: %s"),
             bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
     }
+
+  gdb_bfd_unref (abfd);
   return res;
 }
 
This page took 0.034063 seconds and 4 git commands to generate.