forked from Imagelibrary/binutils-gdb
[gdb] Fix missing symtab includes
[ The test-case requires commit c1a66c0629 "[gdb] Expand symbolless symtabs
using maint expand-symtabs". ]
Consider the debug info for the test-case included in this patch. It consists
of a PU:
...
<0><d2>: Abbrev Number: 2 (DW_TAG_partial_unit)
<1><d3>: Abbrev Number: 0
...
imported by a CU:
...
<0><df>: Abbrev Number: 2 (DW_TAG_compile_unit)
<e0> DW_AT_language : 2 (non-ANSI C)
<e1> DW_AT_stmt_list : 0xe9
<1><e5>: Abbrev Number: 3 (DW_TAG_imported_unit)
<e6> DW_AT_import : <0xd2> [Abbrev Number: 2]
<1><ea>: Abbrev Number: 0
...
and the CU has a dw2-symtab-includes.h file in the .debug_line file name
table:
...
The Directory Table (offset 0x101):
1 /data/gdb_versions/devel/src/gdb/testsuite/gdb.dwarf2
The File Name Table (offset 0x138):
Entry Dir Time Size Name
1 1 0 0 dw2-symtab-includes.h
...
After expanding all symtabs, we can see the CU listed in the user field of the
PU, and vice-versa the PU listed in the includes of the CU:
...
$ gdb.sh -batch \
-iex "set language c" \
outputs/gdb.dwarf2/dw2-symtab-includes/dw2-symtab-includes \
-ex "maint expand-symtabs" \
-ex "maint info symtabs"
...
{ ((struct compunit_symtab *) 0x394dd60)
debugformat DWARF 2
producer (null)
dirname (null)
blockvector ((struct blockvector *) 0x394dea0)
user ((struct compunit_symtab *) 0x394dba0)
}
{ ((struct compunit_symtab *) 0x394dba0)
debugformat DWARF 2
producer (null)
dirname (null)
blockvector ((struct blockvector *) 0x394dd10)
user ((struct compunit_symtab *) (null))
( includes
((struct compunit_symtab *) 0x394dd60)
)
}
...
But if we instead only expand the symtab for the dw2-symtab-includes.h file,
the includes and user links are gone:
...
$ gdb -batch \
-iex "set language c" \
outputs/gdb.dwarf2/dw2-symtab-includes/dw2-symtab-includes \
-ex "maint expand-symtabs dw2-symtab-includes.h" \
-ex "maint info symtabs"
...
{ ((struct compunit_symtab *) 0x2728210)
debugformat DWARF 2
producer (null)
dirname (null)
blockvector ((struct blockvector *) 0x2728350)
user ((struct compunit_symtab *) (null))
}
{ ((struct compunit_symtab *) 0x2728050)
debugformat DWARF 2
producer (null)
dirname (null)
blockvector ((struct blockvector *) 0x27281c0)
user ((struct compunit_symtab *) (null))
}
...
The includes are calculated by process_cu_includes in gdb/dwarf2/read.c.
In the case of expanding all symtabs:
- the CU partial symtab is expanded using psymtab_to_symtab
- psymtab_to_symtab calls dwarf2_psymtab::read_symtab
- dwarf2_psymtab::read_symtab calls dwarf2_psymtab::expand_psymtab
- dwarf2_psymtab::read_symtab calls process_cu_includes, and we have the
includes
In the case of expanding the symtab for dw2-symtab-includes.h:
- the dw2-symtab-includes.h partial symtab is expanded using psymtab_to_symtab
- psymtab_to_symtab calls dwarf2_include_psymtab::read_symtab
- dwarf2_include_psymtab::read_symtab calls
dwarf2_include_psymtab::expand_psymtab
- dwarf2_include_psymtab::expand_psymtab calls
partial_symtab::expand_dependencies
- partial_symtab::expand_dependencies calls dwarf2_psymtab::expand_psymtab
for the CU partial symtab
- the CU partial symtab is expanded using dwarf2_psymtab::expand_psymtab
- process_cu_includes is never called
Fix this by making sure in dwarf2_include_psymtab::read_symtab that
read_symtab is called for the CU partial symtab.
Tested on x86_64-linux, with native, and target board cc-with-dwz and
cc-with-dwz-m.
In addition, tested test-case with target boards cc-with-gdb-index.exp,
cc-with-debug-names.exp and readnow.exp.
gdb/ChangeLog:
2020-04-14 Simon Marchi <simon.marchi@polymtl.ca>
Tom de Vries <tdevries@suse.de>
PR symtab/25718
* psympriv.h (struct partial_symtab::read_symtab)
(struct partial_symtab::expand_psymtab)
(struct partial_symtab::read_dependencies): Update comments.
* dwarf2/read.c (struct dwarf2_include_psymtab::read_symtab): Call
read_symtab for includer.
(struct dwarf2_include_psymtab::expand_psymtab): Assert false.
(struct dwarf2_include_psymtab::readin_p): Call readin_p () for includer.
(struct dwarf2_include_psymtab::m_readin): Remove.
(struct dwarf2_include_psymtab::includer): New member function.
(dwarf2_psymtab::expand_psymtab): Assert !readin.
gdb/testsuite/ChangeLog:
2020-04-14 Tom de Vries <tdevries@suse.de>
PR symtab/25718
* gdb.dwarf2/dw2-symtab-includes.exp: New file.
This commit is contained in:
@@ -1,3 +1,18 @@
|
|||||||
|
2020-04-14 Simon Marchi <simon.marchi@polymtl.ca>
|
||||||
|
Tom de Vries <tdevries@suse.de>
|
||||||
|
|
||||||
|
PR symtab/25718
|
||||||
|
* psympriv.h (struct partial_symtab::read_symtab)
|
||||||
|
(struct partial_symtab::expand_psymtab)
|
||||||
|
(struct partial_symtab::read_dependencies): Update comments.
|
||||||
|
* dwarf2/read.c (struct dwarf2_include_psymtab::read_symtab): Call
|
||||||
|
read_symtab for includer.
|
||||||
|
(struct dwarf2_include_psymtab::expand_psymtab): Assert false.
|
||||||
|
(struct dwarf2_include_psymtab::readin_p): Call readin_p () for includer.
|
||||||
|
(struct dwarf2_include_psymtab::m_readin): Remove.
|
||||||
|
(struct dwarf2_include_psymtab::includer): New member function.
|
||||||
|
(dwarf2_psymtab::expand_psymtab): Assert !readin.
|
||||||
|
|
||||||
2020-04-14 Tom de Vries <tdevries@suse.de>
|
2020-04-14 Tom de Vries <tdevries@suse.de>
|
||||||
|
|
||||||
PR symtab/25720
|
PR symtab/25720
|
||||||
|
|||||||
@@ -5917,22 +5917,31 @@ struct dwarf2_include_psymtab : public partial_symtab
|
|||||||
|
|
||||||
void read_symtab (struct objfile *objfile) override
|
void read_symtab (struct objfile *objfile) override
|
||||||
{
|
{
|
||||||
expand_psymtab (objfile);
|
/* It's an include file, no symbols to read for it.
|
||||||
|
Everything is in the includer symtab. */
|
||||||
|
|
||||||
|
/* The expansion of a dwarf2_include_psymtab is just a trigger for
|
||||||
|
expansion of the includer psymtab. We use the dependencies[0] field to
|
||||||
|
model the includer. But if we go the regular route of calling
|
||||||
|
expand_psymtab here, and having expand_psymtab call expand_dependencies
|
||||||
|
to expand the includer, we'll only use expand_psymtab on the includer
|
||||||
|
(making it a non-toplevel psymtab), while if we expand the includer via
|
||||||
|
another path, we'll use read_symtab (making it a toplevel psymtab).
|
||||||
|
So, don't pretend a dwarf2_include_psymtab is an actual toplevel
|
||||||
|
psymtab, and trigger read_symtab on the includer here directly. */
|
||||||
|
includer ()->read_symtab (objfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void expand_psymtab (struct objfile *objfile) override
|
void expand_psymtab (struct objfile *objfile) override
|
||||||
{
|
{
|
||||||
if (m_readin)
|
/* This is not called by read_symtab, and should not be called by any
|
||||||
return;
|
expand_dependencies. */
|
||||||
/* It's an include file, no symbols to read for it.
|
gdb_assert (false);
|
||||||
Everything is in the parent symtab. */
|
|
||||||
expand_dependencies (objfile);
|
|
||||||
m_readin = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool readin_p () const override
|
bool readin_p () const override
|
||||||
{
|
{
|
||||||
return m_readin;
|
return includer ()->readin_p ();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct compunit_symtab *get_compunit_symtab () const override
|
struct compunit_symtab *get_compunit_symtab () const override
|
||||||
@@ -5941,8 +5950,13 @@ struct dwarf2_include_psymtab : public partial_symtab
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
partial_symtab *includer () const
|
||||||
bool m_readin = false;
|
{
|
||||||
|
/* An include psymtab has exactly one dependency: the psymtab that
|
||||||
|
includes it. */
|
||||||
|
gdb_assert (this->number_of_dependencies == 1);
|
||||||
|
return this->dependencies[0];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Allocate a new partial symtab for file named NAME and mark this new
|
/* Allocate a new partial symtab for file named NAME and mark this new
|
||||||
@@ -8858,8 +8872,7 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
|
|||||||
void
|
void
|
||||||
dwarf2_psymtab::expand_psymtab (struct objfile *objfile)
|
dwarf2_psymtab::expand_psymtab (struct objfile *objfile)
|
||||||
{
|
{
|
||||||
if (readin)
|
gdb_assert (!readin);
|
||||||
return;
|
|
||||||
|
|
||||||
expand_dependencies (objfile);
|
expand_dependencies (objfile);
|
||||||
|
|
||||||
|
|||||||
@@ -124,16 +124,26 @@ struct partial_symtab
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the full symbol table corresponding to this partial symbol
|
/* Psymtab expansion is done in two steps:
|
||||||
table. */
|
- a call to read_symtab
|
||||||
|
- while that call is in progress, calls to expand_psymtab can be made,
|
||||||
|
both for this psymtab, and its dependencies.
|
||||||
|
This makes a distinction between a toplevel psymtab (for which both
|
||||||
|
read_symtab and expand_psymtab will be called) and a non-toplevel
|
||||||
|
psymtab (for which only expand_psymtab will be called). The
|
||||||
|
distinction can be used f.i. to do things before and after all
|
||||||
|
dependencies of a top-level psymtab have been expanded.
|
||||||
|
|
||||||
|
Read the full symbol table corresponding to this partial symbol
|
||||||
|
table. Typically calls expand_psymtab. */
|
||||||
virtual void read_symtab (struct objfile *) = 0;
|
virtual void read_symtab (struct objfile *) = 0;
|
||||||
|
|
||||||
/* Psymtab expansion is done in two steps. The first step is a call
|
/* Expand the full symbol table for this partial symbol table. Typically
|
||||||
to read_symtab; but while that is in progress, calls to
|
calls expand_dependencies. */
|
||||||
expand_psymtab can be made. */
|
|
||||||
virtual void expand_psymtab (struct objfile *) = 0;
|
virtual void expand_psymtab (struct objfile *) = 0;
|
||||||
|
|
||||||
/* Ensure that all the dependencies are read in. */
|
/* Ensure that all the dependencies are read in. Calls
|
||||||
|
expand_psymtab for each non-shared dependency. */
|
||||||
void expand_dependencies (struct objfile *);
|
void expand_dependencies (struct objfile *);
|
||||||
|
|
||||||
/* Return true if the symtab corresponding to this psymtab has been
|
/* Return true if the symtab corresponding to this psymtab has been
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
2020-04-14 Tom de Vries <tdevries@suse.de>
|
||||||
|
|
||||||
|
PR symtab/25718
|
||||||
|
* gdb.dwarf2/dw2-symtab-includes.exp: New file.
|
||||||
|
|
||||||
2020-04-14 Tom de Vries <tdevries@suse.de>
|
2020-04-14 Tom de Vries <tdevries@suse.de>
|
||||||
|
|
||||||
PR symtab/25720
|
PR symtab/25720
|
||||||
|
|||||||
80
gdb/testsuite/gdb.dwarf2/dw2-symtab-includes.exp
Normal file
80
gdb/testsuite/gdb.dwarf2/dw2-symtab-includes.exp
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
# 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/>.
|
||||||
|
|
||||||
|
# Check that symtab user and includes are present after symtab expansion
|
||||||
|
# triggered by an include file.
|
||||||
|
|
||||||
|
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.c .S
|
||||||
|
|
||||||
|
# Create the DWARF.
|
||||||
|
set asm_file [standard_output_file $srcfile2]
|
||||||
|
Dwarf::assemble $asm_file {
|
||||||
|
declare_labels partial_label lines_label
|
||||||
|
global srcdir subdir srcfile
|
||||||
|
|
||||||
|
extern main
|
||||||
|
|
||||||
|
cu {} {
|
||||||
|
partial_label: partial_unit {} {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cu {} {
|
||||||
|
compile_unit {
|
||||||
|
{language @DW_LANG_C}
|
||||||
|
{stmt_list ${lines_label} DW_FORM_sec_offset}
|
||||||
|
} {
|
||||||
|
imported_unit {
|
||||||
|
{import $partial_label ref_addr}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lines {version 2} lines_label {
|
||||||
|
include_dir "${srcdir}/${subdir}"
|
||||||
|
file_name "dw2-symtab-includes.h" 1
|
||||||
|
program {
|
||||||
|
{DW_LNS_advance_line 1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if { [prepare_for_testing "failed to prepare" $testfile \
|
||||||
|
"${asm_file} ${srcfile}" {}] } {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check that no symtabs are expanded.
|
||||||
|
set test "no symtabs expanded"
|
||||||
|
if { [readnow] } {
|
||||||
|
unsupported $test
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
gdb_test_no_output "maint info symtabs" $test
|
||||||
|
|
||||||
|
# Expand dw2-symtab-includes.h symtab
|
||||||
|
gdb_test "maint expand-symtab dw2-symtab-includes.h"
|
||||||
|
|
||||||
|
# Check that there are includes.
|
||||||
|
gdb_test "maint info symtabs" \
|
||||||
|
"\r\n \\( includes\r\n.*" \
|
||||||
|
"check symtab includes"
|
||||||
Reference in New Issue
Block a user