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/symfile.c | |
parent | 4d44946794e68cf79cfba467fa414a958dba2185 (diff) | |
download | gdb-98badbfdc222d1d7f346046f23a64522b88d22a0.zip gdb-98badbfdc222d1d7f346046f23a64522b88d22a0.tar.gz gdb-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/symfile.c')
-rw-r--r-- | gdb/symfile.c | 79 |
1 files changed, 39 insertions, 40 deletions
diff --git a/gdb/symfile.c b/gdb/symfile.c index aea8c76..361274e 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -263,7 +263,8 @@ build_section_addr_info_from_objfile (const struct objfile *objfile) /* Before reread_symbols gets rewritten it is not safe to call: gdb_assert (objfile->num_sections == bfd_count_sections (objfile->obfd)); */ - section_addr_info sap = build_section_addr_info_from_bfd (objfile->obfd); + section_addr_info sap + = build_section_addr_info_from_bfd (objfile->obfd.get ()); for (i = 0; i < sap.size (); i++) { int sectindex = sap[i].sectindex; @@ -281,19 +282,19 @@ init_objfile_sect_indices (struct objfile *objfile) asection *sect; int i; - sect = bfd_get_section_by_name (objfile->obfd, ".text"); + sect = bfd_get_section_by_name (objfile->obfd.get (), ".text"); if (sect) objfile->sect_index_text = sect->index; - sect = bfd_get_section_by_name (objfile->obfd, ".data"); + sect = bfd_get_section_by_name (objfile->obfd.get (), ".data"); if (sect) objfile->sect_index_data = sect->index; - sect = bfd_get_section_by_name (objfile->obfd, ".bss"); + sect = bfd_get_section_by_name (objfile->obfd.get (), ".bss"); if (sect) objfile->sect_index_bss = sect->index; - sect = bfd_get_section_by_name (objfile->obfd, ".rodata"); + sect = bfd_get_section_by_name (objfile->obfd.get (), ".rodata"); if (sect) objfile->sect_index_rodata = sect->index; @@ -626,7 +627,7 @@ void default_symfile_offsets (struct objfile *objfile, const section_addr_info &addrs) { - objfile->section_offsets.resize (gdb_bfd_count_sections (objfile->obfd)); + objfile->section_offsets.resize (gdb_bfd_count_sections (objfile->obfd.get ())); relative_addr_info_to_section_offsets (objfile->section_offsets, addrs); /* For relocatable files, all loadable sections will start at zero. @@ -634,9 +635,9 @@ default_symfile_offsets (struct objfile *objfile, that no loadable sections overlap. This algorithm is quadratic, but the number of sections in a single object file is generally small. */ - if ((bfd_get_file_flags (objfile->obfd) & (EXEC_P | DYNAMIC)) == 0) + if ((bfd_get_file_flags (objfile->obfd.get ()) & (EXEC_P | DYNAMIC)) == 0) { - bfd *abfd = objfile->obfd; + bfd *abfd = objfile->obfd.get (); asection *cur_sec; for (cur_sec = abfd->sections; cur_sec != NULL; cur_sec = cur_sec->next) @@ -652,8 +653,8 @@ default_symfile_offsets (struct objfile *objfile, /* Pick non-overlapping offsets for sections the user did not place explicitly. */ CORE_ADDR lowest = 0; - for (asection *sect : gdb_bfd_sections (objfile->obfd)) - place_section (objfile->obfd, sect, objfile->section_offsets, + for (asection *sect : gdb_bfd_sections (objfile->obfd.get ())) + place_section (objfile->obfd.get (), sect, objfile->section_offsets, lowest); /* Correctly filling in the section offsets is not quite @@ -786,8 +787,7 @@ read_symbols (struct objfile *objfile, symfile_add_flags add_flags) virtual section-as-bfd like the bfd filename containing the section. Therefore use also non-canonical name form for the same file containing the section. */ - symbol_file_add_separate (abfd.get (), - bfd_get_filename (abfd.get ()), + symbol_file_add_separate (abfd, bfd_get_filename (abfd.get ()), add_flags | SYMFILE_NOT_FILENAME, objfile); } } @@ -809,20 +809,20 @@ init_entry_point_info (struct objfile *objfile) /* Save startup file's range of PC addresses to help blockframe.c decide where the bottom of the stack is. */ - if (bfd_get_file_flags (objfile->obfd) & EXEC_P) + if (bfd_get_file_flags (objfile->obfd.get ()) & EXEC_P) { /* Executable file -- record its entry point so we'll recognize the startup file because it contains the entry point. */ - ei->entry_point = bfd_get_start_address (objfile->obfd); + ei->entry_point = bfd_get_start_address (objfile->obfd.get ()); ei->entry_point_p = 1; } - else if (bfd_get_file_flags (objfile->obfd) & DYNAMIC - && bfd_get_start_address (objfile->obfd) != 0) + else if (bfd_get_file_flags (objfile->obfd.get ()) & DYNAMIC + && bfd_get_start_address (objfile->obfd.get ()) != 0) { /* Some shared libraries may have entry points set and be runnable. There's no clear way to indicate this, so just check for values other than zero. */ - ei->entry_point = bfd_get_start_address (objfile->obfd); + ei->entry_point = bfd_get_start_address (objfile->obfd.get ()); ei->entry_point_p = 1; } else @@ -857,7 +857,7 @@ init_entry_point_info (struct objfile *objfile) + bfd_section_size (sect))) { ei->the_bfd_section_index - = gdb_bfd_section_index (objfile->obfd, sect); + = gdb_bfd_section_index (objfile->obfd.get (), sect); found = 1; break; } @@ -900,14 +900,14 @@ syms_from_objfile_1 (struct objfile *objfile, section_addr_info local_addr; const int mainline = add_flags & SYMFILE_MAINLINE; - objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd)); + objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd.get ())); objfile->qf.clear (); if (objfile->sf == NULL) { /* No symbols to load, but we still need to make sure that the section_offsets table is allocated. */ - int num_sections = gdb_bfd_count_sections (objfile->obfd); + int num_sections = gdb_bfd_count_sections (objfile->obfd.get ()); objfile->section_offsets.assign (num_sections, 0); return; @@ -954,7 +954,7 @@ syms_from_objfile_1 (struct objfile *objfile, We no longer warn if the lowest section is not a text segment (as happens for the PA64 port. */ if (addrs->size () > 0) - addr_info_make_relative (addrs, objfile->obfd); + addr_info_make_relative (addrs, objfile->obfd.get ()); /* Initialize symbol reading routines for this objfile, allow complaints to appear for this new file, and record how verbose to be, then do the @@ -1033,7 +1033,7 @@ finish_new_objfile (struct objfile *objfile, symfile_add_flags add_flags) Upon failure, jumps back to command level (never returns). */ static struct objfile * -symbol_file_add_with_addrs (bfd *abfd, const char *name, +symbol_file_add_with_addrs (const gdb_bfd_ref_ptr &abfd, const char *name, symfile_add_flags add_flags, section_addr_info *addrs, objfile_flags flags, struct objfile *parent) @@ -1139,7 +1139,7 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name, see the objfile constructor. */ void -symbol_file_add_separate (bfd *bfd, const char *name, +symbol_file_add_separate (const gdb_bfd_ref_ptr &bfd, const char *name, symfile_add_flags symfile_flags, struct objfile *objfile) { @@ -1160,7 +1160,7 @@ symbol_file_add_separate (bfd *bfd, const char *name, See symbol_file_add_with_addrs's comments for details. */ struct objfile * -symbol_file_add_from_bfd (bfd *abfd, const char *name, +symbol_file_add_from_bfd (const gdb_bfd_ref_ptr &abfd, const char *name, symfile_add_flags add_flags, section_addr_info *addrs, objfile_flags flags, struct objfile *parent) @@ -1178,7 +1178,7 @@ symbol_file_add (const char *name, symfile_add_flags add_flags, { gdb_bfd_ref_ptr bfd (symfile_bfd_open (name)); - return symbol_file_add_from_bfd (bfd.get (), name, add_flags, addrs, + return symbol_file_add_from_bfd (bfd, name, add_flags, addrs, flags, NULL); } @@ -1289,7 +1289,7 @@ separate_debug_file_exists (const std::string &name, unsigned long crc, if (bfd_stat (abfd.get (), &abfd_stat) == 0 && abfd_stat.st_ino != 0 - && bfd_stat (parent_objfile->obfd, &parent_stat) == 0) + && bfd_stat (parent_objfile->obfd.get (), &parent_stat) == 0) { if (abfd_stat.st_dev == parent_stat.st_dev && abfd_stat.st_ino == parent_stat.st_ino) @@ -1325,7 +1325,7 @@ separate_debug_file_exists (const std::string &name, unsigned long crc, if (!verified_as_different) { - if (!gdb_bfd_crc (parent_objfile->obfd, &parent_crc)) + if (!gdb_bfd_crc (parent_objfile->obfd.get (), &parent_crc)) { if (separate_debug_file_debug) gdb_printf (gdb_stdlog, @@ -1516,7 +1516,7 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile) unsigned long crc32; gdb::unique_xmalloc_ptr<char> debuglink - (bfd_get_debug_link_info (objfile->obfd, &crc32)); + (bfd_get_debug_link_info (objfile->obfd.get (), &crc32)); if (debuglink == NULL) { @@ -1747,7 +1747,7 @@ symfile_bfd_open (const char *name) int get_section_index (struct objfile *objfile, const char *section_name) { - asection *sect = bfd_get_section_by_name (objfile->obfd, section_name); + asection *sect = bfd_get_section_by_name (objfile->obfd.get (), section_name); if (sect) return sect->index; @@ -2424,7 +2424,7 @@ reread_symbols (int from_tty) for (objfile *objfile : current_program_space->objfiles ()) { - if (objfile->obfd == NULL) + if (objfile->obfd.get () == NULL) continue; /* Separate debug objfiles are handled in the main objfile. */ @@ -2468,12 +2468,12 @@ reread_symbols (int from_tty) clear_symtab_users_cleanup defer_clear_users (0); if (current_program_space->exec_bfd () != NULL - && filename_cmp (bfd_get_filename (objfile->obfd), + && filename_cmp (bfd_get_filename (objfile->obfd.get ()), bfd_get_filename (current_program_space->exec_bfd ())) == 0) { /* Reload EXEC_BFD without asking anything. */ - exec_file_attach (bfd_get_filename (objfile->obfd), 0); + exec_file_attach (bfd_get_filename (objfile->obfd.get ()), 0); } /* Keep the calls order approx. the same as in free_objfile. */ @@ -2504,14 +2504,14 @@ reread_symbols (int from_tty) /* Clean up any state BFD has sitting around. */ { - gdb_bfd_ref_ptr obfd (objfile->obfd); + gdb_bfd_ref_ptr obfd = objfile->obfd; const char *obfd_filename; - obfd_filename = bfd_get_filename (objfile->obfd); + obfd_filename = bfd_get_filename (objfile->obfd.get ()); /* Open the new BFD before freeing the old one, so that the filename remains live. */ gdb_bfd_ref_ptr temp (gdb_bfd_open (obfd_filename, gnutarget)); - objfile->obfd = temp.release (); + objfile->obfd = std::move (temp); if (objfile->obfd == NULL) error (_("Can't open %s to read symbols."), obfd_filename); } @@ -2519,7 +2519,7 @@ reread_symbols (int from_tty) std::string original_name = objfile->original_name; /* bfd_openr sets cacheable to true, which is what we want. */ - if (!bfd_check_format (objfile->obfd, bfd_object)) + if (!bfd_check_format (objfile->obfd.get (), bfd_object)) error (_("Can't read symbols from %s: %s."), objfile_name (objfile), bfd_errmsg (bfd_get_error ())); @@ -2553,7 +2553,7 @@ reread_symbols (int from_tty) /* Reset the sym_fns pointer. The ELF reader can change it based on whether .gdb_index is present, and we need it to start over. PR symtab/15885 */ - objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd)); + objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd.get ())); objfile->qf.clear (); build_objfile_section_table (objfile); @@ -3674,12 +3674,11 @@ symfile_map_offsets_to_segments (bfd *abfd, static void symfile_find_segment_sections (struct objfile *objfile) { - bfd *abfd = objfile->obfd; + bfd *abfd = objfile->obfd.get (); int i; asection *sect; - symfile_segment_data_up data - = get_symfile_segment_data (objfile->obfd); + symfile_segment_data_up data = get_symfile_segment_data (abfd); if (data == NULL) return; |