*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / objfiles.c
index 35b67258bd4eeaca5d40b1d6b590f43d4a1666b6..cacdabae3b7352e4cd2898608a87c221af49bf4f 100644 (file)
@@ -1,7 +1,7 @@
 /* GDB routines for manipulating objfiles.
 
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
+   2002, 2003, 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
 #include "dictionary.h"
 #include "source.h"
 #include "addrmap.h"
+#include "arch-utils.h"
+#include "exec.h"
+#include "observer.h"
+#include "complaints.h"
+#include "psymtab.h"
+#include "solist.h"
 
 /* Prototypes for local functions */
 
@@ -57,19 +63,57 @@ static void objfile_free_data (struct objfile *objfile);
 /* Externally visible variables that are owned by this module.
    See declarations in objfile.h for more info. */
 
-struct objfile *object_files;  /* Linked list of all objfiles */
 struct objfile *current_objfile;       /* For symbol file being read in */
-struct objfile *symfile_objfile;       /* Main symbol table loaded from */
 struct objfile *rt_common_objfile;     /* For runtime common symbols */
 
+struct objfile_pspace_info
+{
+  int objfiles_changed_p;
+  struct obj_section **sections;
+  int num_sections;
+};
+
+/* Per-program-space data key.  */
+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;
+
+  info = program_space_data (pspace, objfiles_pspace_data);
+  if (info != NULL)
+    {
+      xfree (info->sections);
+      xfree (info);
+    }
+}
+
+/* Get the current svr4 data.  If none is found yet, add it now.  This
+   function always returns a valid object.  */
+
+static struct objfile_pspace_info *
+get_objfile_pspace_data (struct program_space *pspace)
+{
+  struct objfile_pspace_info *info;
+
+  info = program_space_data (pspace, objfiles_pspace_data);
+  if (info == NULL)
+    {
+      info = XZALLOC (struct objfile_pspace_info);
+      set_program_space_data (pspace, objfiles_pspace_data, info);
+    }
+
+  return info;
+}
+
+/* Records whether any objfiles appeared or disappeared since we last updated
+   address to obj section map.  */
+
 /* Locate all mappable sections of a BFD file. 
    objfile_p_char is a char * to get it through
    bfd_map_over_sections; we cast it back to its proper type.  */
 
-#ifndef TARGET_KEEP_SECTION
-#define TARGET_KEEP_SECTION(ASECT)     0
-#endif
-
 /* 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
@@ -85,19 +129,17 @@ add_to_objfile_sections (struct bfd *abfd, struct bfd_section *asect,
 
   aflag = bfd_get_section_flags (abfd, asect);
 
-  if (!(aflag & SEC_ALLOC) && !(TARGET_KEEP_SECTION (asect)))
+  if (!(aflag & SEC_ALLOC))
     return;
 
   if (0 == bfd_section_size (abfd, asect))
     return;
-  section.offset = 0;
   section.objfile = objfile;
   section.the_bfd_section = asect;
   section.ovly_mapped = 0;
-  section.addr = bfd_section_vma (abfd, asect);
-  section.endaddr = section.addr + bfd_section_size (abfd, asect);
   obstack_grow (&objfile->objfile_obstack, (char *) &section, sizeof (section));
-  objfile->sections_end = (struct obj_section *) (((unsigned long) objfile->sections_end) + 1);
+  objfile->sections_end
+    = (struct obj_section *) (((size_t) objfile->sections_end) + 1);
 }
 
 /* Builds a section table for OBJFILE.
@@ -126,10 +168,10 @@ build_objfile_section_table (struct objfile *objfile)
      waste some memory.  */
 
   objfile->sections_end = 0;
-  bfd_map_over_sections (objfile->obfd, add_to_objfile_sections, (char *) objfile);
-  objfile->sections = (struct obj_section *)
-    obstack_finish (&objfile->objfile_obstack);
-  objfile->sections_end = objfile->sections + (unsigned long) objfile->sections_end;
+  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;
   return (0);
 }
 
