Expand symbolless symtabs using maint expand-symtabs

Message ID 20200329160050.GA24275@delia
State New
Headers show
Series
  • Expand symbolless symtabs using maint expand-symtabs
Related show

Commit Message

Tom de Vries March 29, 2020, 4 p.m.
Hi,

Consider this test-case, consisting of header file hello.h:
...
inline static const char*
foo (void)
{
  return "foo";
}
...
and source file hello.c:
...
int
main (void)
{
  printf ("hello: %s\n", foo ());
  return 0;
}
...
compiled with -g:
...
$ gcc hello.c -g
...

When trying to expand the partial symtab for hello.h:
...
$ gdb -batch \
  -iex "set language c" \
  a.out \
  -ex "maint expand-symtabs hello.h" \
  -ex "maint info psymtabs"
...
we in fact find that the partial symtab has not been expanded:
...
  { psymtab hello.h ((struct partial_symtab *) 0x27cf070)
    readin no
...

This is due to the recursively_search_psymtabs call in
psym_expand_symtabs_matching:
...
      if (recursively_search_psymtabs (ps, objfile, domain,
                                      lookup_name, symbol_matcher))
...
which always returns false for symbolless partial symtabs.

Fix this by passing a NULL symbol_matcher and lookup_name to
expand_symtabs_matching in maintenance_expand_symtabs, and skipping the call
to recursively_search_psymtabs if symbol_matcher == NULL and
lookup_name == NULL.

Tested on x86_64-linux.

OK for trunk?

Thanks,
- Tom

[gdb] Expand symbolless symtabs using maint expand-symtabs

gdb/ChangeLog:

2020-03-29  Tom de Vries  <tdevries@suse.de>

	PR symtab/25720
	* symmisc.c (maintenance_expand_symtabs): Call expand_symtabs_matching
	with NULL symbol_matcher and lookup_name.
	* psymtab.c (psym_expand_symtabs_matching): Handle NULL symbol_matcher
	and lookup_name.
	* dwarf2/read.c (dw2_expand_symtabs_matching)
	(dw2_debug_names_expand_symtabs_matching): Same.
	* symfile.h (struct quick_symbol_functions::expand_symtabs_matching):
	Make lookup_name a pointer.  Update comment.
	* symtab.c (global_symbol_searcher::expand_symtabs): Handle
	lookup_name being a pointer.
	* symfile.c (expand_symtabs_matching): Same.
	* symfile-debug.c (debug_qf_expand_symtabs_matching): Same.
	* linespec.c (iterate_over_all_matching_symtabs): Same.

gdb/testsuite/ChangeLog:

2020-03-29  Tom de Vries  <tdevries@suse.de>

	PR symtab/25720
	* gdb.base/maint-expand-symbols-header-file.c: New test.
	* gdb.base/maint-expand-symbols-header-file.exp: New file.
	* gdb.base/maint-expand-symbols-header-file.h: New test.

---
 gdb/dwarf2/read.c                                  | 32 ++++++++++--
 gdb/linespec.c                                     |  2 +-
 gdb/psymtab.c                                      | 10 ++--
 gdb/symfile-debug.c                                |  2 +-
 gdb/symfile.c                                      |  2 +-
 gdb/symfile.h                                      | 13 +++--
 gdb/symmisc.c                                      |  8 +--
 gdb/symtab.c                                       |  2 +-
 .../gdb.base/maint-expand-symbols-header-file.c    |  9 ++++
 .../gdb.base/maint-expand-symbols-header-file.exp  | 57 ++++++++++++++++++++++
 .../gdb.base/maint-expand-symbols-header-file.h    |  5 ++
 11 files changed, 118 insertions(+), 24 deletions(-)

Comments

Tom de Vries March 30, 2020, 11:09 a.m. | #1
On 29-03-2020 18:00, Tom de Vries wrote:

I realized that the copyright is missing in the added .c/.h files. Added.

Also, I realized I could make the test-case work with target boards
cc-with-gdb-index.exp and cc-with-debug-names.exp, by testing the output
of "maint info symtabs" instead of "main info psymtabs".  Updated
accordingly.

Also now handling target board readnow.exp, by marking the test unsupported.

Updated and re-tested patch attached below.

Thanks,
- Tom
[gdb] Expand symbolless symtabs using maint expand-symtabs

Consider this test-case, consisting of header file hello.h:
...
inline static const char*
foo (void)
{
  return "foo";
}
...
and source file hello.c:
...
int
main (void)
{
  printf ("hello: %s\n", foo ());
  return 0;
}
...
compiled with -g:
...
$ gcc hello.c -g
...

When trying to expand the partial symtab for hello.h:
...
$ gdb -batch \
  -iex "set language c" \
  a.out \
  -ex "maint expand-symtabs hello.h" \
  -ex "maint info psymtabs"
...
we in fact find that the partial symtab has not been expanded:
...
  { psymtab hello.h ((struct partial_symtab *) 0x27cf070)
    readin no
...

This is due to the recursively_search_psymtabs call in
psym_expand_symtabs_matching:
...
      if (recursively_search_psymtabs (ps, objfile, domain,
                                      lookup_name, symbol_matcher))
...
which always returns false for symbolless partial symtabs.

Fix this by passing a NULL symbol_matcher and lookup_name to
expand_symtabs_matching in maintenance_expand_symtabs, and skipping the call
to recursively_search_psymtabs if symbol_matcher == NULL and
lookup_name == NULL.

Build and tested on x86_64-linux, with native.

In addition, tested test-case with target boards cc-with-gdb-index.exp,
cc-with-debug-names.exp and readnow.exp.

gdb/ChangeLog:

2020-03-29  Tom de Vries  <tdevries@suse.de>

	PR symtab/25720
	* symmisc.c (maintenance_expand_symtabs): Call expand_symtabs_matching
	with NULL symbol_matcher and lookup_name.
	* psymtab.c (psym_expand_symtabs_matching): Handle NULL symbol_matcher
	and lookup_name.
	* dwarf2/read.c (dw2_expand_symtabs_matching)
	(dw2_debug_names_expand_symtabs_matching): Same.
	* symfile.h (struct quick_symbol_functions::expand_symtabs_matching):
	Make lookup_name a pointer.  Update comment.
	* symtab.c (global_symbol_searcher::expand_symtabs): Handle
	lookup_name being a pointer.
	* symfile.c (expand_symtabs_matching): Same.
	* symfile-debug.c (debug_qf_expand_symtabs_matching): Same.
	* linespec.c (iterate_over_all_matching_symtabs): Same.

gdb/testsuite/ChangeLog:

2020-03-29  Tom de Vries  <tdevries@suse.de>

	PR symtab/25720
	* gdb.base/maint-expand-symbols-header-file.c: New test.
	* gdb.base/maint-expand-symbols-header-file.exp: New file.
	* gdb.base/maint-expand-symbols-header-file.h: New test.

---
 gdb/dwarf2/read.c                                  | 32 +++++++++++++--
 gdb/linespec.c                                     |  2 +-
 gdb/psymtab.c                                      | 10 ++---
 gdb/symfile-debug.c                                |  2 +-
 gdb/symfile.c                                      |  2 +-
 gdb/symfile.h                                      | 13 +++---
 gdb/symmisc.c                                      |  8 +---
 gdb/symtab.c                                       |  2 +-
 .../gdb.base/maint-expand-symbols-header-file.c    | 26 ++++++++++++
 .../gdb.base/maint-expand-symbols-header-file.exp  | 47 ++++++++++++++++++++++
 .../gdb.base/maint-expand-symbols-header-file.h    | 22 ++++++++++
 11 files changed, 142 insertions(+), 24 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 1ec5c1e582..673f2c2904 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -4543,7 +4543,7 @@ static void
 dw2_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain kind)
@@ -4557,9 +4557,21 @@ dw2_expand_symtabs_matching
 
   dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
 
+  if (symbol_matcher == NULL && lookup_name == NULL)
+    {
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+	{
+	  QUIT;
+
+	  dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+					   expansion_notify);
+	}
+      return;
+    }
+
   mapped_index &index = *dwarf2_per_objfile->index_table;
 
