mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 09:08:59 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user