| 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 *) §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 | 
| @@ -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, | 
| -						    ¤t_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); | 
| } | 
|  |