forked from Imagelibrary/binutils-gdb
[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.
This commit is contained in:
@@ -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>
|
2020-04-27 Simon Marchi <simon.marchi@efficios.com>
|
||||||
|
|
||||||
* configure.ac: Remove check for fs_base/gs_base in
|
* configure.ac: Remove check for fs_base/gs_base in
|
||||||
|
|||||||
@@ -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
|
these DIEs are identified by the fact that they have no byte_size
|
||||||
attribute, and a declaration attribute. */
|
attribute, and a declaration attribute. */
|
||||||
if (dwarf2_attr (die, DW_AT_byte_size, cu) != NULL
|
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);
|
struct symbol *sym = new_symbol (die, type, cu);
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
2020-04-25 Tom de Vries <tdevries@suse.de>
|
||||||
|
|
||||||
* boards/debug-types.exp: New file.
|
* boards/debug-types.exp: New file.
|
||||||
|
|||||||
34
gdb/testsuite/gdb.dwarf2/main-foo.c
Normal file
34
gdb/testsuite/gdb.dwarf2/main-foo.c
Normal file
@@ -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;
|
||||||
|
}
|
||||||
141
gdb/testsuite/gdb.dwarf2/struct-with-sig.exp
Normal file
141
gdb/testsuite/gdb.dwarf2/struct-with-sig.exp
Normal file
@@ -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"
|
||||||
Reference in New Issue
Block a user