@@ -154,25 +196,16 @@ build_objfile_section_table (struct objfile *objfile)
 struct objfile *
 allocate_objfile (bfd *abfd, int flags)
 {
-  struct objfile *objfile = NULL;
-  struct objfile *last_one = NULL;
+  struct objfile *objfile;
 
-  /* If we don't support mapped symbol files, didn't ask for the file to be
-     mapped, or failed to open the mapped file for some reason, then revert
-     back to an unmapped objfile. */
-
-  if (objfile == NULL)
-    {
-      objfile = (struct objfile *) xmalloc (sizeof (struct objfile));
-      memset (objfile, 0, sizeof (struct objfile));
-      objfile->md = NULL;
-      objfile->psymbol_cache = bcache_xmalloc ();
-      objfile->macro_cache = bcache_xmalloc ();
-      /* 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 = (struct objfile *) xzalloc (sizeof (struct objfile));
+  objfile->psymbol_cache = bcache_xmalloc ();
+  objfile->macro_cache = bcache_xmalloc ();
+  objfile->filename_cache = bcache_xmalloc ();
+  /* 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);
 
@@ -180,13 +213,16 @@ allocate_objfile (bfd *abfd, int flags)
      that any data that is reference is saved in the per-objfile data
      region. */
 
-  objfile->obfd = abfd;
+  objfile->obfd = gdb_bfd_ref (abfd);
   if (objfile->name != NULL)
     {
       xfree (objfile->name);
     }
   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);
 
@@ -203,6 +239,8 @@ allocate_objfile (bfd *abfd, int flags)
       objfile->name = xstrdup ("<<anonymous objfile>>");
     }
 
+  objfile->pspace = current_program_space;
+
   /* Initialize the section indexes for this objfile, so that we can
      later detect if they are used w/o being properly assigned to. */
 
@@ -222,6 +260,8 @@ allocate_objfile (bfd *abfd, int flags)
     object_files = objfile;
   else
     {
+      struct objfile *last_one;
+
       for (last_one = object_files;
           last_one->next;
           last_one = last_one->next);
@@ -231,7 +271,17 @@ allocate_objfile (bfd *abfd, int flags)
   /* Save passed in flag bits. */
   objfile->flags |= flags;
 
-  return (objfile);
+  /* Rebuild section map next time we need it.  */
+  get_objfile_pspace_data (objfile->pspace)->objfiles_changed_p = 1;
+
+  return objfile;
+}
+
+/* Retrieve the gdbarch associated with OBJFILE.  */
+struct gdbarch *
+get_objfile_arch (struct objfile *objfile)
+{
+  return objfile->gdbarch;
 }
 
 /* Initialize entry point information for this objfile. */
