Skip to content

Commit 05caa1d

Browse files
committed
Handle DW_AT_ranges when reading partial symtabs
add_partial_subprogram does not handle DW_AT_ranges, while the full symtab reader does. This can lead to discrepancies where a function is not put into a partial symtab, and so is not available to "break" and the like -- but is available if the full symtab has somehow been read. This patch fixes the bug by arranging to read DW_AT_ranges when reading partial DIEs. This is PR symtab/23331. The new test case is derived from dw2-ranges-func.exp, which is why I kept the copyright dates. gdb/ChangeLog 2019-04-01 Tom Tromey <[email protected]> PR symtab/23331: * dwarf2read.c (partial_die_info::read): Handle DW_AT_ranges. gdb/testsuite/ChangeLog 2019-04-01 Tom Tromey <[email protected]> PR symtab/23331: * gdb.dwarf2/dw2-ranges-main.c: New file. * gdb.dwarf2/dw2-ranges-psym.c: New file. * gdb.dwarf2/dw2-ranges-psym.exp: New file.
1 parent 9d1447e commit 05caa1d

File tree

6 files changed

+234
-0
lines changed

6 files changed

+234
-0
lines changed

gdb/ChangeLog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2019-04-01 Tom Tromey <[email protected]>
2+
3+
PR symtab/23331:
4+
* dwarf2read.c (partial_die_info::read): Handle DW_AT_ranges.
5+
16
2019-04-01 Sergio Durigan Junior <[email protected]>
27
Pedro Alves <[email protected]>
38

gdb/dwarf2read.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18751,6 +18751,25 @@ partial_die_info::read (const struct die_reader_specs *reader,
1875118751
main_subprogram = DW_UNSND (&attr);
1875218752
break;
1875318753

18754+
case DW_AT_ranges:
18755+
{
18756+
/* It would be nice to reuse dwarf2_get_pc_bounds here,
18757+
but that requires a full DIE, so instead we just
18758+
reimplement it. */
18759+
int need_ranges_base = tag != DW_TAG_compile_unit;
18760+
unsigned int ranges_offset = (DW_UNSND (&attr)
18761+
+ (need_ranges_base
18762+
? cu->ranges_base
18763+
: 0));
18764+
18765+
/* Value of the DW_AT_ranges attribute is the offset in the
18766+
.debug_ranges section. */
18767+
if (dwarf2_ranges_read (ranges_offset, &lowpc, &highpc, cu,
18768+
nullptr))
18769+
has_pc_info = 1;
18770+
}
18771+
break;
18772+
1875418773
default:
1875518774
break;
1875618775
}

gdb/testsuite/ChangeLog

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
2019-04-01 Tom Tromey <[email protected]>
2+
3+
PR symtab/23331:
4+
* gdb.dwarf2/dw2-ranges-main.c: New file.
5+
* gdb.dwarf2/dw2-ranges-psym.c: New file.
6+
* gdb.dwarf2/dw2-ranges-psym.exp: New file.
7+
18
2019-03-30 Simon Marchi <[email protected]>
29

