PR symtab/16426
authorDoug Evans <dje@google.com>
Tue, 14 Jan 2014 01:15:42 +0000 (17:15 -0800)
committerDoug Evans <dje@google.com>
Tue, 14 Jan 2014 01:15:42 +0000 (17:15 -0800)
* dwarf2read.c (dwarf2_get_dwz_file): Call gdb_bfd_record_inclusion.
(try_open_dwop_file): Ditto.
* gdb_bfd.c: #include "vec.h".
(bfdp): New typedef.
(struct gdb_bfd_data): New member included_bfds.
(gdb_bfd_unref): Unref all included bfds.
(gdb_bfd_record_inclusion): New function.
* gdb_bfd.h (gdb_bfd_record_inclusion): Declare.

gdb/ChangeLog
gdb/dwarf2read.c
gdb/gdb_bfd.c
gdb/gdb_bfd.h

index ee33eea1e9b5500d2fc05b15cc5a2301c8887e6f..afcce17bf606ecb3c3ba5865a0ab4b75f731d44c 100644 (file)
@@ -1,3 +1,15 @@
+2014-01-13  Doug Evans  <dje@google.com>
+
+       PR symtab/16426
+       * dwarf2read.c (dwarf2_get_dwz_file): Call gdb_bfd_record_inclusion.
+       (try_open_dwop_file): Ditto.
+       * gdb_bfd.c: #include "vec.h".
+       (bfdp): New typedef.
+       (struct gdb_bfd_data): New member included_bfds.
+       (gdb_bfd_unref): Unref all included bfds.
+       (gdb_bfd_record_inclusion): New function.
+       * gdb_bfd.h (gdb_bfd_record_inclusion): Declare.
+
 2014-01-13  Tom Tromey  <tromey@redhat.com>
 
        * gdbcore.h (deprecated_core_resize_section_table): Remove.
index cbe04bead360f732ff29b5bfb042465d24eade9b..36e8a620c735a9bb25728ccd587031599c056b6d 100644 (file)
@@ -2432,6 +2432,7 @@ dwarf2_get_dwz_file (void)
 
   do_cleanups (cleanup);
 
+  gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, dwz_bfd);
   dwarf2_per_objfile->dwz_file = result;
   return result;
 }
@@ -10122,6 +10123,8 @@ lookup_dwo_unit_in_dwp (struct dwp_file *dwp_file, const char *comp_dir,
    If IS_DWP is TRUE, we're opening a DWP file, otherwise a DWO file.
    SEARCH_CWD is true if the current directory is to be searched.
    It will be searched before debug-file-directory.
+   If successful, the file is added to the bfd include table of the
+   objfile's bfd (see gdb_bfd_record_inclusion).
    If unable to find/open the file, return NULL.
    NOTE: This function is derived from symfile_bfd_open.  */
 
@@ -10169,6 +10172,12 @@ try_open_dwop_file (const char *file_name, int is_dwp, int search_cwd)
       return NULL;
     }
 
+  /* Success.  Record the bfd as having been included by the objfile's bfd.
+     This is important because things like demangled_names_hash lives in the
+     objfile's per_bfd space and may have references to things like symbol
+     names that live in the DWO/DWP file's per_bfd space.  PR 16426.  */
+  gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, sym_bfd);
+
   return sym_bfd;
 }
 
index 5230d213b35cd88566dab40ae8546128fce3d2d1..4d4b0a53593a3560b742a27f7ad51d1dff5e109f 100644 (file)
@@ -25,6 +25,7 @@
 #include "gdbcmd.h"
 #include "hashtab.h"
 #include "filestuff.h"
+#include "vec.h"
 #ifdef HAVE_ZLIB_H
 #include <zlib.h>
 #endif
@@ -35,6 +36,9 @@
 #endif
 #endif
 
+typedef bfd *bfdp;
+DEF_VEC_P (bfdp);
+
 /* An object of this type is stored in the section's user data when
    mapping a section.  */
 
@@ -84,6 +88,9 @@ struct gdb_bfd_data
      BFD.  Otherwise, this is NULL.  */
   bfd *archive_bfd;
 
+  /* Table of all the bfds this bfd has included.  */
+  VEC (bfdp) *included_bfds;
+
   /* The registry.  */
   REGISTRY_FIELDS;
 };
@@ -277,9 +284,10 @@ gdb_bfd_ref (struct bfd *abfd)
 void
 gdb_bfd_unref (struct bfd *abfd)
 {
+  int ix;
   struct gdb_bfd_data *gdata;
   struct gdb_bfd_cache_search search;
-  bfd *archive_bfd;
+  bfd *archive_bfd, *included_bfd;
 
   if (abfd == NULL)
     return;
@@ -307,6 +315,12 @@ gdb_bfd_unref (struct bfd *abfd)
        htab_clear_slot (gdb_bfd_cache, slot);
     }
 
+  for (ix = 0;
+       VEC_iterate (bfdp, gdata->included_bfds, ix, included_bfd);
+       ++ix)
+    gdb_bfd_unref (included_bfd);
+  VEC_free (bfdp, gdata->included_bfds);
+
   bfd_free_data (abfd);
   bfd_usrdata (abfd) = NULL;  /* Paranoia.  */
 
@@ -569,6 +583,18 @@ gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous)
 
 /* See gdb_bfd.h.  */
 
+void
+gdb_bfd_record_inclusion (bfd *includer, bfd *includee)
+{
+  struct gdb_bfd_data *gdata;
+
+  gdb_bfd_ref (includee);
+  gdata = bfd_usrdata (includer);
+  VEC_safe_push (bfdp, gdata->included_bfds, includee);
+}
+
+/* See gdb_bfd.h.  */
+
 bfd *
 gdb_bfd_fdopenr (const char *filename, const char *target, int fd)
 {
index d4150053cebbd3252ff842987f030aa47255963a..61ad3484bb9f7b3a7f37de1d1b6895617979947c 100644 (file)
@@ -52,6 +52,20 @@ void gdb_bfd_unref (struct bfd *abfd);
 
 void gdb_bfd_mark_parent (bfd *child, bfd *parent);
 
+/* Mark INCLUDEE as being included by INCLUDER.
+   This is used to associate the life time of INCLUDEE with INCLUDER.
+   For example, with Fission, one file can refer to debug info in another
+   file, and internal tables we build for the main file (INCLUDER) may refer
+   to data contained in INCLUDEE.  Therefore we want to keep INCLUDEE around
+   at least as long as INCLUDER exists.
+
+   Note that this is different than gdb_bfd_mark_parent because in our case
+   lifetime tracking is based on the "parent" whereas in gdb_bfd_mark_parent
+   lifetime tracking is based on the "child".  Plus in our case INCLUDEE could
+   have multiple different "parents".  */
+
+void gdb_bfd_record_inclusion (bfd *includer, bfd *includee);
+
 /* 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