From: Doug Evans Date: Tue, 14 Jan 2014 01:15:42 +0000 (-0800) Subject: PR symtab/16426 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=13aaf454542c1028a033ac836d7a0d47c63a7029;p=binutils-gdb.git 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ee33eea1e9b..afcce17bf60 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2014-01-13 Doug Evans + + 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 * gdbcore.h (deprecated_core_resize_section_table): Remove. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index cbe04bead36..36e8a620c73 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -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; } diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index 5230d213b35..4d4b0a53593 100644 --- a/gdb/gdb_bfd.c +++ b/gdb/gdb_bfd.c @@ -25,6 +25,7 @@ #include "gdbcmd.h" #include "hashtab.h" #include "filestuff.h" +#include "vec.h" #ifdef HAVE_ZLIB_H #include #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) { diff --git a/gdb/gdb_bfd.h b/gdb/gdb_bfd.h index d4150053ceb..61ad3484bb9 100644 --- a/gdb/gdb_bfd.h +++ b/gdb/gdb_bfd.h @@ -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