public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] [gdb] Use partial symbol table to find language for main
@ 2020-04-02  6:47 Tom de Vries
  0 siblings, 0 replies; only message in thread
From: Tom de Vries @ 2020-04-02  6:47 UTC (permalink / raw)
  To: gdb-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d3214198119c1a2f9a6a2b8fcc56d8c324e1a245

commit d3214198119c1a2f9a6a2b8fcc56d8c324e1a245
Author: Tom de Vries <tdevries@suse.de>
Date:   Thu Apr 2 08:47:49 2020 +0200

    [gdb] Use partial symbol table to find language for main
    
    When language is set to auto, part of loading an executable is to update the
    language accordingly.  This is implemented by set_initial_language.
    
    The implementation of set_initial_language works as follows:
    - check if any objfile in the progspace has name_of_main/language_of_main
      set, and if so, use the first one found. [ This is what you get f.i. when
      using dwarf with DW_AT_main_subprogram. ]
    - otherwise, check for known names in the minimal symbols, and either:
    - use the associated language if any (f.i. for ada), or
    - lookup the symbol in the symtab for the name and use the symbol language
      (f.i. for c/c++).
    
    The symbol lookup can be slow though.
    
    In the case of the cc1 binary from PR23710 comment 1, getting to the initial
    prompt takes ~8s:
    ...
    $ time.sh gdb cc1 -batch -ex "show language"
    The current source language is "auto; currently c++".
    maxmem: 1272260
    real: 8.05
    user: 7.73
    system: 0.38
    ...
    but if we skip guessing the initial language by setting it instead, it takes
    only ~4s:
    ...
    $ time.sh gdb -iex "set language c++" cc1 -batch -ex "show language"
    The current source language is "c++".
    maxmem: 498272
    real: 3.99
    user: 3.90
    system: 0.15
    ...
    
    In both cases, we load the partial symbols for the executable, but in the
    first case only we also do a lookup of main, which causes the corresponding
    partial symtab to be expanded into a full symtab.
    
    Ideally, we'd like to get the language of the symbol without triggering
    expansion into a full symtab, and get the speedup without having to set the
    language manually.
    
    There's a related fixme in the header comment of set_initial_language:
    ...
    /* Set the initial language.
    
       FIXME: A better solution would be to record the language in the
       psymtab when reading partial symbols, and then use it (if known) to
       set the language.  This would be a win for formats that encode the
       language in an easily discoverable place, such as DWARF.  For
       stabs, we can jump through hoops looking for specially named
       symbols or try to intuit the language from the specific type of
       stabs we find, but we can't do that until later when we read in
       full symbols.  */
    
    void
    set_initial_language (void)
    ...
    
    Since we're already tracking the language of partial symbols, use this to set
    the language for the main symbol.
    
    Note that this search in partial symbol tables is not guaranteed to yield the
    same result as the lookup_symbol_in_language call currently done in
    set_initial_language.
    
    Build and reg-tested on x86_64-linux.
    
    gdb/ChangeLog:
    
    2020-04-02  Tom de Vries  <tdevries@suse.de>
    
            * dwarf2/read.c (dwarf2_gdb_index_functions,
            dwarf2_debug_names_functions): Init lookup_global_symbol_language with
            NULL.
            * psymtab.c (psym_lookup_global_symbol_language): New function.
            (psym_functions): Init psym_lookup_global_symbol_language with
            psym_lookup_global_symbol_language.
            * symfile-debug.c (debug_sym_quick_functions): Init
            lookup_global_symbol_language with NULL.
            * symfile.c (set_initial_language): Remove fixme comment.
            * symfile.h (struct quick_symbol_functions): Add
            lookup_global_symbol_language.
            * symtab.c (find_quick_global_symbol_language): New function.
            (find_main_name): Use find_quick_global_symbol_language.
    
    gdb/testsuite/ChangeLog:
    
    2020-04-02  Tom de Vries  <tdevries@suse.de>
    
            * gdb.base/main-psymtab.exp: New file.

