2010-01-06 Tristan Gingold <gingold@adacore.com>
authorTristan Gingold <gingold@adacore.com>
Wed, 6 Jan 2010 10:11:04 +0000 (10:11 +0000)
committerTristan Gingold <gingold@adacore.com>
Wed, 6 Jan 2010 10:11:04 +0000 (10:11 +0000)
* symtab.c (lookup_global_symbol_from_objfile): Rename objfile
parameter to main_objfile.  Iterate on all separate debug objfiles.
* symfile.h (symbol_file_add_separate)
(find_separate_debug_file_by_debuglink): Remove parameter names.
* symfile.c (symbol_file_add_separate): Use add_separate_objfile.
(reread_symbols): Use free_objfile_separate_debug.
* objfiles.h (struct objfile): Add separate_debug_objfile_link.
Adjust comment.
(objfile_separate_debug_iterate, add_separate_debug_objfile)
(free_objfile_separate_debug): New prototypes.
* objfiles.c (objfile_separate_debug_iterate): New function.
(add_separate_debug_objfile, free_objfile_separate_debug): New
functions.
(free_objfile): Use free_objfile_separate_debug.  Adjust for
multiple separate debug objfile.
(objfile_has_symbols): Adjust comment.  Iterate on all separate
debug objfiles.
* minsyms.c (lookup_minimal_symbol): Adjust for multiple separate
debug objfile.
(lookup_minimal_symbol_text): Ditto.
(lookup_minimal_symbol_by_pc_name): Ditto.
(lookup_minimal_symbol_solib_trampoline): Ditto.
(lookup_minimal_symbol_by_pc_section_1): Iterate on all separate
debug objfiles.

gdb/ChangeLog
gdb/minsyms.c
gdb/objfiles.c
gdb/objfiles.h
gdb/symfile.c
gdb/symfile.h
gdb/symtab.c

index 74aba43077c0a6c150665ec5d7b522babfe9f729..3f12d0538387014d6f540855ae01ed97387a777d 100644 (file)
@@ -1,3 +1,30 @@
+2010-01-06  Tristan Gingold  <gingold@adacore.com>
+
+       * symtab.c (lookup_global_symbol_from_objfile): Rename objfile
+       parameter to main_objfile.  Iterate on all separate debug objfiles.
+       * symfile.h (symbol_file_add_separate)
+       (find_separate_debug_file_by_debuglink): Remove parameter names.
+       * symfile.c (symbol_file_add_separate): Use add_separate_objfile.
+       (reread_symbols): Use free_objfile_separate_debug.
+       * objfiles.h (struct objfile): Add separate_debug_objfile_link.
+       Adjust comment.
+       (objfile_separate_debug_iterate, add_separate_debug_objfile)
+       (free_objfile_separate_debug): New prototypes.
+       * objfiles.c (objfile_separate_debug_iterate): New function.
+       (add_separate_debug_objfile, free_objfile_separate_debug): New
+       functions.
+       (free_objfile): Use free_objfile_separate_debug.  Adjust for
+       multiple separate debug objfile.
+       (objfile_has_symbols): Adjust comment.  Iterate on all separate
+       debug objfiles.
+       * minsyms.c (lookup_minimal_symbol): Adjust for multiple separate
+       debug objfile.
+       (lookup_minimal_symbol_text): Ditto.
+       (lookup_minimal_symbol_by_pc_name): Ditto.
+       (lookup_minimal_symbol_solib_trampoline): Ditto.
+       (lookup_minimal_symbol_by_pc_section_1): Iterate on all separate
+       debug objfiles.
+
 2010-01-05  Stan Shebs  <stan@codesourcery.com>
 
        Add fast tracepoints.
