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