310
* gdb.base/default.exp: Add values for $_gdb_major and
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* Copyright 2019 Free Software Foundation, Inc.
2+
3+
This program is free software; you can redistribute it and/or modify
4+
it under the terms of the GNU General Public License as published by
5+
the Free Software Foundation; either version 3 of the License, or
6+
(at your option) any later version.
7+
8+
This program is distributed in the hope that it will be useful,
9+
but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
GNU General Public License for more details.
12+
13+
You should have received a copy of the GNU General Public License
14+
along with this program. If not, see <http://www.gnu.org/licenses/>. */
15+
16+
int main ()
17+
{
18+
return 0;
19+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/* Copyright 2018-2019 Free Software Foundation, Inc.
2+
3+
This program is free software; you can redistribute it and/or modify
4+
it under the terms of the GNU General Public License as published by
5+
the Free Software Foundation; either version 3 of the License, or
6+
(at your option) any later version.
7+
8+
This program is distributed in the hope that it will be useful,
9+
but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
GNU General Public License for more details.
12+
13+
You should have received a copy of the GNU General Public License
14+
along with this program. If not, see <http://www.gnu.org/licenses/>. */
15+
16+
volatile int e = 0;
17+
18+
void
19+
baz (void)
20+
{
21+
asm ("baz_label: .globl baz_label");
22+
} /* baz end */
23+
24+
void
25+
foo_low (void)
26+
{ /* foo_low prologue */
27+
asm ("foo_low_label: .globl foo_low_label");
28+
baz (); /* foo_low baz call */
29+
asm ("foo_low_label2: .globl foo_low_label2");
30+
} /* foo_low end */
31+
32+
void
33+
bar (void)
34+
{
35+
asm ("bar_label: .globl bar_label");
36+
} /* bar end */
37+
38+
void
39+
foo (void)
40+
{ /* foo prologue */
41+
asm ("foo_label: .globl foo_label");
42+
bar (); /* foo bar call */
43+
asm ("foo_label2: .globl foo_label2");
44+
if (e) foo_low (); /* foo foo_low call */
45+
asm ("foo_label3: .globl foo_label3");
46+
} /* foo end */
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# Copyright 2018-2019 Free Software Foundation, Inc.
2+
3+
# This program is free software; you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License as published by
5+
# the Free Software Foundation; either version 3 of the License, or
6+
# (at your option) any later version.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
# GNU General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU General Public License
14+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
16+
load_lib dwarf.exp
17+
18+
# Test that psymbols are made when DW_AT_ranges is used.
19+
20+
# This test can only be run on targets which support DWARF-2 and use gas.
21+
if {![dwarf2_support]} {
22+
unsupported "dwarf2 support required for this test"
23+
return 0
24+
}
25+
26+
if [get_compiler_info] {
27+
return -1
28+
}
29+
if !$gcc_compiled {
30+
unsupported "gcc required for this test"
31+
return 0
32+
}
33+
34+
standard_testfile dw2-ranges-main.c dw2-ranges-psym.c dw2-ranges-psym-dw.S
35+
36+
# We need to know the size of integer and address types in order to
37+
# write some of the debugging info we'd like to generate.
38+
#
39+
# For that, we ask GDB by debugging our test program. Any program
40+
# would do, but since we already have it specifically for this
41+
# testcase, might as well use that.
42+
43+
if { [prepare_for_testing "failed to prepare" ${testfile} \
44+
[list ${srcfile} ${srcfile2}]] } {
45+
return -1
46+
}
47+
48+
set asm_file [standard_output_file $srcfile3]
49+
Dwarf::assemble $asm_file {
50+
global srcdir subdir srcfile srcfile2
51+
declare_labels integer_label volatile_label func_ranges_label cu_ranges_label
52+
set int_size [get_sizeof "int" 4]
53+
54+
# Find start address and length for our functions.
55+
set sources [list ${srcdir}/${subdir}/$srcfile ${srcdir}/${subdir}/$srcfile2]
56+
57+
lassign [function_range foo $sources] \
58+
foo_start foo_len
59+
set foo_end "$foo_start + $foo_len"
60+
61+
lassign [function_range foo_low $sources] \
62+
foo_low_start foo_low_len
63+
set foo_low_end "$foo_low_start + $foo_low_len"
64+
65+
lassign [function_range bar $sources] \
66+
bar_start bar_len
67+
set bar_end "$bar_start + $bar_len"
68+
69+
lassign [function_range baz $sources] \
70+
baz_start baz_len
71+
set baz_end "$baz_start + $baz_len"
72+
73+
cu {} {
74+
compile_unit {
75+
{language @DW_LANG_C}
76+
{name dw-ranges-psym.c}
77+
{low_pc 0 addr}
78+
{ranges ${cu_ranges_label} DW_FORM_sec_offset}
79+
} {
80+
integer_label: DW_TAG_base_type {
81+
{DW_AT_byte_size $int_size DW_FORM_sdata}
82+
{DW_AT_encoding @DW_ATE_signed}
83+
{DW_AT_name integer}
84+
}
85+
volatile_label: DW_TAG_volatile_type {
86+
{type :$integer_label}
87+
}
88+
subprogram {
89+
{external 1 flag}
90+
{name someothername}
91+
{ranges ${func_ranges_label} DW_FORM_sec_offset}
92+
}
93+
subprogram {
94+
{external 1 flag}
95+
{name bar}
96+
{low_pc $bar_start addr}
97+
{high_pc $bar_len DW_FORM_data4}
98+
}
99+
subprogram {
100+
{external 1 flag}
101+
{name baz}
102+
{low_pc $baz_start addr}
103+
{high_pc $baz_len DW_FORM_data4}
104+
}
105+
}
106+
}
107+
108+
# Generate ranges data.
109+
ranges {is_64 [is_64_target]} {
110+
func_ranges_label: sequence {
111+
{range {$foo_start } $foo_end}
112+
{range {$foo_low_start} $foo_low_end}
113+
}
114+
cu_ranges_label: sequence {
115+
{range {$foo_start } $foo_end}
116+
{range {$foo_low_start} $foo_low_end}
117+
{range {$bar_start} $bar_end}
118+
{range {$baz_start} $baz_end}
119+
}
120+
}
121+
}
122+
123+
if { [prepare_for_testing "failed to prepare" ${testfile} \
124+
[list $srcfile $srcfile2 $asm_file] {nodebug}] } {
125+
return -1
126+
}
127+
128+
if ![runto_main] {
129+
return -1
130+
}
131+
132+
# "someothername" should be put into the partial symbol table, but
133+
# there was a bug causing functions using DW_AT_ranges not to be.
134+
# Note we use a name that is very different from the linkage name, in
135+
# order to not set the breakpoint via minsyms.
136+
gdb_test "break someothername" \
137+
"Breakpoint.*at.*" \
138+
"break someothername"

0 commit comments

Comments
 (0)