index c177c02abc6786c382b6ae841996fdb817227871..ee730a449a9ceda261afd723741cefff6de1c975 100644 (file)
@@ -216,7 +216,7 @@ lookup_minimal_symbol (const char *name, const char *sfile,
        objfile = objfile->next)
     {
       if (objf == NULL || objf == objfile
-         || objf->separate_debug_objfile == objfile)
+         || objf == objfile->separate_debug_objfile_backlink)
        {
          /* Do two passes: the first over the ordinary hash table,
             and the second over the demangled hash table.  */
@@ -324,7 +324,7 @@ lookup_minimal_symbol_text (const char *name, struct objfile *objf)
        objfile = objfile->next)
     {
       if (objf == NULL || objf == objfile
-         || objf->separate_debug_objfile == objfile)
+         || objf == objfile->separate_debug_objfile_backlink)
        {
          for (msymbol = objfile->msymbol_hash[hash];
               msymbol != NULL && found_symbol == NULL;
@@ -377,7 +377,7 @@ lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name,
        objfile = objfile->next)
     {
       if (objf == NULL || objf == objfile
-         || objf->separate_debug_objfile == objfile)
+         || objf == objfile->separate_debug_objfile_backlink)
        {
          for (msymbol = objfile->msymbol_hash[hash];
               msymbol != NULL;
@@ -416,7 +416,7 @@ lookup_minimal_symbol_solib_trampoline (const char *name,
        objfile = objfile->next)
     {
       if (objf == NULL || objf == objfile
-         || objf->separate_debug_objfile == objfile)
+         || objf == objfile->separate_debug_objfile_backlink)
        {
          for (msymbol = objfile->msymbol_hash[hash];
               msymbol != NULL && found_symbol == NULL;
@@ -473,11 +473,10 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
      no telling which one will have the minimal symbols.  */
 
   gdb_assert (section != NULL);
-  objfile = section->objfile;
-  if (objfile->separate_debug_objfile)
-    objfile = objfile->separate_debug_objfile;
 
-  for (; objfile != NULL; objfile = objfile->separate_debug_objfile_backlink)
+  for (objfile = section->objfile;
+       objfile != NULL;
+       objfile = objfile_separate_debug_iterate (section->objfile, objfile))
     {
       /* If this objfile has a minimal symbol table, go search it using
          a binary search.  Note that a minimal symbol table always consists
index c241e8fa38ea04823c999dd7c355a528ecb0e938..9f779a47d88783e0cce61d7364a13ff276c925b0 100644 (file)
@@ -378,6 +378,42 @@ 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;
+
+  res = objfile->separate_debug_objfile;
+  if (res)
+    return res;
+
+  res = objfile->separate_debug_objfile_link;
+  if (res)
+    return res;
+
+  /* Common case where there is no separate debug objfile.  */
+  if (objfile == parent)
+    return NULL;
+
+  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
@@ -455,6 +491,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 
@@ -475,16 +546,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
@@ -778,25 +871,16 @@ objfile_has_full_symbols (struct objfile *objfile)
 }
 
 /* Return non-zero if OBJFILE has full or partial symbols, either directly
-   or throught its separate debug file.  */
+   or through a separate debug file.  */
 
 int
 objfile_has_symbols (struct objfile *objfile)
 {
-  struct objfile *separate_objfile;
-
-  if (objfile_has_partial_symbols (objfile)
-      || objfile_has_full_symbols (objfile))
-    return 1;
-
-  separate_objfile = objfile->separate_debug_objfile;
-  if (separate_objfile == NULL)
-    return 0;
-
-  if (objfile_has_partial_symbols (separate_objfile)
-      || objfile_has_full_symbols (separate_objfile))
-    return 1;
+  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;
 }
 
index cf5fc38624d9352316244dfaa9ab08559854ccd8..c689622729666838bb22cd74a2ed7a35e9990e25 100644 (file)
@@ -363,15 +363,25 @@ struct objfile
     struct obj_section
      *sections, *sections_end;
 
-    /* Link to objfile that contains the debug symbols for this one.
-       One is loaded if this file has an debug link to an existing
-       debug file with the right checksum */
+    /* GDB allows to have debug symbols in separate object files.  This is
+       used by .gnu_debuglink, ELF build id note and Mach-O OSO.
+       Although this is a tree structure, GDB only support one level
+       (ie a separate debug for a separate debug is not supported).  Note that
+       separate debug object are in the main chain and therefore will be
+       visited by ALL_OBJFILES & co iterators.  Separate debug objfile always
+       has a non-nul separate_debug_objfile_backlink.  */
+
+    /* Link to the first separate debug object, if any.  */
     struct objfile *separate_debug_objfile;
 
     /* If this is a separate debug object, this is used as a link to the
        actual executable objfile. */
     struct objfile *separate_debug_objfile_backlink;
-    
+
+    /* If this is a separate debug object, this is a link to the next one
+       for the same executable objfile.  */
+    struct objfile *separate_debug_objfile_link;
+
     /* Place to stash various statistics about this objfile */
       OBJSTATS;
 
@@ -452,14 +462,21 @@ extern int build_objfile_section_table (struct objfile *);
 
 extern void terminate_minimal_symbol_table (struct objfile *objfile);
 
+extern struct objfile *objfile_separate_debug_iterate (const struct objfile *,
+                                                       const struct objfile *);
+
 extern void put_objfile_before (struct objfile *, struct objfile *);
 
 extern void objfile_to_front (struct objfile *);
 
+extern void add_separate_debug_objfile (struct objfile *, struct objfile *);
+
 extern void unlink_objfile (struct objfile *);
 
 extern void free_objfile (struct objfile *);
 
+extern void free_objfile_separate_debug (struct objfile *);
+
 extern struct cleanup *make_cleanup_free_objfile (struct objfile *);
 
 extern void free_all_objfiles (void);
index fe91fb664d92167ae4bf61b26058202edf0f2c1f..91b78707adf378007dff28d2f5e7c8d83987c540 100644 (file)
@@ -1042,22 +1042,16 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd,
 void
 symbol_file_add_separate (bfd *bfd, int symfile_flags, struct objfile *objfile)
 {
-  /* Currently only one separate debug objfile is supported.  */
-  gdb_assert (objfile && objfile->separate_debug_objfile == NULL);
+  struct objfile *new_objfile;
 
-  objfile->separate_debug_objfile =
-    symbol_file_add_with_addrs_or_offsets
+  new_objfile = symbol_file_add_with_addrs_or_offsets
     (bfd, symfile_flags,
      0, /* No addr table.  */
      objfile->section_offsets, objfile->num_sections,
      objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW
                       | OBJF_USERLOADED));
-  objfile->separate_debug_objfile->separate_debug_objfile_backlink
-    = 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->separate_debug_objfile, objfile);
+  add_separate_debug_objfile (new_objfile, objfile);
 }
 
 /* Process the symbol file ABFD, as either the main file or as a
@@ -2272,14 +2266,9 @@ reread_symbols (void)
 
          clear_objfile_data (objfile);
 
-         /* Free the separate debug objfile if there is one.  It will be
+         /* Free the separate debug objfiles.  It will be
             automatically recreated by sym_read.  */
-         if (objfile->separate_debug_objfile)
-           {
-             /* Note: no need to clear separate_debug_objfile field as it is
-                done by free_objfile.  */
-             free_objfile (objfile->separate_debug_objfile);
-           }
+          free_objfile_separate_debug (objfile);
 
          /* FIXME: Do we have to free a whole linked list, or is this
             enough?  */
index 8eb1b5e25491a13c06e1e244017e2cb5383cb01b..f9c4daa7b9f97f4b522e6007a8cb18a99634c675 100644 (file)
@@ -238,10 +238,9 @@ extern struct objfile *symbol_file_add_from_bfd (bfd *, int,
                                                  struct section_addr_info *,
                                                  int);
 
-extern void symbol_file_add_separate (bfd *bfd, int symfile_flags,
-                                     struct objfile *objfile);
+extern void symbol_file_add_separate (bfd *, int, struct objfile *);
 
-extern char *find_separate_debug_file_by_debuglink (struct objfile *objfile);
+extern char *find_separate_debug_file_by_debuglink (struct objfile *);
 
 /* Create a new section_addr_info, with room for NUM_SECTIONS.  */
 
index d7b8145926b80eb78b77e90b124206de47f7ca8f..7f5dabdef621f1c67f9262f055793a4ea0cecd4a 100644 (file)
@@ -1499,48 +1499,50 @@ lookup_symbol_aux_block (const char *name, const char *linkage_name,
    psymtabs.  */
 
 struct symbol *
-lookup_global_symbol_from_objfile (const struct objfile *objfile,
+lookup_global_symbol_from_objfile (const struct objfile *main_objfile,
                                   const char *name,
                                   const char *linkage_name,
                                   const domain_enum domain)
 {
+  const struct objfile *objfile;
   struct symbol *sym;
   struct blockvector *bv;
   const struct block *block;
   struct symtab *s;
   struct partial_symtab *ps;
 
-  /* Go through symtabs.  */
-  ALL_OBJFILE_SYMTABS (objfile, s)
-  {
-    bv = BLOCKVECTOR (s);
-    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-    sym = lookup_block_symbol (block, name, linkage_name, domain);
-    if (sym)
-      {
-       block_found = block;
-       return fixup_symbol_section (sym, (struct objfile *)objfile);
-      }
-  }
-
-  /* Now go through psymtabs.  */
-  ALL_OBJFILE_PSYMTABS (objfile, ps)
-  {
-    if (!ps->readin
-       && lookup_partial_symbol (ps, name, linkage_name,
-                                 1, domain))
-      {
-       s = PSYMTAB_TO_SYMTAB (ps);
-       bv = BLOCKVECTOR (s);
-       block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-       sym = lookup_block_symbol (block, name, linkage_name, domain);
-       return fixup_symbol_section (sym, (struct objfile *)objfile);
-      }
-  }
-
-  if (objfile->separate_debug_objfile)
-    return lookup_global_symbol_from_objfile (objfile->separate_debug_objfile,
-                                             name, linkage_name, domain);
+  for (objfile = main_objfile;
+       objfile;
+       objfile = objfile_separate_debug_iterate (main_objfile, objfile))
+    {
+      /* Go through symtabs.  */
+      ALL_OBJFILE_SYMTABS (objfile, s)
+        {
+          bv = BLOCKVECTOR (s);
+          block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+          sym = lookup_block_symbol (block, name, linkage_name, domain);
+          if (sym)
+            {
+              block_found = block;
+              return fixup_symbol_section (sym, (struct objfile *)objfile);
+            }
+        }
+
+      /* Now go through psymtabs.  */
+      ALL_OBJFILE_PSYMTABS (objfile, ps)
+        {
+          if (!ps->readin
+              && lookup_partial_symbol (ps, name, linkage_name,
+                                        1, domain))
+            {
+              s = PSYMTAB_TO_SYMTAB (ps);
+              bv = BLOCKVECTOR (s);
+              block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+              sym = lookup_block_symbol (block, name, linkage_name, domain);
+              return fixup_symbol_section (sym, (struct objfile *)objfile);
+            }
+        }
+    }
 
   return NULL;
 }