X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fobjfiles.c;h=31c27e9c3cb6bca5505cf3e381d6b5b28f5ab260;hb=ef186fe54aa6d281a3ff8a9528417e5cc614c797;hp=f8a0dc27dbfc700ec39f597ddfcd08d5106b0376;hpb=99d89cdea6c296bdd94ce532350d139d3900ff78;p=binutils-gdb.git diff --git a/gdb/objfiles.c b/gdb/objfiles.c index f8a0dc27dbf..31c27e9c3cb 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -1,6 +1,6 @@ /* GDB routines for manipulating objfiles. - Copyright (C) 1992-2019 Free Software Foundation, Inc. + Copyright (C) 1992-2022 Free Software Foundation, Inc. Contributed by Cygnus Support, using pieces from other GDB modules. @@ -36,7 +36,7 @@ #include #include #include -#include "gdb_obstack.h" +#include "gdbsupport/gdb_obstack.h" #include "hashtab.h" #include "breakpoint.h" @@ -52,44 +52,40 @@ #include "solist.h" #include "gdb_bfd.h" #include "btrace.h" -#include "common/pathstuff.h" +#include "gdbsupport/pathstuff.h" +#include #include -/* Keep a registry of per-objfile data-pointers required by other GDB - modules. */ - -DEFINE_REGISTRY (objfile, REGISTRY_ACCESS_FIELD) - /* Externally visible variables that are owned by this module. See declarations in objfile.h for more info. */ 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 registry::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 +96,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,83 +107,42 @@ get_objfile_pspace_data (struct program_space *pspace) /* Per-BFD data key. */ -static const struct bfd_data *objfiles_bfd_data; +static const registry::key objfiles_bfd_data; + +objfile_per_bfd_storage::~objfile_per_bfd_storage () +{ +} /* Create the per-BFD storage object for OBJFILE. If ABFD is not NULL, and it already has a per-BFD storage object, use that. - Otherwise, allocate a new per-BFD storage object. If ABFD is not - NULL, the object is allocated on the BFD; otherwise it is allocated - on OBJFILE's obstack. Note that it is not safe to call this - multiple times for a given OBJFILE -- it can only be called when - allocating or re-initializing OBJFILE. */ - -static struct objfile_per_bfd_storage * -get_objfile_bfd_data (struct objfile *objfile, struct bfd *abfd) + Otherwise, allocate a new per-BFD storage object. */ + +void +set_objfile_per_bfd (struct objfile *objfile) { + bfd *abfd = objfile->obfd.get (); 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) { + storage = new objfile_per_bfd_storage (abfd); /* If the object requires gdb to do relocations, we simply fall back to not sharing data across users. These cases are rare enough that this seems reasonable. */ if (abfd != NULL && !gdb_bfd_requires_relocations (abfd)) - { - storage - = ((struct objfile_per_bfd_storage *) - bfd_alloc (abfd, sizeof (struct objfile_per_bfd_storage))); - /* objfile_per_bfd_storage is not trivially constructible, must - call the ctor manually. */ - storage = new (storage) objfile_per_bfd_storage (); - set_bfd_data (abfd, objfiles_bfd_data, storage); - } + objfiles_bfd_data.set (abfd, storage); else - storage - = obstack_new (&objfile->objfile_obstack); + objfile->per_bfd_storage.reset (storage); /* Look up the gdbarch associated with the BFD. */ if (abfd != NULL) storage->gdbarch = gdbarch_from_bfd (abfd); - - storage->filename_cache = bcache_xmalloc (NULL, NULL); - storage->macro_cache = bcache_xmalloc (NULL, NULL); - storage->language_of_main = language_unknown; } - return storage; -} - -/* Free STORAGE. */ - -static void -free_objfile_per_bfd_storage (struct objfile_per_bfd_storage *storage) -{ - bcache_xfree (storage->filename_cache); - bcache_xfree (storage->macro_cache); - if (storage->demangled_names_hash) - htab_delete (storage->demangled_names_hash); - storage->~objfile_per_bfd_storage (); -} - -/* A wrapper for free_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) -{ - free_objfile_per_bfd_storage ((struct objfile_per_bfd_storage *) d); -} - -/* See objfiles.h. */ - -void -set_objfile_per_bfd (struct objfile *objfile) -{ - objfile->per_bfd = get_objfile_bfd_data (objfile, objfile->obfd); + objfile->per_bfd = storage; } /* Set the objfile's per-BFD notion of the "main" name and @@ -204,8 +155,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; } @@ -255,14 +205,14 @@ objfile_register_static_link (struct objfile *objfile, struct static_link_htab_entry *entry; if (objfile->static_links == NULL) - objfile->static_links = htab_create_alloc + objfile->static_links.reset (htab_create_alloc (1, &static_link_htab_entry_hash, static_link_htab_entry_eq, NULL, - xcalloc, xfree); + xcalloc, xfree)); /* Create a slot for the mapping, make sure it's the first mapping for this block and then create the mapping itself. */ lookup_entry.block = block; - slot = htab_find_slot (objfile->static_links, &lookup_entry, INSERT); + slot = htab_find_slot (objfile->static_links.get (), &lookup_entry, INSERT); gdb_assert (*slot == NULL); entry = XOBNEW (&objfile->objfile_obstack, static_link_htab_entry); @@ -284,9 +234,8 @@ objfile_lookup_static_link (struct objfile *objfile, if (objfile->static_links == NULL) return NULL; lookup_entry.block = block; - entry - = (struct static_link_htab_entry *) htab_find (objfile->static_links, - &lookup_entry); + entry = ((struct static_link_htab_entry *) + htab_find (objfile->static_links.get (), &lookup_entry)); if (entry == NULL) return NULL; @@ -296,13 +245,13 @@ objfile_lookup_static_link (struct objfile *objfile, -/* Called via bfd_map_over_sections to build up the section table that - the objfile references. The objfile contains pointers to the start - of the table (objfile->sections) and to the first location after - the end of the table (objfile->sections_end). */ +/* Build up the section table that the objfile references. The + objfile contains pointers to the start of the table + (objfile->sections) and to the first location after the end of the + table (objfile->sections_end). */ static void -add_to_objfile_sections_full (struct bfd *abfd, struct bfd_section *asect, +add_to_objfile_sections (struct bfd *abfd, struct bfd_section *asect, struct objfile *objfile, int force) { struct obj_section *section; @@ -311,7 +260,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; } @@ -322,13 +271,6 @@ add_to_objfile_sections_full (struct bfd *abfd, struct bfd_section *asect, section->ovly_mapped = 0; } -static void -add_to_objfile_sections (struct bfd *abfd, struct bfd_section *asect, - void *objfilep) -{ - add_to_objfile_sections_full (abfd, asect, (struct objfile *) objfilep, 0); -} - /* Builds a section table for OBJFILE. Note that the OFFSET and OVLY_MAPPED in each table entry are @@ -337,20 +279,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); - bfd_map_over_sections (objfile->obfd, - add_to_objfile_sections, (void *) objfile); + for (asection *sect : gdb_bfd_sections (objfile->obfd)) + add_to_objfile_sections (objfile->obfd.get (), sect, objfile, 0); /* See gdb_bfd_section_index. */ - add_to_objfile_sections_full (objfile->obfd, bfd_com_section_ptr, objfile, 1); - add_to_objfile_sections_full (objfile->obfd, bfd_und_section_ptr, objfile, 1); - add_to_objfile_sections_full (objfile->obfd, bfd_abs_section_ptr, objfile, 1); - add_to_objfile_sections_full (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, @@ -366,24 +312,17 @@ 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), - psymbol_cache (psymbol_bcache_init ()) + obfd (std::move (bfd_)) { const char *expanded_name; - /* We could use obstack_specify_allocation here instead, but - gdb_obstack.h specifies the alloc/dealloc functions. */ - obstack_init (&objfile_obstack); - - objfile_alloc_data (this); - - gdb::unique_xmalloc_ptr name_holder; + std::string name_holder; if (name == NULL) { - gdb_assert (abfd == NULL); + gdb_assert (obfd == nullptr); gdb_assert ((flags & OBJF_NOT_FILENAME) != 0); expanded_name = "<>"; } @@ -393,54 +332,23 @@ objfile::objfile (bfd *abfd, const char *name, objfile_flags flags_) else { name_holder = gdb_abspath (name); - expanded_name = name_holder.get (); + expanded_name = name_holder.c_str (); } - 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 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 (this, abfd); - - terminate_minimal_symbol_table (this); - - /* Add this file onto the tail of the linked list of other such files. */ - - if (object_files == NULL) - object_files = this; - else - { - struct objfile *last_one; - - for (last_one = object_files; - last_one->next; - last_one = last_one->next); - last_one->next = this; - } - - /* Rebuild section map next time we need it. */ - get_objfile_pspace_data (pspace)->new_objfiles_available = 1; -} - -/* Retrieve the gdbarch associated with OBJFILE. */ - -struct gdbarch * -get_objfile_arch (const struct objfile *objfile) -{ - return objfile->per_bfd->gdbarch; + set_objfile_per_bfd (this); } /* If there is a valid and known entry point, function fills *ENTRY_P with it @@ -449,12 +357,12 @@ get_objfile_arch (const struct objfile *objfile) int entry_point_address_query (CORE_ADDR *entry_p) { - if (symfile_objfile == NULL || !symfile_objfile->per_bfd->ei.entry_point_p) + objfile *objf = current_program_space->symfile_object_file; + if (objf == NULL || !objf->per_bfd->ei.entry_point_p) return 0; - *entry_p = (symfile_objfile->per_bfd->ei.entry_point - + ANOFFSET (symfile_objfile->section_offsets, - symfile_objfile->per_bfd->ei.the_bfd_section_index)); + int idx = objf->per_bfd->ei.the_bfd_section_index; + *entry_p = objf->per_bfd->ei.entry_point + objf->section_offsets[idx]; return 1; } @@ -472,105 +380,55 @@ entry_point_address (void) return retval; } -/* Iterator on PARENT and every separate debug objfile of PARENT. - The usage pattern is: - for (objfile = parent; - objfile; - objfile = objfile_separate_debug_iterate (parent, objfile)) - ... -*/ - -struct objfile * -objfile_separate_debug_iterate (const struct objfile *parent, - const struct objfile *objfile) +separate_debug_iterator & +separate_debug_iterator::operator++ () { + gdb_assert (m_objfile != nullptr); + struct objfile *res; /* If any, return the first child. */ - res = objfile->separate_debug_objfile; - if (res) - return res; + res = m_objfile->separate_debug_objfile; + if (res != nullptr) + { + m_objfile = res; + return *this; + } /* Common case where there is no separate debug objfile. */ - if (objfile == parent) - return NULL; - - /* Return the brother if any. Note that we don't iterate on brothers of - the parents. */ - res = objfile->separate_debug_objfile_link; - if (res) - return res; - - for (res = objfile->separate_debug_objfile_backlink; - res != parent; - res = res->separate_debug_objfile_backlink) + if (m_objfile == m_parent) { - gdb_assert (res != NULL); - if (res->separate_debug_objfile_link) - return res->separate_debug_objfile_link; + m_objfile = nullptr; + return *this; } - return NULL; -} -/* 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 ALL_OBJFILES_SAFE to free all objfiles. */ -void -put_objfile_before (struct objfile *objfile, struct objfile *before_this) -{ - struct objfile **objp; - - unlink_objfile (objfile); - - for (objp = &object_files; *objp != NULL; objp = &((*objp)->next)) + /* Return the brother if any. Note that we don't iterate on brothers of + the parents. */ + res = m_objfile->separate_debug_objfile_link; + if (res != nullptr) { - if (*objp == before_this) - { - objfile->next = *objp; - *objp = objfile; - return; - } + m_objfile = res; + return *this; } - - internal_error (__FILE__, __LINE__, - _("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)) + for (res = m_objfile->separate_debug_objfile_backlink; + res != m_parent; + res = res->separate_debug_objfile_backlink) { - if (*objpp == objfile) + gdb_assert (res != nullptr); + if (res->separate_debug_objfile_link != nullptr) { - *objpp = (*objpp)->next; - objfile->next = NULL; - return; + m_objfile = res->separate_debug_objfile_link; + return *this; } } - - internal_error (__FILE__, __LINE__, - _("unlink_objfile: objfile already unlinked")); + m_objfile = nullptr; + return *this; } /* 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); @@ -585,10 +443,33 @@ add_separate_debug_objfile (struct objfile *objfile, struct objfile *parent) objfile->separate_debug_objfile_backlink = parent; objfile->separate_debug_objfile_link = parent->separate_debug_objfile; parent->separate_debug_objfile = objfile; +} + +/* See objfiles.h. */ + +objfile * +objfile::make (gdb_bfd_ref_ptr bfd_, const char *name_, objfile_flags flags_, + objfile *parent) +{ + objfile *result = new objfile (std::move (bfd_), name_, flags_); + if (parent != nullptr) + add_separate_debug_objfile (result, parent); + + current_program_space->add_objfile (std::unique_ptr (result), + parent); + + /* Rebuild section map next time we need it. */ + get_objfile_pspace_data (current_program_space)->new_objfiles_available = 1; + + return result; +} + +/* See objfiles.h. */ - /* Put the separate debug object before the normal one, this is so that - usage of the ALL_OBJFILES_SAFE macro will stay safe. */ - put_objfile_before (objfile, parent); +void +objfile::unlink () +{ + current_program_space->remove_objfile (this); } /* Free all separate debug objfile of OBJFILE, but don't free OBJFILE @@ -602,7 +483,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; } } @@ -626,26 +507,26 @@ objfile::~objfile () child = separate_debug_objfile_backlink->separate_debug_objfile; if (child == this) - { - /* THIS is the first child. */ - separate_debug_objfile_backlink->separate_debug_objfile = - separate_debug_objfile_link; - } + { + /* THIS is the first child. */ + separate_debug_objfile_backlink->separate_debug_objfile = + separate_debug_objfile_link; + } else - { - /* Find THIS in the list. */ - while (1) - { - if (child->separate_debug_objfile_link == this) - { - child->separate_debug_objfile_link = - separate_debug_objfile_link; - break; - } - child = child->separate_debug_objfile_link; - gdb_assert (child); - } - } + { + /* Find THIS in the list. */ + while (1) + { + if (child->separate_debug_objfile_link == this) + { + child->separate_debug_objfile_link = + separate_debug_objfile_link; + break; + } + child = child->separate_debug_objfile_link; + gdb_assert (child); + } + } } /* Remove any references to this objfile in the global value @@ -669,22 +550,6 @@ objfile::~objfile () if (sf != NULL) (*sf->sym_finish) (this); - /* Discard any data modules have associated with the objfile. The function - still may reference obfd. */ - objfile_free_data (this); - - if (obfd) - gdb_bfd_unref (obfd); - else - free_objfile_per_bfd_storage (per_bfd); - - /* Remove it from the chain of all objfiles. */ - - unlink_objfile (this); - - if (this == symfile_objfile) - symfile_objfile = NULL; - /* Before the symbol table code was redone to make it easier to selectively load and remove information particular to a specific linkage unit, gdb used to do these things whenever the monolithic @@ -696,60 +561,27 @@ objfile::~objfile () for example), so we need to call this here. */ clear_pc_function_cache (); - /* Clear globals which might have pointed into a removed objfile. - FIXME: It's not clear which of these are supposed to persist - between expressions and which ought to be reset each time. */ - expression_context_block = NULL; - innermost_block.reset (); - /* Check to see if the current_source_symtab belongs to this objfile, and if so, call clear_current_source_symtab_and_line. */ { struct symtab_and_line cursal = get_current_source_symtab_and_line (); - if (cursal.symtab && SYMTAB_OBJFILE (cursal.symtab) == this) + if (cursal.symtab && cursal.symtab->compunit ()->objfile () == this) clear_current_source_symtab_and_line (); } - /* Free the obstacks for non-reusable objfiles. */ - psymbol_bcache_free (psymbol_cache); - obstack_free (&objfile_obstack, 0); - /* Rebuild section map next time we need it. */ get_objfile_pspace_data (pspace)->section_map_dirty = 1; - - /* Free the map for static links. There's no need to free static link - themselves since they were allocated on the objstack. */ - if (static_links != NULL) - htab_delete (static_links); } -/* Free all the object files at once and clean up their users. */ - -void -free_all_objfiles (void) -{ - struct objfile *objfile, *temp; - struct so_list *so; - - /* Any objfile referencewould become stale. */ - for (so = master_so_list (); so; so = so->next) - gdb_assert (so->objfile == NULL); - - ALL_OBJFILES_SAFE (objfile, temp) - { - delete objfile; - } - clear_symtab_users (0); -} /* A helper function for objfile_relocate1 that relocates a single symbol. */ static void relocate_one_symbol (struct symbol *sym, struct objfile *objfile, - struct section_offsets *delta) + const section_offsets &delta) { fixup_symbol_section (sym, objfile); @@ -757,12 +589,11 @@ relocate_one_symbol (struct symbol *sym, struct objfile *objfile, any symbols in STRUCT_DOMAIN or UNDEF_DOMAIN. But I'm leaving out that test, on the theory that they can't possibly pass the tests below. */ - if ((SYMBOL_CLASS (sym) == LOC_LABEL - || SYMBOL_CLASS (sym) == LOC_STATIC) - && SYMBOL_SECTION (sym) >= 0) - { - SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (delta, SYMBOL_SECTION (sym)); - } + if ((sym->aclass () == LOC_LABEL + || sym->aclass () == LOC_STATIC) + && sym->section_index () >= 0) + sym->set_value_address (sym->value_address () + + delta[sym->section_index ()]); } /* Relocate OBJFILE to NEW_OFFSETS. There should be OBJFILE->NUM_SECTIONS @@ -771,19 +602,16 @@ relocate_one_symbol (struct symbol *sym, struct objfile *objfile, static int objfile_relocate1 (struct objfile *objfile, - const struct section_offsets *new_offsets) + const section_offsets &new_offsets) { - struct section_offsets *delta = - ((struct section_offsets *) - alloca (SIZEOF_N_SECTION_OFFSETS (objfile->num_sections))); + section_offsets delta (objfile->section_offsets.size ()); int something_changed = 0; - for (int i = 0; i < objfile->num_sections; ++i) + for (int i = 0; i < objfile->section_offsets.size (); ++i) { - delta->offsets[i] = - ANOFFSET (new_offsets, i) - ANOFFSET (objfile->section_offsets, i); - if (ANOFFSET (delta, i) != 0) + delta[i] = new_offsets[i] - objfile->section_offsets[i]; + if (delta[i] != 0) something_changed = 1; } if (!something_changed) @@ -791,64 +619,57 @@ objfile_relocate1 (struct objfile *objfile, /* OK, get all the symtabs. */ { - struct compunit_symtab *cust; - struct symtab *s; - - ALL_OBJFILE_FILETABS (objfile, cust, s) - { - struct linetable *l; + for (compunit_symtab *cust : objfile->compunits ()) + { + for (symtab *s : cust->filetabs ()) + { + struct linetable *l; - /* First the line table. */ - l = SYMTAB_LINETABLE (s); - if (l) - { - for (int i = 0; i < l->nitems; ++i) - l->item[i].pc += ANOFFSET (delta, - COMPUNIT_BLOCK_LINE_SECTION - (cust)); - } - } + /* First the line table. */ + l = s->linetable (); + if (l) + { + for (int i = 0; i < l->nitems; ++i) + l->item[i].pc += delta[cust->block_line_section ()]; + } + } + } - ALL_OBJFILE_COMPUNITS (objfile, cust) - { - const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (cust); - int block_line_section = COMPUNIT_BLOCK_LINE_SECTION (cust); + for (compunit_symtab *cust : objfile->compunits ()) + { + struct blockvector *bv = cust->blockvector (); + int block_line_section = cust->block_line_section (); - if (BLOCKVECTOR_MAP (bv)) - addrmap_relocate (BLOCKVECTOR_MAP (bv), - ANOFFSET (delta, block_line_section)); + if (bv->map () != nullptr) + bv->map ()->relocate (delta[block_line_section]); - for (int i = 0; i < BLOCKVECTOR_NBLOCKS (bv); ++i) - { - struct block *b; - struct symbol *sym; - struct dict_iterator iter; + for (block *b : bv->blocks ()) + { + struct symbol *sym; + struct mdict_iterator miter; - b = BLOCKVECTOR_BLOCK (bv, i); - BLOCK_START (b) += ANOFFSET (delta, block_line_section); - BLOCK_END (b) += ANOFFSET (delta, block_line_section); + b->set_start (b->start () + delta[block_line_section]); + b->set_end (b->end () + delta[block_line_section]); - if (BLOCK_RANGES (b) != nullptr) - for (int j = 0; j < BLOCK_NRANGES (b); j++) + for (blockrange &r : b->ranges ()) { - BLOCK_RANGE_START (b, j) - += ANOFFSET (delta, block_line_section); - BLOCK_RANGE_END (b, j) += ANOFFSET (delta, block_line_section); + r.set_start (r.start () + delta[block_line_section]); + r.set_end (r.end () + delta[block_line_section]); } - /* We only want to iterate over the local symbols, not any - symbols in included symtabs. */ - ALL_DICT_SYMBOLS (BLOCK_DICT (b), iter, sym) - { - relocate_one_symbol (sym, objfile, delta); - } - } - } + /* We only want to iterate over the local symbols, not any + symbols in included symtabs. */ + ALL_DICT_SYMBOLS (b->multidict (), miter, sym) + { + relocate_one_symbol (sym, objfile, delta); + } + } + } } - /* This stores relocated addresses and so must be cleared. This - will cause it to be recreated on demand. */ - objfile->psymbol_map.clear (); + /* Notify the quick symbol object. */ + for (const auto &iter : objfile->qf) + iter->relocated (); /* Relocate isolated symbols. */ { @@ -861,8 +682,8 @@ objfile_relocate1 (struct objfile *objfile, { int i; - for (i = 0; i < objfile->num_sections; ++i) - (objfile->section_offsets)->offsets[i] = ANOFFSET (new_offsets, i); + for (i = 0; i < objfile->section_offsets.size (); ++i) + objfile->section_offsets[i] = new_offsets[i]; } /* Rebuild section map next time we need it. */ @@ -874,8 +695,8 @@ objfile_relocate1 (struct objfile *objfile, { int idx = s - objfile->sections; - exec_set_section_address (bfd_get_filename (objfile->obfd), idx, - obj_section_addr (s)); + exec_set_section_address (bfd_get_filename (objfile->obfd.get ()), idx, + s->addr ()); } /* Data changed. */ @@ -893,34 +714,32 @@ objfile_relocate1 (struct objfile *objfile, void objfile_relocate (struct objfile *objfile, - const struct section_offsets *new_offsets) + const section_offsets &new_offsets) { - struct objfile *debug_objfile; int changed = 0; changed |= objfile_relocate1 (objfile, new_offsets); - for (debug_objfile = objfile->separate_debug_objfile; - debug_objfile; - debug_objfile = objfile_separate_debug_iterate (objfile, debug_objfile)) + for (::objfile *debug_objfile : objfile->separate_debug_objfiles ()) { + if (debug_objfile == objfile) + continue; + section_addr_info objfile_addrs = build_section_addr_info_from_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->num_sections - == gdb_bfd_count_sections (debug_objfile->obfd)); - std::vector - new_debug_offsets (SIZEOF_N_SECTION_OFFSETS (debug_objfile->num_sections)); - relative_addr_info_to_section_offsets (new_debug_offsets.data (), - debug_objfile->num_sections, - objfile_addrs); + gdb_assert (debug_objfile->section_offsets.size () + == 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); - changed |= objfile_relocate1 (debug_objfile, new_debug_offsets.data ()); + changed |= objfile_relocate1 (debug_objfile, new_debug_offsets); } /* Relocate breakpoints as necessary, after things are relocated. */ @@ -935,14 +754,7 @@ objfile_relocate (struct objfile *objfile, static int objfile_rebase1 (struct objfile *objfile, CORE_ADDR slide) { - struct section_offsets *new_offsets = - ((struct section_offsets *) - alloca (SIZEOF_N_SECTION_OFFSETS (objfile->num_sections))); - int i; - - for (i = 0; i < objfile->num_sections; ++i) - new_offsets->offsets[i] = slide; - + section_offsets new_offsets (objfile->section_offsets.size (), slide); return objfile_relocate1 (objfile, new_offsets); } @@ -952,14 +764,9 @@ objfile_rebase1 (struct objfile *objfile, CORE_ADDR slide) void objfile_rebase (struct objfile *objfile, CORE_ADDR slide) { - struct objfile *debug_objfile; int changed = 0; - changed |= objfile_rebase1 (objfile, slide); - - for (debug_objfile = objfile->separate_debug_objfile; - debug_objfile; - debug_objfile = objfile_separate_debug_iterate (objfile, debug_objfile)) + for (::objfile *debug_objfile : objfile->separate_debug_objfiles ()) changed |= objfile_rebase1 (debug_objfile, slide); /* Relocate breakpoints as necessary, after things are relocated. */ @@ -967,25 +774,6 @@ objfile_rebase (struct objfile *objfile, CORE_ADDR slide) breakpoint_re_set (); } -/* Return non-zero if OBJFILE has partial symbols. */ - -int -objfile_has_partial_symbols (struct objfile *objfile) -{ - if (!objfile->sf) - return 0; - - /* If we have not read psymbols, but we have a function capable of reading - them, then that is an indication that they are in fact available. Without - this function the symbols may have been already read in but they also may - not be present in this objfile. */ - if ((objfile->flags & OBJF_PSYMTABS_READ) == 0 - && objfile->sf->sym_read_psymbols != NULL) - return 1; - - return objfile->sf->qf->has_symbols (objfile); -} - /* Return non-zero if OBJFILE has full symbols. */ int @@ -1000,10 +788,8 @@ objfile_has_full_symbols (struct objfile *objfile) int objfile_has_symbols (struct objfile *objfile) { - struct objfile *o; - - for (o = objfile; o; o = objfile_separate_debug_iterate (objfile, o)) - if (objfile_has_partial_symbols (o) || objfile_has_full_symbols (o)) + for (::objfile *o : objfile->separate_debug_objfiles ()) + if (o->has_partial_symbols () || objfile_has_full_symbols (o)) return 1; return 0; } @@ -1016,13 +802,11 @@ objfile_has_symbols (struct objfile *objfile) int have_partial_symbols (void) { - struct objfile *ofp; - - ALL_OBJFILES (ofp) - { - if (objfile_has_partial_symbols (ofp)) - return 1; - } + for (objfile *ofp : current_program_space->objfiles ()) + { + if (ofp->has_partial_symbols ()) + return 1; + } return 0; } @@ -1033,13 +817,11 @@ have_partial_symbols (void) int have_full_symbols (void) { - struct objfile *ofp; - - ALL_OBJFILES (ofp) - { - if (objfile_has_full_symbols (ofp)) - return 1; - } + for (objfile *ofp : current_program_space->objfiles ()) + { + if (objfile_has_full_symbols (ofp)) + return 1; + } return 0; } @@ -1051,17 +833,14 @@ have_full_symbols (void) void objfile_purge_solibs (void) { - struct objfile *objf; - struct objfile *temp; - - ALL_OBJFILES_SAFE (objf, temp) - { - /* We assume that the solib package has been purged already, or will - be soon. */ + for (objfile *objf : current_program_space->objfiles_safe ()) + { + /* We assume that the solib package has been purged already, or will + be soon. */ - if (!(objf->flags & OBJF_USERLOADED) && (objf->flags & OBJF_SHARED)) - delete objf; - } + if (!(objf->flags & OBJF_USERLOADED) && (objf->flags & OBJF_SHARED)) + objf->unlink (); + } } @@ -1072,32 +851,28 @@ objfile_purge_solibs (void) int have_minimal_symbols (void) { - struct objfile *ofp; - - ALL_OBJFILES (ofp) - { - if (ofp->per_bfd->minimal_symbol_count > 0) - { - return 1; - } - } + for (objfile *ofp : current_program_space->objfiles ()) + { + if (ofp->per_bfd->minimal_symbol_count > 0) + { + return 1; + } + } return 0; } /* 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); + const CORE_ADDR sect1_addr = sect1->addr (); + const CORE_ADDR sect2_addr = sect2->addr (); 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 @@ -1114,29 +889,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"); @@ -1145,13 +924,11 @@ qsort_cmp (const void *a, const void *b) { /* Sort on sequence number of the objfile in the chain. */ - const struct objfile *objfile; - - ALL_OBJFILES (objfile) + 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"); @@ -1160,7 +937,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 @@ -1172,7 +949,7 @@ qsort_cmp (const void *a, const void *b) static struct obj_section * preferred_obj_section (struct obj_section *a, struct obj_section *b) { - gdb_assert (obj_section_addr (a) == obj_section_addr (b)); + gdb_assert (a->addr () == b->addr ()); gdb_assert ((a->objfile->separate_debug_objfile == b->objfile) || (b->objfile->separate_debug_objfile == a->objfile)); gdb_assert ((a->objfile->separate_debug_objfile_backlink == b->objfile) @@ -1184,23 +961,29 @@ preferred_obj_section (struct obj_section *a, struct obj_section *b) } /* Return 1 if SECTION should be inserted into the section map. - We want to insert only non-overlay and non-TLS section. */ + We want to insert only non-overlay non-TLS non-empty sections. */ 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; + if (bfd_section_size (section) == 0) + { + /* This is an empty section. It has no PCs for find_pc_section (), so + there is no reason to insert it into the section map. */ + return 0; + } return 1; } @@ -1220,8 +1003,8 @@ filter_debuginfo_sections (struct obj_section **map, int map_size) struct obj_section *const sect2 = map[i + 1]; const struct objfile *const objfile1 = sect1->objfile; const struct objfile *const objfile2 = sect2->objfile; - const CORE_ADDR sect1_addr = obj_section_addr (sect1); - const CORE_ADDR sect2_addr = obj_section_addr (sect2); + const CORE_ADDR sect1_addr = sect1->addr (); + const CORE_ADDR sect2_addr = sect2->addr (); if (sect1_addr == sect2_addr && (objfile1->separate_debug_objfile == objfile2 @@ -1265,9 +1048,9 @@ filter_overlapping_sections (struct obj_section **map, int map_size) { struct obj_section *const sect1 = map[i]; struct obj_section *const sect2 = map[k]; - const CORE_ADDR sect1_addr = obj_section_addr (sect1); - const CORE_ADDR sect2_addr = obj_section_addr (sect2); - const CORE_ADDR sect1_endaddr = obj_section_endaddr (sect1); + const CORE_ADDR sect1_addr = sect1->addr (); + const CORE_ADDR sect2_addr = sect2->addr (); + const CORE_ADDR sect1_endaddr = sect1->endaddr (); gdb_assert (sect1_addr <= sect2_addr); @@ -1283,18 +1066,18 @@ filter_overlapping_sections (struct obj_section **map, int map_size) const struct bfd_section *const bfds1 = sect1->the_bfd_section; const struct bfd_section *const bfds2 = sect2->the_bfd_section; - const CORE_ADDR sect2_endaddr = obj_section_endaddr (sect2); + const CORE_ADDR sect2_endaddr = sect2->endaddr (); - struct gdbarch *const gdbarch = get_objfile_arch (objf1); + struct gdbarch *const gdbarch = objf1->arch (); complaint (_("unexpected overlap between:\n" " (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)); } @@ -1331,9 +1114,9 @@ update_section_map (struct program_space *pspace, xfree (map); alloc_size = 0; - for (objfile *objfile : all_objfiles (pspace)) + 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). */ @@ -1347,12 +1130,12 @@ update_section_map (struct program_space *pspace, map = XNEWVEC (struct obj_section *, alloc_size); i = 0; - for (objfile *objfile : all_objfiles (pspace)) + 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; - 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); @@ -1374,9 +1157,9 @@ bsearch_cmp (const void *key, const void *elt) const CORE_ADDR pc = *(CORE_ADDR *) key; const struct obj_section *section = *(const struct obj_section **) elt; - if (pc < obj_section_addr (section)) + if (pc < section->addr ()) return -1; - if (pc < obj_section_endaddr (section)) + if (pc < section->endaddr ()) return 0; return 1; } @@ -1404,7 +1187,7 @@ find_pc_section (CORE_ADDR pc) &pspace_info->num_sections); /* Don't need updates to section map until objfiles are added, - removed or relocated. */ + removed or relocated. */ pspace_info->new_objfiles_available = 0; pspace_info->section_map_dirty = 0; } @@ -1464,66 +1247,59 @@ inhibit_section_map_updates (struct program_space *pspace) (&get_objfile_pspace_data (pspace)->inhibit_updates, 1); } -/* Return 1 if ADDR maps into one of the sections of OBJFILE and 0 - otherwise. */ +/* See objfiles.h. */ -int +bool is_addr_in_objfile (CORE_ADDR addr, const struct objfile *objfile) { struct obj_section *osect; if (objfile == NULL) - return 0; + return false; ALL_OBJFILE_OSECTIONS (objfile, osect) { if (section_is_overlay (osect) && !section_is_mapped (osect)) continue; - if (obj_section_addr (osect) <= addr - && addr < obj_section_endaddr (osect)) - return 1; + if (osect->addr () <= addr && addr < osect->endaddr ()) + return true; } - return 0; + return false; } -int +/* See objfiles.h. */ + +bool shared_objfile_contains_address_p (struct program_space *pspace, CORE_ADDR address) { - for (objfile *objfile : all_objfiles (pspace)) + for (objfile *objfile : pspace->objfiles ()) { if ((objfile->flags & OBJF_SHARED) != 0 && is_addr_in_objfile (address, objfile)) - return 1; + return true; } - return 0; + return false; } /* The default implementation for the "iterate_over_objfiles_in_search_order" - gdbarch method. It is equivalent to use the ALL_OBJFILES macro, + gdbarch method. It is equivalent to use the objfiles iterable, 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 default_iterate_over_objfiles_in_search_order - (struct gdbarch *gdbarch, - iterate_over_objfiles_in_search_order_cb_ftype *cb, - void *cb_data, struct objfile *current_objfile) + (gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype cb, + objfile *current_objfile) { - int stop = 0; - struct objfile *objfile; - - ALL_OBJFILES (objfile) - { - stop = cb (objfile, cb_data); - if (stop) - return; - } + for (objfile *objfile : current_program_space->objfiles ()) + if (cb (objfile)) + return; } /* See objfiles.h. */ @@ -1532,7 +1308,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; } @@ -1543,7 +1319,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; } @@ -1562,17 +1338,32 @@ 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; } -void -_initialize_objfiles (void) +/* See objfiles.h. */ + +struct type * +objfile_int_type (struct objfile *of, int size_in_bytes, bool unsigned_p) { - objfiles_pspace_data - = register_program_space_data_with_cleanup (NULL, - objfiles_pspace_data_cleanup); + struct type *int_type; + + /* Helper macro to examine the various builtin types. */ +#define TRY_TYPE(F) \ + int_type = (unsigned_p \ + ? objfile_type (of)->builtin_unsigned_ ## F \ + : objfile_type (of)->builtin_ ## F); \ + if (int_type != NULL && TYPE_LENGTH (int_type) == size_in_bytes) \ + return int_type + + TRY_TYPE (char); + TRY_TYPE (short); + TRY_TYPE (int); + TRY_TYPE (long); + TRY_TYPE (long_long); + +#undef TRY_TYPE - objfiles_bfd_data = register_bfd_data_with_cleanup (NULL, - objfile_bfd_data_free); + gdb_assert_not_reached ("unable to find suitable integer type"); }