Diff:
---
 gdb/ChangeLog                           | 16 ++++++++++++++
 gdb/dwarf2/read.c                       |  2 ++
 gdb/psymtab.c                           | 31 +++++++++++++++++++++++++++
 gdb/symfile-debug.c                     |  1 +
 gdb/symfile.c                           | 11 +---------
 gdb/symfile.h                           | 11 ++++++++++
 gdb/symtab.c                            | 37 +++++++++++++++++++++++++++++++++
 gdb/testsuite/ChangeLog                 |  4 ++++
 gdb/testsuite/gdb.base/main-psymtab.exp | 34 ++++++++++++++++++++++++++++++
 9 files changed, 137 insertions(+), 10 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4775ff858aa..d5a2ed8fdef 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,19 @@
+2020-04-02  Tom de Vries  <tdevries@suse.de>
+
+	* dwarf2/read.c (dwarf2_gdb_index_functions,
+	dwarf2_debug_names_functions): Init lookup_global_symbol_language with
+	NULL.
+	* psymtab.c (psym_lookup_global_symbol_language): New function.
+	(psym_functions): Init psym_lookup_global_symbol_language with
+	psym_lookup_global_symbol_language.
+	* symfile-debug.c (debug_sym_quick_functions): Init
+	lookup_global_symbol_language with NULL.
+	* symfile.c (set_initial_language): Remove fixme comment.
+	* symfile.h (struct quick_symbol_functions): Add
+	lookup_global_symbol_language.
+	* symtab.c (find_quick_global_symbol_language): New function.
+	(find_main_name): Use find_quick_global_symbol_language.
+
 2020-04-01  Simon Marchi  <simon.marchi@polymtl.ca>
 
 	* windows-tdep.c (is_linked_with_cygwin_dll): Fix style.
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 2db527ecb82..198fac0f416 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -4708,6 +4708,7 @@ const struct quick_symbol_functions dwarf2_gdb_index_functions =
   dw2_forget_cached_source_info,
   dw2_map_symtabs_matching_filename,
   dw2_lookup_symbol,
+  NULL,
   dw2_print_stats,
   dw2_dump,
   dw2_expand_symtabs_for_function,
@@ -5590,6 +5591,7 @@ const struct quick_symbol_functions dwarf2_debug_names_functions =
   dw2_forget_cached_source_info,
   dw2_map_symtabs_matching_filename,
   dw2_debug_names_lookup_symbol,
+  NULL,
   dw2_print_stats,
   dw2_debug_names_dump,
   dw2_debug_names_expand_symtabs_for_function,
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index d3569ff0130..26c55e9bd33 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -521,6 +521,36 @@ psym_lookup_symbol (struct objfile *objfile,
   return stab_best;
 }
 
+/* Psymtab version of lookup_global_symbol_language.  See its definition in
+   the definition of quick_symbol_functions in symfile.h.  */
+
+static enum language
+psym_lookup_global_symbol_language (struct objfile *objfile, const char *name,
+				    domain_enum domain, bool *symbol_found_p)
+{
+  *symbol_found_p = false;
+  if (objfile->sf == NULL)
+    return language_unknown;
+
+  lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
+
+  for (partial_symtab *ps : require_partial_symbols (objfile, true))
+    {
+      struct partial_symbol *psym;
+      if (ps->readin_p ())
+	continue;
+
+      psym = lookup_partial_symbol (objfile, ps, lookup_name, 1, domain);
+      if (psym)
+	{
+	  *symbol_found_p = true;
+	  return psym->ginfo.language ();
+	}
+    }
+
+  return language_unknown;
+}
+
 /* Returns true if PSYM matches LOOKUP_NAME.  */
 
 static bool
@@ -1422,6 +1452,7 @@ const struct quick_symbol_functions psym_functions =
   psym_forget_cached_source_info,
   psym_map_symtabs_matching_filename,
   psym_lookup_symbol,
+  psym_lookup_global_symbol_language,
   psym_print_stats,
   psym_dump,
   psym_expand_symtabs_for_function,
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c
index 53a77a5405d..19dc83a8bdd 100644
--- a/gdb/symfile-debug.c
+++ b/gdb/symfile-debug.c
@@ -362,6 +362,7 @@ static const struct quick_symbol_functions debug_sym_quick_functions =
   debug_qf_forget_cached_source_info,
   debug_qf_map_symtabs_matching_filename,
   debug_qf_lookup_symbol,
+  NULL,
   debug_qf_print_stats,
   debug_qf_dump,
   debug_qf_expand_symtabs_for_function,
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 3b63887ce1b..bd27a1fefef 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1667,16 +1667,7 @@ symbol_file_command (const char *args, int from_tty)
     }
 }
 
