| # Copyright 2010, 2011 Free Software Foundation, Inc. |
| |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 3 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| |
| # This file is part of the gdb testsuite. |
| |
| # Test arm displaced stepping. |
| |
| if $tracelevel { |
| strace $tracelevel |
| } |
| |
| if {![istarget "arm*-*-*"]} then { |
| verbose "Skipping arm displaced stepping tests." |
| return |
| } |
| |
| set testfile "arm-disp-step" |
| set srcfile ${testfile}.S |
| set binfile ${objdir}/${subdir}/${testfile} |
| |
| set additional_flags "-Wa,-g" |
| |
| if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug $additional_flags]] != "" } { |
| untested arm-disp-step.exp |
| return -1 |
| } |
| |
| |
| ######################################### |
| # Test ldm/stm related to PC. |
| proc test_ldm_stm_pc {} { |
| global srcfile |
| # Try to set breakpoint on test_ldm_stm_pc. If symbol 'test_ldm_stm_pc' |
| # can't be resolved, test case is compiled in Thumb mode, skip it. |
| gdb_test_multiple "break *test_ldm_stm_pc" "break test_ldm_stm_pc" { |
| -re "Breakpoint.*at.* file .*$srcfile, line.*" { |
| pass "break test_ldm_stm_pc" |
| } |
| -re "Function \"test_ldm_stm_pc\" not defined\..*Make breakpoint pending on future shared library load.*y or .n.. $" { |
| gdb_test "n" "" "Test case is compiled in Thumb mode" |
| return |
| } |
| } |
| |
| gdb_test "break *test_ldm_pc" \ |
| "Breakpoint.*at.* file .*$srcfile, line.*" \ |
| "break test_ldm_pc" |
| gdb_test "break *test_ldm_stm_pc_ret" \ |
| "Breakpoint.*at.* file .*$srcfile, line.*" \ |
| "break test_ldm_stm_pc_ret" |
| |
| gdb_continue_to_breakpoint "continue to test_ldm_stm_pc" \ |
| ".*stmdb.*sp\!\,.*\{lr\, pc\}.*" |
| gdb_continue_to_breakpoint "continue to test_ldm_pc" \ |
| ".*ldmia.*sp\!\,.*\{pc\}.*" |
| gdb_continue_to_breakpoint "continue to test_ldm_stm_pc_ret" \ |
| ".*bx lr.*" |
| } |
| ########################################## |
| # Test call/ret. |
| proc test_call_ret {} { |
| global srcfile |
| gdb_test "break *test_call_end" \ |
| "Breakpoint.*at.* file .*$srcfile, line.*" \ |
| "break test_call_end" |
| gdb_test "break *test_ret" \ |
| "Breakpoint.*at.* file .*$srcfile, line.*" \ |
| "break test_ret" |
| gdb_test "break *test_ret_end" \ |
| "Breakpoint.*at.* file .*$srcfile, line.*" \ |
| "break test_ret_end" |
| |
| gdb_continue_to_breakpoint "continue to test_call_end" \ |
| ".*@ Location test_call_end.*" |
| gdb_continue_to_breakpoint "continue to test_ret" \ |
| ".*bx lr.*" |
| gdb_continue_to_breakpoint "continue to test_ret_end" \ |
| ".*@ Location test_ret_end.*" |
| } |
| |
| |
| ######################################### |
| # Test branch |
| proc test_branch {} { |
| global srcfile |
| gdb_test "break *test_branch" \ |
| "Breakpoint.*at.* file .*$srcfile, line.*" \ |
| "break test_branch" |
| gdb_test "break *L_branch" \ |
| "Breakpoint.*at.* file .*$srcfile, line.*" \ |
| "break Lbranch" |
| |
| gdb_continue_to_breakpoint "continue to test_branch" \ |
| ".*b.*L_branch.*" |
| gdb_continue_to_breakpoint "continue to Lbranch" \ |
| ".*bx lr.*" |
| } |
| |
| ######################################### |
| |
| # Test ldr from pc |
| proc test_ldr_from_pc {} { |
| global srcfile |
| gdb_test "break *test_ldr_pc" \ |
| "Breakpoint.*at.* file .*$srcfile, line.*" \ |
| "break test_ldr_pc" |
| gdb_test "break test_ldr_pc_ret" \ |
| "Breakpoint.*at.* file .*$srcfile, line.*" \ |
| "break test_ldr_pc_ret" |
| |
| gdb_continue_to_breakpoint "continue to test_ldr_pc" \ |
| ".*ldr.*r1\,.*\[pc, #0\].*" |
| gdb_continue_to_breakpoint "continue to Lbranch" \ |
| ".*bx lr.*" |
| } |
| |
| ########################################### |
| |
| proc test_str_pc {} { |
| global srcfile |
| gdb_test_multiple "break *test_str_pc" "break test_str_pc" { |
| -re "Breakpoint.*at.* file .*$srcfile, line.*" { |
| pass "break test_str_pc" |
| } |
| -re "No symbol.*" { |
| pass "break test_str_pc" |
| return |
| } |
| } |
| gdb_test "break *test_str_pc_end" \ |
| "Breakpoint.*at.* file .*$srcfile, line.*" \ |
| "break test_str_pc_end" |
| |
| # Set breakpoint on both lables pc_offset_right and pc_offset_wrong |
| gdb_test "break *pc_offset_right" \ |
| "Breakpoint.*at.* file .*$srcfile, line.*" \ |
| "break pc_offset_right" |
| gdb_test "break *pc_offset_wrong" \ |
| "Breakpoint.*at.* file .*$srcfile, line.*" \ |
| "break pc_offset_wrong" |
| |
| gdb_continue_to_breakpoint "continue to test_str_pc" \ |
| ".*str.*pc\,.*\[sp, #-4\].*" |
| # If breakpoint on lable pc_offset_wrong is hit, that means the offset |
| # computed in displaced stepping is different from offset computed |
| # without displaced stepping. Report a failure. |
| gdb_continue_to_breakpoint "continue to pc_offset_right" \ |
| ".*b.*test_str_pc_end.*" |
| gdb_continue_to_breakpoint "continue to test_str_pc_end" \ |
| ".*bx lr.*" |
| } |
| |
| # Get things started. |
| |
| clean_restart ${testfile} |
| |
| # Turn displaced stepping off before runto main. When displaced stepping |
| # is on, and we type 'run', GDB will first try to single step on _dl_debug_state, |
| # which is in library might be compiled in Thumb. |
| gdb_test_no_output "set displaced-stepping off" |
| |
| if ![runto_main] then { |
| fail "Can't run to main" |
| return 0 |
| } |
| |
| gdb_test_no_output "set displaced-stepping on" |
| gdb_test "show displaced-stepping" ".* displaced stepping .* is on.*" |
| |
| gdb_test "break *test_call" \ |
| "Breakpoint.*at.* file .*$srcfile, line.*" \ |
| "break test_call" |
| |
| gdb_test_multiple "continue" "continue to test_call" { |
| -re ".*bl test_call_subr.*" { |
| pass "continue to test_call" |
| } |
| -re "Displaced stepping is only supported in" { |
| kfail "gdb/NNNN" $testfile |
| return |
| } |
| } |
| |
| test_call_ret |
| |
| test_branch |
| |
| test_ldr_from_pc |
| |
| test_ldm_stm_pc |
| |
| test_str_pc |
| ########################################## |
| |
| # Done, run program to exit. |
| |
| gdb_continue_to_end "arm-disp-step" |