public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] [gdb/symtab] Handle struct decl with DW_AT_signature
@ 2020-04-28  4:12 Tom de Vries
  0 siblings, 0 replies; only message in thread
From: Tom de Vries @ 2020-04-28  4:12 UTC (permalink / raw)
  To: gdb-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=15cd93d05e8e84644acc8bbeaa3d5f4280cc5159

commit 15cd93d05e8e84644acc8bbeaa3d5f4280cc5159
Author: Tom de Vries <tdevries@suse.de>
Date:   Tue Apr 28 06:12:35 2020 +0200

    [gdb/symtab] Handle struct decl with DW_AT_signature
    
    Consider a test-case with sources 36.c:
    ...
    struct s { int i; };
    extern void f (void);
    int main (void) {
      struct s a;
      f ();
      return 0;
    }
    ...
    and 36b.c:
    ...
    struct s { int j; };
    void f (void) {
      struct s b;
    }
    ...
    compiled like this:
    ...
    $ gcc 36.c 36b.c -g
    ...
    
    It contains DWARF like this:
    ...
     <0><d2>: Abbrev Number: 1 (DW_TAG_compile_unit)
        <d8>   DW_AT_name        : 36.c
     <1><f4>: Abbrev Number: 2 (DW_TAG_structure_type)
        <f5>   DW_AT_name        : s
     <2><fe>: Abbrev Number: 3 (DW_TAG_member)
        <ff>   DW_AT_name        : i
     <1><110>: Abbrev Number: 5 (DW_TAG_subprogram)
        <111>   DW_AT_name        : main
     <2><12d>: Abbrev Number: 6 (DW_TAG_variable)
        <12e>   DW_AT_name        : a
        <132>   DW_AT_type        : <0xf4>
     <0><146>: Abbrev Number: 1 (DW_TAG_compile_unit)
        <14c>   DW_AT_name        : 36b.c
     <1><168>: Abbrev Number: 2 (DW_TAG_structure_type)
        <169>   DW_AT_name        : s
     <2><172>: Abbrev Number: 3 (DW_TAG_member)
        <173>   DW_AT_name        : j
     <1><184>: Abbrev Number: 5 (DW_TAG_subprogram)
        <185>   DW_AT_name        : f
     <2><19b>: Abbrev Number: 6 (DW_TAG_variable)
        <19c>   DW_AT_name        : b
        <1a0>   DW_AT_type        : <0x168>
    ...
    
    And when printing "struct s", we get first a random one (with int j), and then
    context-specific ones (with int i in main, and int j in f):
    ...
    $ gdb -batch a.out \
      -ex "ptype struct s" \
      -ex start \
      -ex "ptype struct s" \
      -ex "break f" -ex continue \
      -ex "ptype struct s" \
      | grep "int [ij];"
        int j;
        int i;
        int j;
    ...
    Same for -readnow.
    
    However, if we use -fdebug-types-section:
    ...
    $ gcc 36.c 36b.c -g -fdebug-types-section
    ...
    we get:
    ...
    $ gdb ... | grep "int [ij];"
        int j;
        int i;
        int i;
    $ gdb -readnow ... | grep "int [ij];"
        int j;
        int j;
        int j;
    ...
    
    This is due to the fact that both "struct s" DIEs have been moved to the
    .debug_types section:
    ...
      Compilation Unit @ offset 0x0:
       Signature:     0xfd1462823bb6f7b7
     <0><17>: Abbrev Number: 1 (DW_TAG_type_unit)
     <1><1d>: Abbrev Number: 2 (DW_TAG_structure_type)
        <1e>   DW_AT_name        : s
     <2><27>: Abbrev Number: 3 (DW_TAG_member)
        <28>   DW_AT_name        : i
      Compilation Unit @ offset 0x3a:
       Signature:     0x534310fbefba324d
     <0><51>: Abbrev Number: 1 (DW_TAG_type_unit)
     <1><57>: Abbrev Number: 2 (DW_TAG_structure_type)
        <58>   DW_AT_name        : s
     <2><61>: Abbrev Number: 3 (DW_TAG_member)
        <62>   DW_AT_name        : j
    ...
    and there's no longer a "struct s" DIE in the 36.c and
    and 36b.c CUs to specify which "struct s" belongs in the CU.  This is gcc
    PR90232.
    
    However, using a tentative patch for gcc that adds these DIEs (according to
    DWARF standard: If the complete declaration of a type has been placed in a
    separate type unit, an incomplete declaration of that type in the compilation
    unit may provide the unique 64-bit signature of the type using a
    DW_AT_signature attribute):
    ...
      <0><d2>: Abbrev Number: 5 (DW_TAG_compile_unit)
         <d8>   DW_AT_name        : 36.c
    + <1><f4>: Abbrev Number: 6 (DW_TAG_structure_type)
    +    <f5>   DW_AT_name        : s
    +    <f7>   DW_AT_signature   : signature: 0xfd1462823bb6f7b7
    +    <ff>   DW_AT_declaration : 1
      <0><13c>: Abbrev Number: 5 (DW_TAG_compile_unit)
         <142>   DW_AT_name        : 36b.c
    + <1><15e>: Abbrev Number: 6 (DW_TAG_structure_type)
    +    <15f>   DW_AT_name        : s
    +    <161>   DW_AT_signature   : signature: 0x534310fbefba324d
    +    <169>   DW_AT_declaration : 1
    ...
    still does not help, because they're declarations, so new_symbol is not called
    for them in process_structure_scope.
    
    Fix this by calling new_symbol for these decls.
    
    Build and tested on x86_64-linux.
    
    Also tested with target board enabling by default -fdebug-types-section
    -gdwarf-4, and with gcc with aforementioned tentative patch.  In this
    configuration, the patch reduces number of FAILs from 2888 to 238.
    
    gdb/ChangeLog:
    
    2020-04-28  Tom de Vries  <tdevries@suse.de>
    
            * dwarf2/read.c (process_structure_scope): Add symbol for struct decl
            with DW_AT_signature.
    
    gdb/testsuite/ChangeLog:
    
    2020-04-28  Tom de Vries  <tdevries@suse.de>
    
            * gdb.dwarf2/main-foo.c: New test.
            * gdb.dwarf2/struct-with-sig.exp: New file.

