Use gdb_bfd_ref_ptr in objfile

This changes struct objfile to use a gdb_bfd_ref_ptr.  In addition to
removing some manual memory management, this fixes a use-after-free
that was introduced by the registry rewrite series.  The issue there
was that, in some cases, registry shutdown could refer to memory that
had already been freed.  This help fix the bug by delaying the
destruction of the BFD reference (and thus the per-bfd object) until
after the registry has been shut down.
This commit is contained in:
Tom Tromey
2022-08-02 09:55:32 -06:00
parent 4d44946794
commit 98badbfdc2
40 changed files with 256 additions and 241 deletions

View File

@@ -147,7 +147,7 @@ get_objfile_bfd_data (bfd *abfd)
void
set_objfile_per_bfd (struct objfile *objfile)
{
objfile->per_bfd = get_objfile_bfd_data (objfile->obfd);
objfile->per_bfd = get_objfile_bfd_data (objfile->obfd.get ());
}
/* Set the objfile's per-BFD notion of the "main" name and
@@ -284,20 +284,24 @@ add_to_objfile_sections (struct bfd *abfd, struct bfd_section *asect,
void
build_objfile_section_table (struct objfile *objfile)
{
int count = gdb_bfd_count_sections (objfile->obfd);
int count = gdb_bfd_count_sections (objfile->obfd.get ());
objfile->sections = OBSTACK_CALLOC (&objfile->objfile_obstack,
count,
struct obj_section);
objfile->sections_end = (objfile->sections + count);
for (asection *sect : gdb_bfd_sections (objfile->obfd))
add_to_objfile_sections (objfile->obfd, sect, objfile, 0);
add_to_objfile_sections (objfile->obfd.get (), sect, objfile, 0);
/* See gdb_bfd_section_index. */
add_to_objfile_sections (objfile->obfd, bfd_com_section_ptr, objfile, 1);
add_to_objfile_sections (objfile->obfd, bfd_und_section_ptr, objfile, 1);
add_to_objfile_sections (objfile->obfd, bfd_abs_section_ptr, objfile, 1);
add_to_objfile_sections (objfile->obfd, bfd_ind_section_ptr, objfile, 1);
add_to_objfile_sections (objfile->obfd.get (), bfd_com_section_ptr,
objfile, 1);
add_to_objfile_sections (objfile->obfd.get (), bfd_und_section_ptr,
objfile, 1);
add_to_objfile_sections (objfile->obfd.get (), bfd_abs_section_ptr,
objfile, 1);
add_to_objfile_sections (objfile->obfd.get (), bfd_ind_section_ptr,
objfile, 1);
}
/* Given a pointer to an initialized bfd (ABFD) and some flag bits,
@@ -313,10 +317,10 @@ build_objfile_section_table (struct objfile *objfile)
requests for specific operations. Other bits like OBJF_SHARED are
simply copied through to the new objfile flags member. */
objfile::objfile (bfd *abfd, const char *name, objfile_flags flags_)
objfile::objfile (gdb_bfd_ref_ptr bfd_, const char *name, objfile_flags flags_)
: flags (flags_),
pspace (current_program_space),
obfd (abfd)
obfd (std::move (bfd_))
{
const char *expanded_name;
@@ -327,7 +331,7 @@ objfile::objfile (bfd *abfd, const char *name, objfile_flags flags_)
std::string name_holder;
if (name == NULL)
{
gdb_assert (abfd == NULL);
gdb_assert (obfd == nullptr);
gdb_assert ((flags & OBJF_NOT_FILENAME) != 0);
expanded_name = "<<anonymous objfile>>";
}
@@ -345,16 +349,15 @@ objfile::objfile (bfd *abfd, const char *name, objfile_flags flags_)
that any data that is reference is saved in the per-objfile data
region. */
gdb_bfd_ref (abfd);
if (abfd != NULL)
if (obfd != nullptr)
{
mtime = bfd_get_mtime (abfd);
mtime = bfd_get_mtime (obfd.get ());
/* Build section table. */
build_objfile_section_table (this);
}
per_bfd = get_objfile_bfd_data (abfd);
per_bfd = get_objfile_bfd_data (obfd.get ());
}
/* If there is a valid and known entry point, function fills *ENTRY_P with it
@@ -454,10 +457,10 @@ add_separate_debug_objfile (struct objfile *objfile, struct objfile *parent)
/* See objfiles.h. */
objfile *
objfile::make (bfd *bfd_, const char *name_, objfile_flags flags_,
objfile::make (gdb_bfd_ref_ptr bfd_, const char *name_, objfile_flags flags_,
objfile *parent)
{
objfile *result = new objfile (bfd_, name_, flags_);
objfile *result = new objfile (std::move (bfd_), name_, flags_);
if (parent != nullptr)
add_separate_debug_objfile (result, parent);
@@ -556,9 +559,7 @@ objfile::~objfile ()
if (sf != NULL)
(*sf->sym_finish) (this);
if (obfd)
gdb_bfd_unref (obfd);
else
if (obfd == nullptr)
delete per_bfd;
/* Before the symbol table code was redone to make it easier to
@@ -709,7 +710,7 @@ objfile_relocate1 (struct objfile *objfile,
{
int idx = s - objfile->sections;
exec_set_section_address (bfd_get_filename (objfile->obfd), idx,
exec_set_section_address (bfd_get_filename (objfile->obfd.get ()), idx,
s->addr ());
}
@@ -745,10 +746,10 @@ objfile_relocate (struct objfile *objfile,
/* Here OBJFILE_ADDRS contain the correct absolute addresses, the
relative ones must be already created according to debug_objfile. */
addr_info_make_relative (&objfile_addrs, debug_objfile->obfd);
addr_info_make_relative (&objfile_addrs, debug_objfile->obfd.get ());
gdb_assert (debug_objfile->section_offsets.size ()
== gdb_bfd_count_sections (debug_objfile->obfd));
== gdb_bfd_count_sections (debug_objfile->obfd.get ()));
section_offsets new_debug_offsets
(debug_objfile->section_offsets.size ());
relative_addr_info_to_section_offsets (new_debug_offsets, objfile_addrs);
@@ -1130,7 +1131,7 @@ update_section_map (struct program_space *pspace,
alloc_size = 0;
for (objfile *objfile : pspace->objfiles ())
ALL_OBJFILE_OSECTIONS (objfile, s)
if (insert_section_p (objfile->obfd, s->the_bfd_section))
if (insert_section_p (objfile->obfd.get (), s->the_bfd_section))
alloc_size += 1;
/* This happens on detach/attach (e.g. in gdb.base/attach.exp). */
@@ -1146,7 +1147,7 @@ update_section_map (struct program_space *pspace,
i = 0;
for (objfile *objfile : pspace->objfiles ())
ALL_OBJFILE_OSECTIONS (objfile, s)
if (insert_section_p (objfile->obfd, s->the_bfd_section))
if (insert_section_p (objfile->obfd.get (), s->the_bfd_section))
map[i++] = s;
std::sort (map, map + alloc_size, sort_cmp);
@@ -1322,7 +1323,7 @@ const char *
objfile_name (const struct objfile *objfile)
{
if (objfile->obfd != NULL)
return bfd_get_filename (objfile->obfd);
return bfd_get_filename (objfile->obfd.get ());
return objfile->original_name;
}
@@ -1333,7 +1334,7 @@ const char *
objfile_filename (const struct objfile *objfile)
{
if (objfile->obfd != NULL)
return bfd_get_filename (objfile->obfd);
return bfd_get_filename (objfile->obfd.get ());
return NULL;
}
@@ -1352,7 +1353,7 @@ const char *
objfile_flavour_name (struct objfile *objfile)
{
if (objfile->obfd != NULL)
return bfd_flavour_name (bfd_get_flavour (objfile->obfd));
return bfd_flavour_name (bfd_get_flavour (objfile->obfd.get ()));
return NULL;
}