Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Unified Diff: gdb/objfiles.c

Issue 124383005: GDB 7.6.50 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@upstream
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gdb/objfiles.h ('k') | gdb/obsd-tdep.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gdb/objfiles.c
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index f5e5c75b86f4f64acdc91eb6c8d3c90ab27a150c..2960ff9b00fa4ba0d368a922d249989169538376 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -1,6 +1,6 @@
/* GDB routines for manipulating objfiles.
- Copyright (C) 1992-2004, 2007-2012 Free Software Foundation, Inc.
+ Copyright (C) 1992-2013 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
@@ -30,16 +30,15 @@
#include "gdb-stabs.h"
#include "target.h"
#include "bcache.h"
-#include "mdebugread.h"
#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 <string.h>
#include "hashtab.h"
#include "breakpoint.h"
@@ -53,22 +52,31 @@
#include "complaints.h"
#include "psymtab.h"
#include "solist.h"
+#include "gdb_bfd.h"
+#include "btrace.h"
-/* Prototypes for local functions */
+/* Keep a registry of per-objfile data-pointers required by other GDB
+ modules. */
-static void objfile_alloc_data (struct objfile *objfile);
-static void objfile_free_data (struct objfile *objfile);
+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 *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. */
@@ -77,14 +85,10 @@ static const struct program_space_data *objfiles_pspace_data;
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
@@ -105,56 +109,140 @@ get_objfile_pspace_data (struct program_space *pspace)
return info;
}
+
+
+/* Per-BFD data key. */
+
+static const struct bfd_data *objfiles_bfd_data;
+
+/* 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)
+{
+ struct objfile_per_bfd_storage *storage = NULL;
+
+ if (abfd != NULL)
+ storage = bfd_data (abfd, objfiles_bfd_data);
+
+ if (storage == 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);
+ }
+ else
+ 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);
+ }
+
+ 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);
+ obstack_free (&storage->storage_obstack, 0);
+}
+
+/* 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 (d);
+}
+
+/* See objfiles.h. */
+
+void
+set_objfile_per_bfd (struct objfile *objfile)
+{
+ objfile->per_bfd = get_objfile_bfd_data (objfile, objfile->obfd);
+}
+
+
+
/* 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). */
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 *) &section, 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
@@ -162,6 +250,11 @@ build_objfile_section_table (struct objfile *objfile)
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. */
@@ -176,14 +269,13 @@ build_objfile_section_table (struct objfile *objfile)
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->psymbol_cache = psymbol_bcache_init ();
- objfile->macro_cache = bcache_xmalloc (NULL, NULL);
- objfile->filename_cache = bcache_xmalloc (NULL, NULL);
/* We could use obstack_specify_allocation here instead, but
gdb_obstack.h specifies the alloc/dealloc functions. */
obstack_init (&objfile->objfile_obstack);
@@ -191,27 +283,40 @@ allocate_objfile (bfd *abfd, int flags)
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)
+ 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. */
+
/* 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->obfd = gdb_bfd_ref (abfd);
+ objfile->obfd = abfd;
+ gdb_bfd_ref (abfd);
if (abfd != NULL)
{
- /* Look up the gdbarch associated with the BFD. */
- objfile->gdbarch = gdbarch_from_bfd (abfd);
-
- objfile->name = xstrdup (bfd_get_filename (abfd));
objfile->mtime = bfd_get_mtime (abfd);
/* Build section table. */
build_objfile_section_table (objfile);
}
- else
- {
- objfile->name = xstrdup ("<<anonymous objfile>>");
- }
+ objfile->per_bfd = get_objfile_bfd_data (objfile, abfd);
objfile->pspace = current_program_space;
/* Initialize the section indexes for this objfile, so that we can
@@ -241,7 +346,7 @@ allocate_objfile (bfd *abfd, int flags)
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;
}
@@ -250,38 +355,7 @@ allocate_objfile (bfd *abfd, int flags)
struct gdbarch *
get_objfile_arch (struct objfile *objfile)
{
- return objfile->gdbarch;
-}
-
-/* Initialize entry point information for this objfile. */
-
-void
-init_entry_point_info (struct objfile *objfile)
-{
- /* Save startup file's range of PC addresses to help blockframe.c
- decide where the bottom of the stack is. */
-
- if (bfd_get_file_flags (objfile->obfd) & EXEC_P)
- {
- /* Executable file -- record its entry point so we'll recognize
- the startup file because it contains the entry point. */
- objfile->ei.entry_point = bfd_get_start_address (objfile->obfd);
- objfile->ei.entry_point_p = 1;
- }
- else if (bfd_get_file_flags (objfile->obfd) & DYNAMIC
- && bfd_get_start_address (objfile->obfd) != 0)
- {
- /* Some shared libraries may have entry points set and be
- runnable. There's no clear way to indicate this, so just check
- for values other than zero. */
- objfile->ei.entry_point = bfd_get_start_address (objfile->obfd);
- objfile->ei.entry_point_p = 1;
- }
- else
- {
- /* Examination of non-executable.o files. Short-circuit this stuff. */
- objfile->ei.entry_point_p = 0;
- }
+ return objfile->per_bfd->gdbarch;
}
/* If there is a valid and known entry point, function fills *ENTRY_P with it
@@ -290,26 +364,11 @@ init_entry_point_info (struct objfile *objfile)
int
entry_point_address_query (CORE_ADDR *entry_p)
{
- struct gdbarch *gdbarch;
- CORE_ADDR entry_point;
-
if (symfile_objfile == NULL || !symfile_objfile->ei.entry_point_p)
return 0;
- gdbarch = get_objfile_arch (symfile_objfile);
-
- entry_point = symfile_objfile->ei.entry_point;
+ *entry_p = symfile_objfile->ei.entry_point;
- /* Make certain that the address points at real code, and not a
- function descriptor. */
- entry_point = gdbarch_convert_from_func_ptr_addr (gdbarch, entry_point,
- &current_target);
-
- /* Remove any ISA markers, so that this matches entries in the
- symbol table. */
- entry_point = gdbarch_addr_bits_remove (gdbarch, entry_point);
-
- *entry_p = entry_point;
return 1;
}
@@ -390,26 +449,6 @@ put_objfile_before (struct objfile *objfile, struct objfile *before_this)
_("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.
@@ -452,6 +491,9 @@ add_separate_debug_objfile (struct objfile *objfile, struct objfile *parent)
/* Must not be already in a list. */
gdb_assert (objfile->separate_debug_objfile_backlink == NULL);
gdb_assert (objfile->separate_debug_objfile_link == NULL);
+ gdb_assert (objfile->separate_debug_objfile == NULL);
+ gdb_assert (parent->separate_debug_objfile_backlink == NULL);
+ gdb_assert (parent->separate_debug_objfile_link == NULL);
objfile->separate_debug_objfile_backlink = parent;
objfile->separate_debug_objfile_link = parent->separate_debug_objfile;
@@ -478,25 +520,14 @@ free_objfile_separate_debug (struct objfile *objfile)
}
}
-/* 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);
@@ -539,6 +570,9 @@ free_objfile (struct objfile *objfile)
the symbol file data. */
forget_cached_source_info_for_objfile (objfile);
+ breakpoint_free_objfile (objfile);
+ btrace_free_objfile (objfile);
+
/* First do any symbol file specific actions required when we are
finished with a particular symbol file. Note that if the objfile
is using reusable symbol information (via mmalloc) then each of
@@ -555,7 +589,10 @@ free_objfile (struct objfile *objfile)
still may reference objfile->obfd. */
objfile_free_data (objfile);
- gdb_bfd_unref (objfile->obfd);
+ if (objfile->obfd)
+ gdb_bfd_unref (objfile->obfd);
+ else
+ free_objfile_per_bfd_storage (objfile->per_bfd);
/* Remove it from the chain of all objfiles. */
@@ -564,9 +601,6 @@ free_objfile (struct objfile *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
@@ -594,24 +628,18 @@ free_objfile (struct objfile *objfile)
clear_current_source_symtab_and_line ();
}
- /* The last thing we do is free the objfile struct itself. */
-
- xfree (objfile->name);
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);
- bcache_xfree (objfile->macro_cache);
- bcache_xfree (objfile->filename_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;
+ /* The last thing we do is free the objfile struct itself. */
xfree (objfile);
}
@@ -673,7 +701,7 @@ relocate_one_symbol (struct symbol *sym, struct objfile *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 =
@@ -773,7 +801,11 @@ objfile_relocate1 (struct objfile *objfile,
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);
+ {
+ int idx = gdb_bfd_section_index (objfile->obfd, s->the_bfd_section);
+
+ objfile->ei.entry_point += ANOFFSET (delta, idx);
+ }
else
objfile->ei.entry_point += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
}
@@ -786,12 +818,12 @@ objfile_relocate1 (struct objfile *objfile,
}
/* 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));
@@ -816,7 +848,8 @@ objfile_relocate1 (struct objfile *objfile,
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;
@@ -840,7 +873,7 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
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);
@@ -857,6 +890,45 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
if (changed)
breakpoint_re_set ();
}
+
+/* Rebase (add to the offsets) OBJFILE by SLIDE. SEPARATE_DEBUG_OBJFILE is
+ not touched here.
+ Return non-zero iff any change happened. */
+
+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;
+
+ return objfile_relocate1 (objfile, new_offsets);
+}
+
+/* Rebase (add to the offsets) OBJFILE by SLIDE. Process also OBJFILE's
+ SEPARATE_DEBUG_OBJFILEs. */
+
+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))
+ changed |= objfile_rebase1 (debug_objfile, slide);
+
+ /* Relocate breakpoints as necessary, after things are relocated. */
+ if (changed)
+ breakpoint_re_set ();
+}
/* Return non-zero if OBJFILE has partial symbols. */
@@ -1171,9 +1243,6 @@ filter_overlapping_sections (struct obj_section **map, int map_size)
struct objfile *const objf1 = sect1->objfile;
struct objfile *const objf2 = sect2->objfile;
- const struct bfd *const abfd1 = objf1->obfd;
- const struct bfd *const abfd2 = objf2->obfd;
-
const struct bfd_section *const bfds1 = sect1->the_bfd_section;
const struct bfd_section *const bfds2 = sect2->the_bfd_section;
@@ -1186,10 +1255,10 @@ filter_overlapping_sections (struct obj_section **map, int map_size)
" (A) section `%s' from `%s' [%s, %s)\n"
" (B) section `%s' from `%s' [%s, %s).\n"
"Will ignore section B"),
- bfd_section_name (abfd1, bfds1), 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));
}
@@ -1214,11 +1283,14 @@ static void
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);
@@ -1288,7 +1360,9 @@ find_pc_section (CORE_ADDR pc)
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,
@@ -1296,7 +1370,8 @@ find_pc_section (CORE_ADDR pc)
/* 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
@@ -1318,12 +1393,10 @@ find_pc_section (CORE_ADDR pc)
}
-/* 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;
@@ -1332,197 +1405,66 @@ in_plt_section (CORE_ADDR pc, char *name)
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);
}
-/* Keep a registry of per-objfile data-pointers required by other GDB
- modules. */
-
-struct objfile_data
-{
- unsigned index;
- void (*save) (struct objfile *, void *);
- void (*free) (struct objfile *, void *);
-};
-
-struct objfile_data_registration
-{
- struct objfile_data *data;
- struct objfile_data_registration *next;
-};
-
-struct objfile_data_registry
-{
- struct objfile_data_registration *registrations;
- unsigned num_registrations;
-};
-
-static struct objfile_data_registry objfile_data_registry = { NULL, 0 };
-
-const struct objfile_data *
-register_objfile_data_with_cleanup (void (*save) (struct objfile *, void *),
- void (*free) (struct objfile *, void *))
-{
- struct objfile_data_registration **curr;
-
- /* Append new registration. */
- for (curr = &objfile_data_registry.registrations;
- *curr != NULL; curr = &(*curr)->next);
-
- *curr = XMALLOC (struct objfile_data_registration);
- (*curr)->next = NULL;
- (*curr)->data = XMALLOC (struct objfile_data);
- (*curr)->data->index = objfile_data_registry.num_registrations++;
- (*curr)->data->save = save;
- (*curr)->data->free = free;
-
- return (*curr)->data;
-}
-
-const struct objfile_data *
-register_objfile_data (void)
-{
- return register_objfile_data_with_cleanup (NULL, NULL);
-}
+/* Set section_map_dirty so section map will be rebuilt next time it
+ is used. Called by reread_symbols. */
-static void
-objfile_alloc_data (struct objfile *objfile)
+void
+objfiles_changed (void)
{
- gdb_assert (objfile->data == NULL);
- objfile->num_data = objfile_data_registry.num_registrations;
- objfile->data = XCALLOC (objfile->num_data, void *);
+ /* Rebuild section map next time we need it. */
+ get_objfile_pspace_data (current_program_space)->section_map_dirty = 1;
}
-static void
-objfile_free_data (struct objfile *objfile)
-{
- gdb_assert (objfile->data != NULL);
- clear_objfile_data (objfile);
- xfree (objfile->data);
- objfile->data = NULL;
-}
+/* See comments in objfiles.h. */
void
-clear_objfile_data (struct objfile *objfile)
+inhibit_section_map_updates (struct program_space *pspace)
{
- struct objfile_data_registration *registration;
- int i;
-
- gdb_assert (objfile->data != NULL);
-
- /* Process all the save handlers. */
-
- for (registration = objfile_data_registry.registrations, i = 0;
- i < objfile->num_data;
- registration = registration->next, i++)
- if (objfile->data[i] != NULL && registration->data->save != NULL)
- registration->data->save (objfile, objfile->data[i]);
-
- /* Now process all the free handlers. */
-
- for (registration = objfile_data_registry.registrations, i = 0;
- i < objfile->num_data;
- registration = registration->next, i++)
- if (objfile->data[i] != NULL && registration->data->free != NULL)
- registration->data->free (objfile, objfile->data[i]);
-
- memset (objfile->data, 0, objfile->num_data * sizeof (void *));
+ get_objfile_pspace_data (pspace)->inhibit_updates = 1;
}
-void
-set_objfile_data (struct objfile *objfile, const struct objfile_data *data,
- void *value)
-{
- gdb_assert (data->index < objfile->num_data);
- objfile->data[data->index] = value;
-}
+/* See comments in objfiles.h. */
-void *
-objfile_data (struct objfile *objfile, const struct objfile_data *data)
+void
+resume_section_map_updates (struct program_space *pspace)
{
- gdb_assert (data->index < objfile->num_data);
- return objfile->data[data->index];
+ get_objfile_pspace_data (pspace)->inhibit_updates = 0;
}
-/* Set objfiles_changed_p so section map will be rebuilt next time it
- is used. Called by reread_symbols. */
+/* See comments in objfiles.h. */
void
-objfiles_changed (void)
+resume_section_map_updates_cleanup (void *arg)
{
- /* Rebuild section map next time we need it. */
- get_objfile_pspace_data (current_program_space)->objfiles_changed_p = 1;
+ resume_section_map_updates (arg);
}
-/* Close ABFD, and warn if that fails. */
+/* Return 1 if ADDR maps into one of the sections of OBJFILE and 0
+ otherwise. */
int
-gdb_bfd_close_or_warn (struct bfd *abfd)
-{
- int ret;
- char *name = bfd_get_filename (abfd);
-
- ret = bfd_close (abfd);
-
- if (!ret)
- warning (_("cannot close \"%s\": %s"),
- name, bfd_errmsg (bfd_get_error ()));
-
- return ret;
-}
-
-/* Add reference to ABFD. Returns ABFD. */
-struct bfd *
-gdb_bfd_ref (struct bfd *abfd)
+is_addr_in_objfile (CORE_ADDR addr, const struct objfile *objfile)
{
- int *p_refcount;
-
- if (abfd == NULL)
- return NULL;
+ struct obj_section *osect;
- p_refcount = bfd_usrdata (abfd);
+ if (objfile == NULL)
+ return 0;
- if (p_refcount != NULL)
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
{
- *p_refcount += 1;
- return abfd;
- }
-
- p_refcount = xmalloc (sizeof (*p_refcount));
- *p_refcount = 1;
- bfd_usrdata (abfd) = p_refcount;
-
- return abfd;
-}
-
-/* Unreference and possibly close ABFD. */
-void
-gdb_bfd_unref (struct bfd *abfd)
-{
- int *p_refcount;
- char *name;
-
- if (abfd == NULL)
- return;
-
- p_refcount = bfd_usrdata (abfd);
-
- /* Valid range for p_refcount: a pointer to int counter, which has a
- value of 1 (single owner) or 2 (shared). */
- gdb_assert (*p_refcount == 1 || *p_refcount == 2);
-
- *p_refcount -= 1;
- if (*p_refcount > 0)
- return;
-
- xfree (p_refcount);
- bfd_usrdata (abfd) = NULL; /* Paranoia. */
+ if (section_is_overlay (osect) && !section_is_mapped (osect))
+ continue;
- name = bfd_get_filename (abfd);
- gdb_bfd_close_or_warn (abfd);
- xfree (name);
+ if (obj_section_addr (osect) <= addr
+ && addr < obj_section_endaddr (osect))
+ return 1;
+ }
+ return 0;
}
/* The default implementation for the "iterate_over_objfiles_in_search_order"
@@ -1550,6 +1492,17 @@ default_iterate_over_objfiles_in_search_order
}
}
+/* Return canonical name for OBJFILE. */
+
+const char *
+objfile_name (const struct objfile *objfile)
+{
+ if (objfile->obfd != NULL)
+ return bfd_get_filename (objfile->obfd);
+
+ return objfile->original_name;
+}
+
/* Provide a prototype to silence -Wmissing-prototypes. */
extern initialize_file_ftype _initialize_objfiles;
@@ -1557,5 +1510,9 @@ void
_initialize_objfiles (void)
{
objfiles_pspace_data
- = register_program_space_data_with_cleanup (objfiles_pspace_data_cleanup);
+ = register_program_space_data_with_cleanup (NULL,
+ objfiles_pspace_data_cleanup);
+
+ objfiles_bfd_data = register_bfd_data_with_cleanup (NULL,
+ objfile_bfd_data_free);
}
« no previous file with comments | « gdb/objfiles.h ('k') | gdb/obsd-tdep.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698