/* GDB routines for manipulating objfiles.
- Copyright (C) 1992-2014 Free Software Foundation, Inc.
+ Copyright (C) 1992-2017 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
#include "expression.h"
#include "parser-defs.h"
-#include "gdb_assert.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "gdb_obstack.h"
-#include <string.h>
#include "hashtab.h"
#include "breakpoint.h"
#include "gdb_bfd.h"
#include "btrace.h"
+#include <vector>
+
/* Keep a registry of per-objfile data-pointers required by other GDB
modules. */
static void
objfiles_pspace_data_cleanup (struct program_space *pspace, void *arg)
{
- struct objfile_pspace_info *info = arg;
+ struct objfile_pspace_info *info = (struct objfile_pspace_info *) arg;
xfree (info->sections);
xfree (info);
{
struct objfile_pspace_info *info;
- info = program_space_data (pspace, objfiles_pspace_data);
+ info = ((struct objfile_pspace_info *)
+ program_space_data (pspace, objfiles_pspace_data));
if (info == NULL)
{
info = XCNEW (struct objfile_pspace_info);
struct objfile_per_bfd_storage *storage = NULL;
if (abfd != NULL)
- storage = bfd_data (abfd, objfiles_bfd_data);
+ storage = ((struct objfile_per_bfd_storage *)
+ bfd_data (abfd, objfiles_bfd_data));
if (storage == NULL)
{
enough that this seems reasonable. */
if (abfd != NULL && !gdb_bfd_requires_relocations (abfd))
{
- storage = bfd_zalloc (abfd, sizeof (struct objfile_per_bfd_storage));
+ storage
+ = ((struct objfile_per_bfd_storage *)
+ bfd_zalloc (abfd, sizeof (struct objfile_per_bfd_storage)));
set_bfd_data (abfd, objfiles_bfd_data, storage);
}
else
static void
objfile_bfd_data_free (struct bfd *unused, void *d)
{
- free_objfile_per_bfd_storage (d);
+ free_objfile_per_bfd_storage ((struct objfile_per_bfd_storage *) d);
}
/* See objfiles.h. */
if (objfile->per_bfd->name_of_main == NULL
|| strcmp (objfile->per_bfd->name_of_main, name) != 0)
objfile->per_bfd->name_of_main
- = obstack_copy0 (&objfile->per_bfd->storage_obstack, name, strlen (name));
+ = (const char *) obstack_copy0 (&objfile->per_bfd->storage_obstack, name,
+ strlen (name));
objfile->per_bfd->language_of_main = lang;
}
+/* Helper structure to map blocks to static link properties in hash tables. */
+
+struct static_link_htab_entry
+{
+ const struct block *block;
+ const struct dynamic_prop *static_link;
+};
+
+/* Return a hash code for struct static_link_htab_entry *P. */
+
+static hashval_t
+static_link_htab_entry_hash (const void *p)
+{
+ const struct static_link_htab_entry *e
+ = (const struct static_link_htab_entry *) p;
+
+ return htab_hash_pointer (e->block);
+}
+
+/* Return whether P1 an P2 (pointers to struct static_link_htab_entry) are
+ mappings for the same block. */
+
+static int
+static_link_htab_entry_eq (const void *p1, const void *p2)
+{
+ const struct static_link_htab_entry *e1
+ = (const struct static_link_htab_entry *) p1;
+ const struct static_link_htab_entry *e2
+ = (const struct static_link_htab_entry *) p2;
+
+ return e1->block == e2->block;
+}
+
+/* Register STATIC_LINK as the static link for BLOCK, which is part of OBJFILE.
+ Must not be called more than once for each BLOCK. */
+
+void
+objfile_register_static_link (struct objfile *objfile,
+ const struct block *block,
+ const struct dynamic_prop *static_link)
+{
+ void **slot;
+ struct static_link_htab_entry lookup_entry;
+ struct static_link_htab_entry *entry;
+
+ if (objfile->static_links == NULL)
+ objfile->static_links = htab_create_alloc
+ (1, &static_link_htab_entry_hash, static_link_htab_entry_eq, NULL,
+ 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);
+ gdb_assert (*slot == NULL);
+
+ entry = (struct static_link_htab_entry *) obstack_alloc
+ (&objfile->objfile_obstack, sizeof (*entry));
+ entry->block = block;
+ entry->static_link = static_link;
+ *slot = (void *) entry;
+}
+
+/* Look for a static link for BLOCK, which is part of OBJFILE. Return NULL if
+ none was found. */
+
+const struct dynamic_prop *
+objfile_lookup_static_link (struct objfile *objfile,
+ const struct block *block)
+{
+ struct static_link_htab_entry *entry;
+ struct static_link_htab_entry lookup_entry;
+
+ if (objfile->static_links == NULL)
+ return NULL;
+ lookup_entry.block = block;
+ entry
+ = (struct static_link_htab_entry *) htab_find (objfile->static_links,
+ &lookup_entry);
+ if (entry == NULL)
+ return NULL;
+
+ gdb_assert (entry->block == block);
+ return entry->static_link;
+}
+
\f
/* Called via bfd_map_over_sections to build up the section table that
add_to_objfile_sections (struct bfd *abfd, struct bfd_section *asect,
void *objfilep)
{
- add_to_objfile_sections_full (abfd, asect, objfilep, 0);
+ add_to_objfile_sections_full (abfd, asect, (struct objfile *) objfilep, 0);
}
/* Builds a section table for OBJFILE.
requests for specific operations. Other bits like OBJF_SHARED are
simply copied through to the new objfile flags member. */
-/* NOTE: carlton/2003-02-04: This function is called with args NULL, 0
- by jv-lang.c, to create an artificial objfile used to hold
- information about dynamically-loaded Java classes. Unfortunately,
- that branch of this function doesn't get tested very frequently, so
- it's prone to breakage. (E.g. at one time the name was set to NULL
- in that situation, which broke a loop over all names in the dynamic
- library loader.) If you change this function, please try to leave
- things in a consistent state even if abfd is NULL. */
-
struct objfile *
-allocate_objfile (bfd *abfd, const char *name, int flags)
+allocate_objfile (bfd *abfd, const char *name, objfile_flags flags)
{
struct objfile *objfile;
char *expanded_name;
- objfile = (struct objfile *) xzalloc (sizeof (struct objfile));
+ objfile = XCNEW (struct objfile);
objfile->psymbol_cache = psymbol_bcache_init ();
/* We could use obstack_specify_allocation here instead, but
gdb_obstack.h specifies the alloc/dealloc functions. */
obstack_init (&objfile->objfile_obstack);
- terminate_minimal_symbol_table (objfile);
objfile_alloc_data (objfile);
gdb_assert ((flags & OBJF_NOT_FILENAME) != 0);
expanded_name = xstrdup ("<<anonymous objfile>>");
}
- else if ((flags & OBJF_NOT_FILENAME) != 0)
+ else if ((flags & OBJF_NOT_FILENAME) != 0
+ || is_target_filename (name))
expanded_name = xstrdup (name);
else
expanded_name = gdb_abspath (name);
- objfile->original_name = obstack_copy0 (&objfile->objfile_obstack,
- expanded_name,
- strlen (expanded_name));
+ objfile->original_name
+ = (char *) obstack_copy0 (&objfile->objfile_obstack,
+ expanded_name,
+ strlen (expanded_name));
xfree (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. */
-
/* 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. */
objfile->per_bfd = get_objfile_bfd_data (objfile, abfd);
objfile->pspace = current_program_space;
+ terminate_minimal_symbol_table (objfile);
+
/* Initialize the section indexes for this objfile, so that we can
later detect if they are used w/o being properly assigned to. */
}
/* Retrieve the gdbarch associated with OBJFILE. */
+
struct gdbarch *
-get_objfile_arch (struct objfile *objfile)
+get_objfile_arch (const struct objfile *objfile)
{
return objfile->per_bfd->gdbarch;
}
{
struct symtab_and_line cursal = get_current_source_symtab_and_line ();
- if (cursal.symtab && cursal.symtab->objfile == objfile)
+ if (cursal.symtab && SYMTAB_OBJFILE (cursal.symtab) == objfile)
clear_current_source_symtab_and_line ();
}
/* Rebuild section map next time we need it. */
get_objfile_pspace_data (objfile->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 (objfile->static_links != NULL)
+ htab_delete (objfile->static_links);
+
/* The last thing we do is free the objfile struct itself. */
xfree (objfile);
}
static void
do_free_objfile_cleanup (void *obj)
{
- free_objfile (obj);
+ free_objfile ((struct objfile *) obj);
}
struct cleanup *
/* OK, get all the symtabs. */
{
+ struct compunit_symtab *cust;
struct symtab *s;
- ALL_OBJFILE_SYMTABS (objfile, s)
+ ALL_OBJFILE_FILETABS (objfile, cust, s)
{
struct linetable *l;
- struct blockvector *bv;
int i;
/* First the line table. */
- l = LINETABLE (s);
+ l = SYMTAB_LINETABLE (s);
if (l)
{
for (i = 0; i < l->nitems; ++i)
- l->item[i].pc += ANOFFSET (delta, s->block_line_section);
+ l->item[i].pc += ANOFFSET (delta,
+ COMPUNIT_BLOCK_LINE_SECTION
+ (cust));
}
+ }
- /* Don't relocate a shared blockvector more than once. */
- if (!s->primary)
- continue;
+ ALL_OBJFILE_COMPUNITS (objfile, cust)
+ {
+ const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (cust);
+ int block_line_section = COMPUNIT_BLOCK_LINE_SECTION (cust);
- bv = BLOCKVECTOR (s);
if (BLOCKVECTOR_MAP (bv))
addrmap_relocate (BLOCKVECTOR_MAP (bv),
- ANOFFSET (delta, s->block_line_section));
+ ANOFFSET (delta, block_line_section));
for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); ++i)
{
struct dict_iterator iter;
b = BLOCKVECTOR_BLOCK (bv, i);
- BLOCK_START (b) += ANOFFSET (delta, s->block_line_section);
- BLOCK_END (b) += ANOFFSET (delta, s->block_line_section);
+ BLOCK_START (b) += ANOFFSET (delta, block_line_section);
+ BLOCK_END (b) += ANOFFSET (delta, block_line_section);
/* We only want to iterate over the local symbols, not any
symbols in included symtabs. */
if (objfile->sf)
objfile->sf->qf->relocate (objfile, new_offsets, delta);
- {
- struct minimal_symbol *msym;
-
- ALL_OBJFILE_MSYMBOLS (objfile, msym)
- if (SYMBOL_SECTION (msym) >= 0)
- SYMBOL_VALUE_ADDRESS (msym) += ANOFFSET (delta, SYMBOL_SECTION (msym));
- }
- /* Relocating different sections by different amounts may cause the symbols
- to be out of order. */
- msymbols_sort (objfile);
-
{
int i;
obj_section_addr (s));
}
- /* Relocating probes. */
- if (objfile->sf && objfile->sf->sym_probe_fns)
- objfile->sf->sym_probe_fns->sym_relocate_probe (objfile,
- new_offsets, delta);
-
/* Data changed. */
return 1;
}
debug_objfile = objfile_separate_debug_iterate (objfile, debug_objfile))
{
struct section_addr_info *objfile_addrs;
- struct section_offsets *new_debug_offsets;
struct cleanup *my_cleanups;
objfile_addrs = build_section_addr_info_from_objfile (objfile);
gdb_assert (debug_objfile->num_sections
== gdb_bfd_count_sections (debug_objfile->obfd));
- new_debug_offsets =
- xmalloc (SIZEOF_N_SECTION_OFFSETS (debug_objfile->num_sections));
- make_cleanup (xfree, new_debug_offsets);
- relative_addr_info_to_section_offsets (new_debug_offsets,
+ std::vector<struct section_offsets>
+ 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);
- changed |= objfile_relocate1 (debug_objfile, new_debug_offsets);
+ changed |= objfile_relocate1 (debug_objfile, new_debug_offsets.data ());
do_cleanups (my_cleanups);
}
int
objfile_has_full_symbols (struct objfile *objfile)
{
- return objfile->symtabs != NULL;
+ return objfile->compunit_symtabs != NULL;
}
/* Return non-zero if OBJFILE has full or partial symbols, either directly
ALL_OBJFILES (ofp)
{
- if (ofp->minimal_symbol_count > 0)
+ if (ofp->per_bfd->minimal_symbol_count > 0)
{
return 1;
}
return;
}
- map = xmalloc (alloc_size * sizeof (*map));
+ map = XNEWVEC (struct obj_section *, alloc_size);
i = 0;
ALL_PSPACE_OBJFILES (pspace, objfile)
if (map_size < alloc_size)
/* Some sections were eliminated. Trim excess space. */
- map = xrealloc (map, map_size * sizeof (*map));
+ map = XRESIZEVEC (struct obj_section *, map, map_size);
else
gdb_assert (alloc_size == map_size);
void
resume_section_map_updates_cleanup (void *arg)
{
- resume_section_map_updates (arg);
+ resume_section_map_updates ((struct program_space *) arg);
}
/* Return 1 if ADDR maps into one of the sections of OBJFILE and 0
return 0;
}
+int
+shared_objfile_contains_address_p (struct program_space *pspace,
+ CORE_ADDR address)
+{
+ struct objfile *objfile;
+
+ ALL_PSPACE_OBJFILES (pspace, objfile)
+ {
+ if ((objfile->flags & OBJF_SHARED) != 0
+ && is_addr_in_objfile (address, objfile))
+ return 1;
+ }
+
+ return 0;
+}
+
/* The default implementation for the "iterate_over_objfiles_in_search_order"
gdbarch method. It is equivalent to use the ALL_OBJFILES macro,
searching the objfiles in the order they are stored internally,
}
}
-/* Return canonical name for OBJFILE. */
+/* See objfiles.h. */
const char *
objfile_name (const struct objfile *objfile)
return objfile->original_name;
}
+/* See objfiles.h. */
+
+const char *
+objfile_filename (const struct objfile *objfile)
+{
+ if (objfile->obfd != NULL)
+ return bfd_get_filename (objfile->obfd);
+
+ return NULL;
+}
+
+/* See objfiles.h. */
+
+const char *
+objfile_debug_name (const struct objfile *objfile)
+{
+ return lbasename (objfile->original_name);
+}
+
+/* See objfiles.h. */
+
+const char *
+objfile_flavour_name (struct objfile *objfile)
+{
+ if (objfile->obfd != NULL)
+ return bfd_flavour_name (bfd_get_flavour (objfile->obfd));
+ return NULL;
+}
+
/* Provide a prototype to silence -Wmissing-prototypes. */
extern initialize_file_ftype _initialize_objfiles;