Improve MSP430 section placement.
[deliverable/binutils-gdb.git] / gdb / objfiles.c
index 4cc2feab2de4b0fa100f0888ab3575f9554b362e..c49c7ea2e43efb82b3fc0c950518e12b86949664 100644 (file)
@@ -1,6 +1,6 @@
 /* GDB routines for manipulating objfiles.
 
-   Copyright (C) 1992-2004, 2007-2012 Free Software Foundation, Inc.
+   Copyright (C) 1992-2017 Free Software Foundation, Inc.
 
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
 #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 "hashtab.h"
 
 #include "breakpoint.h"
@@ -54,6 +51,9 @@
 #include "psymtab.h"
 #include "solist.h"
 #include "gdb_bfd.h"
+#include "btrace.h"
+
+#include <vector>
 
 /* Keep a registry of per-objfile data-pointers required by other GDB
    modules.  */
@@ -63,13 +63,20 @@ 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.  */
@@ -78,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 = (struct objfile_pspace_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
@@ -96,10 +99,11 @@ get_objfile_pspace_data (struct program_space *pspace)
 {
   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 = XZALLOC (struct objfile_pspace_info);
+      info = XCNEW (struct objfile_pspace_info);
       set_program_space_data (pspace, objfiles_pspace_data, info);
     }
 
@@ -126,22 +130,40 @@ 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);
+    storage = ((struct objfile_per_bfd_storage *)
+              bfd_data (abfd, objfiles_bfd_data));
 
   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));
+         storage
+           = ((struct objfile_per_bfd_storage *)
+              bfd_alloc (abfd, sizeof (struct objfile_per_bfd_storage)));
          set_bfd_data (abfd, objfiles_bfd_data, storage);
        }
       else
-       storage = OBSTACK_ZALLOC (&objfile->objfile_obstack,
-                                 struct objfile_per_bfd_storage);
+       {
+         storage = (objfile_per_bfd_storage *)
+           obstack_alloc (&objfile->objfile_obstack,
+                          sizeof (objfile_per_bfd_storage));
+       }
+
+      /* objfile_per_bfd_storage is not trivially constructible, must
+        call the ctor manually.  */
+      storage = new (storage) objfile_per_bfd_storage ();
+
+      /* 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;
@@ -154,7 +176,9 @@ free_objfile_per_bfd_storage (struct objfile_per_bfd_storage *storage)
 {
   bcache_xfree (storage->filename_cache);
   bcache_xfree (storage->macro_cache);
-  obstack_free (&storage->storage_obstack, 0);
+  if (storage->demangled_names_hash)
+    htab_delete (storage->demangled_names_hash);
+  storage->~objfile_per_bfd_storage ();
 }
 
 /* A wrapper for free_objfile_per_bfd_storage that can be passed as a
@@ -163,7 +187,7 @@ free_objfile_per_bfd_storage (struct objfile_per_bfd_storage *storage)
 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.  */
@@ -174,6 +198,107 @@ set_objfile_per_bfd (struct objfile *objfile)
   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
+      = (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
@@ -181,51 +306,56 @@ set_objfile_per_bfd (struct objfile *objfile)
    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, (struct objfile *) 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
@@ -233,33 +363,49 @@ 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.  */
 
-/* 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, int flags)
+allocate_objfile (bfd *abfd, const char *name, objfile_flags flags)
 {
   struct objfile *objfile;
+  const 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::unique_xmalloc_ptr<char> name_holder;
+  if (name == NULL)
+    {
+      gdb_assert (abfd == NULL);
+      gdb_assert ((flags & OBJF_NOT_FILENAME) != 0);
+      expanded_name = "<<anonymous objfile>>";
+    }
+  else if ((flags & OBJF_NOT_FILENAME) != 0
+          || is_target_filename (name))
+    expanded_name = name;
+  else
+    {
+      name_holder = gdb_abspath (name);
+      expanded_name = name_holder.get ();
+    }
+  objfile->original_name
+    = (char *) obstack_copy0 (&objfile->objfile_obstack,
+                             expanded_name,
+                             strlen (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.  */
@@ -268,23 +414,17 @@ allocate_objfile (bfd *abfd, int flags)
   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.  */
 
@@ -312,47 +452,17 @@ 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;
 }
 
 /* Retrieve the gdbarch associated with OBJFILE.  */
+
 struct gdbarch *
-get_objfile_arch (struct objfile *objfile)
+get_objfile_arch (const 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
@@ -361,26 +471,13 @@ 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)
+  if (symfile_objfile == NULL || !symfile_objfile->per_bfd->ei.entry_point_p)
     return 0;
 
-  gdbarch = get_objfile_arch (symfile_objfile);
-
-  entry_point = 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 = (symfile_objfile->per_bfd->ei.entry_point
+             + ANOFFSET (symfile_objfile->section_offsets,
+                         symfile_objfile->per_bfd->ei.the_bfd_section_index));
 
-  *entry_p = entry_point;
   return 1;
 }
 
@@ -461,26 +558,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.
 
@@ -523,6 +600,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;
@@ -549,25 +629,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);
 
@@ -610,6 +679,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
@@ -638,9 +710,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
@@ -664,32 +733,34 @@ free_objfile (struct objfile *objfile)
   {
     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 void
 do_free_objfile_cleanup (void *obj)
 {
-  free_objfile (obj);
+  free_objfile ((struct objfile *) obj);
 }
 
 struct cleanup *
@@ -744,7 +815,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 =
@@ -766,30 +837,33 @@ objfile_relocate1 (struct objfile *objfile,
 
   /* 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)
        {
@@ -798,8 +872,8 @@ objfile_relocate1 (struct objfile *objfile,
          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.  */
@@ -826,29 +900,6 @@ objfile_relocate1 (struct objfile *objfile,
   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;
 
@@ -857,22 +908,17 @@ 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));
     }
 
-  /* 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;
 }
@@ -887,7 +933,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;
@@ -899,7 +946,6 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
        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);
@@ -911,15 +957,14 @@ 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));
-      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,
+                 == gdb_bfd_count_sections (debug_objfile->obfd));
+      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);
     }
@@ -928,6 +973,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 ();
+}
 \f
 /* Return non-zero if OBJFILE has partial symbols.  */
 
@@ -953,7 +1037,7 @@ objfile_has_partial_symbols (struct objfile *objfile)
 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
@@ -1038,7 +1122,7 @@ have_minimal_symbols (void)
 
   ALL_OBJFILES (ofp)
   {
-    if (ofp->minimal_symbol_count > 0)
+    if (ofp->per_bfd->minimal_symbol_count > 0)
       {
        return 1;
       }
@@ -1242,9 +1326,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;
 
@@ -1257,10 +1338,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));
            }
@@ -1285,11 +1366,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);
@@ -1308,7 +1392,7 @@ update_section_map (struct program_space *pspace,
       return;
     }
 
-  map = xmalloc (alloc_size * sizeof (*map));
+  map = XNEWVEC (struct obj_section *, alloc_size);
 
   i = 0;
   ALL_PSPACE_OBJFILES (pspace, objfile)
@@ -1322,7 +1406,7 @@ update_section_map (struct program_space *pspace,
 
   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);
 
@@ -1359,7 +1443,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,
@@ -1367,7 +1453,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
@@ -1389,12 +1476,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, const char *name)
 {
   struct obj_section *s;
   int retval = 0;
@@ -1403,19 +1488,82 @@ 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);
 }
 \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 ((struct program_space *) 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"
@@ -1443,6 +1591,46 @@ default_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;
 
This page took 0.041941 seconds and 4 git commands to generate.