add short-circuit logic to elfread.c
authorTom Tromey <tromey@redhat.com>
Tue, 15 Oct 2013 17:50:58 +0000 (11:50 -0600)
committerTom Tromey <tromey@redhat.com>
Wed, 26 Feb 2014 19:11:18 +0000 (12:11 -0700)
If minimal symbols have already been read into a per-BFD object, then
a symbol reader can skip re-reading them.  This changes the ELF reader
to do so.

We only skip the work if the file is ELF+DWARF.  If it has stabs or
mdebug sections, then I think extra information is computed during the
minsym creation pass; and so we must still repeat it.  Eventually even
this will go away, once all symbol types have switched to being
progspace-independent.  In the meantime this has no negative effect --
it is just a missing optimization for a small set of users.

This change also required a somewhat non-obvious change to the OBJSTAT
accounting code.  If a symbol reader skips re-reading minimal symbols,
then the corresponding OBJSTAT will not be updated.  This leads to a
test failure in gdb.base/maint.exp.

To fix this, I've moved the needed stat field out of objfile and into
the per-BFD object.

2014-02-26  Tom Tromey  <tromey@redhat.com>

* elfread.c (elf_read_minimal_symbols): Return early if
minimal symbols have already been read.  Add "ei" parameter.
(elf_symfile_read): Call elf_read_minimal_symbols earlier.
* minsyms.c (prim_record_minimal_symbol_full): Update.
* objfiles.h (struct objstats) <n_minsyms>: Move...
(struct objfile_per_bfd_storage) <n_minsyms>: ... here.
* symmisc.c (print_objfile_statistics): Update.

gdb/ChangeLog
gdb/elfread.c
gdb/minsyms.c
gdb/objfiles.h
gdb/symmisc.c

index 1d1a370e26c8a1e198acc908aa598445b93c7311..f5df2f2724c48f9f7f5f8d7e655d1c65b7f0b952 100644 (file)
@@ -1,3 +1,13 @@
+2014-02-26  Tom Tromey  <tromey@redhat.com>
+
+       * elfread.c (elf_read_minimal_symbols): Return early if
+       minimal symbols have already been read.  Add "ei" parameter.
+       (elf_symfile_read): Call elf_read_minimal_symbols earlier.
+       * minsyms.c (prim_record_minimal_symbol_full): Update.
+       * objfiles.h (struct objstats) <n_minsyms>: Move...
+       (struct objfile_per_bfd_storage) <n_minsyms>: ... here.
+       * symmisc.c (print_objfile_statistics): Update.
+
 2014-02-26  Tom Tromey  <tromey@redhat.com>
 
        * elfread.c (elf_read_minimal_symbols): New function, from
index 3aec3526a0bb587ee79550ee910e0cb9f8d787bc..88fb01809c7d31f05f13dc6015121eb416b079fe 100644 (file)
@@ -1084,7 +1084,8 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
    symbols.  */
 
 static void
-elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags)
+elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags,
+                         const struct elfinfo *ei)
 {
   bfd *synth_abfd, *abfd = objfile->obfd;
   struct cleanup *back_to;
@@ -1100,6 +1101,21 @@ elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags)
                          objfile_name (objfile));
     }
 
+  /* If we already have minsyms, then we can skip some work here.
+     However, if there were stabs or mdebug sections, we go ahead and
+     redo all the work anyway, because the psym readers for those
+     kinds of debuginfo need extra information found here.  This can
+     go away once all types of symbols are in the per-BFD object.  */
+  if (objfile->per_bfd->minsyms_read
+      && ei->stabsect == NULL
+      && ei->mdebugsect == NULL)
+    {
+      if (symtab_create_debug)
+       fprintf_unfiltered (gdb_stdlog,
+                           "... minimal symbols previously read\n");
+      return;
+    }
+
   init_minimal_symbol_collection ();
   back_to = make_cleanup_discard_minimal_symbols ();
 
@@ -1242,16 +1258,11 @@ elf_symfile_read (struct objfile *objfile, int symfile_flags)
   bfd *abfd = objfile->obfd;
   struct elfinfo ei;
 
-  elf_read_minimal_symbols (objfile, symfile_flags);
-
   memset ((char *) &ei, 0, sizeof (ei));
-
-  /* Now process debugging information, which is contained in
-     special ELF sections.  */
-
-  /* We first have to find them...  */
   bfd_map_over_sections (abfd, elf_locate_sections, (void *) & ei);
 
+  elf_read_minimal_symbols (objfile, symfile_flags, &ei);
+
   /* ELF debugging information is inserted into the psymtab in the
      order of least informative first - most informative last.  Since
      the psymtab table is searched `most recent insertion first' this
index 1dc86eb70036187ca49fab6b57fd1a98988a57bd..6f1fb35b71fa8bc295a91c5b6933ed3052638a8e 100644 (file)
@@ -977,9 +977,11 @@ prim_record_minimal_symbol_full (const char *name, int name_len, int copy_name,
   /* If we already read minimal symbols for this objfile, then don't
      ever allocate a new one.  */
   if (!objfile->per_bfd->minsyms_read)
-    msym_bunch_index++;
+    {
+      msym_bunch_index++;
+      objfile->per_bfd->n_minsyms++;
+    }
   msym_count++;
-  OBJSTAT (objfile, n_minsyms++);
   return msymbol;
 }
 
index d585bc47794a9e504d11a90e5cb24db0387212e1..dc06c7bec5650530620e2b178950a3497f9575c3 100644 (file)
@@ -151,7 +151,6 @@ struct obj_section
 
 struct objstats
   {
-    int n_minsyms;             /* Number of minimal symbols read */
     int n_psyms;               /* Number of partial symbols read */
     int n_syms;                        /* Number of full symbols read */
     int n_stabs;               /* Number of ".stabs" read (if applicable) */
@@ -224,6 +223,12 @@ struct objfile_per_bfd_storage
   struct minimal_symbol *msymbols;
   int minimal_symbol_count;
 
+  /* The number of minimal symbols read, before any minimal symbol
+     de-duplication is applied.  Note in particular that this has only
+     a passing relationship with the actual size of the table above;
+     use minimal_symbol_count if you need the true size.  */
+  int n_minsyms;
+
   /* This is true if minimal symbols have already been read.  Symbol
      readers can use this to bypass minimal symbol reading.  Also, the
      minimal symbol table management code in minsyms.c uses this to
index eb15ecc1bbd60de15d3dcd600e9e8d1c5d60cd23..7ea97bdd40cb9e0016641eb7761d2b8cdd5c2f6d 100644 (file)
@@ -111,9 +111,9 @@ print_objfile_statistics (void)
     if (OBJSTAT (objfile, n_stabs) > 0)
       printf_filtered (_("  Number of \"stab\" symbols read: %d\n"),
                       OBJSTAT (objfile, n_stabs));
-    if (OBJSTAT (objfile, n_minsyms) > 0)
+    if (objfile->per_bfd->n_minsyms > 0)
       printf_filtered (_("  Number of \"minimal\" symbols read: %d\n"),
-                      OBJSTAT (objfile, n_minsyms));
+                      objfile->per_bfd->n_minsyms);
     if (OBJSTAT (objfile, n_psyms) > 0)
       printf_filtered (_("  Number of \"partial\" symbols read: %d\n"),
                       OBJSTAT (objfile, n_psyms));