Ignore __fu<digits>__ symbols from COFF symbol tables
authorJoel Brobecker <brobecker@gnat.com>
Fri, 29 Mar 2013 02:04:15 +0000 (02:04 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Fri, 29 Mar 2013 02:04:15 +0000 (02:04 +0000)
The debugger sometimes prints strange function names for given
addresses. For instance, with the following source code...

4    procedure Foo is
5       A : Integer;
6    begin
7       Do_Nothing (A'Address);
8    end Foo;

... we can see...

    (gdb) info line 5
    Line 5 of "foo.adb" starts at address 0x4017ca <_ada_foo+6>
       and ends at 0x4017d2 <_fu29__system__scalar_values__is_is4+7>.
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

_fu29__system__scalar_values__is_is4 is an artificial symbol
generated by the linker, and interferes with the pc-to-symbol
resolution.  There isn't much in the general minimal_symbol
data that could help us identify them, so this patch changes
the COFF reader to simply ignore them.

gdb/ChangeLog:

* coffread.c (is_import_fixup_symbol): New function.
(record_minimal_symbol): Use is_import_fixup_symbol to
detect import fixup symbols, and discard them.

gdb/testsuite/ChangeLog:

        * gdb.ada/win_fu_syms: New testcase.

gdb/ChangeLog
gdb/coffread.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.ada/win_fu_syms.exp [new file with mode: 0644]
gdb/testsuite/gdb.ada/win_fu_syms/foo.adb [new file with mode: 0644]
gdb/testsuite/gdb.ada/win_fu_syms/pck.adb [new file with mode: 0644]
gdb/testsuite/gdb.ada/win_fu_syms/pck.ads [new file with mode: 0644]

index 9dbcc161a361b5f82cb93eec88337a81e9de88e1..3b7926adb1b330bb46fcb528da8baf7011ac2101 100644 (file)
@@ -1,3 +1,9 @@
+2013-03-28  Joel Brobecker  <brobecker@adacore.com>
+
+       * coffread.c (is_import_fixup_symbol): New function.
+       (record_minimal_symbol): Use is_import_fixup_symbol to
+       detect import fixup symbols, and discard them.
+
 2013-03-28  Doug Evans  <dje@google.com>
 
        * dwarf2read.c (create_debug_types_hash_table): Don't allocate the
index c3908803900a67fa1499ada194c2e4e31308362a..eff8d646b08f98c1871966b991b5b1b9a2970b03 100644 (file)
@@ -418,6 +418,39 @@ coff_end_symtab (struct objfile *objfile)
   set_last_source_file (NULL);
 }
 \f
+/* The linker sometimes generates some non-function symbols inside
+   functions referencing variables imported from another DLL.
+   Return nonzero if the given symbol corresponds to one of them.  */
+
+static int
+is_import_fixup_symbol (struct coff_symbol *cs,
+                       enum minimal_symbol_type type)
+{
+  /* The following is a bit of a heuristic using the characterictics
+     of these fixup symbols, but should work well in practice...  */
+  int i;
+
+  /* Must be a non-static text symbol.  */
+  if (type != mst_text)
+    return 0;
+
+  /* Must be a non-function symbol.  */
+  if (ISFCN (cs->c_type))
+    return 0;
+
+  /* The name must start with "__fu<digits>__".  */
+  if (strncmp (cs->c_name, "__fu", 4) != 0)
+    return 0;
+  if (! isdigit (cs->c_name[4]))
+    return 0;
+  for (i = 5; cs->c_name[i] != '\0' && isdigit (cs->c_name[i]); i++)
+    /* Nothing, just incrementing index past all digits.  */;
+  if (cs->c_name[i] != '_' || cs->c_name[i + 1] != '_')
+    return 0;
+
+  return 1;
+}
+
 static struct minimal_symbol *
 record_minimal_symbol (struct coff_symbol *cs, CORE_ADDR address,
                       enum minimal_symbol_type type, int section, 
@@ -429,6 +462,16 @@ record_minimal_symbol (struct coff_symbol *cs, CORE_ADDR address,
   if (cs->c_name[0] == '@')
     return NULL;
 
+  if (is_import_fixup_symbol (cs, type))
+    {
+      /* Because the value of these symbols is within a function code
+        range, these symbols interfere with the symbol-from-address
+        reverse lookup; this manifests itselfs in backtraces, or any
+        other commands that prints symbolic addresses.  Just pretend
+        these symbols do not exist.  */
+      return NULL;
+    }
+
   bfd_section = cs_to_bfd_section (cs, objfile);
   return prim_record_minimal_symbol_and_info (cs->c_name, address,
                                              type, section,
index f153116c3bf7eec96f549b78e876e3be329440f1..9c835f2efa5bddf51e5857f7eba2abc42cbb22b0 100644 (file)
@@ -1,3 +1,7 @@
+2013-03-28  Joel Brobecker  <brobecker@adacore.com>
+
+       * gdb.ada/win_fu_syms: New testcase.
+
 2013-03-28  Doug Evans  <dje@google.com>
 
        * gdb.base/maint.exp (maint print statistics): Update expected output.
diff --git a/gdb/testsuite/gdb.ada/win_fu_syms.exp b/gdb/testsuite/gdb.ada/win_fu_syms.exp
new file mode 100644 (file)
index 0000000..c3cbf16
--- /dev/null
@@ -0,0 +1,35 @@
+# Copyright 2013 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/>.
+
+load_lib "ada.exp"
+
+standard_ada_testfile foo
+
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug additional_flags=-bargs additional_flags=-shared additional_flags=-margs]] != "" } {
+  return -1
+}
+
+clean_restart ${testfile}
+
+set loc [gdb_get_line_number "Integer" ${testdir}/foo.adb]
+gdb_test "info line foo.adb:$loc" \
+         "Line $decimal of \".*foo\\.adb\" starts at address $hex <_ada_foo\\+$decimal> and ends at $hex <_ada_foo\\+$decimal>\\." \
+         "info line on variable declaration"
+
+set loc [gdb_get_line_number "Do_Nothing" ${testdir}/foo.adb]
+gdb_test "info line foo.adb:$loc" \
+         "Line $decimal of \".*foo\\.adb\" starts at address $hex <_ada_foo\\+$decimal> and ends at $hex <_ada_foo\\+$decimal>\\." \
+         "info line on Do_Nothing call"
+
diff --git a/gdb/testsuite/gdb.ada/win_fu_syms/foo.adb b/gdb/testsuite/gdb.ada/win_fu_syms/foo.adb
new file mode 100644 (file)
index 0000000..a09a346
--- /dev/null
@@ -0,0 +1,23 @@
+--  Copyright 2013 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/>.
+
+pragma Initialize_Scalars;
+with Pck; use Pck;
+
+procedure Foo is
+   A : Integer;
+begin
+   Do_Nothing (A'Address);
+end Foo;
diff --git a/gdb/testsuite/gdb.ada/win_fu_syms/pck.adb b/gdb/testsuite/gdb.ada/win_fu_syms/pck.adb
new file mode 100644 (file)
index 0000000..808da4d
--- /dev/null
@@ -0,0 +1,21 @@
+--  Copyright 2007-2013 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/>.
+
+package body Pck is
+   procedure Do_Nothing (A : System.Address) is
+   begin
+      null;
+   end Do_Nothing;
+end Pck;
diff --git a/gdb/testsuite/gdb.ada/win_fu_syms/pck.ads b/gdb/testsuite/gdb.ada/win_fu_syms/pck.ads
new file mode 100644 (file)
index 0000000..d5791b2
--- /dev/null
@@ -0,0 +1,19 @@
+--  Copyright 2007-2013 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/>.
+
+with System;
+package Pck is
+   procedure Do_Nothing (A : System.Address);
+end Pck;