This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH v2 9/9] add short-circuit logic to elfread.c
- From: Tom Tromey <tromey at redhat dot com>
- To: gdb-patches at sourceware dot org
- Cc: Tom Tromey <tromey at redhat dot com>
- Date: Thu, 17 Oct 2013 11:49:53 -0600
- Subject: [PATCH v2 9/9] add short-circuit logic to elfread.c
- Authentication-results: sourceware.org; auth=none
- References: <1382032193-9115-1-git-send-email-tromey at redhat dot com>
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.
After looking at a few fixes for this minor problem, I decided to just
remove minimal symbols from OBJSTATS. This seemed best to me first
because it eliminates duplicate accounting, and second because the
OBJSTATS were historically wrong here -- including minsyms that were
deleted by de-duplication.
* 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>: Remove.
* symmisc.c (print_objfile_statistics): Update.
---
gdb/elfread.c | 27 +++++++++++++++++++--------
gdb/minsyms.c | 1 -
gdb/objfiles.h | 1 -
gdb/symmisc.c | 4 ++--
4 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 5bf4598..5bb3ddf 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1076,7 +1076,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;
@@ -1092,6 +1093,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 ();
@@ -1234,16 +1250,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
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index 14ca922..21fc468 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -981,7 +981,6 @@ prim_record_minimal_symbol_full (const char *name, int name_len, int copy_name,
if (!objfile->per_bfd->minsyms_read)
msym_bunch_index++;
msym_count++;
- OBJSTAT (objfile, n_minsyms++);
return msymbol;
}
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index deabad4..1064a36 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -145,7 +145,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) */
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index 8d91c8d..4580485 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -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->minimal_symbol_count > 0)
printf_filtered (_(" Number of \"minimal\" symbols read: %d\n"),
- OBJSTAT (objfile, n_minsyms));
+ objfile->per_bfd->minimal_symbol_count);
if (OBJSTAT (objfile, n_psyms) > 0)
printf_filtered (_(" Number of \"partial\" symbols read: %d\n"),
OBJSTAT (objfile, n_psyms));
--
1.8.1.4