* gdb_bfd.c (struct gdb_bfd_data) <archive_bfd>: New field.
authorTom Tromey <tromey@redhat.com>
Wed, 15 Aug 2012 14:33:40 +0000 (14:33 +0000)
committerTom Tromey <tromey@redhat.com>
Wed, 15 Aug 2012 14:33:40 +0000 (14:33 +0000)
(gdb_bfd_ref): Initialize new field.
(gdb_bfd_unref): Unref the archive BFD.
(gdb_bfd_openr_next_archived_file): Acquire a reference to the
parent archive.

gdb/ChangeLog
gdb/gdb_bfd.c

index 8886b8cf526cedf7fe153d39e21144fdf3629948..3999aa74df4741b2fe099b61458a88ab077b5266 100644 (file)
@@ -1,3 +1,11 @@
+2012-08-15  Tom Tromey  <tromey@redhat.com>
+
+       * gdb_bfd.c (struct gdb_bfd_data) <archive_bfd>: New field.
+       (gdb_bfd_ref): Initialize new field.
+       (gdb_bfd_unref): Unref the archive BFD.
+       (gdb_bfd_openr_next_archived_file): Acquire a reference to the
+       parent archive.
+
 2012-08-15  Tom Tromey  <tromey@redhat.com>
 
        PR python/14387:
index a8210db6410f5f2517b27b1ed185cff4b1762f65..5781d57070877fc759315c44c8a12785ef079b7e 100644 (file)
@@ -81,6 +81,10 @@ struct gdb_bfd_data
 
   /* The mtime of the BFD at the point the cache entry was made.  */
   time_t mtime;
+
+  /* If the BFD comes from an archive, this points to the archive's
+     BFD.  Otherwise, this is NULL.  */
+  bfd *archive_bfd;
 };
 
 /* A hash table storing all the BFDs maintained in the cache.  */
@@ -249,6 +253,7 @@ gdb_bfd_ref (struct bfd *abfd)
   gdata = bfd_zalloc (abfd, sizeof (struct gdb_bfd_data));
   gdata->refc = 1;
   gdata->mtime = bfd_get_mtime (abfd);
+  gdata->archive_bfd = NULL;
   bfd_usrdata (abfd) = gdata;
 
   /* This is the first we've seen it, so add it to the hash table.  */
@@ -264,6 +269,7 @@ gdb_bfd_unref (struct bfd *abfd)
 {
   struct gdb_bfd_data *gdata;
   struct gdb_bfd_cache_search search;
+  bfd *archive_bfd;
 
   if (abfd == NULL)
     return;
@@ -275,6 +281,7 @@ gdb_bfd_unref (struct bfd *abfd)
   if (gdata->refc > 0)
     return;
 
+  archive_bfd = gdata->archive_bfd;
   search.filename = bfd_get_filename (abfd);
 
   if (gdb_bfd_cache && search.filename)
@@ -295,6 +302,8 @@ gdb_bfd_unref (struct bfd *abfd)
   htab_remove_elt (all_bfds, abfd);
 
   gdb_bfd_close_or_warn (abfd);
+
+  gdb_bfd_unref (archive_bfd);
 }
 
 /* A helper function that returns the section data descriptor
@@ -588,8 +597,16 @@ gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous)
 
   if (result)
     {
+      struct gdb_bfd_data *gdata;
+
       gdb_bfd_ref (result);
-      /* No need to stash the filename here.  */
+      /* 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);
     }
 
   return result;