X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fobjfiles.c;h=a635f7783e6e9e545ae141bb3292592040bc1306;hb=268e4f09144c48e02f01d82ab3aab359457df214;hp=30823c2d8895ba55b4ff3757e41435091fd490ae;hpb=bde09ab7026edf3d79122872b79c6a8f164ee0ff;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 30823c2d88..a635f7783e 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -52,7 +52,7 @@ #include "solist.h" #include "gdb_bfd.h" #include "btrace.h" -#include "common/pathstuff.h" +#include "gdbsupport/pathstuff.h" #include @@ -66,30 +66,30 @@ DEFINE_REGISTRY (objfile, REGISTRY_ACCESS_FIELD) struct objfile_pspace_info { - struct obj_section **sections; - int num_sections; + objfile_pspace_info () = default; + ~objfile_pspace_info (); + + struct obj_section **sections = nullptr; + int num_sections = 0; /* Nonzero if object files have been added since the section map was last updated. */ - int new_objfiles_available; + int new_objfiles_available = 0; /* Nonzero if the section map MUST be updated before use. */ - int section_map_dirty; + int section_map_dirty = 0; /* Nonzero if section map updates should be inhibited if possible. */ - int inhibit_updates; + int inhibit_updates = 0; }; /* Per-program-space data key. */ -static const struct program_space_data *objfiles_pspace_data; +static const struct program_space_key + objfiles_pspace_data; -static void -objfiles_pspace_data_cleanup (struct program_space *pspace, void *arg) +objfile_pspace_info::~objfile_pspace_info () { - struct objfile_pspace_info *info = (struct objfile_pspace_info *) arg; - - xfree (info->sections); - xfree (info); + xfree (sections); } /* Get the current svr4 data. If none is found yet, add it now. This @@ -100,13 +100,9 @@ get_objfile_pspace_data (struct program_space *pspace) { struct objfile_pspace_info *info; - info = ((struct objfile_pspace_info *) - program_space_data (pspace, objfiles_pspace_data)); + info = objfiles_pspace_data.get (pspace); if (info == NULL) - { - info = XCNEW (struct objfile_pspace_info); - set_program_space_data (pspace, objfiles_pspace_data, info); - } + info = objfiles_pspace_data.emplace (pspace); return info; } @@ -115,7 +111,7 @@ get_objfile_pspace_data (struct program_space *pspace) /* Per-BFD data key. */ -static const struct bfd_data *objfiles_bfd_data; +static const struct bfd_key objfiles_bfd_data; objfile_per_bfd_storage::~objfile_per_bfd_storage () { @@ -133,8 +129,7 @@ get_objfile_bfd_data (struct objfile *objfile, struct bfd *abfd) struct objfile_per_bfd_storage *storage = NULL; if (abfd != NULL) - storage = ((struct objfile_per_bfd_storage *) - bfd_data (abfd, objfiles_bfd_data)); + storage = objfiles_bfd_data.get (abfd); if (storage == NULL) { @@ -143,7 +138,7 @@ get_objfile_bfd_data (struct objfile *objfile, struct bfd *abfd) back to not sharing data across users. These cases are rare enough that this seems reasonable. */ if (abfd != NULL && !gdb_bfd_requires_relocations (abfd)) - set_bfd_data (abfd, objfiles_bfd_data, storage); + objfiles_bfd_data.set (abfd, storage); /* Look up the gdbarch associated with the BFD. */ if (abfd != NULL) @@ -153,15 +148,6 @@ get_objfile_bfd_data (struct objfile *objfile, struct bfd *abfd) return storage; } -/* A deleter for objfile_per_bfd_storage that can be passed as a - cleanup function to the BFD registry. */ - -static void -objfile_bfd_data_free (struct bfd *unused, void *d) -{ - delete (struct objfile_per_bfd_storage *) d; -} - /* See objfiles.h. */ void @@ -180,8 +166,7 @@ set_objfile_main_name (struct objfile *objfile, if (objfile->per_bfd->name_of_main == NULL || strcmp (objfile->per_bfd->name_of_main, name) != 0) objfile->per_bfd->name_of_main - = (const char *) obstack_copy0 (&objfile->per_bfd->storage_obstack, name, - strlen (name)); + = obstack_strdup (&objfile->per_bfd->storage_obstack, name); objfile->per_bfd->language_of_main = lang; } @@ -286,7 +271,7 @@ add_to_objfile_sections_full (struct bfd *abfd, struct bfd_section *asect, { flagword aflag; - aflag = bfd_get_section_flags (abfd, asect); + aflag = bfd_section_flags (asect); if (!(aflag & SEC_ALLOC)) return; } @@ -370,10 +355,7 @@ objfile::objfile (bfd *abfd, const char *name, objfile_flags flags_) name_holder = gdb_abspath (name); expanded_name = name_holder.get (); } - original_name - = (char *) obstack_copy0 (&objfile_obstack, - expanded_name, - strlen (expanded_name)); + original_name = obstack_strdup (&objfile_obstack, expanded_name); /* Update the per-objfile information that comes from the bfd, ensuring that any data that is reference is saved in the per-objfile data @@ -491,10 +473,31 @@ separate_debug_iterator::operator++ () return *this; } +/* Unlink OBJFILE from the list of known objfiles. */ + +static void +unlink_objfile (struct objfile *objfile) +{ + struct objfile **objpp; + + for (objpp = &object_files; *objpp != NULL; objpp = &((*objpp)->next)) + { + if (*objpp == objfile) + { + *objpp = (*objpp)->next; + objfile->next = NULL; + return; + } + } + + internal_error (__FILE__, __LINE__, + _("unlink_objfile: objfile already unlinked")); +} + /* Put one object file before a specified on in the global list. This can be used to make sure an object file is destroyed before another when using objfiles_safe to free all objfiles. */ -void +static void put_objfile_before (struct objfile *objfile, struct objfile *before_this) { struct objfile **objp; @@ -515,41 +518,9 @@ put_objfile_before (struct objfile *objfile, struct objfile *before_this) _("put_objfile_before: before objfile not in list")); } -/* Unlink OBJFILE from the list of known objfiles, if it is found in the - list. - - It is not a bug, or error, to call this function if OBJFILE is not known - to be in the current list. This is done in the case of mapped objfiles, - for example, just to ensure that the mapped objfile doesn't appear twice - in the list. Since the list is threaded, linking in a mapped objfile - twice would create a circular list. - - If OBJFILE turns out to be in the list, we zap it's NEXT pointer after - unlinking it, just to ensure that we have completely severed any linkages - between the OBJFILE and the list. */ - -void -unlink_objfile (struct objfile *objfile) -{ - struct objfile **objpp; - - for (objpp = &object_files; *objpp != NULL; objpp = &((*objpp)->next)) - { - if (*objpp == objfile) - { - *objpp = (*objpp)->next; - objfile->next = NULL; - return; - } - } - - internal_error (__FILE__, __LINE__, - _("unlink_objfile: objfile already unlinked")); -} - /* Add OBJFILE as a separate debug objfile of PARENT. */ -void +static void add_separate_debug_objfile (struct objfile *objfile, struct objfile *parent) { gdb_assert (objfile && parent); @@ -570,6 +541,26 @@ add_separate_debug_objfile (struct objfile *objfile, struct objfile *parent) put_objfile_before (objfile, parent); } +/* See objfiles.h. */ + +objfile * +objfile::make (bfd *bfd_, const char *name_, objfile_flags flags_, + objfile *parent) +{ + objfile *result = new objfile (bfd_, name_, flags_); + if (parent != nullptr) + add_separate_debug_objfile (result, parent); + return result; +} + +/* See objfiles.h. */ + +void +objfile::unlink () +{ + delete this; +} + /* Free all separate debug objfile of OBJFILE, but don't free OBJFILE itself. */ @@ -581,7 +572,7 @@ free_objfile_separate_debug (struct objfile *objfile) for (child = objfile->separate_debug_objfile; child;) { struct objfile *next_child = child->separate_debug_objfile_link; - delete child; + child->unlink (); child = next_child; } } @@ -704,7 +695,7 @@ free_all_objfiles (void) gdb_assert (so->objfile == NULL); for (objfile *objfile : current_program_space->objfiles_safe ()) - delete objfile; + objfile->unlink (); clear_symtab_users (0); } @@ -725,7 +716,9 @@ relocate_one_symbol (struct symbol *sym, struct objfile *objfile, || SYMBOL_CLASS (sym) == LOC_STATIC) && SYMBOL_SECTION (sym) >= 0) { - SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (delta, SYMBOL_SECTION (sym)); + SET_SYMBOL_VALUE_ADDRESS (sym, + SYMBOL_VALUE_ADDRESS (sym) + + ANOFFSET (delta, SYMBOL_SECTION (sym))); } } @@ -1011,7 +1004,7 @@ objfile_purge_solibs (void) be soon. */ if (!(objf->flags & OBJF_USERLOADED) && (objf->flags & OBJF_SHARED)) - delete objf; + objf->unlink (); } } @@ -1035,18 +1028,16 @@ have_minimal_symbols (void) /* Qsort comparison function. */ -static int -qsort_cmp (const void *a, const void *b) +static bool +sort_cmp (const struct obj_section *sect1, const obj_section *sect2) { - const struct obj_section *sect1 = *(const struct obj_section **) a; - const struct obj_section *sect2 = *(const struct obj_section **) b; const CORE_ADDR sect1_addr = obj_section_addr (sect1); const CORE_ADDR sect2_addr = obj_section_addr (sect2); if (sect1_addr < sect2_addr) - return -1; + return true; else if (sect1_addr > sect2_addr) - return 1; + return false; else { /* Sections are at the same address. This could happen if @@ -1063,29 +1054,33 @@ qsort_cmp (const void *a, const void *b) /* Case A. The ordering doesn't matter: separate debuginfo files will be filtered out later. */ - return 0; + return false; } /* Case B. Maintain stable sort order, so bugs in GDB are easier to triage. This section could be slow (since we iterate over all - objfiles in each call to qsort_cmp), but this shouldn't happen + objfiles in each call to sort_cmp), but this shouldn't happen very often (GDB is already in a confused state; one hopes this doesn't happen at all). If you discover that significant time is spent in the loops below, do 'set complaints 100' and examine the resulting complaints. */ - if (objfile1 == objfile2) { - /* Both sections came from the same objfile. We are really confused. - Sort on sequence order of sections within the objfile. */ + /* Both sections came from the same objfile. We are really + confused. Sort on sequence order of sections within the + objfile. The order of checks is important here, if we find a + match on SECT2 first then either SECT2 is before SECT1, or, + SECT2 == SECT1, in both cases we should return false. The + second case shouldn't occur during normal use, but std::sort + does check that '!(a < a)' when compiled in debug mode. */ const struct obj_section *osect; ALL_OBJFILE_OSECTIONS (objfile1, osect) - if (osect == sect1) - return -1; - else if (osect == sect2) - return 1; + if (osect == sect2) + return false; + else if (osect == sect1) + return true; /* We should have found one of the sections before getting here. */ gdb_assert_not_reached ("section not found"); @@ -1096,9 +1091,9 @@ qsort_cmp (const void *a, const void *b) for (objfile *objfile : current_program_space->objfiles ()) if (objfile == objfile1) - return -1; + return true; else if (objfile == objfile2) - return 1; + return false; /* We should have found one of the objfiles before getting here. */ gdb_assert_not_reached ("objfile not found"); @@ -1107,7 +1102,7 @@ qsort_cmp (const void *a, const void *b) /* Unreachable. */ gdb_assert_not_reached ("unexpected code path"); - return 0; + return false; } /* Select "better" obj_section to keep. We prefer the one that came from @@ -1137,15 +1132,15 @@ static int insert_section_p (const struct bfd *abfd, const struct bfd_section *section) { - const bfd_vma lma = bfd_section_lma (abfd, section); + const bfd_vma lma = bfd_section_lma (section); - if (overlay_debugging && lma != 0 && lma != bfd_section_vma (abfd, section) + if (overlay_debugging && lma != 0 && lma != bfd_section_vma (section) && (bfd_get_file_flags (abfd) & BFD_IN_MEMORY) == 0) /* This is an overlay section. IN_MEMORY check is needed to avoid discarding sections from the "system supplied DSO" (aka vdso) on some Linux systems (e.g. Fedora 11). */ return 0; - if ((bfd_get_section_flags (abfd, section) & SEC_THREAD_LOCAL) != 0) + if ((bfd_section_flags (section) & SEC_THREAD_LOCAL) != 0) /* This is a TLS section. */ return 0; @@ -1238,10 +1233,10 @@ filter_overlapping_sections (struct obj_section **map, int map_size) " (A) section `%s' from `%s' [%s, %s)\n" " (B) section `%s' from `%s' [%s, %s).\n" "Will ignore section B"), - bfd_section_name (abfd1, bfds1), objfile_name (objf1), + bfd_section_name (bfds1), objfile_name (objf1), paddress (gdbarch, sect1_addr), paddress (gdbarch, sect1_endaddr), - bfd_section_name (abfd2, bfds2), objfile_name (objf2), + bfd_section_name (bfds2), objfile_name (objf2), paddress (gdbarch, sect2_addr), paddress (gdbarch, sect2_endaddr)); } @@ -1299,7 +1294,7 @@ update_section_map (struct program_space *pspace, if (insert_section_p (objfile->obfd, s->the_bfd_section)) map[i++] = s; - qsort (map, alloc_size, sizeof (*map), qsort_cmp); + std::sort (map, map + alloc_size, sort_cmp); map_size = filter_debuginfo_sections(map, alloc_size); map_size = filter_overlapping_sections(map, map_size); @@ -1453,7 +1448,7 @@ shared_objfile_contains_address_p (struct program_space *pspace, searching the objfiles in the order they are stored internally, ignoring CURRENT_OBJFILE. - On most platorms, it should be close enough to doing the best + On most platforms, it should be close enough to doing the best we can without some knowledge specific to the architecture. */ void @@ -1511,14 +1506,3 @@ objfile_flavour_name (struct objfile *objfile) return bfd_flavour_name (bfd_get_flavour (objfile->obfd)); return NULL; } - -void -_initialize_objfiles (void) -{ - objfiles_pspace_data - = register_program_space_data_with_cleanup (NULL, - objfiles_pspace_data_cleanup); - - objfiles_bfd_data = register_bfd_data_with_cleanup (NULL, - objfile_bfd_data_free); -}