Diff:
---
 gdb/ChangeLog                                |   5 +
 gdb/dwarf2/read.c                            |   3 +-
 gdb/testsuite/ChangeLog                      |   5 +
 gdb/testsuite/gdb.dwarf2/main-foo.c          |  34 +++++++
 gdb/testsuite/gdb.dwarf2/struct-with-sig.exp | 141 +++++++++++++++++++++++++++
 5 files changed, 187 insertions(+), 1 deletion(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 78b3ed80244..76f6cf78961 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2020-04-28  Tom de Vries  <tdevries@suse.de>
+
+	* dwarf2/read.c (process_structure_scope): Add symbol for struct decl
+	with DW_AT_signature.
+
 2020-04-27  Simon Marchi  <simon.marchi@efficios.com>
 
 	* configure.ac: Remove check for fs_base/gs_base in
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 976261372bc..82564edd7b2 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -15748,7 +15748,8 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
      these DIEs are identified by the fact that they have no byte_size
      attribute, and a declaration attribute.  */
   if (dwarf2_attr (die, DW_AT_byte_size, cu) != NULL
-      || !die_is_declaration (die, cu))
+      || !die_is_declaration (die, cu)
+      || dwarf2_attr (die, DW_AT_signature, cu) != NULL)
     {
       struct symbol *sym = new_symbol (die, type, cu);
 
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 366ecc29edc..2fef7c587ee 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-04-28  Tom de Vries  <tdevries@suse.de>
+
+	* gdb.dwarf2/main-foo.c: New test.
+	* gdb.dwarf2/struct-with-sig.exp: New file.
+
 2020-04-25  Tom de Vries  <tdevries@suse.de>
 
 	* boards/debug-types.exp: New file.
diff --git a/gdb/testsuite/gdb.dwarf2/main-foo.c b/gdb/testsuite/gdb.dwarf2/main-foo.c
new file mode 100644
index 00000000000..82d7b1f40ed
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/main-foo.c
@@ -0,0 +1,34 @@
+/* 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/>.  */
+
+/* Dummy foo function.  */
+
+void
+foo (void)
+{
+  asm ("foo_label: .globl foo_label");
+}
+
+/* Dummy main function.  */
+
+int
+main()
+{
+  asm ("main_label: .globl main_label");
+  foo ();
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.dwarf2/struct-with-sig.exp b/gdb/testsuite/gdb.dwarf2/struct-with-sig.exp
new file mode 100644
index 00000000000..1ce013dfea6
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/struct-with-sig.exp
@@ -0,0 +1,141 @@
+# 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/>.
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+    return 0
+}
+
+standard_testfile main-foo.c .S
+
+# Make some DWARF for the test.
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+    global srcdir subdir srcfile
+
+    lassign [function_range main ${srcdir}/${subdir}/${srcfile}] \
+	main_start main_length
+
+    lassign [function_range foo ${srcdir}/${subdir}/${srcfile}] \
+	foo_start foo_length
+
+    cu {} {
+	compile_unit {
+	    {DW_AT_language @DW_LANG_C}
+	    {DW_AT_name main.c}
+	} {
+	    structure_type {
+		{name s}
+		{signature 0x0000000000000001 ref_sig8}
+		{declaration 1 flag}
+	    }
+	    DW_TAG_subprogram {
+		{name "main"}
+		{low_pc $main_start addr}
+		{high_pc "$main_start + $main_length" addr}
+	    }
+	}
+    }
+
+    cu {} {
+	compile_unit {
+	    {DW_AT_language @DW_LANG_C}
+	    {DW_AT_name     foo.c}
+	} {
+	    structure_type {
+		{name s}
+		{signature 0x0000000000000002 ref_sig8}
+		{declaration 1 flag}
+	    }
+	    DW_TAG_subprogram {
+		{name "foo"}
+		{low_pc $foo_start addr}
+		{high_pc "$foo_start + $foo_length" addr}
+	    }
+	}
+    }
+
+    tu {} 0x0000000000000001 the_type_i {
+	type_unit {} {
+	    declare_labels int_type
+
+	    the_type_i: structure_type {
+		{name s}
+		{byte_size 4 sdata}
+	    } {
+		member {
+		    {name i}
+		    {type :$int_type}
+		}
+	    }
+	    int_type: base_type {
+		{name int}
+		{encoding @DW_ATE_signed}
+		{byte_size 4 sdata}
+	    }
+	}
+    }
+
+    tu {} 0x0000000000000002 the_type_j {
+	type_unit {} {
+	    declare_labels int_type
+
+	    the_type_j: structure_type {
+		{name s}
+		{byte_size 4 sdata}
+	    } {
+		member {
+		    {name j}
+		    {type :$int_type}
+		}
+	    }
+	    int_type: base_type {
+		{name int}
+		{encoding @DW_ATE_signed}
+		{byte_size 4 sdata}
+	    }
+	}
+    }
+}
+
+if { [prepare_for_testing "failed to prepare" ${testfile} \
+	  [list $srcfile $asm_file] {nodebug}] } {
+    return -1
+}
+
+set struct_s_i_re \
+    [multi_line \
+	 "type = struct s {" \
+	 "    int i;" \
+	 "}"]
+set struct_s_j_re \
+    [multi_line \
+	 "type = struct s {" \
+	 "    int j;" \
+	 "}"]
+
+if ![runto_main] {
+    return -1
+}
+
+gdb_test "ptype struct s" $struct_s_i_re \
+    "struct s with int i"
+
+gdb_breakpoint "foo"
+gdb_continue_to_breakpoint "foo"
+
+gdb_test "ptype struct s" $struct_s_j_re \
+    "struct s with int j"


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-04-28  4:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-28  4:12 [binutils-gdb] [gdb/symtab] Handle struct decl with DW_AT_signature Tom de Vries

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).