@@ -247,20 +297,64 @@ init_entry_point_info (struct objfile *objfile)
       /* 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 = INVALID_ENTRY_POINT;
+      objfile->ei.entry_point_p = 0;
     }
 }
 
-/* Get current entry point address.  */
+/* If there is a valid and known entry point, function fills *ENTRY_P with it
+   and returns non-zero; otherwise it returns zero.  */
+
+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;
+
+  /* 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;
+}
+
+/* Get current entry point address.  Call error if it is not known.  */
 
 CORE_ADDR
 entry_point_address (void)
 {
-  return symfile_objfile ? symfile_objfile->ei.entry_point : 0;
+  CORE_ADDR retval;
+
+  if (!entry_point_address_query (&retval))
+    error (_("Entry point address is not known."));
+
+  return retval;
 }
 
 /* Create the terminating entry of OBJFILE's minimal symbol table.
@@ -286,6 +380,45 @@ terminate_minimal_symbol_table (struct objfile *objfile)
   }
 }
 
+/* Iterator on PARENT and every separate debug objfile of PARENT.
+   The usage pattern is:
+     for (objfile = parent;
+          objfile;
+          objfile = objfile_separate_debug_iterate (parent, objfile))
+       ...
+*/
+
+struct objfile *
+objfile_separate_debug_iterate (const struct objfile *parent,
+                                const struct objfile *objfile)
+{
+  struct objfile *res;
+
+  /* If any, return the first child.  */
+  res = objfile->separate_debug_objfile;
+  if (res)
+    return res;
+
+  /* Common case where there is no separate debug objfile.  */
+  if (objfile == parent)
+    return NULL;
+
+  /* Return the brother if any.  Note that we don't iterate on brothers of
+     the parents.  */
+  res = objfile->separate_debug_objfile_link;
+  if (res)
+    return res;
+
+  for (res = objfile->separate_debug_objfile_backlink;
+       res != parent;
+       res = res->separate_debug_objfile_backlink)
+    {
+      gdb_assert (res != NULL);
+      if (res->separate_debug_objfile_link)
+        return res->separate_debug_objfile_link;
+    }
+  return NULL;
+}
 
 /* Put one object file before a specified on in the global list.
    This can be used to make sure an object file is destroyed before
@@ -363,6 +496,41 @@ unlink_objfile (struct objfile *objfile)
                  _("unlink_objfile: objfile already unlinked"));
 }
 
+/* Add OBJFILE as a separate debug objfile of PARENT.  */
+
+void
+add_separate_debug_objfile (struct objfile *objfile, struct objfile *parent)
+{
+  gdb_assert (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);
+
+  objfile->separate_debug_objfile_backlink = parent;
+  objfile->separate_debug_objfile_link = parent->separate_debug_objfile;
+  parent->separate_debug_objfile = objfile;
+
+  /* Put the separate debug object before the normal one, this is so that
+     usage of the ALL_OBJFILES_SAFE macro will stay safe. */
+  put_objfile_before (objfile, parent);
+}
+
+/* Free all separate debug objfile of OBJFILE, but don't free OBJFILE
+   itself.  */
+
+void
+free_objfile_separate_debug (struct objfile *objfile)
+{
+  struct objfile *child;
+
+  for (child = objfile->separate_debug_objfile; child;)
+    {
+      struct objfile *next_child = child->separate_debug_objfile_link;
+      free_objfile (child);
+      child = next_child;
+    }
+}
 
 /* Destroy an objfile and all the symtabs and psymtabs under it.  Note
    that as much as possible is allocated on the objfile_obstack 
@@ -383,16 +551,38 @@ unlink_objfile (struct objfile *objfile)
 void
 free_objfile (struct objfile *objfile)
 {
-  if (objfile->separate_debug_objfile)
-    {
-      free_objfile (objfile->separate_debug_objfile);
-    }
-  
+  /* Free all separate debug objfiles.  */
+  free_objfile_separate_debug (objfile);
+
   if (objfile->separate_debug_objfile_backlink)
     {
       /* We freed the separate debug file, make sure the base objfile
         doesn't reference it.  */
-      objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL;
+      struct objfile *child;
+
+      child = objfile->separate_debug_objfile_backlink->separate_debug_objfile;
+
+      if (child == objfile)
+        {
+          /* OBJFILE is the first child.  */
+          objfile->separate_debug_objfile_backlink->separate_debug_objfile =
+            objfile->separate_debug_objfile_link;
+        }
+      else
+        {
+          /* Find OBJFILE in the list.  */
+          while (1)
+            {
+              if (child->separate_debug_objfile_link == objfile)
+                {
+                  child->separate_debug_objfile_link =
+                    objfile->separate_debug_objfile_link;
+                  break;
+                }
+              child = child->separate_debug_objfile_link;
+              gdb_assert (child);
+            }
+        }
     }
   
   /* Remove any references to this objfile in the global value
@@ -411,23 +601,17 @@ free_objfile (struct objfile *objfile)
       (*objfile->sf->sym_finish) (objfile);
     }
 
-  /* We always close the bfd. */
+  /* Discard any data modules have associated with the objfile.  */
+  objfile_free_data (objfile);
 
-  if (objfile->obfd != NULL)
-    {
-      char *name = bfd_get_filename (objfile->obfd);
-      if (!bfd_close (objfile->obfd))
-       warning (_("cannot close \"%s\": %s"),
-                name, bfd_errmsg (bfd_get_error ()));
-      xfree (name);
-    }
+  gdb_bfd_unref (objfile->obfd);
 
   /* Remove it from the chain of all objfiles. */
 
   unlink_objfile (objfile);
 
-  /* If we are going to free the runtime common objfile, mark it
-     as unallocated.  */
+  if (objfile == symfile_objfile)
+    symfile_objfile = NULL;
 
   if (objfile == rt_common_objfile)
     rt_common_objfile = NULL;
@@ -465,7 +649,6 @@ free_objfile (struct objfile *objfile)
 
   /* The last thing we do is free the objfile struct itself. */
 
-  objfile_free_data (objfile);
   if (objfile->name != NULL)
     {
       xfree (objfile->name);
@@ -477,11 +660,15 @@ free_objfile (struct objfile *objfile)
   /* Free the obstacks for non-reusable objfiles */
   bcache_xfree (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;
+
   xfree (objfile);
-  objfile = NULL;
 }
 
 static void
@@ -502,6 +689,11 @@ void
 free_all_objfiles (void)
 {
   struct objfile *objfile, *temp;
+  struct so_list *so;
+
+  /* Any objfile referencewould become stale.  */
+  for (so = master_so_list (); so; so = so->next)
+    gdb_assert (so->objfile == NULL);
 
   ALL_OBJFILES_SAFE (objfile, temp)
   {
@@ -511,10 +703,13 @@ free_all_objfiles (void)
 }
 \f
 /* Relocate OBJFILE to NEW_OFFSETS.  There should be OBJFILE->NUM_SECTIONS
-   entries in new_offsets.  */
-void
-objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
+   entries in new_offsets.  SEPARATE_DEBUG_OBJFILE is not touched here.
+   Return non-zero iff any change happened.  */
+
+static int
+objfile_relocate1 (struct objfile *objfile, struct section_offsets *new_offsets)
 {
+  struct obj_section *s;
   struct section_offsets *delta =
     ((struct section_offsets *) 
      alloca (SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)));
@@ -530,7 +725,7 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
          something_changed = 1;
       }
     if (!something_changed)
-      return;
+      return 0;
   }
 
   /* OK, get all the symtabs.  */
