]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/testsuite/gdb.dwarf2/dw2-ranges-func.exp
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.dwarf2 / dw2-ranges-func.exp
1 # Copyright 2018-2024 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 load_lib dwarf.exp
16
17 # Test DW_AT_ranges in the context of a subprogram scope.
18
19 # This test can only be run on targets which support DWARF-2 and use gas.
20 require dwarf2_support
21
22 require is_c_compiler_gcc
23
24 proc do_test {suffix} {
25 global gdb_test_file_name
26 global testfile binfile srcfile srcfile2 gdb_prompt hex
27
28 # Don't use standard_testfile; we want different binaries for
29 # each suffix.
30 set testfile $gdb_test_file_name-$suffix
31 set binfile [standard_output_file ${testfile}]
32 set srcfile $testfile.c
33 set srcfile2 $testfile-dw2.S
34
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.
37 #
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.
41
42 if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
43 return -1
44 }
45
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]
51
52 # Find start address and length for our functions.
53 lassign [function_range main [list ${srcdir}/${subdir}/$srcfile]] \
54 main_start main_len
55 set main_end "$main_start + $main_len"
56 lassign [function_range foo [list ${srcdir}/${subdir}/$srcfile]] \
57 foo_start foo_len
58 set foo_end "$foo_start + $foo_len"
59 lassign [function_range foo_cold [list ${srcdir}/${subdir}/$srcfile]] \
60 foo_cold_start foo_cold_len
61 set foo_cold_end "$foo_cold_start + $foo_cold_len"
62 lassign [function_range bar [list ${srcdir}/${subdir}/$srcfile]] \
63 bar_start bar_len
64 set bar_end "$bar_start + $bar_len"
65 lassign [function_range baz [list ${srcdir}/${subdir}/$srcfile]] \
66 baz_start baz_len
67 set baz_end "$baz_start + $baz_len"
68
69 set e_var [gdb_target_symbol e]
70
71 cu {} {
72 compile_unit {
73 {language @DW_LANG_C}
74 {name dw-ranges-func2.c}
75 {stmt_list $L DW_FORM_sec_offset}
76 {low_pc 0 addr}
77 {ranges ${cu_ranges_label} DW_FORM_sec_offset}
78 } {
79 integer_label: DW_TAG_base_type {
80 {DW_AT_byte_size $int_size DW_FORM_sdata}
81 {DW_AT_encoding @DW_ATE_signed}
82 {DW_AT_name integer}
83 }
84 volatile_label: DW_TAG_volatile_type {
85 {type :$integer_label}
86 }
87 DW_TAG_variable {
88 {name e}
89 {external 1 flag}
90 {type :$volatile_label}
91 {location {addr $e_var} SPECIAL_expr}
92 }
93 subprogram {
94 {external 1 flag}
95 {name main}
96 {DW_AT_type :$integer_label}
97 {low_pc $main_start addr}
98 {high_pc $main_len DW_FORM_data4}
99 }
100 subprogram {
101 {external 1 flag}
102 {name foo}
103 {ranges ${func_ranges_label} DW_FORM_sec_offset}
104 }
105 subprogram {
106 {external 1 flag}
107 {name bar}
108 {low_pc $bar_start addr}
109 {high_pc $bar_len DW_FORM_data4}
110 }
111 subprogram {
112 {external 1 flag}
113 {name baz}
114 {low_pc $baz_start addr}
115 {high_pc $baz_len DW_FORM_data4}
116 }
117 }
118 }
119
120 lines {version 2} L {
121 include_dir "${srcdir}/${subdir}"
122 file_name "$srcfile" 1
123
124 # Generate a line table program. An attempt was made to make it
125 # reasonably accurate as it made debugging the test case easier.
126 program {
127 DW_LNE_set_address $main_start
128 line [gdb_get_line_number "main prologue"]
129 DW_LNS_copy
130 DW_LNE_set_address main_label
131 line [gdb_get_line_number "main foo call"]
132 DW_LNS_copy
133 DW_LNE_set_address main_label2
134 line [gdb_get_line_number "main return"]
135 DW_LNS_copy
136 DW_LNE_set_address $main_end
137 line [expr [gdb_get_line_number "main end"] + 1]
138 DW_LNS_copy
139 DW_LNE_end_sequence
140
141 DW_LNE_set_address $foo_start
142 line [gdb_get_line_number "foo prologue"]
143 DW_LNS_copy
144 DW_LNE_set_address foo_label
145 line [gdb_get_line_number "foo bar call"]
146 DW_LNS_copy
147 DW_LNE_set_address foo_label2
148 line [gdb_get_line_number "foo foo_cold call"]
149 DW_LNS_copy
150 DW_LNE_set_address foo_label3
151 line [gdb_get_line_number "foo end"]
152 DW_LNS_copy
153 DW_LNE_set_address $foo_end
154 DW_LNS_advance_line 1
155 DW_LNS_copy
156 DW_LNE_end_sequence
157
158 DW_LNE_set_address $bar_start
159 line [gdb_get_line_number "bar end"]
160 DW_LNS_copy
161 DW_LNS_advance_pc $bar_len
162 DW_LNS_advance_line 1
163 DW_LNS_copy
164 DW_LNE_end_sequence
165
166 DW_LNE_set_address $baz_start
167 line [gdb_get_line_number "baz end"]
168 DW_LNS_copy
169 DW_LNS_advance_pc $baz_len
170 DW_LNS_advance_line 1
171 DW_LNS_copy
172 DW_LNE_end_sequence
173
174 DW_LNE_set_address $foo_cold_start
175 line [gdb_get_line_number "foo_cold prologue"]
176 DW_LNS_copy
177 DW_LNE_set_address foo_cold_label
178 line [gdb_get_line_number "foo_cold baz call"]
179 DW_LNS_copy
180 DW_LNE_set_address foo_cold_label2
181 line [gdb_get_line_number "foo_cold end"]
182 DW_LNS_copy
183 DW_LNE_set_address $foo_cold_end
184 DW_LNS_advance_line 1
185 DW_LNS_copy
186 DW_LNE_end_sequence
187 }
188 }
189
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_cold_start $foo_cold_end
195 }
196 cu_ranges_label: sequence {
197 range $foo_start $foo_end
198 range $foo_cold_start $foo_cold_end
199 range $main_start $main_end
200 range $bar_start $bar_end
201 range $baz_start $baz_end
202 }
203 }
204 }
205
206 if { [prepare_for_testing "failed to prepare" ${testfile} \
207 [list $srcfile $asm_file] {nodebug}] } {
208 return -1
209 }
210
211 if ![runto_main] {
212 return -1
213 }
214
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 .*"
219
220 with_test_prefix "step-test-1" {
221 set bp_foo_bar [gdb_get_line_number "foo bar call"]
222
223 gdb_test "break $bp_foo_bar" \
224 "Breakpoint.*at.* file .*$srcfile, line $bp_foo_bar\\." \
225 "break at call to bar"
226
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"
230
231 gdb_test "step" \
232 "bar \\(\\).*bar end.*" \
233 "step into bar"
234
235 gdb_test "step" \
236 "foo \\(\\).*foo foo_cold call.*" \
237 "step out of bar, back into foo"
238 }
239
240 with_test_prefix "step-test-2" {
241 clean_restart ${testfile}
242 if ![runto_main] {
243 return -1
244 }
245
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+\\."
252
253 # Continue to foo. Allow execution to stop either on the prologue
254 # or on the call to bar since either behavior is acceptable though
255 # the latter is preferred.
256 set test "continue to foo"
257 gdb_test_multiple "continue" $test {
258 -re "Breakpoint \\d+, foo \\(\\).*foo prologue.*${gdb_prompt}" {
259 pass $test
260 gdb_test "step" \
261 "foo bar call .*" \
262 "step to call of bar after landing on prologue"
263 }
264 -re "Breakpoint \\d+, foo \\(\\).*foo bar call.*${gdb_prompt}" {
265 pass $test
266 }
267 }
268
269 gdb_test "step" \
270 "bar \\(\\).*bar end.*" \
271 "step into bar"
272
273 gdb_test "step" \
274 "foo \\(\\).*foo foo_cold call.*" \
275 "step out of bar, back into foo"
276 }
277
278 clean_restart ${testfile}
279 if ![runto_main] {
280 return -1
281 }
282
283 # Disassembly of foo should have multiple address ranges.
284 gdb_test_sequence "disassemble foo" "" [list \
285 "Dump of assembler code for function foo:" \
286 "Address range $hex to $hex:" \
287 " $hex <\\+0>:" \
288 "Address range $hex to $hex:" \
289 " $hex <(.+?)>:" \
290 "End of assembler dump\\." \
291 ]
292
293 set foo_cold_addr -1
294 set test "x/i foo_cold"
295 gdb_test_multiple $test $test {
296 -re " ($hex) <foo.*?>.*${gdb_prompt}" {
297 set foo_cold_addr $expect_out(1,string)
298 pass $test
299 }
300 }
301
302 set foo_addr -1
303 set test "x/i foo"
304 gdb_test_multiple $test $test {
305 -re " ($hex) <foo.*?>.*${gdb_prompt}" {
306 set foo_addr $expect_out(1,string)
307 pass $test
308 }
309 }
310
311 gdb_assert {$foo_cold_addr != $foo_addr} "foo and foo_cold are at different addresses"
312
313 # This more permissive RE for "break foo" will allow a breakpoint on
314 # multiple locations to PASS. */
315 gdb_test "break foo" \
316 "Breakpoint.*at.*"
317
318 gdb_test "break baz" \
319 "Breakpoint.*at.* file .*$srcfile, line \\d+\\."
320
321 gdb_test "continue" \
322 "Breakpoint \\d+, foo \\(\\).*" \
323 "continue to foo"
324
325 gdb_test_no_output "set variable e=1"
326
327 # If GDB incorrectly places the foo breakpoint on multiple locations,
328 # then GDB will (incorrectly) stop in foo_cold instead of in baz.
329 gdb_test "continue" \
330 "Breakpoint \\d+, (?:$hex in )?baz \\(\\).*" \
331 "continue to baz"
332
333 with_test_prefix "no-cold-names" {
334
335 # Due to the calling sequence, this backtrace would normally
336 # show function foo_cold for frame #1. However, we don't want
337 # this to be the case due to placing it in the same block
338 # (albeit at a different range) as foo. Thus it is correct to
339 # see foo for frames #1 and #2. It is incorrect to see
340 # foo_cold at frame #1.
341 gdb_test_sequence "bt" "backtrace from baz" {
342 "\[\r\n\]#0 .*? baz \\(\\) "
343 "\[\r\n\]#1 .*? foo \\(\\) "
344 "\[\r\n\]#2 .*? foo \\(\\) "
345 "\[\r\n\]#3 .*? main \\(\\) "
346 }
347
348 # Doing x/2i foo_cold should show foo_cold as the first symbolic
349 # address and an offset from foo for the second. We also check to
350 # make sure that the offset is not too large - we don't GDB to
351 # display really large offsets that would (try to) wrap around the
352 # address space.
353 set foo_cold_offset 0
354 set test "x/2i foo_cold"
355 gdb_test_multiple $test $test {
356 -re " (?:$hex) <foo_cold>.*?\n (?:$hex) <foo\[+-\](\[0-9\]+)>.*${gdb_prompt}" {
357 set foo_cold_offset $expect_out(1,string)
358 pass $test
359 }
360 }
361 gdb_assert {$foo_cold_offset <= 10000} "offset to foo_cold is not too large"
362
363 # Likewise, verify that second address shown by "info line" is at
364 # and offset from foo instead of foo_cold.
365 gdb_test "info line *foo_cold" "starts at address $hex <foo_cold> and ends at $hex <foo\[+-\].*?>.*"
366
367 }
368
369 with_test_prefix "step-test-3" {
370 clean_restart ${testfile}
371 if ![runto_main] {
372 return -1
373 }
374
375 gdb_test "step" \
376 "foo \\(\\).*bar \\(\\);.*foo bar call.*" \
377 "step into foo from main"
378
379 gdb_test "step" \
380 "bar \\(\\).*\}.* bar end.*" \
381 "step into bar from foo"
382
383 gdb_test "step" \
384 "foo(_label2)? \\(\\).*foo_cold \\(\\);.*foo foo_cold call.*" \
385 "step out of bar to foo"
386
387 # Tests in the "enable_foo_cold_stepping" section, below, did
388 # not work prior to July, 2019. They had been disabled via
389 # use of the "enable_foo_cold_stepping" flag.
390 #
391 # As noted elsewhere, this test case causes foo_cold,
392 # originally a separate function invoked via a subroutine
393 # call, to be considered as part of foo via use of
394 # DW_AT_ranges. Real code that I've looked at uses a branch
395 # instruction to cause code in the "cold" range to be
396 # executed. These tests used to fail which is why they were
397 # disabled.
398 #
399 # After adding a "hi" cold test, I found that we were able to
400 # step into foo_cold from foo for the "hi" version, but for
401 # the "lo" version, GDB would run to either the next
402 # breakpoint or until the inferior exited when there were no
403 # breakpoints. Not being able to step is definitely a bug
404 # even if it's unlikely that this problem would ever be hit in
405 # a real program. Therefore, the bug was fixed in GDB and
406 # these tests are now enabled.
407 #
408 # I've left in place the flag (and test) which may be used to
409 # disable these tests.
410
411 set enable_foo_cold_stepping true
412
413 if { $enable_foo_cold_stepping } {
414 gdb_test_no_output "set variable e=1"
415
416 set test "step into foo_cold from foo"
417 gdb_test_multiple "step" $test {
418 -re "foo(_low)? \\(\\).*\{.*foo_cold prologue.*${gdb_prompt}" {
419 pass $test
420 gdb_test "step" \
421 "foo \\(\\).*baz \\(\\);.*foo_cold baz call.*" \
422 "step to baz call in foo_cold"
423
424 }
425 -re "foo(_cold)? \\(\\).*baz \\(\\);.*foo_cold baz call.*${gdb_prompt}" {
426 pass $test
427 }
428 }
429
430 gdb_test "step" \
431 "baz \\(\\).*\}.*baz end.*" \
432 "step into baz from foo_cold"
433
434 gdb_test "step" \
435 "foo(?:_low(?:_label2)?)? \\(\\).*\}.*foo_cold end.*" \
436 "step out of baz to foo_cold"
437
438 gdb_test "step" \
439 "foo(?:_label3)? \\(\\).*\}.*foo end.*" \
440 "step out of foo_cold to foo"
441 } else {
442 gdb_test "next" \
443 ".*foo end.*" \
444 "next over foo_cold call"
445 }
446
447 gdb_test "step" \
448 "main(?:_label2)? \\(\\).*" \
449 "step out of foo to main"
450 }
451 }
452
453 # foreach_with_prefix could be used here, but the log file output is somewhat
454 # less verbose when using an explicit "with_test_prefix".
455
456 foreach test_suffix { "lo-cold" "hi-cold" } {
457 with_test_prefix $test_suffix {
458 do_test $test_suffix
459 }
460 }