1# Copyright 2010-2015 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# This file is part of the gdb testsuite. 17 18# Test arm displaced stepping. 19 20if {![istarget "arm*-*-*"]} then { 21 verbose "Skipping arm displaced stepping tests." 22 return 23} 24 25set testfile "arm-disp-step" 26set srcfile ${testfile}.S 27set binfile ${objdir}/${subdir}/${testfile} 28 29set additional_flags "-Wa,-g" 30 31if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug $additional_flags]] != "" } { 32 untested arm-disp-step.exp 33 return -1 34} 35 36 37######################################### 38# Test ldm/stm related to PC. 39proc test_ldm_stm_pc {} { 40 global srcfile 41 global gdb_prompt 42 43 # Try to set breakpoint on test_ldm_stm_pc. If symbol 'test_ldm_stm_pc' 44 # can't be resolved, test case is compiled in Thumb mode, skip it. 45 gdb_test_multiple "break *test_ldm_stm_pc" "break test_ldm_stm_pc" { 46 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" { 47 pass "break test_ldm_stm_pc" 48 } 49 -re "No symbol.*\r\n$gdb_prompt $" { 50 pass "break test_ldm_stm_pc" 51 return 0 52 } 53 } 54 55 gdb_test "break *test_ldm_pc" \ 56 "Breakpoint.*at.* file .*$srcfile, line.*" \ 57 "break test_ldm_pc" 58 gdb_test "break *test_ldm_stm_pc_ret" \ 59 "Breakpoint.*at.* file .*$srcfile, line.*" \ 60 "break test_ldm_stm_pc_ret" 61 62 gdb_continue_to_breakpoint "continue to test_ldm_stm_pc" \ 63 ".*stmdb.*sp\!\,.*\{lr\, pc\}.*" 64 gdb_continue_to_breakpoint "continue to test_ldm_pc" \ 65 ".*ldmia.*sp\!\,.*\{pc\}.*" 66 gdb_continue_to_breakpoint "continue to test_ldm_stm_pc_ret" \ 67 ".*bx lr.*" 68} 69 70######################################### 71# Test ldrX literal 72proc test_ldr_literal {} { 73 global srcfile 74 global gdb_prompt 75 76 gdb_test_multiple "break *test_ldr_literal" "break test_ldr_literal" { 77 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" { 78 pass "break test_ldr_literal" 79 } 80 -re "No symbol.*\r\n$gdb_prompt $" { 81 return 0 82 } 83 } 84 85 gdb_test "break *test_ldrsb_literal" \ 86 "Breakpoint.*at.* file .*$srcfile, line.*" \ 87 "break test_ldrsb_literal" 88 gdb_test "break *test_ldrsh_literal" \ 89 "Breakpoint.*at.* file .*$srcfile, line.*" \ 90 "break test_ldrsh_literal" 91 gdb_test "break *test_ldr_literal_end" \ 92 "Breakpoint.*at.* file .*$srcfile, line.*" \ 93 "break test_test_ldr_literal_end" 94 95 gdb_continue_to_breakpoint "continue to test_ldr_literal" \ 96 ".*ldrh.*r0\,.*\[pc\].*" 97 gdb_continue_to_breakpoint "continue to test_ldrsb_literal" \ 98 ".*ldrsb.*r0\,.*\[pc\].*" 99 gdb_continue_to_breakpoint "continue to test_ldrsh_literal" \ 100 ".*ldrsh.*r0\,.*\[pc\].*" 101 gdb_continue_to_breakpoint "continue to test_ldr_literal_ret" \ 102 ".*bx lr.*" 103} 104 105proc test_ldr_literal_16 {} { 106 global srcfile 107 global gdb_prompt 108 109 gdb_test_multiple "break *test_ldr_literal_16" "break test_ldr_literal_16" { 110 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" { 111 pass "break test_ldr_literal" 112 } 113 -re "No symbol.*\r\n$gdb_prompt $" { 114 return 0 115 } 116 } 117 gdb_test "break *test_ldr_literal_16_end" \ 118 "Breakpoint.*at.* file .*$srcfile, line.*" \ 119 "break test_ldr_literal_16_end" 120 121 gdb_continue_to_breakpoint "continue to test_ldr_literal_16" \ 122 ".*ldr.*r0\,.*L2.*" 123 gdb_continue_to_breakpoint "continue to test_ldr_literal_16_end" \ 124 ".*bx lr.*" 125} 126 127########################################## 128# Test call/ret. 129proc test_call_ret {} { 130 global srcfile 131 global testfile 132 133 gdb_test "break *test_call" \ 134 "Breakpoint.*at.* file .*$srcfile, line.*" \ 135 "break test_call" 136 137 gdb_test "break *test_call_end" \ 138 "Breakpoint.*at.* file .*$srcfile, line.*" \ 139 "break test_call_end" 140 gdb_test "break *test_ret" \ 141 "Breakpoint.*at.* file .*$srcfile, line.*" \ 142 "break test_ret" 143 gdb_test "break *test_ret_end" \ 144 "Breakpoint.*at.* file .*$srcfile, line.*" \ 145 "break test_ret_end" 146 147 gdb_continue_to_breakpoint "test_call" ".*bl test_call_subr.*" 148 gdb_continue_to_breakpoint "test_call_end" \ 149 ".*@ Location test_call_end.*" 150 gdb_continue_to_breakpoint "test_ret" \ 151 ".*bx lr.*" 152 gdb_continue_to_breakpoint "continue to test_ret_end" \ 153 ".*@ Location test_ret_end.*" 154} 155 156 157######################################### 158# Test branch 159proc test_branch {} { 160 global srcfile 161 gdb_test "break *test_branch" \ 162 "Breakpoint.*at.* file .*$srcfile, line.*" \ 163 "break test_branch" 164 gdb_test "break *L_branch" \ 165 "Breakpoint.*at.* file .*$srcfile, line.*" \ 166 "break Lbranch" 167 168 gdb_continue_to_breakpoint "continue to test_branch" \ 169 ".*b.*L_branch.*" 170 gdb_continue_to_breakpoint "continue to Lbranch" \ 171 ".*bx lr.*" 172} 173 174######################################### 175 176# Test ldr from pc 177proc test_ldr_from_pc {} { 178 global srcfile 179 gdb_test "break *test_ldr_pc" \ 180 "Breakpoint.*at.* file .*$srcfile, line.*" \ 181 "break test_ldr_pc" 182 gdb_test "break test_ldr_pc_ret" \ 183 "Breakpoint.*at.* file .*$srcfile, line.*" \ 184 "break test_ldr_pc_ret" 185 186 gdb_continue_to_breakpoint "continue to test_ldr_pc" \ 187 ".*ldr.*r1\,.*\[pc, #0\].*" 188 gdb_continue_to_breakpoint "continue to test_ldr_pc_ret" \ 189 ".*bx lr.*" 190} 191 192######################################### 193 194# Test cbz and cbnz 195proc test_cbz_cbnz {} { 196 global srcfile 197 global gdb_prompt 198 199 gdb_test_multiple "break *test_zero_cbnz" "break test_zero_cbnz" { 200 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" { 201 pass "break test_ldr_literal" 202 } 203 -re "No symbol.*\r\n$gdb_prompt $" { 204 return 0 205 } 206 } 207 208 gdb_test "break *test_zero_cbz" \ 209 "Breakpoint.*at.* file .*$srcfile, line.*" \ 210 "break test_zero_cbz" 211 gdb_test "break *test_non_zero_cbnz" \ 212 "Breakpoint.*at.* file .*$srcfile, line.*" \ 213 "break test_non_zero_cbnz" 214 gdb_test "break *test_non_zero_cbz" \ 215 "Breakpoint.*at.* file .*$srcfile, line.*" \ 216 "break test_non_zero_cbz" 217 218 gdb_continue_to_breakpoint "continue to test_zero_cbnz" \ 219 ".*cbnz.*r0\,.*\.L3.*" 220 gdb_continue_to_breakpoint "continue to test_zero_cbz" \ 221 ".*cbz.*r0\,.*\.L3.*" 222 gdb_continue_to_breakpoint "continue to test_non_zero_cbz" \ 223 ".*cbz.*r0\,.*\.L4.*" 224 gdb_continue_to_breakpoint "continue to test_non_zero_cbnz" \ 225 ".*cbnz.*r0\,.*\.L4.*" 226} 227 228# Test adr 229 230proc test_adr {} { 231 global srcfile 232 global gdb_prompt 233 234 gdb_test_multiple "break *test_adr" "break test_adr" { 235 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" { 236 pass "break test_adr" 237 } 238 -re "No symbol.*\r\n$gdb_prompt $" { 239 return 0 240 } 241 } 242 243 gdb_test "break *test_adr_end" \ 244 "Breakpoint.*at.* file .*$srcfile, line.*" \ 245 "break test_adr_end" 246 247 gdb_continue_to_breakpoint "test_adr" \ 248 ".*adr.*r0\,.*\.L8.*" 249 gdb_continue_to_breakpoint "test_adr_end" \ 250 ".*bx lr.*" 251} 252 253proc test_adr_32bit {} { 254 global srcfile 255 global gdb_prompt 256 257 gdb_test_multiple "break *test_adr_32bit" "break test_adr_32bit" { 258 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" { 259 pass "break test_adr" 260 } 261 -re "No symbol.*\r\n$gdb_prompt $" { 262 return 0 263 } 264 } 265 266 gdb_test "break *test_adr_32bit_after" \ 267 "Breakpoint.*at.* file .*$srcfile, line.*" \ 268 "break test_adr_32bit_after" 269 270 gdb_test "break *test_adr_32bit_end" \ 271 "Breakpoint.*at.* file .*$srcfile, line.*" \ 272 "break test_adr_32bit_end" 273 274 gdb_continue_to_breakpoint "test_adr_32bit" \ 275 ".*adr.*r0\,.*\.L6.*" 276 gdb_continue_to_breakpoint "test_adr_32bit_after" \ 277 ".*adr.*r0\,.*\.L6.*" 278 gdb_continue_to_breakpoint "test_adr_32bit_end" \ 279 ".*bx lr.*" 280} 281 282######################################### 283# Test pop to PC 284proc test_pop_pc {} { 285 global srcfile 286 gdb_test "break *test_pop_pc_1" \ 287 "Breakpoint.*at.* file .*$srcfile, line.*" \ 288 "break test_pop_pc_1" 289 gdb_test "break *test_pop_pc_2" \ 290 "Breakpoint.*at.* file .*$srcfile, line.*" \ 291 "break test_pop_pc_2" 292 gdb_test "break *test_pop_pc_3" \ 293 "Breakpoint.*at.* file .*$srcfile, line.*" \ 294 "break test_pop_pc_3" 295 296 gdb_test "break *test_pop_pc_ret" \ 297 "Breakpoint.*at.* file .*$srcfile, line.*" \ 298 "break test_pop_pc_ret" 299 300 gdb_test "break *test_pop_pc_1_right" \ 301 "Breakpoint.*at.* file .*$srcfile, line.*" \ 302 "break test_pop_pc_1_right" 303 gdb_test "break *test_pop_pc_1_wrong" \ 304 "Breakpoint.*at.* file .*$srcfile, line.*" \ 305 "break test_pop_pc_1_wrong" 306 gdb_test "break *test_pop_pc_2_right" \ 307 "Breakpoint.*at.* file .*$srcfile, line.*" \ 308 "break test_pop_pc_2_right" 309 gdb_test "break *test_pop_pc_2_wrong" \ 310 "Breakpoint.*at.* file .*$srcfile, line.*" \ 311 "break test_pop_pc_2_wrong" 312 gdb_test "break *test_pop_pc_3_right" \ 313 "Breakpoint.*at.* file .*$srcfile, line.*" \ 314 "break test_pop_pc_3_right" 315 gdb_test "break *test_pop_pc_3_wrong" \ 316 "Breakpoint.*at.* file .*$srcfile, line.*" \ 317 "break test_pop_pc_1_wrong" 318 319 gdb_continue_to_breakpoint "continue to test_pop_pc_1" \ 320 ".*b.*\{r1\, pc\}.*" 321 gdb_continue_to_breakpoint "continue to test_pop_pc_1_check" \ 322 ".*b.*right.*" 323 324 gdb_continue_to_breakpoint "continue to test_pop_pc_2" \ 325 ".*\{pc\}.*" 326 gdb_continue_to_breakpoint "continue to test_pop_pc_2_check" \ 327 ".*b.*right.*" 328 gdb_continue_to_breakpoint "continue to test_pop_pc_3" \ 329 ".*\{r0\,r1\,r2\,r3\,r4\,r5\,r6\,r7\,pc\}.*" 330 gdb_continue_to_breakpoint "continue to test_pop_pc_3_check" \ 331 ".*b.*right.*" 332 gdb_continue_to_breakpoint "continue to test_pop_pc_ret" \ 333 ".*r7.*" 334} 335 336########################################### 337 338proc test_str_pc {} { 339 global srcfile 340 global gdb_prompt 341 342 gdb_test_multiple "break *test_str_pc" "break test_str_pc" { 343 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" { 344 pass "break test_str_pc" 345 } 346 -re "No symbol.*\r\n$gdb_prompt $" { 347 pass "break test_str_pc" 348 return 349 } 350 } 351 gdb_test "break *test_str_pc_end" \ 352 "Breakpoint.*at.* file .*$srcfile, line.*" \ 353 "break test_str_pc_end" 354 355 # Set breakpoint on both lables pc_offset_right and pc_offset_wrong 356 gdb_test "break *pc_offset_right" \ 357 "Breakpoint.*at.* file .*$srcfile, line.*" \ 358 "break pc_offset_right" 359 gdb_test "break *pc_offset_wrong" \ 360 "Breakpoint.*at.* file .*$srcfile, line.*" \ 361 "break pc_offset_wrong" 362 363 gdb_continue_to_breakpoint "continue to test_str_pc" \ 364 ".*str.*pc\,.*\[sp, #-4\].*" 365 # If breakpoint on lable pc_offset_wrong is hit, that means the offset 366 # computed in displaced stepping is different from offset computed 367 # without displaced stepping. Report a failure. 368 gdb_continue_to_breakpoint "continue to pc_offset_right" \ 369 ".*b.*test_str_pc_end.*" 370 gdb_continue_to_breakpoint "continue to test_str_pc_end" \ 371 ".*bx lr.*" 372} 373 374# Test 16 bit thumb instruction 'add rd, pc'. 375 376proc test_add_rn_pc {} { 377 global srcfile gdb_prompt 378 379 set test "break test_add_rn_pc" 380 gdb_test_multiple "break *test_add_rn_pc" $test { 381 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" { 382 pass $test 383 } 384 -re "No symbol.*\r\n$gdb_prompt $" { 385 return 386 } 387 } 388 389 gdb_continue_to_breakpoint "continue to test_add_rn_pc" \ 390 ".*mov.*r3, 4.*" 391 392 gdb_test "break *test_add_rn_pc_start" \ 393 "Breakpoint.*at.* file .*$srcfile, line.*" \ 394 "break test_add_rn_pc_start" 395 396 gdb_continue_to_breakpoint "continue to test_add_rn_pc_start" \ 397 ".*add.*r3,.*pc.*" 398 399 set pc_val [get_integer_valueof "\$pc" 0] 400 401 gdb_test "break *test_add_rn_pc_end" \ 402 "Breakpoint.*at.* file .*$srcfile, line.*" \ 403 "break test_add_rn_pc_end" 404 405 gdb_continue_to_breakpoint "continue to test_add_rn_pc_end" \ 406 ".*bx lr.*" 407 408 set r3_val [get_integer_valueof "\$r3" 0] 409 # Test the value in r3 is correct. 410 gdb_assert { [expr {$pc_val + 4 + 4} == $r3_val] } 411} 412 413# Get things started. 414 415clean_restart ${testfile} 416 417# Turn displaced stepping off before runto main. When displaced stepping 418# is on, and we type 'run', GDB will first try to single step on _dl_debug_state, 419# which is in library might be compiled in Thumb. 420gdb_test_no_output "set displaced-stepping off" 421 422if ![runto_main] then { 423 fail "Can't run to main" 424 return 0 425} 426 427gdb_test_no_output "set displaced-stepping on" 428gdb_test "show displaced-stepping" ".* displaced stepping .* is on.*" 429 430test_call_ret 431 432test_branch 433 434test_ldr_from_pc 435 436test_ldm_stm_pc 437 438test_ldr_literal 439 440test_ldr_literal_16 441 442test_cbz_cbnz 443 444test_adr 445 446test_adr_32bit 447 448test_pop_pc 449 450test_str_pc 451 452test_add_rn_pc 453 454########################################## 455 456# Done, run program to exit. 457 458gdb_continue_to_end "arm-disp-step" 459