From: Tom de Vries Date: Tue, 14 Apr 2020 13:08:42 +0000 (+0200) Subject: [gdb] Expand symbolless symtabs using maint expand-symtabs X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c1a66c0629d3b62075a73793f1a7e7393e23e7e2;p=binutils-gdb.git [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-04-14 Tom de Vries 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-04-14 Tom de Vries 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f624c15a4fe..8c9fbe37e2f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,20 @@ +2020-04-14 Tom de Vries + + 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. + 2020-04-13 Tom Tromey * run-on-main-thread.c: Update include. diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index da702205c60..9fa4970556c 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 file_matcher, - const lookup_name_info &lookup_name, + const lookup_name_info *lookup_name, gdb::function_view symbol_matcher, gdb::function_view 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 file_matcher, - const lookup_name_info &lookup_name, + const lookup_name_info *lookup_name, gdb::function_view symbol_matcher, gdb::function_view 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 d853e02d8f6..e1349e78a0d 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 44d4978d539..d952f453d99 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 file_matcher, - const lookup_name_info &lookup_name_in, + const lookup_name_info *lookup_name, gdb::function_view symbol_matcher, gdb::function_view 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 19dc83a8bdd..75e6f2d0d89 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 file_matcher, - const lookup_name_info &lookup_name, + const lookup_name_info *lookup_name, gdb::function_view symbol_matcher, gdb::function_view expansion_notify, enum search_domain kind) diff --git a/gdb/symfile.c b/gdb/symfile.c index 61053298a89..8c002ebfabe 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 84fa283e85c..5ada6c370e7 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 file_matcher, - const lookup_name_info &lookup_name, + const lookup_name_info *lookup_name, gdb::function_view symbol_matcher, gdb::function_view expansion_notify, enum search_domain kind); diff --git a/gdb/symmisc.c b/gdb/symmisc.c index bee136ed465..1076a0bcaf8 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 13a5a108e6f..45d75a3cd11 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/ChangeLog b/gdb/testsuite/ChangeLog index 0afe9d0f875..73931c51da3 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2020-04-14 Tom de Vries + + 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. + 2020-04-14 Andrew Burgess * gdb.dwarf2/dw2-inline-many-frames.exp (get_func_info): Delete. 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 00000000000..649c5b97c5f --- /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 . */ + +#include +#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 00000000000..f73be404c99 --- /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 . +# +# 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 00000000000..d8d2517c7b4 --- /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 . */ + +inline static const char* +foo (void) +{ + return "foo"; +}