* lib/mi-support.exp (varobj_tree::walk_tree): Set _root_idx
[deliverable/binutils-gdb.git] / gdb / objfiles.c
index 8c17c148de287441c8f8f44b395c55934e1011f4..b10f803540fa3767c276e5ac7a834e26cf0f3dd1 100644 (file)
@@ -53,6 +53,7 @@
 #include "psymtab.h"
 #include "solist.h"
 #include "gdb_bfd.h"
+#include "btrace.h"
 
 /* Keep a registry of per-objfile data-pointers required by other GDB
    modules.  */
@@ -62,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.  */
@@ -133,6 +141,9 @@ get_objfile_bfd_data (struct objfile *objfile, struct bfd *abfd)
        {
          storage = bfd_zalloc (abfd, sizeof (struct objfile_per_bfd_storage));
          set_bfd_data (abfd, objfiles_bfd_data, storage);
+
+         /* Look up the gdbarch associated with the BFD.  */
+         storage->gdbarch = gdbarch_from_bfd (abfd);
        }
       else
        storage = OBSTACK_ZALLOC (&objfile->objfile_obstack,
@@ -180,51 +191,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, 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
@@ -232,6 +248,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.  */
@@ -246,7 +267,7 @@ 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;
 
@@ -259,6 +280,14 @@ allocate_objfile (bfd *abfd, int flags)
 
   objfile_alloc_data (objfile);
 
+  if (name == NULL)
+    {
+      gdb_assert (abfd == NULL);
+      name = "<<anonymous objfile>>";
+    }
+  objfile->original_name = obstack_copy0 (&objfile->objfile_obstack, name,
+                                         strlen (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.  */
@@ -267,19 +296,11 @@ 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;
@@ -311,7 +332,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;
 }
@@ -320,7 +341,7 @@ allocate_objfile (bfd *abfd, int flags)
 struct gdbarch *
 get_objfile_arch (struct objfile *objfile)
 {
-  return objfile->gdbarch;
+  return objfile->per_bfd->gdbarch;
 }
 
 /* If there is a valid and known entry point, function fills *ENTRY_P with it
@@ -567,6 +588,7 @@ free_objfile (struct objfile *objfile)
   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
@@ -596,9 +618,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
@@ -626,8 +645,6 @@ free_objfile (struct objfile *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)
@@ -639,8 +656,9 @@ free_objfile (struct objfile *objfile)
   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);
 }
 
@@ -702,7 +720,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 =
@@ -802,7 +820,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));
     }
@@ -815,12 +837,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));
@@ -845,7 +867,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;
@@ -869,7 +892,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);
@@ -1251,10 +1274,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));
            }
@@ -1279,11 +1302,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);
@@ -1353,7 +1379,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,
@@ -1361,7 +1389,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
@@ -1383,12 +1412,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;
@@ -1397,19 +1424,43 @@ 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 (arg);
 }
 
 /* The default implementation for the "iterate_over_objfiles_in_search_order"
@@ -1437,6 +1488,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;
 
This page took 0.029197 seconds and 4 git commands to generate.