diff options
-rw-r--r-- | gdb/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/linespec.c | 88 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 10 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/msym-bp-2.c | 21 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/msym-bp-shl-lib.c | 21 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/msym-bp-shl-main-2.c | 21 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/msym-bp-shl-main.c | 25 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/msym-bp-shl.exp | 107 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/msym-bp.c | 27 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/msym-bp.exp | 83 |
10 files changed, 363 insertions, 47 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7459334..eae0796 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2020-09-13 Pedro Alves <pedro@palves.net> + + * linespec.c (classify_mtype, compare_msyms): Delete. + (search_minsyms_for_name): Remove classification logic. Instead + filter out trampoline symbols if we also found an external + function of the same name. + 2020-09-13 Joel Brobecker <brobecker@adacore.com> * NEWS: Create a new section for the next release branch. diff --git a/gdb/linespec.c b/gdb/linespec.c index e8f3d59..9c80864 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -4252,41 +4252,6 @@ minsym_found (struct linespec_state *self, struct objfile *objfile, add_sal_to_sals (self, result, &sal, msymbol->natural_name (), 0); } -/* A helper function to classify a minimal_symbol_type according to - priority. */ - -static int -classify_mtype (enum minimal_symbol_type t) -{ - switch (t) - { - case mst_file_text: - case mst_file_data: - case mst_file_bss: - /* Intermediate priority. */ - return 1; - - case mst_solib_trampoline: - /* Lowest priority. */ - return 2; - - default: - /* Highest priority. */ - return 0; - } -} - -/* Callback for std::sort that sorts symbols by priority. */ - -static bool -compare_msyms (const bound_minimal_symbol &a, const bound_minimal_symbol &b) -{ - enum minimal_symbol_type ta = MSYMBOL_TYPE (a.minsym); - enum minimal_symbol_type tb = MSYMBOL_TYPE (b.minsym); - - return classify_mtype (ta) < classify_mtype (tb); -} - /* Helper for search_minsyms_for_name that adds the symbol to the result. */ @@ -4373,24 +4338,53 @@ search_minsyms_for_name (struct collect_info *info, } } - if (!minsyms.empty ()) + /* Return true if TYPE is a static symbol. */ + auto msymbol_type_is_static = [] (enum minimal_symbol_type type) { - int classification; + switch (type) + { + case mst_file_text: + case mst_file_data: + case mst_file_bss: + return true; + default: + return false; + } + }; - std::sort (minsyms.begin (), minsyms.end (), compare_msyms); + /* Add minsyms to the result set, but filter out trampoline symbols + if we also found extern symbols with the same name. I.e., don't + set a breakpoint on both '<foo@plt>' and 'foo', assuming that + 'foo' is the symbol that the plt resolves to. */ + for (const bound_minimal_symbol &item : minsyms) + { + bool skip = false; + if (MSYMBOL_TYPE (item.minsym) == mst_solib_trampoline) + { + for (const bound_minimal_symbol &item2 : minsyms) + { + if (&item2 == &item) + continue; - /* Now the minsyms are in classification order. So, we walk - over them and process just the minsyms with the same - classification as the very first minsym in the list. */ - classification = classify_mtype (MSYMBOL_TYPE (minsyms[0].minsym)); + /* Trampoline symbols can only jump to exported + symbols. */ + if (msymbol_type_is_static (MSYMBOL_TYPE (item2.minsym))) + continue; - for (const bound_minimal_symbol &item : minsyms) - { - if (classify_mtype (MSYMBOL_TYPE (item.minsym)) != classification) - break; + if (strcmp (item.minsym->linkage_name (), + item2.minsym->linkage_name ()) != 0) + continue; - info->result.minimal_symbols->push_back (item); + /* Found a global minsym with the same name as the + trampoline. Don't create a location for this + trampoline. */ + skip = true; + break; + } } + + if (!skip) + info->result.minimal_symbols->push_back (item); } } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index f8ac411..76c66ac 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2020-09-13 Pedro Alves <pedro@palves.net> + + * gdb.base/msym-bp-2.c: New. + * gdb.base/msym-bp-shl-lib.c: New file. + * gdb.base/msym-bp-shl-main-2.c: New file. + * gdb.base/msym-bp-shl-main.c: New file. + * gdb.base/msym-bp-shl.exp: New file. + * gdb.base/msym-bp.c: New file. + * gdb.base/msym-bp.exp: New file. + 2020-09-13 Joel Brobecker <brobecker@adacore.com> * gdb.base/default.exp: Change $_gdb_major to 11. diff --git a/gdb/testsuite/gdb.base/msym-bp-2.c b/gdb/testsuite/gdb.base/msym-bp-2.c new file mode 100644 index 0000000..b5a399e --- /dev/null +++ b/gdb/testsuite/gdb.base/msym-bp-2.c @@ -0,0 +1,21 @@ +/* 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/>. */ + +void +foo (void) +{ +} diff --git a/gdb/testsuite/gdb.base/msym-bp-shl-lib.c b/gdb/testsuite/gdb.base/msym-bp-shl-lib.c new file mode 100644 index 0000000..b5a399e --- /dev/null +++ b/gdb/testsuite/gdb.base/msym-bp-shl-lib.c @@ -0,0 +1,21 @@ +/* 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/>. */ + +void +foo (void) +{ +} diff --git a/gdb/testsuite/gdb.base/msym-bp-shl-main-2.c b/gdb/testsuite/gdb.base/msym-bp-shl-main-2.c new file mode 100644 index 0000000..520701e --- /dev/null +++ b/gdb/testsuite/gdb.base/msym-bp-shl-main-2.c @@ -0,0 +1,21 @@ +/* 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/>. */ + +static void +foo (void) +{ +} diff --git a/gdb/testsuite/gdb.base/msym-bp-shl-main.c b/gdb/testsuite/gdb.base/msym-bp-shl-main.c new file mode 100644 index 0000000..d6f3222 --- /dev/null +++ b/gdb/testsuite/gdb.base/msym-bp-shl-main.c @@ -0,0 +1,25 @@ +/* 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/>. */ + +extern void foo (void); + +int +main () +{ + foo (); + return 0; +} diff --git a/gdb/testsuite/gdb.base/msym-bp-shl.exp b/gdb/testsuite/gdb.base/msym-bp-shl.exp new file mode 100644 index 0000000..fee1d72 --- /dev/null +++ b/gdb/testsuite/gdb.base/msym-bp-shl.exp @@ -0,0 +1,107 @@ +# 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 that when setting a breakpoint at "foo", GDB creates a location +# for an unresolved <foo@plt> PLT in the main binary, even when a +# static function named "foo" exists in the shared library. Tests +# both with and without debug info. + +if {[skip_shlib_tests]} { + return 0 +} + +standard_testfile msym-bp-shl-main.c msym-bp-shl-main-2.c msym-bp-shl-lib.c +set srcfile ${srcdir}/${subdir}/${srcfile} +set srcfile2 ${srcdir}/${subdir}/${srcfile2} +set libsrc ${srcdir}/${subdir}/${srcfile3} + +# Run "info breakpoints", and check that we find the two locations, +# LOC_A and LOC_B, in either order. +proc test_info_break_2 {loc_a loc_b} { + set re1 ".*\.1.*${loc_a}\r\n.*\.2.*${loc_b}" + set re2 ".*\.1.*${loc_b}\r\n.*\.2.*${loc_a}" + gdb_test "info breakpoint" "$re1|$re2" +} + +proc test {debug} { + global testfile binfile srcfile srcfile2 libsrc + global decimal + + if {$debug} { + set options "debug" + } else { + set options "" + } + + set bin ${binfile}-$debug + set lib [standard_output_file msym-bp-shl-lib-$debug.sl] + + set exec_opts [list $options shlib=${lib}] + + if { [gdb_compile_shlib $libsrc $lib $options] != "" + || [gdb_compile [list $srcfile $srcfile2] $bin \ + executable $exec_opts] != ""} { + untested "failed to compile" + return + } + + clean_restart $bin + gdb_load_shlib $lib + + # Should find two locations: the static foo in the + # msym-bp-shl-main-2 file, and <foo@plt>, both in the main binary. + with_test_prefix "before run" { + gdb_test "break foo" "\\(2 locations\\)" + + if {$debug} { + test_info_break_2 \ + "<foo@plt.*>" \ + "in foo at .*msym-bp-shl-main-2.c:$decimal" + } else { + test_info_break_2 \ + "<foo@plt.*>" \ + "<foo\\+$decimal>" + } + } + + if ![runto_main] { + fail "can't run to main" + return + } + + delete_breakpoints + + # Should still find two locations, but the <foo@plt> PLT location + # should not be present anymore. I.e., we should find the static + # foo in the msym-bp-shl-main-2 file, and the extern foo in the + # shared library. + with_test_prefix "at main" { + gdb_test "break foo" "\\(2 locations\\)" + + if {$debug} { + test_info_break_2 \ + "in foo at .*msym-bp-shl-main-2.c:$decimal" \ + "in foo at .*msym-bp-shl-lib.c:$decimal" + } else { + test_info_break_2 \ + "<foo\\+$decimal>" \ + "<foo\\+$decimal>" + } + } +} + +foreach_with_prefix debug {0 1} { + test $debug +} diff --git a/gdb/testsuite/gdb.base/msym-bp.c b/gdb/testsuite/gdb.base/msym-bp.c new file mode 100644 index 0000000..2257d3f --- /dev/null +++ b/gdb/testsuite/gdb.base/msym-bp.c @@ -0,0 +1,27 @@ +/* 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/>. */ + +static void +foo (void) +{ +} + +int +main (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.base/msym-bp.exp b/gdb/testsuite/gdb.base/msym-bp.exp new file mode 100644 index 0000000..c4bef7c --- /dev/null +++ b/gdb/testsuite/gdb.base/msym-bp.exp @@ -0,0 +1,83 @@ +# 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/>. + +# Test that when setting breakpoints, setting a breakpoint on "foo" +# creates locations for all external and static functions called "foo" +# in the program, with and without debug info. + +standard_testfile .c msym-bp-2.c + +# Run "info breakpoints", and check that we find the two locations, +# LOC_A and LOC_B, in either order. +proc test_info_break_2 {loc_a loc_b} { + set re1 ".*\.1.*${loc_a}\r\n.*\.2.*${loc_b}" + set re2 ".*\.1.*${loc_b}\r\n.*\.2.*${loc_a}" + gdb_test "info breakpoint" "$re1|$re2" +} + +proc test {debug} { + global testfile srcfile srcfile2 + global decimal + + if {$debug} { + set options "debug" + } else { + set options "" + } + + if { [prepare_for_testing "failed to prepare" $testfile-$debug \ + [list $srcfile $srcfile2] $options] } { + return -1 + } + + # Should find two locations: the static foo in the msym-bp.c file, + # and the extern foo in the msym-bp-2.c file. Same result + # expected before and after running to main. + proc test_break {prefix} { + global decimal + upvar debug debug + + with_test_prefix $prefix { + gdb_test "break foo" "\\(2 locations\\)" + + if {$debug} { + test_info_break_2 \ + "in foo at .*msym-bp.c:$decimal" \ + "in foo at .*msym-bp-2.c:$decimal" + } else { + test_info_break_2 \ + "<foo\\+$decimal>" \ + "<foo\\+$decimal>" + } + } + } + + test_break "before run" + + if ![runto_main] { + fail "can't run to main" + return + } + + delete_breakpoints + + test_break "at main" +} + +foreach_with_prefix debug {0 1} { + test $debug +} |