* 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 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.
do_cleanups (cleanup);
+ gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, dwz_bfd);
dwarf2_per_objfile->dwz_file = result;
return result;
}
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. */
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;
}
#include "gdbcmd.h"
#include "hashtab.h"
#include "filestuff.h"
+#include "vec.h"
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif
#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. */
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;
};
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;
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. */
/* 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)
{
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