@@ -556,6 +751,10 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
        continue;
 
       bv = BLOCKVECTOR (s);
+      if (BLOCKVECTOR_MAP (bv))
+       addrmap_relocate (BLOCKVECTOR_MAP (bv),
+                         ANOFFSET (delta, s->block_line_section));
+
       for (i = 0; i < BLOCKVECTOR_NBLOCKS (bv); ++i)
        {
          struct block *b;
@@ -565,9 +764,6 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
          b = BLOCKVECTOR_BLOCK (bv, i);
          BLOCK_START (b) += ANOFFSET (delta, s->block_line_section);
          BLOCK_END (b) += ANOFFSET (delta, s->block_line_section);
-          if (BLOCKVECTOR_MAP (bv))
-            addrmap_relocate (BLOCKVECTOR_MAP (bv),
-                              ANOFFSET (delta, s->block_line_section));
 
          ALL_BLOCK_SYMBOLS (b, iter, sym)
            {
@@ -578,8 +774,7 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
                 But I'm leaving out that test, on the theory that
                 they can't possibly pass the tests below.  */
              if ((SYMBOL_CLASS (sym) == LOC_LABEL
-                  || SYMBOL_CLASS (sym) == LOC_STATIC
-                  || SYMBOL_CLASS (sym) == LOC_INDIRECT)
+                  || SYMBOL_CLASS (sym) == LOC_STATIC)
                  && SYMBOL_SECTION (sym) >= 0)
                {
                  SYMBOL_VALUE_ADDRESS (sym) +=
@@ -590,38 +785,12 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
     }
   }
 
-  {
-    struct partial_symtab *p;
+  if (objfile->psymtabs_addrmap)
+    addrmap_relocate (objfile->psymtabs_addrmap,
+                     ANOFFSET (delta, SECT_OFF_TEXT (objfile)));
 
-    ALL_OBJFILE_PSYMTABS (objfile, p)
-    {
-      p->textlow += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
-      p->texthigh += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
-    }
-  }
-
-  {
-    struct partial_symbol **psym;
-
-    for (psym = objfile->global_psymbols.list;
-        psym < objfile->global_psymbols.next;
-        psym++)
-      {
-       fixup_psymbol_section (*psym, objfile);
-       if (SYMBOL_SECTION (*psym) >= 0)
-         SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
-                                                   SYMBOL_SECTION (*psym));
-      }
-    for (psym = objfile->static_psymbols.list;
-        psym < objfile->static_psymbols.next;
-        psym++)
-      {
-       fixup_psymbol_section (*psym, objfile);
-       if (SYMBOL_SECTION (*psym) >= 0)
-         SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
-                                                   SYMBOL_SECTION (*psym));
-      }
-  }
+  if (objfile->sf)
+    objfile->sf->qf->relocate (objfile, new_offsets, delta);
 
   {
     struct minimal_symbol *msym;
@@ -633,13 +802,7 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
      to be out of order.  */
   msymbols_sort (objfile);
 
-  {
-    int i;
-    for (i = 0; i < objfile->num_sections; ++i)
-      (objfile->section_offsets)->offsets[i] = ANOFFSET (new_offsets, i);
-  }
-
-  if (objfile->ei.entry_point != ~(CORE_ADDR) 0)
+  if (objfile->ei.entry_point_p)
     {
       /* Relocate ei.entry_point with its section offset, use SECT_OFF_TEXT
         only as a fallback.  */
@@ -652,24 +815,111 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
     }
 
   {
-    struct obj_section *s;
-    bfd *abfd;
+    int i;
+    for (i = 0; i < objfile->num_sections; ++i)
+      (objfile->section_offsets)->offsets[i] = ANOFFSET (new_offsets, i);
+  }
 
-    abfd = objfile->obfd;
+  /* Rebuild section map next time we need it.  */
+  get_objfile_pspace_data (objfile->pspace)->objfiles_changed_p = 1;
 
-    ALL_OBJFILE_OSECTIONS (objfile, s)
-      {
-       int idx = s->the_bfd_section->index;
-       
-       s->addr += ANOFFSET (delta, idx);
-       s->endaddr += ANOFFSET (delta, idx);
-      }
-  }
+  /* Update the table in exec_ops, used to read memory.  */
+  ALL_OBJFILE_OSECTIONS (objfile, s)
+    {
+      int idx = s->the_bfd_section->index;
+
+      exec_set_section_address (bfd_get_filename (objfile->obfd), idx,
+                               obj_section_addr (s));
+    }
+
+  /* Data changed.  */
+  return 1;
+}
+
+/* Relocate OBJFILE to NEW_OFFSETS.  There should be OBJFILE->NUM_SECTIONS
+   entries in new_offsets.  Process also OBJFILE's SEPARATE_DEBUG_OBJFILEs.
+
+   The number and ordering of sections does differ between the two objfiles.
+   Only their names match.  Also the file offsets will differ (objfile being
+   possibly prelinked but separate_debug_objfile is probably not prelinked) but
+   the in-memory absolute address as specified by NEW_OFFSETS must match both
+   files.  */
+
+void
+objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
+{
+  struct objfile *debug_objfile;
+  int changed = 0;
+
+  changed |= objfile_relocate1 (objfile, new_offsets);
+
+  for (debug_objfile = objfile->separate_debug_objfile;
+       debug_objfile;
+       debug_objfile = objfile_separate_debug_iterate (objfile, debug_objfile))
+    {
+      struct section_addr_info *objfile_addrs;
+      struct section_offsets *new_debug_offsets;
+      int new_debug_num_sections;
+      struct cleanup *my_cleanups;
+
+      objfile_addrs = build_section_addr_info_from_objfile (objfile);
+      my_cleanups = make_cleanup (xfree, objfile_addrs);
+
+      /* Here OBJFILE_ADDRS contain the correct absolute addresses, the
+        relative ones must be already created according to debug_objfile.  */
+
+      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,
+                                            debug_objfile->num_sections,
+                                            objfile_addrs);
+
+      changed |= objfile_relocate1 (debug_objfile, new_debug_offsets);
+
+      do_cleanups (my_cleanups);
+    }
 
   /* Relocate breakpoints as necessary, after things are relocated. */
