1# Copyright 2018-2020 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/>. 15load_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. 20if {![dwarf2_support]} { 21 unsupported "dwarf2 support required for this test" 22 return 0 23} 24 25if [get_compiler_info] { 26 return -1 27} 28if !$gcc_compiled { 29 unsupported "gcc required for this test" 30 return 0 31} 32 33proc 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. 50 51 if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { 52 return -1 53 } 54 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 } 126 } 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 {line [gdb_get_line_number "main prologue"]} 138 {DW_LNS_copy} 139 {DW_LNE_set_address main_label} 140 {line [gdb_get_line_number "main foo call"]} 141 {DW_LNS_copy} 142 {DW_LNE_set_address main_label2} 143 {line [gdb_get_line_number "main return"]} 144 {DW_LNS_copy} 145 {DW_LNE_set_address $main_end} 146 {line [expr [gdb_get_line_number "main end"] + 1]} 147 {DW_LNS_copy} 148 {DW_LNE_end_sequence} 149 150 {DW_LNE_set_address $foo_start} 151 {line [gdb_get_line_number "foo prologue"]} 152 {DW_LNS_copy} 153 {DW_LNE_set_address foo_label} 154 {line [gdb_get_line_number "foo bar call"]} 155 {DW_LNS_copy} 156 {DW_LNE_set_address foo_label2} 157 {line [gdb_get_line_number "foo foo_cold call"]} 158 {DW_LNS_copy} 159 {DW_LNE_set_address foo_label3} 160 {line [gdb_get_line_number "foo end"]} 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 {line [gdb_get_line_number "bar end"]} 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 {line [gdb_get_line_number "baz end"]} 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 {line [gdb_get_line_number "foo_cold prologue"]} 185 {DW_LNS_copy} 186 {DW_LNE_set_address foo_cold_label} 187 {line [gdb_get_line_number "foo_cold baz call"]} 188 {DW_LNS_copy} 189 {DW_LNE_set_address foo_cold_label2} 190 {line [gdb_get_line_number "foo_cold end"]} 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} 196 } 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} 204 } 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} 211 } 212 } 213 } 214 215 if { [prepare_for_testing "failed to prepare" ${testfile} \ 216 [list $srcfile $asm_file] {nodebug}] } { 217 return -1 218 } 219 220 if ![runto_main] { 221 return -1 222 } 223 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 .*" 228 229 with_test_prefix "step-test-1" { 230 set bp_foo_bar [gdb_get_line_number "foo bar call"] 231 232 gdb_test "break $bp_foo_bar" \ 233 "Breakpoint.*at.* file .*$srcfile, line $bp_foo_bar\\." \ 234 "break at call to bar" 235 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" 239 240 gdb_test "step" \ 241 "bar \\(\\).*bar end.*" \ 242 "step into bar" 243 244 gdb_test "step" \ 245 "foo \\(\\).*foo foo_cold call.*" \ 246 "step out of bar, back into foo" 247 } 248 249 with_test_prefix "step-test-2" { 250 clean_restart ${testfile} 251 if ![runto_main] { 252 return -1 253 } 254 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" \ 260 "Breakpoint.*at.* file .*$srcfile, line \\d+\\." 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 } 286 287 clean_restart ${testfile} 288 if ![runto_main] { 289 return -1 290 } 291 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) 307 pass $test 308 } 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) 316 pass $test 317 } 318 } 319 320 gdb_assert {$foo_cold_addr != $foo_addr} "foo and foo_cold are at different addresses" 321 322 # This more permissive RE for "break foo" will allow a breakpoint on 323 # multiple locations to PASS. */ 324 gdb_test "break foo" \ 325 "Breakpoint.*at.*" 326 327 gdb_test "break baz" \ 328 "Breakpoint.*at.* file .*$srcfile, line \\d+\\." 329 330 gdb_test "continue" \ 331 "Breakpoint \\d+, foo \\(\\).*" \ 332 "continue to foo" 333 334 gdb_test_no_output "set variable e=1" 335 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 } 356 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" 371 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\[+-\].*?>.*" 375 376 } 377 378 with_test_prefix "step-test-3" { 379 clean_restart ${testfile} 380 if ![runto_main] { 381 return -1 382 } 383 384 gdb_test "step" \ 385 "foo \\(\\).*bar \\(\\);.*foo bar call.*" \ 386 "step into foo from main" 387 388 gdb_test "step" \ 389 "bar \\(\\).*\}.* bar end.*" \ 390 "step into bar from foo" 391 392 gdb_test "step" \ 393 "foo(_label2)? \\(\\).*foo_cold \\(\\);.*foo foo_cold call.*" \ 394 "step out of bar to foo" 395 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. 407 # 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. 419 420 set enable_foo_cold_stepping true 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 } 434 -re "foo(_cold)? \\(\\).*baz \\(\\);.*foo_cold baz call.*${gdb_prompt}" { 435 pass $test 436 } 437 } 438 439 gdb_test "step" \ 440 "baz \\(\\).*\}.*baz end.*" \ 441 "step into baz from foo_cold" 442 443 gdb_test "step" \ 444 "foo(?:_low(?:_label2)?)? \\(\\).*\}.*foo_cold end.*" \ 445 "step out of baz to foo_cold" 446 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" 454 } 455 456 gdb_test "step" \ 457 "main(?:_label2)? \\(\\).*" \ 458 "step out of foo to main" 459 } 460} 461 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". 464 465foreach test_suffix { "lo-cold" "hi-cold" } { 466 with_test_prefix $test_suffix { 467 do_test $test_suffix 468 } 469} 470