diff options
author | Tom Tromey <tom@tromey.com> | 2022-08-02 09:55:32 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2022-08-03 13:26:58 -0600 |
commit | 98badbfdc222d1d7f346046f23a64522b88d22a0 (patch) | |
tree | a57a95b75f64a0e318e0b1bd31dd6b246e4797d8 /gdb/objfiles.c | |
parent | 4d44946794e68cf79cfba467fa414a958dba2185 (diff) | |
download | binutils-98badbfdc222d1d7f346046f23a64522b88d22a0.zip binutils-98badbfdc222d1d7f346046f23a64522b88d22a0.tar.gz binutils-98badbfdc222d1d7f346046f23a64522b88d22a0.tar.bz2 |
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.
Diffstat (limited to 'gdb/objfiles.c')
-rw-r--r-- | gdb/objfiles.c | 55 |
1 files changed, 28 insertions, 27 deletions
diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 7759311..3db9135a6 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -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; } |