-  breakpoint_re_set ();
+  if (changed)
+    breakpoint_re_set ();
 }
 \f
+/* Return non-zero if OBJFILE has partial symbols.  */
+
+int
+objfile_has_partial_symbols (struct objfile *objfile)
+{
+  return objfile->sf ? objfile->sf->qf->has_symbols (objfile) : 0;
+}
+
+/* Return non-zero if OBJFILE has full symbols.  */
+
+int
+objfile_has_full_symbols (struct objfile *objfile)
+{
+  return objfile->symtabs != NULL;
+}
+
+/* Return non-zero if OBJFILE has full or partial symbols, either directly
+   or through a separate debug file.  */
+
+int
+objfile_has_symbols (struct objfile *objfile)
+{
+  struct objfile *o;
+
+  for (o = objfile; o; o = objfile_separate_debug_iterate (objfile, o))
+    if (objfile_has_partial_symbols (o) || objfile_has_full_symbols (o))
+      return 1;
+  return 0;
+}
+
+
 /* Many places in gdb want to test just to see if we have any partial
    symbols available.  This function returns zero if none are currently
    available, nonzero otherwise. */
@@ -681,10 +931,8 @@ have_partial_symbols (void)
 
   ALL_OBJFILES (ofp)
   {
-    if (ofp->psymtabs != NULL)
-      {
-       return 1;
-      }
+    if (objfile_has_partial_symbols (ofp))
+      return 1;
   }
   return 0;
 }
@@ -700,10 +948,8 @@ have_full_symbols (void)
 
   ALL_OBJFILES (ofp)
   {
-    if (ofp->symtabs != NULL)
-      {
-       return 1;
-      }
+    if (objfile_has_full_symbols (ofp))
+      return 1;
   }
   return 0;
 }
@@ -749,33 +995,347 @@ have_minimal_symbols (void)
   return 0;
 }
 
-/* Returns a section whose range includes PC and SECTION, or NULL if
-   none found.  Note the distinction between the return type, struct
-   obj_section (which is defined in gdb), and the input type "struct
-   bfd_section" (which is a bfd-defined data type).  The obj_section
-   contains a pointer to the "struct bfd_section".  */
+/* Qsort comparison function.  */
 
