1 # Copyright 2010-2024 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 require is_aarch32_target
24 if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
29 #########################################
30 # Test ldm/stm related to PC.
31 proc test_ldm_stm_pc {} {
35 # Try to set breakpoint on test_ldm_stm_pc. If symbol 'test_ldm_stm_pc'
36 # can't be resolved, test case is compiled in Thumb mode, skip it.
37 gdb_test_multiple "break *test_ldm_stm_pc" "" {
38 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
41 -re "No symbol.*\r\n$gdb_prompt $" {
47 gdb_test "break *test_ldm_pc" \
48 "Breakpoint.*at.* file .*$srcfile, line.*" \
50 gdb_test "break *test_ldm_stm_pc_ret" \
51 "Breakpoint.*at.* file .*$srcfile, line.*" \
52 "break test_ldm_stm_pc_ret"
54 gdb_continue_to_breakpoint "continue to test_ldm_stm_pc" \
55 ".*stmdb.*sp\!\,.*\{lr\, pc\}.*"
56 gdb_continue_to_breakpoint "continue to test_ldm_pc" \
57 ".*ldmia.*sp\!\,.*\{pc\}.*"
58 gdb_continue_to_breakpoint "continue to test_ldm_stm_pc_ret" \
62 #########################################
64 proc test_ldr_literal {} {
68 gdb_test_multiple "break *test_ldr_literal" "" {
69 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
72 -re "No symbol.*\r\n$gdb_prompt $" {
77 gdb_test "break *test_ldrsb_literal" \
78 "Breakpoint.*at.* file .*$srcfile, line.*" \
79 "break test_ldrsb_literal"
80 gdb_test "break *test_ldrsh_literal" \
81 "Breakpoint.*at.* file .*$srcfile, line.*" \
82 "break test_ldrsh_literal"
83 gdb_test "break *test_ldr_literal_end" \
84 "Breakpoint.*at.* file .*$srcfile, line.*" \
85 "break test_test_ldr_literal_end"
87 gdb_continue_to_breakpoint "continue to test_ldr_literal" \
88 ".*ldrh.*r0\,.*\[pc\].*"
89 gdb_continue_to_breakpoint "continue to test_ldrsb_literal" \
90 ".*ldrsb.*r0\,.*\[pc\].*"
91 gdb_continue_to_breakpoint "continue to test_ldrsh_literal" \
92 ".*ldrsh.*r0\,.*\[pc\].*"
93 gdb_continue_to_breakpoint "continue to test_ldr_literal_ret" \
97 proc test_ldr_literal_16 {} {
101 gdb_test_multiple "break *test_ldr_literal_16" "" {
102 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
105 -re "No symbol.*\r\n$gdb_prompt $" {
109 gdb_test "break *test_ldr_literal_16_end" \
110 "Breakpoint.*at.* file .*$srcfile, line.*" \
111 "break test_ldr_literal_16_end"
113 gdb_continue_to_breakpoint "continue to test_ldr_literal_16" \
115 gdb_continue_to_breakpoint "continue to test_ldr_literal_16_end" \
119 ##########################################
121 proc test_call_ret {} {
125 gdb_test "break *test_call" \
126 "Breakpoint.*at.* file .*$srcfile, line.*" \
129 gdb_test "break *test_call_end" \
130 "Breakpoint.*at.* file .*$srcfile, line.*" \
131 "break test_call_end"
132 gdb_test "break *test_ret" \
133 "Breakpoint.*at.* file .*$srcfile, line.*" \
135 gdb_test "break *test_ret_end" \
136 "Breakpoint.*at.* file .*$srcfile, line.*" \
139 gdb_continue_to_breakpoint "test_call" ".*bl test_call_subr.*"
140 gdb_continue_to_breakpoint "test_call_end" \
141 ".*@ Location test_call_end.*"
142 gdb_continue_to_breakpoint "test_ret" \
144 gdb_continue_to_breakpoint "continue to test_ret_end" \
145 ".*@ Location test_ret_end.*"
149 #########################################
151 proc test_branch {} {
153 gdb_test "break *test_branch" \
154 "Breakpoint.*at.* file .*$srcfile, line.*" \
156 gdb_test "break *L_branch" \
157 "Breakpoint.*at.* file .*$srcfile, line.*" \
160 gdb_continue_to_breakpoint "continue to test_branch" \
162 gdb_continue_to_breakpoint "continue to Lbranch" \
166 #########################################
169 proc test_ldr_from_pc {} {
171 gdb_test "break *test_ldr_pc" \
172 "Breakpoint.*at.* file .*$srcfile, line.*" \
174 gdb_test "break test_ldr_pc_ret" \
175 "Breakpoint.*at.* file .*$srcfile, line.*" \
176 "break test_ldr_pc_ret"
178 gdb_continue_to_breakpoint "continue to test_ldr_pc" \
179 ".*ldr.*r1\,.*\[pc, #0\].*"
180 gdb_continue_to_breakpoint "continue to test_ldr_pc_ret" \
184 #########################################
187 proc test_cbz_cbnz {} {
191 gdb_test_multiple "break *test_zero_cbnz" "" {
192 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
195 -re "No symbol.*\r\n$gdb_prompt $" {
200 gdb_test "break *test_zero_cbz" \
201 "Breakpoint.*at.* file .*$srcfile, line.*" \
202 "break test_zero_cbz"
203 gdb_test "break *test_non_zero_cbnz" \
204 "Breakpoint.*at.* file .*$srcfile, line.*" \
205 "break test_non_zero_cbnz"
206 gdb_test "break *test_non_zero_cbz" \
207 "Breakpoint.*at.* file .*$srcfile, line.*" \
208 "break test_non_zero_cbz"
210 gdb_continue_to_breakpoint "continue to test_zero_cbnz" \
211 ".*cbnz.*r0\,.*\.L3.*"
212 gdb_continue_to_breakpoint "continue to test_zero_cbz" \
213 ".*cbz.*r0\,.*\.L3.*"
214 gdb_continue_to_breakpoint "continue to test_non_zero_cbz" \
215 ".*cbz.*r0\,.*\.L4.*"
216 gdb_continue_to_breakpoint "continue to test_non_zero_cbnz" \
217 ".*cbnz.*r0\,.*\.L4.*"
226 gdb_test_multiple "break *test_adr" "" {
227 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
230 -re "No symbol.*\r\n$gdb_prompt $" {
235 gdb_test "break *test_adr_end" \
236 "Breakpoint.*at.* file .*$srcfile, line.*" \
239 gdb_continue_to_breakpoint "test_adr" \
240 ".*adr.*r0\,.*\.L8.*"
241 gdb_continue_to_breakpoint "test_adr_end" \
245 proc test_adr_32bit {} {
249 gdb_test_multiple "break *test_adr_32bit" "" {
250 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
253 -re "No symbol.*\r\n$gdb_prompt $" {
258 gdb_test "break *test_adr_32bit_after" \
259 "Breakpoint.*at.* file .*$srcfile, line.*" \
260 "break test_adr_32bit_after"
262 gdb_test "break *test_adr_32bit_end" \
263 "Breakpoint.*at.* file .*$srcfile, line.*" \
264 "break test_adr_32bit_end"
266 gdb_continue_to_breakpoint "test_adr_32bit" \
267 ".*adr.*r0\,.*\.L6.*"
268 gdb_continue_to_breakpoint "test_adr_32bit_after" \
269 ".*adr.*r0\,.*\.L6.*"
270 gdb_continue_to_breakpoint "test_adr_32bit_end" \
274 #########################################
276 proc test_pop_pc {} {
278 gdb_test "break *test_pop_pc_1" \
279 "Breakpoint.*at.* file .*$srcfile, line.*" \
280 "break test_pop_pc_1"
281 gdb_test "break *test_pop_pc_2" \
282 "Breakpoint.*at.* file .*$srcfile, line.*" \
283 "break test_pop_pc_2"
284 gdb_test "break *test_pop_pc_3" \
285 "Breakpoint.*at.* file .*$srcfile, line.*" \
286 "break test_pop_pc_3"
288 gdb_test "break *test_pop_pc_ret" \
289 "Breakpoint.*at.* file .*$srcfile, line.*" \
290 "break test_pop_pc_ret"
292 gdb_test "break *test_pop_pc_1_right" \
293 "Breakpoint.*at.* file .*$srcfile, line.*" \
294 "break test_pop_pc_1_right"
295 gdb_test "break *test_pop_pc_1_wrong" \
296 "Breakpoint.*at.* file .*$srcfile, line.*" \
297 "break test_pop_pc_1_wrong"
298 gdb_test "break *test_pop_pc_2_right" \
299 "Breakpoint.*at.* file .*$srcfile, line.*" \
300 "break test_pop_pc_2_right"
301 gdb_test "break *test_pop_pc_2_wrong" \
302 "Breakpoint.*at.* file .*$srcfile, line.*" \
303 "break test_pop_pc_2_wrong"
304 gdb_test "break *test_pop_pc_3_right" \
305 "Breakpoint.*at.* file .*$srcfile, line.*" \
306 "break test_pop_pc_3_right"
307 gdb_test "break *test_pop_pc_3_wrong" \
308 "Breakpoint.*at.* file .*$srcfile, line.*" \
309 "break test_pop_pc_3_wrong"
311 gdb_continue_to_breakpoint "continue to test_pop_pc_1" \
313 gdb_continue_to_breakpoint "continue to test_pop_pc_1_check" \
316 gdb_continue_to_breakpoint "continue to test_pop_pc_2" \
318 gdb_continue_to_breakpoint "continue to test_pop_pc_2_check" \
320 gdb_continue_to_breakpoint "continue to test_pop_pc_3" \
321 ".*\{r0\,r1\,r2\,r3\,r4\,r5\,r6\,r7\,pc\}.*"
322 gdb_continue_to_breakpoint "continue to test_pop_pc_3_check" \
324 gdb_continue_to_breakpoint "continue to test_pop_pc_ret" \
328 ###########################################
330 proc test_str_pc {} {
334 gdb_test_multiple "break *test_str_pc" "" {
335 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
338 -re "No symbol.*\r\n$gdb_prompt $" {
343 gdb_test "break *test_str_pc_end" \
344 "Breakpoint.*at.* file .*$srcfile, line.*" \
345 "break test_str_pc_end"
347 # Set breakpoint on both lables pc_offset_right and pc_offset_wrong
348 gdb_test "break *pc_offset_right" \
349 "Breakpoint.*at.* file .*$srcfile, line.*" \
350 "break pc_offset_right"
351 gdb_test "break *pc_offset_wrong" \
352 "Breakpoint.*at.* file .*$srcfile, line.*" \
353 "break pc_offset_wrong"
355 gdb_continue_to_breakpoint "continue to test_str_pc" \
356 ".*str.*pc\,.*\[sp, #-4\].*"
357 # If breakpoint on lable pc_offset_wrong is hit, that means the offset
358 # computed in displaced stepping is different from offset computed
359 # without displaced stepping. Report a failure.
360 gdb_continue_to_breakpoint "continue to pc_offset_right" \
361 ".*b.*test_str_pc_end.*"
362 gdb_continue_to_breakpoint "continue to test_str_pc_end" \
366 # Test 16 bit thumb instruction 'add rd, pc'.
368 proc test_add_rn_pc {} {
369 global srcfile gdb_prompt
371 gdb_test_multiple "break *test_add_rn_pc" "" {
372 -re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
375 -re "No symbol.*\r\n$gdb_prompt $" {
380 gdb_continue_to_breakpoint "continue to test_add_rn_pc" \
383 gdb_test "break *test_add_rn_pc_start" \
384 "Breakpoint.*at.* file .*$srcfile, line.*" \
385 "break test_add_rn_pc_start"
387 gdb_continue_to_breakpoint "continue to test_add_rn_pc_start" \
390 set pc_val [get_integer_valueof "\$pc" 0]
392 gdb_test "break *test_add_rn_pc_end" \
393 "Breakpoint.*at.* file .*$srcfile, line.*" \
394 "break test_add_rn_pc_end"
396 gdb_continue_to_breakpoint "continue to test_add_rn_pc_end" \
399 set r3_val [get_integer_valueof "\$r3" 0]
400 # Test the value in r3 is correct.
401 gdb_assert { [expr {$pc_val + 4 + 4} == $r3_val] }
404 # Turn displaced stepping off before runto main. When displaced stepping
405 # is on, and we type 'run', GDB will first try to single step on _dl_debug_state,
406 # which is in library might be compiled in Thumb.
407 gdb_test_no_output "set displaced-stepping off"
413 gdb_test_no_output "set displaced-stepping on"
414 gdb_test "show displaced-stepping" ".* displaced stepping .* is on.*"
440 ##########################################
442 # Done, run program to exit.
444 gdb_continue_to_end "arm-disp-step"