-  dw2_expand_symtabs_matching_symbol (index, lookup_name,
+  dw2_expand_symtabs_matching_symbol (index, *lookup_name,
 				      symbol_matcher,
 				      kind, [&] (offset_type idx)
     {
@@ -5551,7 +5563,7 @@ static void
 dw2_debug_names_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain kind)
@@ -5565,9 +5577,21 @@ dw2_debug_names_expand_symtabs_matching
 
   dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
 
+  if (symbol_matcher == NULL && lookup_name == NULL)
+    {
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+	{
+	  QUIT;
+
+	  dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+					   expansion_notify);
+	}
+      return;
+    }
+
   mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
 
-  dw2_expand_symtabs_matching_symbol (map, lookup_name,
+  dw2_expand_symtabs_matching_symbol (map, *lookup_name,
 				      symbol_matcher,
 				      kind, [&] (offset_type namei)
     {
diff --git a/gdb/linespec.c b/gdb/linespec.c
index d853e02d8f..e1349e78a0 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -1149,7 +1149,7 @@ iterate_over_all_matching_symtabs
 	if (objfile->sf)
 	  objfile->sf->qf->expand_symtabs_matching (objfile,
 						    NULL,
-						    lookup_name,
+						    &lookup_name,
 						    NULL, NULL,
 						    search_domain);
 
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 56c1b68b54..1399edbfa7 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -1301,13 +1301,11 @@ static void
 psym_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name_in,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain domain)
 {
-  lookup_name_info lookup_name = lookup_name_in.make_ignore_params ();
-
   /* Clear the search flags.  */
   for (partial_symtab *ps : require_partial_symbols (objfile, true))
     ps->searched_flag = PST_NOT_SEARCHED;
@@ -1344,8 +1342,10 @@ psym_expand_symtabs_matching
 	    continue;
 	}
 
-      if (recursively_search_psymtabs (ps, objfile, domain,
-				       lookup_name, symbol_matcher))
+      if ((symbol_matcher == NULL && lookup_name == NULL)
+	  || recursively_search_psymtabs (ps, objfile, domain,
+					  lookup_name->make_ignore_params (),
+					  symbol_matcher))
 	{
 	  struct compunit_symtab *symtab =
 	    psymtab_to_symtab (objfile, ps);
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c
index 53a77a5405..60489dbfa5 100644
--- a/gdb/symfile-debug.c
+++ b/gdb/symfile-debug.c
@@ -254,7 +254,7 @@ static void
 debug_qf_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain kind)
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 3b63887ce1..8b29516b4e 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -3786,7 +3786,7 @@ expand_symtabs_matching
     {
       if (objfile->sf)
 	objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher,
-						  lookup_name,
+						  &lookup_name,
 						  symbol_matcher,
 						  expansion_notify, kind);
     }
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 85f8e7c155..68b1813ec5 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -242,11 +242,14 @@ struct quick_symbol_functions
      names (the passed file name is already only the lbasename'd
      part).
 
-     Otherwise, if KIND does not match, this symbol is skipped.
+     If the file is not skipped, and SYMBOL_MATCHER and LOOKUP_NAME are NULL,
+     the symbol table is expanded.
 
-     If even KIND matches, SYMBOL_MATCHER is called for each symbol
-     defined in the file.  The symbol "search" name is passed to
-     SYMBOL_MATCHER.
+     Otherwise, individual symbols are considered.
+
+     If KIND does not match, the symbol is skipped.
+
+     If the symbol name does not match LOOKUP_NAME, the symbol is skipped.
 
      If SYMBOL_MATCHER returns false, then the symbol is skipped.
 
@@ -254,7 +257,7 @@ struct quick_symbol_functions
   void (*expand_symtabs_matching)
     (struct objfile *objfile,
      gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-     const lookup_name_info &lookup_name,
+     const lookup_name_info *lookup_name,
      gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
      gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
      enum search_domain kind);
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index bee136ed46..1076a0bcaf 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -977,12 +977,8 @@ maintenance_expand_symtabs (const char *args, int from_tty)
 		 return (!basenames
 			 && (regexp == NULL || re_exec (filename)));
 	       },
-	       lookup_name_info::match_any (),
-	       [] (const char *symname)
-	       {
-		 /* Since we're not searching on symbols, just return true.  */
-		 return true;
-	       },
+	       NULL,
+	       NULL,
 	       NULL,
 	       ALL_DOMAIN);
 	  }
