diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/objfiles.c | 39 | ||||
-rw-r--r-- | gdb/objfiles.h | 1 | ||||
-rw-r--r-- | gdb/solib.c | 7 | ||||
-rw-r--r-- | gdb/symfile.c | 2 |
4 files changed, 32 insertions, 17 deletions
diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 92db65e..109a66e 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -181,7 +181,7 @@ allocate_objfile (bfd *abfd, int flags) that any data that is reference is saved in the per-objfile data region. */ - objfile->obfd = abfd; + objfile->obfd = gdb_bfd_ref (abfd); if (objfile->name != NULL) { xfree (objfile->name); @@ -1062,7 +1062,26 @@ objfiles_changed (void) objfiles_changed_p = 1; /* Rebuild section map next time we need it. */ } -/* Unreference and possibly close abfd. */ +/* Add reference to ABFD. Returns ABFD. */ +struct bfd * +gdb_bfd_ref (struct bfd *abfd) +{ + int *p_refcount = bfd_usrdata (abfd); + + if (p_refcount != NULL) + { + *p_refcount += 1; + return abfd; + } + + p_refcount = xmalloc (sizeof (*p_refcount)); + *p_refcount = 1; + bfd_usrdata (abfd) = p_refcount; + + return abfd; +} + +/* Unreference and possibly close ABFD. */ void gdb_bfd_unref (struct bfd *abfd) { @@ -1074,16 +1093,14 @@ gdb_bfd_unref (struct bfd *abfd) p_refcount = bfd_usrdata (abfd); - /* Valid range for p_refcount: NULL (single owner), or a pointer - to int counter, which has a value of 1 (single owner) or 2 (shared). */ - gdb_assert (p_refcount == NULL || *p_refcount == 1 || *p_refcount == 2); + /* Valid range for p_refcount: a pointer to int counter, which has a + value of 1 (single owner) or 2 (shared). */ + gdb_assert (*p_refcount == 1 || *p_refcount == 2); + + *p_refcount -= 1; + if (*p_refcount > 0) + return; - if (p_refcount != NULL) - { - *p_refcount -= 1; - if (*p_refcount > 0) - return; - } xfree (p_refcount); bfd_usrdata (abfd) = NULL; /* Paranoia. */ diff --git a/gdb/objfiles.h b/gdb/objfiles.h index aecf8d8..bd9382b 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -505,6 +505,7 @@ extern void set_objfile_data (struct objfile *objfile, extern void *objfile_data (struct objfile *objfile, const struct objfile_data *data); +extern struct bfd *gdb_bfd_ref (struct bfd *abfd); extern void gdb_bfd_unref (struct bfd *abfd); diff --git a/gdb/solib.c b/gdb/solib.c index aad2d59..8e86769 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -361,7 +361,7 @@ solib_map_sections (void *arg) do_cleanups (old_chain); /* Leave bfd open, core_xfer_memory and "info files" need it. */ - so->abfd = abfd; + so->abfd = gdb_bfd_ref (abfd); /* copy full path name into so_name, so that later symbol_file_add can find it */ @@ -444,7 +444,6 @@ static void symbol_add_stub (struct so_list *so, int flags) { struct section_addr_info *sap; - int *p_refcount; /* Have we already loaded this shared object? */ ALL_OBJFILES (so->objfile) @@ -457,10 +456,6 @@ symbol_add_stub (struct so_list *so, int flags) so->sections_end); so->objfile = symbol_file_add_from_bfd (so->abfd, flags, sap, OBJF_SHARED); - p_refcount = xmalloc (sizeof (*p_refcount)); - *p_refcount = 2; /* Both solib and objfile refer to this abfd. */ - bfd_usrdata (so->abfd) = p_refcount; - free_section_addr_info (sap); return; diff --git a/gdb/symfile.c b/gdb/symfile.c index 5151966..5a50a09 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -2333,6 +2333,8 @@ reread_symbols (void) objfile->obfd = bfd_openr (obfd_filename, gnutarget); if (objfile->obfd == NULL) error (_("Can't open %s to read symbols."), objfile->name); + else + objfile->obfd = gdb_bfd_ref (objfile->obfd); /* bfd_openr sets cacheable to true, which is what we want. */ if (!bfd_check_format (objfile->obfd, bfd_object)) error (_("Can't read symbols from %s: %s."), objfile->name, |