-struct obj_section *
-find_pc_sect_section (CORE_ADDR pc, struct bfd_section *section)
+static int
+qsort_cmp (const void *a, const void *b)
 {
-  struct obj_section *s;
+  const struct obj_section *sect1 = *(const struct obj_section **) a;
+  const struct obj_section *sect2 = *(const struct obj_section **) b;
+  const CORE_ADDR sect1_addr = obj_section_addr (sect1);
+  const CORE_ADDR sect2_addr = obj_section_addr (sect2);
+
+  if (sect1_addr < sect2_addr)
+    return -1;
+  else if (sect1_addr > sect2_addr)
+    return 1;
+  else
+   {
+     /* Sections are at the same address.  This could happen if
+       A) we have an objfile and a separate debuginfo.
+       B) we are confused, and have added sections without proper relocation,
+       or something like that. */
+
+     const struct objfile *const objfile1 = sect1->objfile;
+     const struct objfile *const objfile2 = sect2->objfile;
+
+     if (objfile1->separate_debug_objfile == objfile2
+        || objfile2->separate_debug_objfile == objfile1)
+       {
+        /* Case A.  The ordering doesn't matter: separate debuginfo files
+           will be filtered out later.  */
+
+        return 0;
+       }
+
+     /* Case B.  Maintain stable sort order, so bugs in GDB are easier to
+       triage.  This section could be slow (since we iterate over all
+       objfiles in each call to qsort_cmp), but this shouldn't happen
+       very often (GDB is already in a confused state; one hopes this
+       doesn't happen at all).  If you discover that significant time is
+       spent in the loops below, do 'set complaints 100' and examine the
+       resulting complaints.  */
+
+     if (objfile1 == objfile2)
+       {
+        /* Both sections came from the same objfile.  We are really confused.
+           Sort on sequence order of sections within the objfile.  */
+
+        const struct obj_section *osect;
+
+        ALL_OBJFILE_OSECTIONS (objfile1, osect)
+          if (osect == sect1)
+            return -1;
+          else if (osect == sect2)
+            return 1;
+
+        /* We should have found one of the sections before getting here.  */
+        gdb_assert (0);
+       }
+     else
+       {
+        /* Sort on sequence number of the objfile in the chain.  */
+
+        const struct objfile *objfile;
+
+        ALL_OBJFILES (objfile)
+          if (objfile == objfile1)
+            return -1;
+          else if (objfile == objfile2)
+            return 1;
+
+        /* We should have found one of the objfiles before getting here.  */
+        gdb_assert (0);
+       }
+
+   }
+
+  /* Unreachable.  */
+  gdb_assert (0);
+  return 0;
+}
+
+/* Select "better" obj_section to keep.  We prefer the one that came from
+   the real object, rather than the one from separate debuginfo.
+   Most of the time the two sections are exactly identical, but with
+   prelinking the .rel.dyn section in the real object may have different
+   size.  */
+
+static struct obj_section *
+preferred_obj_section (struct obj_section *a, struct obj_section *b)
+{
+  gdb_assert (obj_section_addr (a) == obj_section_addr (b));
+  gdb_assert ((a->objfile->separate_debug_objfile == b->objfile)
+             || (b->objfile->separate_debug_objfile == a->objfile));
+  gdb_assert ((a->objfile->separate_debug_objfile_backlink == b->objfile)
+             || (b->objfile->separate_debug_objfile_backlink == a->objfile));
+
+  if (a->objfile->separate_debug_objfile != NULL)
+    return a;
+  return b;
+}
+
+/* Return 1 if SECTION should be inserted into the section map.
+   We want to insert only non-overlay and non-TLS section.  */
+
+static int
+insert_section_p (const struct bfd *abfd,
+                 const struct bfd_section *section)
+{
+  const bfd_vma lma = bfd_section_lma (abfd, section);
+
+  if (lma != 0 && lma != bfd_section_vma (abfd, section)
+      && (bfd_get_file_flags (abfd) & BFD_IN_MEMORY) == 0)
+    /* This is an overlay section.  IN_MEMORY check is needed to avoid
+       discarding sections from the "system supplied DSO" (aka vdso)
+       on some Linux systems (e.g. Fedora 11).  */
+    return 0;
+  if ((bfd_get_section_flags (abfd, section) & SEC_THREAD_LOCAL) != 0)
+    /* This is a TLS section.  */
+    return 0;
+
+  return 1;
+}
+
+/* Filter out overlapping sections where one section came from the real
+   objfile, and the other from a separate debuginfo file.
+   Return the size of table after redundant sections have been eliminated.  */
+
+static int
+filter_debuginfo_sections (struct obj_section **map, int map_size)
+{
+  int i, j;
+
+  for (i = 0, j = 0; i < map_size - 1; i++)
+    {
+      struct obj_section *const sect1 = map[i];
+      struct obj_section *const sect2 = map[i + 1];
+      const struct objfile *const objfile1 = sect1->objfile;
+      const struct objfile *const objfile2 = sect2->objfile;
+      const CORE_ADDR sect1_addr = obj_section_addr (sect1);
+      const CORE_ADDR sect2_addr = obj_section_addr (sect2);
+
+      if (sect1_addr == sect2_addr
+         && (objfile1->separate_debug_objfile == objfile2
+             || objfile2->separate_debug_objfile == objfile1))
+       {
+         map[j++] = preferred_obj_section (sect1, sect2);
+         ++i;
+       }
+      else
+       map[j++] = sect1;
+    }
+
+  if (i < map_size)
+    {
+      gdb_assert (i == map_size - 1);
+      map[j++] = map[i];
+    }
+
+  /* The map should not have shrunk to less than half the original size.  */
+  gdb_assert (map_size / 2 <= j);
+
+  return j;
+}
+
+/* Filter out overlapping sections, issuing a warning if any are found.
+   Overlapping sections could really be overlay sections which we didn't
+   classify as such in insert_section_p, or we could be dealing with a
+   corrupt binary.  */
+
+static int
+filter_overlapping_sections (struct obj_section **map, int map_size)
+{
+  int i, j;
+
+  for (i = 0, j = 0; i < map_size - 1; )
+    {
+      int k;
+
+      map[j++] = map[i];
+      for (k = i + 1; k < map_size; k++)
+       {
+         struct obj_section *const sect1 = map[i];
+         struct obj_section *const sect2 = map[k];
+         const CORE_ADDR sect1_addr = obj_section_addr (sect1);
+         const CORE_ADDR sect2_addr = obj_section_addr (sect2);
+         const CORE_ADDR sect1_endaddr = obj_section_endaddr (sect1);
+
+         gdb_assert (sect1_addr <= sect2_addr);
+
+         if (sect1_endaddr <= sect2_addr)
+           break;
+         else
+           {
+             /* We have an overlap.  Report it.  */
+
+             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;
+
+             const CORE_ADDR sect2_endaddr = obj_section_endaddr (sect2);
+
+             struct gdbarch *const gdbarch = get_objfile_arch (objf1);
+
+             complaint (&symfile_complaints,
+                        _("unexpected overlap between:\n"
+                          " (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,
+                        paddress (gdbarch, sect1_addr),
+                        paddress (gdbarch, sect1_endaddr),
+                        bfd_section_name (abfd2, bfds2), objf2->name,
+                        paddress (gdbarch, sect2_addr),
+                        paddress (gdbarch, sect2_endaddr));
+           }
+       }
+      i = k;
+    }
+
+  if (i < map_size)
+    {
+      gdb_assert (i == map_size - 1);
+      map[j++] = map[i];
+    }
+
+  return j;
+}
+
+
+/* Update PMAP, PMAP_SIZE with sections from all objfiles, excluding any
+   TLS, overlay and overlapping sections.  */
+
+static void
+update_section_map (struct program_space *pspace,
+                   struct obj_section ***pmap, int *pmap_size)
+{
+  int alloc_size, map_size, i;
+  struct obj_section *s, **map;
   struct objfile *objfile;
 
-  ALL_OBJSECTIONS (objfile, s)
-    if ((section == 0 || section == s->the_bfd_section) &&
-       s->addr <= pc && pc < s->endaddr)
-      return (s);
+  gdb_assert (get_objfile_pspace_data (pspace)->objfiles_changed_p != 0);
+
+  map = *pmap;
+  xfree (map);
 
-  return (NULL);
+  alloc_size = 0;
+  ALL_PSPACE_OBJFILES (pspace, objfile)
+    ALL_OBJFILE_OSECTIONS (objfile, s)
+      if (insert_section_p (objfile->obfd, s->the_bfd_section))
+       alloc_size += 1;
+
+  /* This happens on detach/attach (e.g. in gdb.base/attach.exp).  */
+  if (alloc_size == 0)
+    {
+      *pmap = NULL;
+      *pmap_size = 0;
+      return;
+    }
+
+  map = xmalloc (alloc_size * sizeof (*map));
+
+  i = 0;
+  ALL_PSPACE_OBJFILES (pspace, objfile)
+    ALL_OBJFILE_OSECTIONS (objfile, s)
+      if (insert_section_p (objfile->obfd, s->the_bfd_section))
+       map[i++] = s;
+
+  qsort (map, alloc_size, sizeof (*map), qsort_cmp);
+  map_size = filter_debuginfo_sections(map, alloc_size);
+  map_size = filter_overlapping_sections(map, map_size);
+
+  if (map_size < alloc_size)
+    /* Some sections were eliminated.  Trim excess space.  */
+    map = xrealloc (map, map_size * sizeof (*map));
+  else
+    gdb_assert (alloc_size == map_size);
+
+  *pmap = map;
+  *pmap_size = map_size;
 }
 
-/* Returns a section whose range includes PC or NULL if none found. 
-   Backward compatibility, no section.  */
+/* Bsearch comparison function. */
+
+static int
+bsearch_cmp (const void *key, const void *elt)
+{
+  const CORE_ADDR pc = *(CORE_ADDR *) key;
+  const struct obj_section *section = *(const struct obj_section **) elt;
+
+  if (pc < obj_section_addr (section))
+    return -1;
+  if (pc < obj_section_endaddr (section))
+    return 0;
+  return 1;
+}
+
+/* Returns a section whose range includes PC or NULL if none found.   */
 
 struct obj_section *
 find_pc_section (CORE_ADDR pc)
 {
-  return find_pc_sect_section (pc, find_pc_mapped_section (pc));
+  struct objfile_pspace_info *pspace_info;
+  struct obj_section *s, **sp;
+
+  /* Check for mapped overlay section first.  */
+  s = find_pc_mapped_section (pc);
+  if (s)
+    return s;
+
+  pspace_info = get_objfile_pspace_data (current_program_space);
+  if (pspace_info->objfiles_changed_p != 0)
+    {
+      update_section_map (current_program_space,
+                         &pspace_info->sections,
+                         &pspace_info->num_sections);
+
+      /* Don't need updates to section map until objfiles are added,
+         removed or relocated.  */
+      pspace_info->objfiles_changed_p = 0;
+    }
+
+  /* The C standard (ISO/IEC 9899:TC2) requires the BASE argument to
+     bsearch be non-NULL.  */
+  if (pspace_info->sections == NULL)
+    {
+      gdb_assert (pspace_info->num_sections == 0);
+      return NULL;
+    }
+
+  sp = (struct obj_section **) bsearch (&pc,
+                                       pspace_info->sections,
+                                       pspace_info->num_sections,
+                                       sizeof (*pspace_info->sections),
+                                       bsearch_cmp);
+  if (sp != NULL)
+    return *sp;
+  return NULL;
 }
 
 
@@ -804,6 +1364,8 @@ in_plt_section (CORE_ADDR pc, char *name)
 struct objfile_data
 {
   unsigned index;
+  void (*save) (struct objfile *, void *);
+  void (*free) (struct objfile *, void *);
 };
 
 struct objfile_data_registration
@@ -821,7 +1383,8 @@ struct objfile_data_registry
 static struct objfile_data_registry objfile_data_registry = { NULL, 0 };
 
 const struct objfile_data *
-register_objfile_data (void)
+register_objfile_data_with_cleanup (void (*save) (struct objfile *, void *),
+                                   void (*free) (struct objfile *, void *))
 {
   struct objfile_data_registration **curr;
 
@@ -833,10 +1396,18 @@ register_objfile_data (void)
   (*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);
+}
+
 static void
 objfile_alloc_data (struct objfile *objfile)
 {
@@ -849,6 +1420,7 @@ static void
 objfile_free_data (struct objfile *objfile)
 {
   gdb_assert (objfile->data != NULL);
+  clear_objfile_data (objfile);
   xfree (objfile->data);
   objfile->data = NULL;
 }
@@ -856,7 +1428,27 @@ objfile_free_data (struct objfile *objfile)
 void
 clear_objfile_data (struct objfile *objfile)
 {
+  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 *));
 }
 
@@ -874,3 +1466,92 @@ objfile_data (struct objfile *objfile, const struct objfile_data *data)
   gdb_assert (data->index < objfile->num_data);
   return objfile->data[data->index];
 }
+
+/* Set objfiles_changed_p 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;
+}
+
+/* Close ABFD, and warn if that fails.  */
+
+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)
+{
+  int *p_refcount;
+
+  if (abfd == NULL)
+    return NULL;
+
+  p_refcount = bfd_usrdata (abfd);
+
+  if (p_refcount != NULL)
+    {
+      *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.  */
+
+  name = bfd_get_filename (abfd);
+  gdb_bfd_close_or_warn (abfd);
+  xfree (name);
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern initialize_file_ftype _initialize_objfiles;
+
+void
+_initialize_objfiles (void)
+{
+  objfiles_pspace_data
+    = register_program_space_data_with_cleanup (objfiles_pspace_data_cleanup);
+}
This page took 0.036796 seconds and 4 git commands to generate.