diff --git a/gdb/symtab.c b/gdb/symtab.c
index f300d759e0..073b76db2d 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -4513,7 +4513,7 @@ global_symbol_searcher::expand_symtabs
        {
 	 return file_matches (filename, filenames, basenames);
        },
-       lookup_name_info::match_any (),
+       &lookup_name_info::match_any (),
        [&] (const char *symname)
        {
 	 return (!preg.has_value ()
diff --git a/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.c b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.c
new file mode 100644
index 0000000000..649c5b97c5
--- /dev/null
+++ b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.c
@@ -0,0 +1,26 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   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/>.  */
+
+#include <stdio.h>
+#include "maint-expand-symbols-header-file.h"
+
+int
+main (void)
+{
+  printf ("hello: %s\n", foo ());
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.exp b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.exp
new file mode 100644
index 0000000000..85376662df
--- /dev/null
+++ b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.exp
@@ -0,0 +1,47 @@
+# 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/>.
+#
+# Test-case to verify that symbol-less symtabs are expanded by
+# "maint expand-symtabs".
+
+standard_testfile .c
+
+if {[build_executable "failed to prepare" $testfile \
+	 $srcfile {debug nowarnings}]} {
+    return -1
+}
+
+clean_restart
+
+# Make sure that no symtabs are expanded, by setting language before
+# loading exec.
+gdb_test_no_output "set language c"
+gdb_load ${binfile}
+
+set test "verify no symtabs are expanded"
+if { [readnow] } {
+    unsupported $test
+    return -1
+}
+gdb_test_no_output "maint info symtabs" $test
+
+# Expand the header file symtab.
+gdb_test_no_output "maint expand-symtabs maint-expand-symbols-header-file.h"
+
+# Check that the header file symtab was in fact expanded.
+set file_re "\[^\r\n\]*/maint-expand-symbols-header-file.h"
+gdb_test "maint info symtabs" \
+    "\r\n\t{ symtab $file_re \\(\\(struct symtab \\*\\) $hex\\)\r\n.*" \
+    "check header file psymtab expansion"
diff --git a/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.h b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.h
new file mode 100644
index 0000000000..d8d2517c7b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.h
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   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/>.  */
+
+inline static const char*
+foo (void)
+{
+  return "foo";
+}
Tom Tromey April 1, 2020, 7:45 p.m. | #2
>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:


Tom> When trying to expand the partial symtab for hello.h:
Tom> ...
Tom> $ gdb -batch \
Tom>   -iex "set language c" \
Tom>   a.out \
Tom>   -ex "maint expand-symtabs hello.h" \
Tom>   -ex "maint info psymtabs"
Tom> ...
Tom> we in fact find that the partial symtab has not been expanded:
Tom> ...
Tom>   { psymtab hello.h ((struct partial_symtab *) 0x27cf070)
Tom>     readin no
Tom> ...

Does this matter, though?
I thought include psymtabs like these were kind of placeholders.

Tom> Fix this by passing a NULL symbol_matcher and lookup_name to
Tom> expand_symtabs_matching in maintenance_expand_symtabs, and skipping the call
Tom> to recursively_search_psymtabs if symbol_matcher == NULL and
Tom> lookup_name == NULL.

Could this code use map_symtabs_matching_filename instead?

I guess I'm not super fond of turning the reference arguments to
pointers, unless there's really no other way.

Tom
Tom de Vries April 2, 2020, 8:44 a.m. | #3
On 01-04-2020 21:45, Tom Tromey wrote:
>>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:

> 

> Tom> When trying to expand the partial symtab for hello.h:

> Tom> ...

> Tom> $ gdb -batch \

> Tom>   -iex "set language c" \

> Tom>   a.out \

> Tom>   -ex "maint expand-symtabs hello.h" \

> Tom>   -ex "maint info psymtabs"

> Tom> ...

> Tom> we in fact find that the partial symtab has not been expanded:

> Tom> ...

> Tom>   { psymtab hello.h ((struct partial_symtab *) 0x27cf070)

> Tom>     readin no

> Tom> ...

> 

> Does this matter, though?

> I thought include psymtabs like these were kind of placeholders.

> 


Right, but the includer symtab they're pointing towards are also not
expanded.

Concretely, it does matter for dwarf assembly test-cases, in the sense
that this patch allows me to have the symtab effect of setting a
breakpoint in a certain file, without actually setting the breakpoint,
which means there's no need to flesh out the .debug_line section in
detail, or indeed even create the file.

[ I mentioned this patch as a prerequisite for a dwarf assembly
test-case here :
https://sourceware.org/pipermail/gdb-patches/2020-March/167152.html ]

Furthermore, I found this problem originally not with include psymtabs,
but with this type of one-DIE CUs:
...
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <c>   DW_AT_stmt_list   : 0x0
    <10>   DW_AT_low_pc      : 0x400430
    <18>   DW_AT_high_pc     : 0x40045b
    <20>   DW_AT_name        : ../sysdeps/x86_64/start.S
    <24>   DW_AT_comp_dir    : /home/abuild/rpmbuild/BUILD/glibc-2.26/csu
    <28>   DW_AT_producer    : GNU AS 2.31.1
    <2c>   DW_AT_language    : 32769    (MIPS assembler)
...
which I get in every exec on openSUSE Leap 15.1.

In that case, the problem means that "maint expand-symtabs" doesn't
expand the symtab, in violation of the "maint expand-symtabs"
documentation, while also being inconsistent with -readnow which does
create a symbolless symtab.

I used the include psymtabs as test-case and running example because it
reproduces on all platforms in a standard test-case.

> Tom> Fix this by passing a NULL symbol_matcher and lookup_name to

> Tom> expand_symtabs_matching in maintenance_expand_symtabs, and skipping the call

> Tom> to recursively_search_psymtabs if symbol_matcher == NULL and

> Tom> lookup_name == NULL.

> 

> Could this code use map_symtabs_matching_filename instead?

> 


I can see how that would help with "maint expand-symtabs <file>", but
still "maint expand-symtabs" would not expand the partial symtab for
../sysdeps/x86_64/start.S.

Thanks,
- Tom

> I guess I'm not super fond of turning the reference arguments to

> pointers, unless there's really no other way.
Tom de Vries April 14, 2020, 1:09 p.m. | #4
On 02-04-2020 10:44, Tom de Vries wrote:
> On 01-04-2020 21:45, Tom Tromey wrote:

>>>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:

>>

>> Tom> When trying to expand the partial symtab for hello.h:

>> Tom> ...

>> Tom> $ gdb -batch \

>> Tom>   -iex "set language c" \

>> Tom>   a.out \

>> Tom>   -ex "maint expand-symtabs hello.h" \

>> Tom>   -ex "maint info psymtabs"

>> Tom> ...

>> Tom> we in fact find that the partial symtab has not been expanded:

>> Tom> ...

>> Tom>   { psymtab hello.h ((struct partial_symtab *) 0x27cf070)

>> Tom>     readin no

>> Tom> ...

>>

>> Does this matter, though?

>> I thought include psymtabs like these were kind of placeholders.

>>

> 

> Right, but the includer symtab they're pointing towards are also not

> expanded.

> 


I've updated the log message to reflect this, as well as the test-case.

> Concretely, it does matter for dwarf assembly test-cases, in the sense

> that this patch allows me to have the symtab effect of setting a

> breakpoint in a certain file, without actually setting the breakpoint,

> which means there's no need to flesh out the .debug_line section in

> detail, or indeed even create the file.

> 

> [ I mentioned this patch as a prerequisite for a dwarf assembly

> test-case here :

> https://sourceware.org/pipermail/gdb-patches/2020-March/167152.html ]

> 

> Furthermore, I found this problem originally not with include psymtabs,

> but with this type of one-DIE CUs:

> ...

>  <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)

>     <c>   DW_AT_stmt_list   : 0x0

>     <10>   DW_AT_low_pc      : 0x400430

>     <18>   DW_AT_high_pc     : 0x40045b

>     <20>   DW_AT_name        : ../sysdeps/x86_64/start.S

>     <24>   DW_AT_comp_dir    : /home/abuild/rpmbuild/BUILD/glibc-2.26/csu

>     <28>   DW_AT_producer    : GNU AS 2.31.1

>     <2c>   DW_AT_language    : 32769    (MIPS assembler)

> ...

> which I get in every exec on openSUSE Leap 15.1.

> 

> In that case, the problem means that "maint expand-symtabs" doesn't

> expand the symtab, in violation of the "maint expand-symtabs"

> documentation, while also being inconsistent with -readnow which does

> create a symbolless symtab.

> 


I've also noted this in the log message.

> I used the include psymtabs as test-case and running example because it

> reproduces on all platforms in a standard test-case.

> 

>> Tom> Fix this by passing a NULL symbol_matcher and lookup_name to

>> Tom> expand_symtabs_matching in maintenance_expand_symtabs, and skipping the call

>> Tom> to recursively_search_psymtabs if symbol_matcher == NULL and

>> Tom> lookup_name == NULL.

>>

>> Could this code use map_symtabs_matching_filename instead?

>>

> 

> I can see how that would help with "maint expand-symtabs <file>", but

> still "maint expand-symtabs" would not expand the partial symtab for

> ../sysdeps/x86_64/start.S.

> 

> Thanks,

> - Tom

> 

>> I guess I'm not super fond of turning the reference arguments to

>> pointers, unless there's really no other way.


Unfortunately I don't see another way atm, so I'm committing this as
attached below.

[ FWIW, something I'm not very happy with myself is the undoing of the
micro-optimization of having this outside of the partial symtabs loop:
...
  lookup_name_info lookup_name = lookup_name_in.make_ignore_params ();
...
but I'm not sure how to address that. ]

Thanks,
- Tom
[gdb] Expand symbolless symtabs using maint expand-symtabs

Consider this test-case, consisting of header file hello.h:
...
inline static const char*
foo (void)
{
  return "foo";
}
...
and source file hello.c:
...
int
main (void)
{
  printf ("hello: %s\n", foo ());
  return 0;
}
...
compiled with -g:
...
$ gcc hello.c -g
...

When trying to expand the partial symtab for hello.h:
...
$ gdb -batch \
  -iex "set language c" \
  a.out \
  -ex "maint expand-symtabs hello.h" \
  -ex "maint info psymtabs"
...
we in fact find that the partial symtab for hello.h (and corresponding
includer partial symtab hello.c) have not been expanded:
...
  { psymtab hello.h ((struct partial_symtab *) 0x27cf070)
    readin no
  ...
  { psymtab hello.c ((struct partial_symtab *) 0x2cf09e0)
    readin no
...

This is due to the recursively_search_psymtabs call in
psym_expand_symtabs_matching:
...
      if (recursively_search_psymtabs (ps, objfile, domain,
                                      lookup_name, symbol_matcher))
...
which always returns false for symbolless partial symtabs.

The same problem occurs with CUs where the dwarf is generated by gas
--gdwarf-2 for a foo.S: if we read such a test-case with -readnow, we'll have
a symbolless symtab for foo.S.  But if we read the test-case with partial
symtabs, and expand those using "maint expand-symtabs", the foo.S psymtab
remains unexpanded.

Fix this by passing a NULL symbol_matcher and lookup_name to
expand_symtabs_matching in maintenance_expand_symtabs, and skipping the call
to recursively_search_psymtabs if symbol_matcher == NULL and
lookup_name == NULL.

Build and tested on x86_64-linux, with native.

In addition, tested test-case with target boards cc-with-gdb-index.exp,
cc-with-debug-names.exp and readnow.exp.

gdb/ChangeLog:

2020-03-29  Tom de Vries  <tdevries@suse.de>

	PR symtab/25720
	* symmisc.c (maintenance_expand_symtabs): Call expand_symtabs_matching
	with NULL symbol_matcher and lookup_name.
	* psymtab.c (psym_expand_symtabs_matching): Handle NULL symbol_matcher
	and lookup_name.
	* dwarf2/read.c (dw2_expand_symtabs_matching)
	(dw2_debug_names_expand_symtabs_matching): Same.
	* symfile.h (struct quick_symbol_functions::expand_symtabs_matching):
	Make lookup_name a pointer.  Update comment.
	* symtab.c (global_symbol_searcher::expand_symtabs): Handle
	lookup_name being a pointer.
	* symfile.c (expand_symtabs_matching): Same.
	* symfile-debug.c (debug_qf_expand_symtabs_matching): Same.
	* linespec.c (iterate_over_all_matching_symtabs): Same.

gdb/testsuite/ChangeLog:

2020-03-29  Tom de Vries  <tdevries@suse.de>

	PR symtab/25720
	* gdb.base/maint-expand-symbols-header-file.c: New test.
	* gdb.base/maint-expand-symbols-header-file.exp: New file.
	* gdb.base/maint-expand-symbols-header-file.h: New test.

---
 gdb/dwarf2/read.c                                  | 32 +++++++++++++--
 gdb/linespec.c                                     |  2 +-
 gdb/psymtab.c                                      | 10 ++---
 gdb/symfile-debug.c                                |  2 +-
 gdb/symfile.c                                      |  2 +-
 gdb/symfile.h                                      | 13 +++---
 gdb/symmisc.c                                      |  8 +---
 gdb/symtab.c                                       |  2 +-
 .../gdb.base/maint-expand-symbols-header-file.c    | 26 ++++++++++++
 .../gdb.base/maint-expand-symbols-header-file.exp  | 46 ++++++++++++++++++++++
 .../gdb.base/maint-expand-symbols-header-file.h    | 22 +++++++++++
 11 files changed, 141 insertions(+), 24 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index da702205c6..9fa4970556 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -4603,7 +4603,7 @@ static void
 dw2_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain kind)
@@ -4617,9 +4617,21 @@ dw2_expand_symtabs_matching
 
   dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
 
+  if (symbol_matcher == NULL && lookup_name == NULL)
+    {
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+	{
+	  QUIT;
+
+	  dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+					   expansion_notify);
+	}
+      return;
+    }
+
   mapped_index &index = *dwarf2_per_objfile->index_table;
 
-  dw2_expand_symtabs_matching_symbol (index, lookup_name,
+  dw2_expand_symtabs_matching_symbol (index, *lookup_name,
 				      symbol_matcher,
 				      kind, [&] (offset_type idx)
     {
@@ -5612,7 +5624,7 @@ static void
 dw2_debug_names_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain kind)
@@ -5626,9 +5638,21 @@ dw2_debug_names_expand_symtabs_matching
 
   dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
 
+  if (symbol_matcher == NULL && lookup_name == NULL)
+    {
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+	{
+	  QUIT;
+
+	  dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+					   expansion_notify);
+	}
+      return;
+    }
+
   mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
 
-  dw2_expand_symtabs_matching_symbol (map, lookup_name,
+  dw2_expand_symtabs_matching_symbol (map, *lookup_name,
 				      symbol_matcher,
 				      kind, [&] (offset_type namei)
     {
diff --git a/gdb/linespec.c b/gdb/linespec.c
index d853e02d8f..e1349e78a0 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -1149,7 +1149,7 @@ iterate_over_all_matching_symtabs
 	if (objfile->sf)
 	  objfile->sf->qf->expand_symtabs_matching (objfile,
 						    NULL,
-						    lookup_name,
+						    &lookup_name,
 						    NULL, NULL,
 						    search_domain);
 
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 44d4978d53..d952f453d9 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -1304,13 +1304,11 @@ static void
 psym_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name_in,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain domain)
 {
-  lookup_name_info lookup_name = lookup_name_in.make_ignore_params ();
-
   /* Clear the search flags.  */
   for (partial_symtab *ps : require_partial_symbols (objfile, true))
     ps->searched_flag = PST_NOT_SEARCHED;
@@ -1347,8 +1345,10 @@ psym_expand_symtabs_matching
 	    continue;
 	}
 
-      if (recursively_search_psymtabs (ps, objfile, domain,
-				       lookup_name, symbol_matcher))
+      if ((symbol_matcher == NULL && lookup_name == NULL)
+	  || recursively_search_psymtabs (ps, objfile, domain,
+					  lookup_name->make_ignore_params (),
+					  symbol_matcher))
 	{
 	  struct compunit_symtab *symtab =
 	    psymtab_to_symtab (objfile, ps);
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c
index 19dc83a8bd..75e6f2d0d8 100644
--- a/gdb/symfile-debug.c
+++ b/gdb/symfile-debug.c
@@ -254,7 +254,7 @@ static void
 debug_qf_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain kind)
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 61053298a8..8c002ebfab 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -3777,7 +3777,7 @@ expand_symtabs_matching
     {
       if (objfile->sf)
 	objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher,
-						  lookup_name,
+						  &lookup_name,
 						  symbol_matcher,
 						  expansion_notify, kind);
     }
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 84fa283e85..5ada6c370e 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -253,11 +253,14 @@ struct quick_symbol_functions
      names (the passed file name is already only the lbasename'd
      part).
 
-     Otherwise, if KIND does not match, this symbol is skipped.
+     If the file is not skipped, and SYMBOL_MATCHER and LOOKUP_NAME are NULL,
+     the symbol table is expanded.
 
-     If even KIND matches, SYMBOL_MATCHER is called for each symbol
-     defined in the file.  The symbol "search" name is passed to
-     SYMBOL_MATCHER.
+     Otherwise, individual symbols are considered.
+
+     If KIND does not match, the symbol is skipped.
+
+     If the symbol name does not match LOOKUP_NAME, the symbol is skipped.
 
      If SYMBOL_MATCHER returns false, then the symbol is skipped.
 
@@ -265,7 +268,7 @@ struct quick_symbol_functions
   void (*expand_symtabs_matching)
     (struct objfile *objfile,
      gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-     const lookup_name_info &lookup_name,
+     const lookup_name_info *lookup_name,
      gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
      gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
      enum search_domain kind);
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index bee136ed46..1076a0bcaf 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -977,12 +977,8 @@ maintenance_expand_symtabs (const char *args, int from_tty)
 		 return (!basenames
 			 && (regexp == NULL || re_exec (filename)));
 	       },
-	       lookup_name_info::match_any (),
-	       [] (const char *symname)
-	       {
-		 /* Since we're not searching on symbols, just return true.  */
-		 return true;
-	       },
+	       NULL,
+	       NULL,
 	       NULL,
 	       ALL_DOMAIN);
 	  }
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 13a5a108e6..45d75a3cd1 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -4540,7 +4540,7 @@ global_symbol_searcher::expand_symtabs
        {
 	 return file_matches (filename, filenames, basenames);
        },
-       lookup_name_info::match_any (),
+       &lookup_name_info::match_any (),
        [&] (const char *symname)
        {
 	 return (!preg.has_value ()
diff --git a/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.c b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.c
new file mode 100644
index 0000000000..649c5b97c5
--- /dev/null
+++ b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.c
@@ -0,0 +1,26 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   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/>.  */
+
+#include <stdio.h>
+#include "maint-expand-symbols-header-file.h"
+
+int
+main (void)
+{
+  printf ("hello: %s\n", foo ());
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.exp b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.exp
new file mode 100644
index 0000000000..f73be404c9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.exp
@@ -0,0 +1,46 @@
+# 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/>.
+#
+# Test-case to verify that symbol-less symtabs are expanded by
+# "maint expand-symtabs".
+
+standard_testfile .c
+
+if {[prepare_for_testing "failed to prepare" $testfile \
+	 $srcfile {debug nowarnings}]} {
+    return -1
+}
+
+set test "verify no symtabs are expanded"
+if { [readnow] } {
+    unsupported $test
+    return -1
+}
+gdb_test_no_output "maint info symtabs" $test
+
+# Expand the header file symtab.
+gdb_test_no_output "maint expand-symtabs maint-expand-symbols-header-file.h"
+
+# Check that the include symtab was in fact expanded.
+set file_re "\[^\r\n\]*/maint-expand-symbols-header-file.h"
+gdb_test "maint info symtabs" \
+    "\r\n\t{ symtab $file_re \\(\\(struct symtab \\*\\) $hex\\)\r\n.*" \
+    "check header file psymtab expansion"
+
+# Check that the symtab the include symtab was referring to was expanded.
+set file_re "\[^\r\n\]*/maint-expand-symbols-header-file.c"
+gdb_test "maint info symtabs" \
+    "\r\n\t{ symtab $file_re \\(\\(struct symtab \\*\\) $hex\\)\r\n.*" \
+    "check source file psymtab expansion"
diff --git a/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.h b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.h
new file mode 100644
index 0000000000..d8d2517c7b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.h
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   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/>.  */
+
+inline static const char*
+foo (void)
+{
+  return "foo";
+}

Patch

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 8c5046ef41..f033087ea6 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -4543,7 +4543,7 @@  static void
 dw2_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain kind)
@@ -4557,9 +4557,21 @@  dw2_expand_symtabs_matching
 
   dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
 
+  if (symbol_matcher == NULL && lookup_name == NULL)
+    {
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+	{
+	  QUIT;
+
+	  dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+					   expansion_notify);
+	}
+      return;
+    }
+
   mapped_index &index = *dwarf2_per_objfile->index_table;
 
-  dw2_expand_symtabs_matching_symbol (index, lookup_name,
+  dw2_expand_symtabs_matching_symbol (index, *lookup_name,
 				      symbol_matcher,
 				      kind, [&] (offset_type idx)
     {
@@ -5551,7 +5563,7 @@  static void
 dw2_debug_names_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain kind)
@@ -5565,9 +5577,21 @@  dw2_debug_names_expand_symtabs_matching
 
   dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
 
+  if (symbol_matcher == NULL && lookup_name == NULL)
+    {
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+	{
+	  QUIT;
+
+	  dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+					   expansion_notify);
+	}
+      return;
+    }
+
   mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
 
-  dw2_expand_symtabs_matching_symbol (map, lookup_name,
+  dw2_expand_symtabs_matching_symbol (map, *lookup_name,
 				      symbol_matcher,
 				      kind, [&] (offset_type namei)
     {
diff --git a/gdb/linespec.c b/gdb/linespec.c
index d853e02d8f..e1349e78a0 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -1149,7 +1149,7 @@  iterate_over_all_matching_symtabs
 	if (objfile->sf)
 	  objfile->sf->qf->expand_symtabs_matching (objfile,
 						    NULL,
-						    lookup_name,
+						    &lookup_name,
 						    NULL, NULL,
 						    search_domain);
 
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 8aa9c6e87b..e77eb07da4 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -1301,13 +1301,11 @@  static void
 psym_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name_in,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain domain)
 {
-  lookup_name_info lookup_name = lookup_name_in.make_ignore_params ();
-
   /* Clear the search flags.  */
   for (partial_symtab *ps : require_partial_symbols (objfile, true))
     ps->searched_flag = PST_NOT_SEARCHED;
@@ -1344,8 +1342,10 @@  psym_expand_symtabs_matching
 	    continue;
 	}
 
-      if (recursively_search_psymtabs (ps, objfile, domain,
-				       lookup_name, symbol_matcher))
+      if ((symbol_matcher == NULL && lookup_name == NULL)
+	  || recursively_search_psymtabs (ps, objfile, domain,
+					  lookup_name->make_ignore_params (),
+					  symbol_matcher))
 	{
 	  struct compunit_symtab *symtab =
 	    psymtab_to_symtab (objfile, ps);
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c
index 53a77a5405..60489dbfa5 100644
--- a/gdb/symfile-debug.c
+++ b/gdb/symfile-debug.c
@@ -254,7 +254,7 @@  static void
 debug_qf_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain kind)
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 3b63887ce1..8b29516b4e 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -3786,7 +3786,7 @@  expand_symtabs_matching
     {
       if (objfile->sf)
 	objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher,
-						  lookup_name,
+						  &lookup_name,
 						  symbol_matcher,
 						  expansion_notify, kind);
     }
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 85f8e7c155..68b1813ec5 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -242,11 +242,14 @@  struct quick_symbol_functions
      names (the passed file name is already only the lbasename'd
      part).
 
-     Otherwise, if KIND does not match, this symbol is skipped.
+     If the file is not skipped, and SYMBOL_MATCHER and LOOKUP_NAME are NULL,
+     the symbol table is expanded.
 
-     If even KIND matches, SYMBOL_MATCHER is called for each symbol
-     defined in the file.  The symbol "search" name is passed to
-     SYMBOL_MATCHER.
+     Otherwise, individual symbols are considered.
+
+     If KIND does not match, the symbol is skipped.
+
+     If the symbol name does not match LOOKUP_NAME, the symbol is skipped.
 
      If SYMBOL_MATCHER returns false, then the symbol is skipped.
 
@@ -254,7 +257,7 @@  struct quick_symbol_functions
   void (*expand_symtabs_matching)
     (struct objfile *objfile,
      gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-     const lookup_name_info &lookup_name,
+     const lookup_name_info *lookup_name,
      gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
      gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
      enum search_domain kind);
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index bee136ed46..1076a0bcaf 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -977,12 +977,8 @@  maintenance_expand_symtabs (const char *args, int from_tty)
 		 return (!basenames
 			 && (regexp == NULL || re_exec (filename)));
 	       },
-	       lookup_name_info::match_any (),
-	       [] (const char *symname)
-	       {
-		 /* Since we're not searching on symbols, just return true.  */
-		 return true;
-	       },
+	       NULL,
+	       NULL,
 	       NULL,
 	       ALL_DOMAIN);
 	  }
diff --git a/gdb/symtab.c b/gdb/symtab.c
index f300d759e0..073b76db2d 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -4513,7 +4513,7 @@  global_symbol_searcher::expand_symtabs
        {
 	 return file_matches (filename, filenames, basenames);
        },
-       lookup_name_info::match_any (),
+       &lookup_name_info::match_any (),
        [&] (const char *symname)
        {
 	 return (!preg.has_value ()
diff --git a/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.c b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.c
new file mode 100644
index 0000000000..36e3de75c2
--- /dev/null
+++ b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.c
@@ -0,0 +1,9 @@ 
+#include <stdio.h>
+#include "maint-expand-symbols-header-file.h"
+
+int
+main (void)
+{
+  printf ("hello: %s\n", foo ());
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.exp b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.exp
new file mode 100644
index 0000000000..ef5238f5c9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.exp
@@ -0,0 +1,57 @@ 
+# 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/>.
+#
+# Test-case to verify that symbol-less partial symtabs are expanded by
+# "maint expand-symtabs".
+
+standard_testfile .c
+
+if {[build_executable "failed to prepare" $testfile \
+	 $srcfile {debug nowarnings}]} {
+    return -1
+}
+
+clean_restart
+
+# Make sure that no partial symtabs are expanded, by setting language before
+# loading exec.
+gdb_test_no_output "set language c"
+gdb_load ${binfile}
+
+set cmd "maint info psymtabs"
+gdb_test_multiple $cmd "" {
+    -re "$cmd\r\n$gdb_prompt $" {
+	# Give up for target boards readnow.exp, cc-with-gdb-index.exp and
+	# cc-with-debug-names.exp.
+	unsupported $gdb_test_name
+	return -1
+    }
+    -re -wrap "" {
+	pass $gdb_test_name
+    }
+}
+
+# Expand the header file symtab.
+gdb_test_no_output "maint expand-symtabs maint-expand-symbols-header-file.h"
+
+# Check that the header file symtab was in fact expanded.
+set file_re "\[^\r\n\]*/maint-expand-symbols-header-file.h"
+gdb_test "maint info psymtabs" \
+    [multi_line \
+	 "" \
+	 "  { psymtab $file_re \\(\\(struct partial_symtab \\*\\) $hex\\)" \
+	 "    readin yes" \
+	 ".*"] \
+    "check header file psymtab expansion"
diff --git a/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.h b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.h
new file mode 100644
index 0000000000..4671321615
--- /dev/null
+++ b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.h
@@ -0,0 +1,5 @@ 
+inline static const char*
+foo (void)
+{
+  return "foo";
+}