-/* Set the initial language.
-
-   FIXME: A better solution would be to record the language in the
-   psymtab when reading partial symbols, and then use it (if known) to
-   set the language.  This would be a win for formats that encode the
-   language in an easily discoverable place, such as DWARF.  For
-   stabs, we can jump through hoops looking for specially named
-   symbols or try to intuit the language from the specific type of
-   stabs we find, but we can't do that until later when we read in
-   full symbols.  */
+/* Set the initial language.  */
 
 void
 set_initial_language (void)
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 85f8e7c1558..84fa283e85c 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -183,6 +183,17 @@ struct quick_symbol_functions
 					    const char *name,
 					    domain_enum domain);
 
+  /* Check to see if the global symbol is defined in a "partial" symbol table
+     of OBJFILE. NAME is the name of the symbol to look for.  DOMAIN
+     indicates what sort of symbol to search for.
+
+     If found, sets *symbol_found_p to true and returns the symbol language.
+     defined, or NULL if no such symbol table exists.  */
+  enum language (*lookup_global_symbol_language) (struct objfile *objfile,
+						  const char *name,
+						  domain_enum domain,
+						  bool *symbol_found_p);
+
   /* Print statistics about any indices loaded for OBJFILE.  The
      statistics should be printed to gdb_stdout.  This is used for
      "maint print statistics".  */
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 680280105f5..5f07f3cc93e 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -2560,6 +2560,33 @@ lookup_symbol_in_objfile (struct objfile *objfile, enum block_enum block_index,
   return result;
 }
 
+/* Find the language for partial symbol with NAME.  */
+
+static enum language
+find_quick_global_symbol_language (const char *name, const domain_enum domain)
+{
+  for (objfile *objfile : current_program_space->objfiles ())
+    {
+      if (objfile->sf && objfile->sf->qf
+	  && objfile->sf->qf->lookup_global_symbol_language)
+	continue;
+      return language_unknown;
+    }
+
+  for (objfile *objfile : current_program_space->objfiles ())
+    {
+      bool symbol_found_p;
+      enum language lang
+	= objfile->sf->qf->lookup_global_symbol_language (objfile, name, domain,
+							  &symbol_found_p);
+      if (!symbol_found_p)
+	continue;
+      return lang;
+    }
+
+  return language_unknown;
+}
+
 /* Private data to be used with lookup_symbol_global_iterator_cb.  */
 
 struct global_or_static_sym_lookup_data
@@ -6144,6 +6171,16 @@ find_main_name (void)
 
   /* The languages above didn't identify the name of the main procedure.
      Fallback to "main".  */
+
+  /* Try to find language for main in psymtabs.  */
+  enum language lang
+    = find_quick_global_symbol_language ("main", VAR_DOMAIN);
+  if (lang != language_unknown)
+    {
+      set_main_name ("main", lang);
+      return;
+    }
+
   set_main_name ("main", language_unknown);
 }
 
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index a6af43437c1..5dcb844bfde 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2020-04-02  Tom de Vries  <tdevries@suse.de>
+
+	* gdb.base/main-psymtab.exp: New file.
+
 2020-04-02  Tom de Vries  <tdevries@suse.de>
 
 	* gdb.fortran/mixed-lang-stack.exp: Accept new complex printing style.
diff --git a/gdb/testsuite/gdb.base/main-psymtab.exp b/gdb/testsuite/gdb.base/main-psymtab.exp
new file mode 100644
index 00000000000..72596f632b4
--- /dev/null
+++ b/gdb/testsuite/gdb.base/main-psymtab.exp
@@ -0,0 +1,34 @@
+# Copyright 2020 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+standard_testfile persistent-lang.cc
+
+if {[build_executable "failed to prepare" $testfile $srcfile debug]} {
+    return -1
+}
+
+clean_restart
+
+set auto_cpp \
+    {The current source language is "auto; currently c\+\+"\.}
+
+gdb_load ${binfile}
+gdb_test "show language" $auto_cpp \
+    "language auto/c++ after load"
+
+# Verify that partial symtab expansion has not taken place for
+# persistent-lang.cc
+
+verify_psymtab_expanded persistent-lang.cc no


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-04-02  6:47 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-02  6:47 [binutils-gdb] [gdb] Use partial symbol table to find language for main Tom de Vries

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).