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