1 # Copyright
2018-2019 Free Software Foundation
, Inc.
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.
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.
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
/>.
17 # Test DW_AT_ranges in the
context of a subprogram scope.
19 # This test can only be run
on targets which support DWARF
-2 and use gas.
20 if {![dwarf2_support
]} {
21 unsupported
"dwarf2 support required for this test"
25 if [get_compiler_info
] {
29 unsupported
"gcc required for this test"
33 standard_testfile dw2
-ranges
-func.c dw2
-ranges
-func
-dw.S
35 # We need to know the size of
integer and address types in order to
36 # write some of the debugging
info we
'd like to generate.
38 # For that, we ask GDB by debugging our test program. Any program
39 # would do, but since we already have it specifically for this
40 # testcase, might as well use that.
42 if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
46 set asm_file [standard_output_file $srcfile2]
47 Dwarf::assemble $asm_file {
48 global srcdir subdir srcfile srcfile2
49 declare_labels integer_label volatile_label func_ranges_label cu_ranges_label L
50 set int_size [get_sizeof "int" 4]
52 # Find start address and length for our functions.
53 lassign [function_range main [list ${srcdir}/${subdir}/$srcfile]] \
55 set main_end "$main_start + $main_len"
56 lassign [function_range foo [list ${srcdir}/${subdir}/$srcfile]] \
58 set foo_end "$foo_start + $foo_len"
59 lassign [function_range foo_low [list ${srcdir}/${subdir}/$srcfile]] \
60 foo_low_start foo_low_len
61 set foo_low_end "$foo_low_start + $foo_low_len"
62 lassign [function_range bar [list ${srcdir}/${subdir}/$srcfile]] \
64 set bar_end "$bar_start + $bar_len"
65 lassign [function_range baz [list ${srcdir}/${subdir}/$srcfile]] \
67 set baz_end "$baz_start + $baz_len"
69 set e_var [gdb_target_symbol e]
74 {name dw-ranges-func.c}
75 {stmt_list $L DW_FORM_sec_offset}
77 {ranges ${cu_ranges_label} DW_FORM_sec_offset}
79 integer_label: DW_TAG_base_type {
80 {DW_AT_byte_size $int_size DW_FORM_sdata}
81 {DW_AT_encoding @DW_ATE_signed}
84 volatile_label: DW_TAG_volatile_type {
85 {type :$integer_label}
90 {type :$volatile_label}
91 {location {addr $e_var} SPECIAL_expr}
96 {DW_AT_type :$integer_label}
97 {low_pc $main_start addr}
98 {high_pc $main_len DW_FORM_data4}
103 {ranges ${func_ranges_label} DW_FORM_sec_offset}
108 {low_pc $bar_start addr}
109 {high_pc $bar_len DW_FORM_data4}
114 {low_pc $baz_start addr}
115 {high_pc $baz_len DW_FORM_data4}
120 lines {version 2} L {
121 include_dir "${srcdir}/${subdir}"
122 file_name "$srcfile" 1
124 # Generate a line table program. An attempt was made to make it
125 # reasonably accurate as it made debugging the test case easier.
127 {DW_LNE_set_address $main_start}
128 {DW_LNS_advance_line [expr [gdb_get_line_number "main prologue"] - 1]}
130 {DW_LNE_set_address main_label}
131 {DW_LNS_advance_line [expr [gdb_get_line_number "main foo call"] - [gdb_get_line_number "main prologue"]]}
133 {DW_LNE_set_address main_label2}
134 {DW_LNS_advance_line [expr [gdb_get_line_number "main return"] - [gdb_get_line_number "main foo call"]]}
136 {DW_LNE_set_address $main_end}
137 {DW_LNS_advance_line [expr [gdb_get_line_number "main end"] - [gdb_get_line_number "main return"] + 1]}
139 {DW_LNE_end_sequence}
141 {DW_LNE_set_address $foo_start}
142 {DW_LNS_advance_line [expr [gdb_get_line_number "foo prologue"] - 1] }
144 {DW_LNE_set_address foo_label}
145 {DW_LNS_advance_line [expr [gdb_get_line_number "foo bar call"] - [gdb_get_line_number "foo prologue"]]}
147 {DW_LNE_set_address foo_label2}
148 {DW_LNS_advance_line [expr [gdb_get_line_number "foo foo_low call"] - [gdb_get_line_number "foo bar call"]]}
150 {DW_LNE_set_address foo_label3}
151 {DW_LNS_advance_line [expr [gdb_get_line_number "foo end"] - [gdb_get_line_number "foo foo_low call"]]}
153 {DW_LNE_set_address $foo_end}
154 {DW_LNS_advance_line 1}
156 {DW_LNE_end_sequence}
158 {DW_LNE_set_address $bar_start}
159 {DW_LNS_advance_line [expr [gdb_get_line_number "bar end"] - 1]}
161 {DW_LNS_advance_pc $bar_len}
162 {DW_LNS_advance_line 1}
164 {DW_LNE_end_sequence}
166 {DW_LNE_set_address $baz_start}
167 {DW_LNS_advance_line [expr [gdb_get_line_number "baz end"] - 1]}
169 {DW_LNS_advance_pc $baz_len}
170 {DW_LNS_advance_line 1}
172 {DW_LNE_end_sequence}
174 {DW_LNE_set_address $foo_low_start}
175 {DW_LNS_advance_line [expr [gdb_get_line_number "foo_low prologue"] - 1]}
177 {DW_LNE_set_address foo_low_label}
178 {DW_LNS_advance_line [expr [gdb_get_line_number "foo_low baz call"] - [gdb_get_line_number "foo_low prologue"]]}
180 {DW_LNE_set_address foo_low_label2}
181 {DW_LNS_advance_line [expr [gdb_get_line_number "foo_low end"] - [gdb_get_line_number "foo_low baz call"]]}
183 {DW_LNE_set_address $foo_low_end}
184 {DW_LNS_advance_line 1}
186 {DW_LNE_end_sequence}
190 # Generate ranges data.
191 ranges {is_64 [is_64_target]} {
192 func_ranges_label: sequence {
193 {range {$foo_start } $foo_end}
194 {range {$foo_low_start} $foo_low_end}
196 cu_ranges_label: sequence {
197 {range {$foo_start } $foo_end}
198 {range {$foo_low_start} $foo_low_end}
199 {range {$main_start} $main_end}
200 {range {$bar_start} $bar_end}
201 {range {$baz_start} $baz_end}
206 if { [prepare_for_testing "failed to prepare" ${testfile} \
207 [list $srcfile $asm_file] {nodebug}] } {
215 set main_prologue_line_num [gdb_get_line_number "main prologue"]
216 # Do a sanity check to make sure that line number info is available.
217 gdb_test "info line main" \
218 "Line ${main_prologue_line_num} of .* starts at address .* and ends at .*"
220 with_test_prefix "step-test-1" {
221 set bp_foo_bar [gdb_get_line_number "foo bar call"]
223 gdb_test "break $bp_foo_bar" \
224 "Breakpoint.*at.* file .*$srcfile, line $bp_foo_bar\\." \
225 "break at call to bar"
227 gdb_test "continue" \
228 "Continuing\\..*Breakpoint \[0-9\]+, foo \\(\\).*$bp_foo_bar\\s+bar\\s\\(\\);.*foo bar call.*" \
229 "continue to call of bar"
232 "bar \\(\\).*bar end.*" \
236 "foo \\(\\).*foo foo_low call.*" \
237 "step out of bar, back into foo"
240 with_test_prefix "step-test-2" {
241 clean_restart ${testfile}
246 # Note that the RE used for the following test will fail when the
247 # breakpoint has been set on multiple locations. E.g. "(2 locations)".
248 # This is intentional since that behavior is one of the bugs that
249 # this test case tests for.
250 gdb_test "break foo" \
251 "Breakpoint.*at.* file .*$srcfile, line \\d+\\." \
254 # Continue to foo. Allow execution to stop either on the prologue
255 # or on the call to bar since either behavior is acceptable though
256 # the latter is preferred.
257 set test "continue to foo"
258 gdb_test_multiple "continue" $test {
259 -re "Breakpoint \\d+, foo \\(\\).*foo prologue.*${gdb_prompt}" {
263 "step to call of bar after landing on prologue"
265 -re "Breakpoint \\d+, foo \\(\\).*foo bar call.*${gdb_prompt}" {
271 "bar \\(\\).*bar end.*" \
275 "foo \\(\\).*foo foo_low call.*" \
276 "step out of bar, back into foo"
279 clean_restart ${testfile}
284 # Disassembly of foo should have multiple address ranges.
285 gdb_test_sequence "disassemble foo" "" [list \
286 "Dump of assembler code for function foo:" \
287 "Address range $hex to $hex:" \
289 "Address range $hex to $hex:" \
291 "End of assembler dump\\." \
295 set test "x/i foo_low"
296 gdb_test_multiple $test $test {
297 -re " ($hex) <foo.*?>.*${gdb_prompt}" {
298 set foo_low_addr $expect_out(1,string)
305 gdb_test_multiple $test $test {
306 -re " ($hex) <foo.*?>.*${gdb_prompt}" {
307 set foo_addr $expect_out(1,string)
312 gdb_assert {$foo_low_addr != $foo_addr} "foo and foo_low are at different addresses"
314 # This more permissive RE for "break foo" will allow a breakpoint on
315 # multiple locations to PASS. */
316 gdb_test "break foo" \
320 gdb_test "break baz" \
321 "Breakpoint.*at.* file .*$srcfile, line \\d+\\."
323 gdb_test "continue" \
324 "Breakpoint \\d+, foo \\(\\).*" \
327 gdb_test_no_output "set variable e=1"
329 # If GDB incorrectly places the foo breakpoint on multiple locations,
330 # then GDB will (incorrectly) stop in foo_low instead of in baz.
331 gdb_test "continue" \
332 "Breakpoint \\d+, (?:$hex in )?baz \\(\\).*" \
335 with_test_prefix "step-test-3" {
336 clean_restart ${testfile}
342 "foo \\(\\).*bar \\(\\);.*foo bar call.*" \
343 "step into foo from main"
346 "bar \\(\\).*\}.* bar end.*" \
347 "step into bar from foo"
350 "foo(_label2)? \\(\\).*foo_low \\(\\);.*foo foo_low call.*" \
351 "step out of bar to foo"
353 # The tests in the "enable_foo_low_stepping" section, below, work
354 # with some versions of gcc, though it's not clear that they
355 # should. This test case causes foo_low
, originally a separate
356 # function invoked via a subroutine
call, to be considered as part
357 # of foo via use of DW_AT_ranges. Real code that I
've looked at
358 # uses a branch instruction to cause code in the "cold" range to
361 # For the moment though, these tests have been left in place, but
362 # disabled, in case we decide that making such a subroutine call
363 # is a reasonable thing to do that should also be supported by
366 set enable_foo_low_stepping false
368 if { $enable_foo_low_stepping } {
369 gdb_test_no_output "set variable e=1"
371 set test "step into foo_low from foo"
372 gdb_test_multiple "step" $test {
373 -re "foo(_low)? \\(\\).*\{.*foo_low prologue.*${gdb_prompt}" {
376 "foo \\(\\).*baz \\(\\);.*foo_low baz call.*" \
377 "step to baz call in foo_low"
380 -re "foo(_low)? \\(\\).*baz \\(\\);.*foo_low baz call.*${gdb_prompt}" {
386 "baz \\(\\).*\}.*baz end.*" \
387 "step into baz from foo_low"
390 "foo(?:_low(?:_label2)?)? \\(\\).*\}.*foo_low end.*" \
391 "step out of baz to foo_low"
394 "foo(?:_label3)? \\(\\).*\}.*foo end.*" \
395 "step out of foo_low to foo"
399 "next over foo_low call"
403 "main(?:_label2)? \\(\\).*" \
404 "step out of foo to main"