Index: objfiles.h =================================================================== RCS file: /cvs/src/src/gdb/objfiles.h,v retrieving revision 1.61 diff -u -p -u -r1.61 objfiles.h --- objfiles.h 4 Aug 2009 18:46:05 -0000 1.61 +++ objfiles.h 19 Aug 2009 23:30:43 -0000 @@ -505,6 +505,7 @@ extern void set_objfile_data (struct obj 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); Index: objfiles.c =================================================================== RCS file: /cvs/src/src/gdb/objfiles.c,v retrieving revision 1.92 diff -u -p -u -r1.92 objfiles.c --- objfiles.c 17 Aug 2009 11:16:13 -0000 1.92 +++ objfiles.c 19 Aug 2009 23:30:43 -0000 @@ -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. */ Index: solib.c =================================================================== RCS file: /cvs/src/src/gdb/solib.c,v retrieving revision 1.124 diff -u -p -u -r1.124 solib.c --- solib.c 10 Aug 2009 22:09:22 -0000 1.124 +++ solib.c 19 Aug 2009 23:30:44 -0000 @@ -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 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; Index: symfile.c =================================================================== RCS file: /cvs/src/src/gdb/symfile.c,v retrieving revision 1.243 diff -u -p -u -r1.243 symfile.c --- symfile.c 17 Aug 2009 20:09:38 -0000 1.243 +++ symfile.c 19 Aug 2009 23:30:45 -0000 @@ -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,