+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.
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. */
}
}
- 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);
}
}
+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.
--- /dev/null
+/* 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)
+{
+}
--- /dev/null
+/* 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)
+{
+}
--- /dev/null
+/* 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)
+{
+}
--- /dev/null
+/* 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;
+}
--- /dev/null
+# 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
+}
--- /dev/null
+/* 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;
+}
--- /dev/null
+# 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
+}