/* GDB routines for manipulating objfiles.
- Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ Copyright (C) 1992-2019 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
#include "addrmap.h"
#include "arch-utils.h"
#include "exec.h"
-#include "observer.h"
+#include "observable.h"
#include "complaints.h"
#include "psymtab.h"
#include "solist.h"
#include "gdb_bfd.h"
#include "btrace.h"
+#include "common/pathstuff.h"
#include <vector>
static const struct bfd_data *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. */
+ Otherwise, allocate a new per-BFD storage object. 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)
if (storage == NULL)
{
+ storage = new objfile_per_bfd_storage;
/* 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)));
- set_bfd_data (abfd, objfiles_bfd_data, storage);
- }
- else
- {
- storage = (objfile_per_bfd_storage *)
- obstack_alloc (&objfile->objfile_obstack,
- sizeof (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);
/* 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
+/* 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)
{
- free_objfile_per_bfd_storage ((struct objfile_per_bfd_storage *) d);
+ delete (struct objfile_per_bfd_storage *) d;
}
/* See objfiles.h. */
slot = htab_find_slot (objfile->static_links, &lookup_entry, INSERT);
gdb_assert (*slot == NULL);
- entry = (struct static_link_htab_entry *) obstack_alloc
- (&objfile->objfile_obstack, sizeof (*entry));
+ entry = XOBNEW (&objfile->objfile_obstack, static_link_htab_entry);
entry->block = block;
entry->static_link = static_link;
*slot = (void *) entry;
objfile::objfile (bfd *abfd, const char *name, objfile_flags flags_)
: flags (flags_),
pspace (current_program_space),
- obfd (abfd),
- psymbol_cache (psymbol_bcache_init ())
+ partial_symtabs (new psymtab_storage ()),
+ obfd (abfd)
{
const char *expanded_name;
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)
/* 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. */
+ another when using objfiles_safe to free all objfiles. */
void
put_objfile_before (struct objfile *objfile, struct objfile *before_this)
{
parent->separate_debug_objfile = objfile;
/* Put the separate debug object before the normal one, this is so that
- usage of the ALL_OBJFILES_SAFE macro will stay safe. */
+ usage of objfiles_safe will stay safe. */
put_objfile_before (objfile, parent);
}
objfile::~objfile ()
{
/* First notify observers that this objfile is about to be freed. */
- observer_notify_free_objfile (this);
+ gdb::observers::free_objfile.notify (this);
/* Free all separate debug objfiles. */
free_objfile_separate_debug (this);
if (obfd)
gdb_bfd_unref (obfd);
else
- free_objfile_per_bfd_storage (per_bfd);
+ delete per_bfd;
/* Remove it from the chain of all objfiles. */
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 = NULL;
-
/* Check to see if the current_source_symtab belongs to this objfile,
and if so, call 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. */
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)
- {
+ for (objfile *objfile : current_program_space->objfiles_safe ())
delete objfile;
- }
clear_symtab_users (0);
}
\f
objfile_relocate1 (struct objfile *objfile,
const struct section_offsets *new_offsets)
{
- struct obj_section *s;
struct section_offsets *delta =
((struct section_offsets *)
alloca (SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)));
- int i;
int something_changed = 0;
- for (i = 0; i < objfile->num_sections; ++i)
+ for (int i = 0; i < objfile->num_sections; ++i)
{
delta->offsets[i] =
ANOFFSET (new_offsets, i) - ANOFFSET (objfile->section_offsets, i);
/* OK, get all the symtabs. */
{
- struct compunit_symtab *cust;
- struct symtab *s;
-
- ALL_OBJFILE_FILETABS (objfile, cust, s)
- {
- struct linetable *l;
- int i;
-
- /* First the line table. */
- l = SYMTAB_LINETABLE (s);
- if (l)
- {
- for (i = 0; i < l->nitems; ++i)
- l->item[i].pc += ANOFFSET (delta,
- COMPUNIT_BLOCK_LINE_SECTION
- (cust));
- }
- }
-
- ALL_OBJFILE_COMPUNITS (objfile, cust)
- {
- const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (cust);
- int block_line_section = COMPUNIT_BLOCK_LINE_SECTION (cust);
-
- if (BLOCKVECTOR_MAP (bv))
- addrmap_relocate (BLOCKVECTOR_MAP (bv),
- ANOFFSET (delta, block_line_section));
-
- for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); ++i)
- {
- struct block *b;
- struct symbol *sym;
- struct dict_iterator iter;
-
- b = BLOCKVECTOR_BLOCK (bv, i);
- BLOCK_START (b) += ANOFFSET (delta, block_line_section);
- BLOCK_END (b) += ANOFFSET (delta, block_line_section);
+ for (compunit_symtab *cust : objfile->compunits ())
+ {
+ for (symtab *s : compunit_filetabs (cust))
+ {
+ 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));
+ }
+ }
+ }
- /* 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);
- }
- }
- }
+ for (compunit_symtab *cust : objfile->compunits ())
+ {
+ const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (cust);
+ int block_line_section = COMPUNIT_BLOCK_LINE_SECTION (cust);
+
+ if (BLOCKVECTOR_MAP (bv))
+ addrmap_relocate (BLOCKVECTOR_MAP (bv),
+ ANOFFSET (delta, block_line_section));
+
+ for (int i = 0; i < BLOCKVECTOR_NBLOCKS (bv); ++i)
+ {
+ struct block *b;
+ 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);
+
+ if (BLOCK_RANGES (b) != nullptr)
+ for (int j = 0; j < BLOCK_NRANGES (b); j++)
+ {
+ BLOCK_RANGE_START (b, j)
+ += ANOFFSET (delta, block_line_section);
+ BLOCK_RANGE_END (b, j) += ANOFFSET (delta,
+ block_line_section);
+ }
+
+ /* We only want to iterate over the local symbols, not any
+ symbols in included symtabs. */
+ ALL_DICT_SYMBOLS (BLOCK_MULTIDICT (b), 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 ();
+
/* Relocate isolated symbols. */
{
struct symbol *iter;
relocate_one_symbol (iter, objfile, delta);
}
- if (objfile->psymtabs_addrmap)
- addrmap_relocate (objfile->psymtabs_addrmap,
- ANOFFSET (delta, SECT_OFF_TEXT (objfile)));
-
- if (objfile->sf)
- objfile->sf->qf->relocate (objfile, new_offsets, delta);
-
{
int i;
get_objfile_pspace_data (objfile->pspace)->section_map_dirty = 1;
/* Update the table in exec_ops, used to read memory. */
+ struct obj_section *s;
ALL_OBJFILE_OSECTIONS (objfile, s)
{
int idx = s - objfile->sections;
debug_objfile;
debug_objfile = objfile_separate_debug_iterate (objfile, debug_objfile))
{
- struct section_addr_info *objfile_addrs;
- struct cleanup *my_cleanups;
-
- objfile_addrs = build_section_addr_info_from_objfile (objfile);
- my_cleanups = make_cleanup (xfree, objfile_addrs);
+ 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);
gdb_assert (debug_objfile->num_sections
== gdb_bfd_count_sections (debug_objfile->obfd));
objfile_addrs);
changed |= objfile_relocate1 (debug_objfile, new_debug_offsets.data ());
-
- do_cleanups (my_cleanups);
}
/* Relocate breakpoints as necessary, after things are relocated. */
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 (objfile_has_partial_symbols (ofp))
+ return 1;
+ }
return 0;
}
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;
}
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))
+ delete objf;
+ }
}
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;
}
{
/* 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;
else if (objfile == objfile2)
struct gdbarch *const gdbarch = get_objfile_arch (objf1);
- complaint (&symfile_complaints,
- _("unexpected overlap between:\n"
+ 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"),
struct objfile_pspace_info *pspace_info;
int alloc_size, map_size, i;
struct obj_section *s, **map;
- struct objfile *objfile;
pspace_info = get_objfile_pspace_data (pspace);
gdb_assert (pspace_info->section_map_dirty != 0
xfree (map);
alloc_size = 0;
- ALL_PSPACE_OBJFILES (pspace, objfile)
+ for (objfile *objfile : pspace->objfiles ())
ALL_OBJFILE_OSECTIONS (objfile, s)
if (insert_section_p (objfile->obfd, s->the_bfd_section))
alloc_size += 1;
map = XNEWVEC (struct obj_section *, alloc_size);
i = 0;
- ALL_PSPACE_OBJFILES (pspace, objfile)
+ for (objfile *objfile : pspace->objfiles ())
ALL_OBJFILE_OSECTIONS (objfile, s)
if (insert_section_p (objfile->obfd, s->the_bfd_section))
map[i++] = s;
/* See comments in objfiles.h. */
-void
+scoped_restore_tmpl<int>
inhibit_section_map_updates (struct program_space *pspace)
{
- get_objfile_pspace_data (pspace)->inhibit_updates = 1;
-}
-
-/* See comments in objfiles.h. */
-
-void
-resume_section_map_updates (struct program_space *pspace)
-{
- get_objfile_pspace_data (pspace)->inhibit_updates = 0;
-}
-
-/* See comments in objfiles.h. */
-
-void
-resume_section_map_updates_cleanup (void *arg)
-{
- resume_section_map_updates ((struct program_space *) arg);
+ return scoped_restore_tmpl<int>
+ (&get_objfile_pspace_data (pspace)->inhibit_updates, 1);
}
/* Return 1 if ADDR maps into one of the sections of OBJFILE and 0
shared_objfile_contains_address_p (struct program_space *pspace,
CORE_ADDR address)
{
- struct objfile *objfile;
-
- ALL_PSPACE_OBJFILES (pspace, objfile)
+ for (objfile *objfile : pspace->objfiles ())
{
if ((objfile->flags & OBJF_SHARED) != 0
&& is_addr_in_objfile (address, objfile))
}
/* 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.
void *cb_data, struct objfile *current_objfile)
{
int stop = 0;
- struct objfile *objfile;
- ALL_OBJFILES (objfile)
+ for (objfile *objfile : current_program_space->objfiles ())
{
stop = cb (objfile, cb_data);
if (stop)