1 # Copyright 2010-2016 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/>.
16 # This file is part of the gdb testsuite.
18 # Test arm displaced stepping.
20 if {![is_aarch32_target]} then {
21 verbose "Skipping arm displaced stepping tests."
27 set additional_flags "-Wa,-g"
29 if { [prepare_for_testing $testfile.exp $testfile $srcfile [list debug $additional_flags]] } {
34 #########################################
35 # Test ldm/stm related to PC.
36 proc test_ldm_stm_pc {} {
40 # Try to set breakpoint on test_ldm_stm_pc. If symbol 'test_ldm_stm_pc'
41 # can't be resolved, test case is compiled in Thumb mode, skip it.
42 gdb_test_multiple "break *test_ldm_stm_pc" "break test_ldm_stm_pc" {
43 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
44 pass "break test_ldm_stm_pc"
46 -re "No symbol.*\r\n$gdb_prompt $" {
47 pass "break test_ldm_stm_pc"
52 gdb_test "break *test_ldm_pc" \
53 "Breakpoint.*at.* file .*$srcfile, line.*" \
55 gdb_test "break *test_ldm_stm_pc_ret" \
56 "Breakpoint.*at.* file .*$srcfile, line.*" \
57 "break test_ldm_stm_pc_ret"
59 gdb_continue_to_breakpoint "continue to test_ldm_stm_pc" \
60 ".*stmdb.*sp\!\,.*\{lr\, pc\}.*"
61 gdb_continue_to_breakpoint "continue to test_ldm_pc" \
62 ".*ldmia.*sp\!\,.*\{pc\}.*"
63 gdb_continue_to_breakpoint "continue to test_ldm_stm_pc_ret" \
67 #########################################
69 proc test_ldr_literal {} {
73 gdb_test_multiple "break *test_ldr_literal" "break test_ldr_literal" {
74 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
75 pass "break test_ldr_literal"
77 -re "No symbol.*\r\n$gdb_prompt $" {
82 gdb_test "break *test_ldrsb_literal" \
83 "Breakpoint.*at.* file .*$srcfile, line.*" \
84 "break test_ldrsb_literal"
85 gdb_test "break *test_ldrsh_literal" \
86 "Breakpoint.*at.* file .*$srcfile, line.*" \
87 "break test_ldrsh_literal"
88 gdb_test "break *test_ldr_literal_end" \
89 "Breakpoint.*at.* file .*$srcfile, line.*" \
90 "break test_test_ldr_literal_end"
92 gdb_continue_to_breakpoint "continue to test_ldr_literal" \
93 ".*ldrh.*r0\,.*\[pc\].*"
94 gdb_continue_to_breakpoint "continue to test_ldrsb_literal" \
95 ".*ldrsb.*r0\,.*\[pc\].*"
96 gdb_continue_to_breakpoint "continue to test_ldrsh_literal" \
97 ".*ldrsh.*r0\,.*\[pc\].*"
98 gdb_continue_to_breakpoint "continue to test_ldr_literal_ret" \
102 proc test_ldr_literal_16 {} {
106 gdb_test_multiple "break *test_ldr_literal_16" "break test_ldr_literal_16" {
107 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
108 pass "break test_ldr_literal"
110 -re "No symbol.*\r\n$gdb_prompt $" {
114 gdb_test "break *test_ldr_literal_16_end" \
115 "Breakpoint.*at.* file .*$srcfile, line.*" \
116 "break test_ldr_literal_16_end"
118 gdb_continue_to_breakpoint "continue to test_ldr_literal_16" \
120 gdb_continue_to_breakpoint "continue to test_ldr_literal_16_end" \
124 ##########################################
126 proc test_call_ret {} {
130 gdb_test "break *test_call" \
131 "Breakpoint.*at.* file .*$srcfile, line.*" \
134 gdb_test "break *test_call_end" \
135 "Breakpoint.*at.* file .*$srcfile, line.*" \
136 "break test_call_end"
137 gdb_test "break *test_ret" \
138 "Breakpoint.*at.* file .*$srcfile, line.*" \
140 gdb_test "break *test_ret_end" \
141 "Breakpoint.*at.* file .*$srcfile, line.*" \
144 gdb_continue_to_breakpoint "test_call" ".*bl test_call_subr.*"
145 gdb_continue_to_breakpoint "test_call_end" \
146 ".*@ Location test_call_end.*"
147 gdb_continue_to_breakpoint "test_ret" \
149 gdb_continue_to_breakpoint "continue to test_ret_end" \
150 ".*@ Location test_ret_end.*"
154 #########################################
156 proc test_branch {} {
158 gdb_test "break *test_branch" \
159 "Breakpoint.*at.* file .*$srcfile, line.*" \
161 gdb_test "break *L_branch" \
162 "Breakpoint.*at.* file .*$srcfile, line.*" \
165 gdb_continue_to_breakpoint "continue to test_branch" \
167 gdb_continue_to_breakpoint "continue to Lbranch" \
171 #########################################
174 proc test_ldr_from_pc {} {
176 gdb_test "break *test_ldr_pc" \
177 "Breakpoint.*at.* file .*$srcfile, line.*" \
179 gdb_test "break test_ldr_pc_ret" \
180 "Breakpoint.*at.* file .*$srcfile, line.*" \
181 "break test_ldr_pc_ret"
183 gdb_continue_to_breakpoint "continue to test_ldr_pc" \
184 ".*ldr.*r1\,.*\[pc, #0\].*"
185 gdb_continue_to_breakpoint "continue to test_ldr_pc_ret" \
189 #########################################
192 proc test_cbz_cbnz {} {
196 gdb_test_multiple "break *test_zero_cbnz" "break test_zero_cbnz" {
197 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
198 pass "break test_ldr_literal"
200 -re "No symbol.*\r\n$gdb_prompt $" {
205 gdb_test "break *test_zero_cbz" \
206 "Breakpoint.*at.* file .*$srcfile, line.*" \
207 "break test_zero_cbz"
208 gdb_test "break *test_non_zero_cbnz" \
209 "Breakpoint.*at.* file .*$srcfile, line.*" \
210 "break test_non_zero_cbnz"
211 gdb_test "break *test_non_zero_cbz" \
212 "Breakpoint.*at.* file .*$srcfile, line.*" \
213 "break test_non_zero_cbz"
215 gdb_continue_to_breakpoint "continue to test_zero_cbnz" \
216 ".*cbnz.*r0\,.*\.L3.*"
217 gdb_continue_to_breakpoint "continue to test_zero_cbz" \
218 ".*cbz.*r0\,.*\.L3.*"
219 gdb_continue_to_breakpoint "continue to test_non_zero_cbz" \
220 ".*cbz.*r0\,.*\.L4.*"
221 gdb_continue_to_breakpoint "continue to test_non_zero_cbnz" \
222 ".*cbnz.*r0\,.*\.L4.*"
231 gdb_test_multiple "break *test_adr" "break test_adr" {
232 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
233 pass "break test_adr"
235 -re "No symbol.*\r\n$gdb_prompt $" {
240 gdb_test "break *test_adr_end" \
241 "Breakpoint.*at.* file .*$srcfile, line.*" \
244 gdb_continue_to_breakpoint "test_adr" \
245 ".*adr.*r0\,.*\.L8.*"
246 gdb_continue_to_breakpoint "test_adr_end" \
250 proc test_adr_32bit {} {
254 gdb_test_multiple "break *test_adr_32bit" "break test_adr_32bit" {
255 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
256 pass "break test_adr"
258 -re "No symbol.*\r\n$gdb_prompt $" {
263 gdb_test "break *test_adr_32bit_after" \
264 "Breakpoint.*at.* file .*$srcfile, line.*" \
265 "break test_adr_32bit_after"
267 gdb_test "break *test_adr_32bit_end" \
268 "Breakpoint.*at.* file .*$srcfile, line.*" \
269 "break test_adr_32bit_end"
271 gdb_continue_to_breakpoint "test_adr_32bit" \
272 ".*adr.*r0\,.*\.L6.*"
273 gdb_continue_to_breakpoint "test_adr_32bit_after" \
274 ".*adr.*r0\,.*\.L6.*"
275 gdb_continue_to_breakpoint "test_adr_32bit_end" \
279 #########################################
281 proc test_pop_pc {} {
283 gdb_test "break *test_pop_pc_1" \
284 "Breakpoint.*at.* file .*$srcfile, line.*" \
285 "break test_pop_pc_1"
286 gdb_test "break *test_pop_pc_2" \
287 "Breakpoint.*at.* file .*$srcfile, line.*" \
288 "break test_pop_pc_2"
289 gdb_test "break *test_pop_pc_3" \
290 "Breakpoint.*at.* file .*$srcfile, line.*" \
291 "break test_pop_pc_3"
293 gdb_test "break *test_pop_pc_ret" \
294 "Breakpoint.*at.* file .*$srcfile, line.*" \
295 "break test_pop_pc_ret"
297 gdb_test "break *test_pop_pc_1_right" \
298 "Breakpoint.*at.* file .*$srcfile, line.*" \
299 "break test_pop_pc_1_right"
300 gdb_test "break *test_pop_pc_1_wrong" \
301 "Breakpoint.*at.* file .*$srcfile, line.*" \
302 "break test_pop_pc_1_wrong"
303 gdb_test "break *test_pop_pc_2_right" \
304 "Breakpoint.*at.* file .*$srcfile, line.*" \
305 "break test_pop_pc_2_right"
306 gdb_test "break *test_pop_pc_2_wrong" \
307 "Breakpoint.*at.* file .*$srcfile, line.*" \
308 "break test_pop_pc_2_wrong"
309 gdb_test "break *test_pop_pc_3_right" \
310 "Breakpoint.*at.* file .*$srcfile, line.*" \
311 "break test_pop_pc_3_right"
312 gdb_test "break *test_pop_pc_3_wrong" \
313 "Breakpoint.*at.* file .*$srcfile, line.*" \
314 "break test_pop_pc_1_wrong"
316 gdb_continue_to_breakpoint "continue to test_pop_pc_1" \
318 gdb_continue_to_breakpoint "continue to test_pop_pc_1_check" \
321 gdb_continue_to_breakpoint "continue to test_pop_pc_2" \
323 gdb_continue_to_breakpoint "continue to test_pop_pc_2_check" \
325 gdb_continue_to_breakpoint "continue to test_pop_pc_3" \
326 ".*\{r0\,r1\,r2\,r3\,r4\,r5\,r6\,r7\,pc\}.*"
327 gdb_continue_to_breakpoint "continue to test_pop_pc_3_check" \
329 gdb_continue_to_breakpoint "continue to test_pop_pc_ret" \
333 ###########################################
335 proc test_str_pc {} {
339 gdb_test_multiple "break *test_str_pc" "break test_str_pc" {
340 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
341 pass "break test_str_pc"
343 -re "No symbol.*\r\n$gdb_prompt $" {
344 pass "break test_str_pc"
348 gdb_test "break *test_str_pc_end" \
349 "Breakpoint.*at.* file .*$srcfile, line.*" \
350 "break test_str_pc_end"
352 # Set breakpoint on both lables pc_offset_right and pc_offset_wrong
353 gdb_test "break *pc_offset_right" \
354 "Breakpoint.*at.* file .*$srcfile, line.*" \
355 "break pc_offset_right"
356 gdb_test "break *pc_offset_wrong" \
357 "Breakpoint.*at.* file .*$srcfile, line.*" \
358 "break pc_offset_wrong"
360 gdb_continue_to_breakpoint "continue to test_str_pc" \
361 ".*str.*pc\,.*\[sp, #-4\].*"
362 # If breakpoint on lable pc_offset_wrong is hit, that means the offset
363 # computed in displaced stepping is different from offset computed
364 # without displaced stepping. Report a failure.
365 gdb_continue_to_breakpoint "continue to pc_offset_right" \
366 ".*b.*test_str_pc_end.*"
367 gdb_continue_to_breakpoint "continue to test_str_pc_end" \
371 # Test 16 bit thumb instruction 'add rd, pc'.
373 proc test_add_rn_pc {} {
374 global srcfile gdb_prompt
376 set test "break test_add_rn_pc"
377 gdb_test_multiple "break *test_add_rn_pc" $test {
378 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
381 -re "No symbol.*\r\n$gdb_prompt $" {
386 gdb_continue_to_breakpoint "continue to test_add_rn_pc" \
389 gdb_test "break *test_add_rn_pc_start" \
390 "Breakpoint.*at.* file .*$srcfile, line.*" \
391 "break test_add_rn_pc_start"
393 gdb_continue_to_breakpoint "continue to test_add_rn_pc_start" \
396 set pc_val [get_integer_valueof "\$pc" 0]
398 gdb_test "break *test_add_rn_pc_end" \
399 "Breakpoint.*at.* file .*$srcfile, line.*" \
400 "break test_add_rn_pc_end"
402 gdb_continue_to_breakpoint "continue to test_add_rn_pc_end" \
405 set r3_val [get_integer_valueof "\$r3" 0]
406 # Test the value in r3 is correct.
407 gdb_assert { [expr {$pc_val + 4 + 4} == $r3_val] }
410 # Turn displaced stepping off before runto main. When displaced stepping
411 # is on, and we type 'run', GDB will first try to single step on _dl_debug_state,
412 # which is in library might be compiled in Thumb.
413 gdb_test_no_output "set displaced-stepping off"
415 if ![runto_main] then {
416 fail "can't run to main"
420 gdb_test_no_output "set displaced-stepping on"
421 gdb_test "show displaced-stepping" ".* displaced stepping .* is on.*"
447 ##########################################
449 # Done, run program to exit.
451 gdb_continue_to_end "arm-disp-step"