/* GDB routines for manipulating objfiles.
- Copyright (C) 1992-2013 Free Software Foundation, Inc.
+ Copyright (C) 1992-2015 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 "gdb_stat.h"
+#include <sys/stat.h>
#include <fcntl.h>
#include "gdb_obstack.h"
-#include "gdb_string.h"
#include "hashtab.h"
#include "breakpoint.h"
/* Externally visible variables that are owned by this module.
See declarations in objfile.h for more info. */
-struct objfile *rt_common_objfile; /* For runtime common symbols */
-
struct objfile_pspace_info
{
- int objfiles_changed_p;
struct obj_section **sections;
int num_sections;
+
+ /* Nonzero if object files have been added since the section map
+ was last updated. */
+ int new_objfiles_available;
+
+ /* Nonzero if the section map MUST be updated before use. */
+ int section_map_dirty;
+
+ /* Nonzero if section map updates should be inhibited if possible. */
+ int inhibit_updates;
};
/* Per-program-space data key. */
static void
objfiles_pspace_data_cleanup (struct program_space *pspace, void *arg)
{
- struct objfile_pspace_info *info;
+ struct objfile_pspace_info *info = arg;
- info = program_space_data (pspace, objfiles_pspace_data);
- if (info != NULL)
- {
- xfree (info->sections);
- xfree (info);
- }
+ xfree (info->sections);
+ xfree (info);
}
/* Get the current svr4 data. If none is found yet, add it now. This
info = program_space_data (pspace, objfiles_pspace_data);
if (info == NULL)
{
- info = XZALLOC (struct objfile_pspace_info);
+ info = XCNEW (struct objfile_pspace_info);
set_program_space_data (pspace, objfiles_pspace_data, info);
}
if (storage == NULL)
{
- if (abfd != NULL)
+ /* 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 = bfd_zalloc (abfd, sizeof (struct objfile_per_bfd_storage));
set_bfd_data (abfd, objfiles_bfd_data, storage);
storage = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct objfile_per_bfd_storage);
+ /* Look up the gdbarch associated with the BFD. */
+ if (abfd != NULL)
+ storage->gdbarch = gdbarch_from_bfd (abfd);
+
obstack_init (&storage->storage_obstack);
storage->filename_cache = bcache_xmalloc (NULL, NULL);
storage->macro_cache = bcache_xmalloc (NULL, NULL);
+ storage->language_of_main = language_unknown;
}
return storage;
{
bcache_xfree (storage->filename_cache);
bcache_xfree (storage->macro_cache);
+ if (storage->demangled_names_hash)
+ htab_delete (storage->demangled_names_hash);
obstack_free (&storage->storage_obstack, 0);
}
objfile->per_bfd = get_objfile_bfd_data (objfile, objfile->obfd);
}
+/* Set the objfile's per-BFD notion of the "main" name and
+ language. */
+
+void
+set_objfile_main_name (struct objfile *objfile,
+ const char *name, enum language lang)
+{
+ 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));
+ 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
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,
+ struct objfile *objfile, int force)
+{
+ struct obj_section *section;
+
+ if (!force)
+ {
+ flagword aflag;
+
+ aflag = bfd_get_section_flags (abfd, asect);
+ if (!(aflag & SEC_ALLOC))
+ return;
+ }
+
+ section = &objfile->sections[gdb_bfd_section_index (abfd, asect)];
+ section->objfile = objfile;
+ section->the_bfd_section = asect;
+ section->ovly_mapped = 0;
+}
+
static void
add_to_objfile_sections (struct bfd *abfd, struct bfd_section *asect,
void *objfilep)
{
- struct objfile *objfile = (struct objfile *) objfilep;
- struct obj_section section;
- flagword aflag;
-
- aflag = bfd_get_section_flags (abfd, asect);
- if (!(aflag & SEC_ALLOC))
- return;
- if (bfd_section_size (abfd, asect) == 0)
- return;
-
- section.objfile = objfile;
- section.the_bfd_section = asect;
- section.ovly_mapped = 0;
- obstack_grow (&objfile->objfile_obstack,
- (char *) §ion, sizeof (section));
- objfile->sections_end
- = (struct obj_section *) (((size_t) objfile->sections_end) + 1);
+ add_to_objfile_sections_full (abfd, asect, objfilep, 0);
}
/* Builds a section table for OBJFILE.
- Note that while we are building the table, which goes into the
- objfile obstack, we hijack the sections_end pointer to instead hold
- a count of the number of sections. When bfd_map_over_sections
- returns, this count is used to compute the pointer to the end of
- the sections table, which then overwrites the count.
-
- Also note that the OFFSET and OVLY_MAPPED in each table entry
- are initialized to zero.
-
- Also note that if anything else writes to the objfile obstack while
- we are building the table, we're pretty much hosed. */
+ Note that the OFFSET and OVLY_MAPPED in each table entry are
+ initialized to zero. */
void
build_objfile_section_table (struct objfile *objfile)
{
- objfile->sections_end = 0;
+ int count = gdb_bfd_count_sections (objfile->obfd);
+
+ 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);
- objfile->sections = obstack_finish (&objfile->objfile_obstack);
- objfile->sections_end = objfile->sections + (size_t) objfile->sections_end;
+
+ /* 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);
}
/* Given a pointer to an initialized bfd (ABFD) and some flag bits
into the list of all known objfiles, and return a pointer to the
new objfile struct.
+ NAME should contain original non-canonicalized filename or other
+ identifier as entered by user. If there is no better source use
+ bfd_get_filename (ABFD). NAME may be NULL only if ABFD is NULL.
+ NAME content is copied into returned objfile.
+
The FLAGS word contains various bits (OBJF_*) that can be taken as
requests for specific operations. Other bits like OBJF_SHARED are
simply copied through to the new objfile flags member. */
things in a consistent state even if abfd is NULL. */
struct objfile *
-allocate_objfile (bfd *abfd, int flags)
+allocate_objfile (bfd *abfd, const char *name, int 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);
+ if (name == NULL)
+ {
+ gdb_assert (abfd == NULL);
+ gdb_assert ((flags & OBJF_NOT_FILENAME) != 0);
+ expanded_name = xstrdup ("<<anonymous objfile>>");
+ }
+ 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));
+ 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. */
gdb_bfd_ref (abfd);
if (abfd != NULL)
{
- /* Look up the gdbarch associated with the BFD. */
- objfile->gdbarch = gdbarch_from_bfd (abfd);
-
- objfile->name = bfd_get_filename (abfd);
objfile->mtime = bfd_get_mtime (abfd);
/* Build section table. */
build_objfile_section_table (objfile);
}
- else
- {
- objfile->name = "<<anonymous objfile>>";
- }
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. */
objfile->flags |= flags;
/* Rebuild section map next time we need it. */
- get_objfile_pspace_data (objfile->pspace)->objfiles_changed_p = 1;
+ get_objfile_pspace_data (objfile->pspace)->new_objfiles_available = 1;
return objfile;
}
/* Retrieve the gdbarch associated with OBJFILE. */
+
struct gdbarch *
-get_objfile_arch (struct objfile *objfile)
+get_objfile_arch (const struct objfile *objfile)
{
- return objfile->gdbarch;
+ return objfile->per_bfd->gdbarch;
}
/* If there is a valid and known entry point, function fills *ENTRY_P with it
int
entry_point_address_query (CORE_ADDR *entry_p)
{
- if (symfile_objfile == NULL || !symfile_objfile->ei.entry_point_p)
+ if (symfile_objfile == NULL || !symfile_objfile->per_bfd->ei.entry_point_p)
return 0;
- *entry_p = symfile_objfile->ei.entry_point;
+ *entry_p = (symfile_objfile->per_bfd->ei.entry_point
+ + ANOFFSET (symfile_objfile->section_offsets,
+ symfile_objfile->per_bfd->ei.the_bfd_section_index));
return 1;
}
_("put_objfile_before: before objfile not in list"));
}
-/* Put OBJFILE at the front of the list. */
-
-void
-objfile_to_front (struct objfile *objfile)
-{
- struct objfile **objp;
- for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
- {
- if (*objp == objfile)
- {
- /* Unhook it from where it is. */
- *objp = objfile->next;
- /* Put it in the front. */
- objfile->next = object_files;
- object_files = objfile;
- break;
- }
- }
-}
-
/* Unlink OBJFILE from the list of known objfiles, if it is found in the
list.
}
}
-/* Destroy an objfile and all the symtabs and psymtabs under it. Note
- that as much as possible is allocated on the objfile_obstack
- so that the memory can be efficiently freed.
-
- Things which we do NOT free because they are not in malloc'd memory
- or not in memory specific to the objfile include:
-
- objfile -> sf
-
- FIXME: If the objfile is using reusable symbol information (via mmalloc),
- then we need to take into account the fact that more than one process
- may be using the symbol information at the same time (when mmalloc is
- extended to support cooperative locking). When more than one process
- is using the mapped symbol info, we need to be more careful about when
- we free objects in the reusable area. */
+/* Destroy an objfile and all the symtabs and psymtabs under it. */
void
free_objfile (struct objfile *objfile)
{
+ /* First notify observers that this objfile is about to be freed. */
+ observer_notify_free_objfile (objfile);
+
/* Free all separate debug objfiles. */
free_objfile_separate_debug (objfile);
if (objfile == symfile_objfile)
symfile_objfile = NULL;
- if (objfile == rt_common_objfile)
- rt_common_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
{
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 ();
}
- /* The last thing we do is free the objfile struct itself. */
-
if (objfile->global_psymbols.list)
xfree (objfile->global_psymbols.list);
if (objfile->static_psymbols.list)
xfree (objfile->static_psymbols.list);
/* Free the obstacks for non-reusable objfiles. */
psymbol_bcache_free (objfile->psymbol_cache);
- if (objfile->demangled_names_hash)
- htab_delete (objfile->demangled_names_hash);
obstack_free (&objfile->objfile_obstack, 0);
/* Rebuild section map next time we need it. */
- get_objfile_pspace_data (objfile->pspace)->objfiles_changed_p = 1;
+ 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 int
objfile_relocate1 (struct objfile *objfile,
- struct section_offsets *new_offsets)
+ const struct section_offsets *new_offsets)
{
struct obj_section *s;
struct section_offsets *delta =
/* 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);
-
- if (objfile->ei.entry_point_p)
- {
- /* Relocate ei.entry_point with its section offset, use SECT_OFF_TEXT
- only as a fallback. */
- struct obj_section *s;
- s = find_pc_section (objfile->ei.entry_point);
- if (s)
- objfile->ei.entry_point += ANOFFSET (delta, s->the_bfd_section->index);
- else
- objfile->ei.entry_point += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
- }
-
{
int i;
}
/* Rebuild section map next time we need it. */
- get_objfile_pspace_data (objfile->pspace)->objfiles_changed_p = 1;
+ get_objfile_pspace_data (objfile->pspace)->section_map_dirty = 1;
/* Update the table in exec_ops, used to read memory. */
ALL_OBJFILE_OSECTIONS (objfile, s)
{
- int idx = s->the_bfd_section->index;
+ int idx = s - objfile->sections;
exec_set_section_address (bfd_get_filename (objfile->obfd), idx,
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;
}
files. */
void
-objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
+objfile_relocate (struct objfile *objfile,
+ const struct section_offsets *new_offsets)
{
struct objfile *debug_objfile;
int changed = 0;
addr_info_make_relative (objfile_addrs, debug_objfile->obfd);
gdb_assert (debug_objfile->num_sections
- == bfd_count_sections (debug_objfile->obfd));
+ == 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);
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;
}
" (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), objf1->name,
+ bfd_section_name (abfd1, bfds1), objfile_name (objf1),
paddress (gdbarch, sect1_addr),
paddress (gdbarch, sect1_endaddr),
- bfd_section_name (abfd2, bfds2), objf2->name,
+ bfd_section_name (abfd2, bfds2), objfile_name (objf2),
paddress (gdbarch, sect2_addr),
paddress (gdbarch, sect2_endaddr));
}
update_section_map (struct program_space *pspace,
struct obj_section ***pmap, int *pmap_size)
{
+ struct objfile_pspace_info *pspace_info;
int alloc_size, map_size, i;
struct obj_section *s, **map;
struct objfile *objfile;
- gdb_assert (get_objfile_pspace_data (pspace)->objfiles_changed_p != 0);
+ pspace_info = get_objfile_pspace_data (pspace);
+ gdb_assert (pspace_info->section_map_dirty != 0
+ || pspace_info->new_objfiles_available != 0);
map = *pmap;
xfree (map);
return;
}
- map = xmalloc (alloc_size * sizeof (*map));
+ map = XNEWVEC (struct obj_section *, alloc_size);
i = 0;
ALL_PSPACE_OBJFILES (pspace, objfile)
return s;
pspace_info = get_objfile_pspace_data (current_program_space);
- if (pspace_info->objfiles_changed_p != 0)
+ if (pspace_info->section_map_dirty
+ || (pspace_info->new_objfiles_available
+ && !pspace_info->inhibit_updates))
{
update_section_map (current_program_space,
&pspace_info->sections,
/* Don't need updates to section map until objfiles are added,
removed or relocated. */
- pspace_info->objfiles_changed_p = 0;
+ pspace_info->new_objfiles_available = 0;
+ pspace_info->section_map_dirty = 0;
}
/* The C standard (ISO/IEC 9899:TC2) requires the BASE argument to
}
-/* In SVR4, we recognize a trampoline by it's section name.
- That is, if the pc is in a section named ".plt" then we are in
- a trampoline. */
+/* Return non-zero if PC is in a section called NAME. */
int
-in_plt_section (CORE_ADDR pc, char *name)
+pc_in_section (CORE_ADDR pc, char *name)
{
struct obj_section *s;
int retval = 0;
retval = (s != NULL
&& s->the_bfd_section->name != NULL
- && strcmp (s->the_bfd_section->name, ".plt") == 0);
+ && strcmp (s->the_bfd_section->name, name) == 0);
return (retval);
}
\f
-/* Set objfiles_changed_p so section map will be rebuilt next time it
+/* Set section_map_dirty so section map will be rebuilt next time it
is used. Called by reread_symbols. */
void
objfiles_changed (void)
{
/* Rebuild section map next time we need it. */
- get_objfile_pspace_data (current_program_space)->objfiles_changed_p = 1;
+ get_objfile_pspace_data (current_program_space)->section_map_dirty = 1;
+}
+
+/* See comments in objfiles.h. */
+
+void
+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 (arg);
+}
+
+/* Return 1 if ADDR maps into one of the sections of OBJFILE and 0
+ otherwise. */
+
+int
+is_addr_in_objfile (CORE_ADDR addr, const struct objfile *objfile)
+{
+ struct obj_section *osect;
+
+ if (objfile == NULL)
+ return 0;
+
+ 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;
+ }
+ 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"
}
}
+/* See objfiles.h. */
+
+const char *
+objfile_name (const struct objfile *objfile)
+{
+ if (objfile->obfd != NULL)
+ return bfd_get_filename (objfile->obfd);
+
+ 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;