1 # Copyright 2023-2024 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 # Test i386 displaced stepping over a call instruction that calls to 17 # itself. This is pretty unlikely to be seen in the wild, but does 18 # test a corner case of our displaced step handling. 19 20 require is_x86_like_target 21 22 set newline "\[\r\n\]*" 23 24 set opts {debug nopie} 25 standard_testfile .S -alarm.c 26 27 if { [prepare_for_testing "failed to prepare" $testfile "$srcfile $srcfile2" $opts] } { 28 return -1 29 } 30 31 gdb_test "set displaced-stepping on" "" 32 gdb_test "show displaced-stepping" ".* displaced stepping .* is on.*" 33 34 if {![runto_main]} { 35 return 0 36 } 37 38 # Proceed to the test function. 39 gdb_breakpoint "test_call" 40 gdb_continue_to_breakpoint "test_call" 41 42 # Get the current stack pointer value. 43 set sp [get_hexadecimal_valueof "\$sp" "*UNKNOWN*"] 44 45 # Get the address of the next instruction. 46 set next_insn_addr "" 47 gdb_test_multiple "x/2i \$pc" "get address of next insn" { 48 -re "\r\n=> $hex \[^\r\n\]+\r\n" { 49 exp_continue 50 } 51 -re "^ ($hex) \[^\r\n\]+\r\n" { 52 set next_insn_addr $expect_out(1,string) 53 exp_continue 54 } 55 -re "^$::gdb_prompt $" { 56 gdb_assert {![string equal $next_insn_addr ""]} \ 57 $gdb_test_name 58 } 59 } 60 61 # Clear the slot on the stack and confirm it was set to zero. 62 set sp [expr $sp - 0x4] 63 gdb_test_no_output "set {unsigned int} $sp = 0" \ 64 "clear stack slot" 65 set zero_val 0x[format %08x 0] 66 gdb_test "x/1wx 0x[format %x $sp]" "$hex:\\s+${zero_val}" \ 67 "check return address slot was set to zero" 68 69 # Single step. 70 gdb_test "stepi" \ 71 "Breakpoint $decimal, test_call \\(\\) at .*" 72 73 # Check stack pointer was updated to the expected value. 74 set new_sp [get_hexadecimal_valueof "\$sp" "*UNKNOWN*" \ 75 "get stack pointer after step"] 76 gdb_assert {[expr $sp == $new_sp]} \ 77 "check stack pointer was updated as expected" 78 79 # Check the contents of the stack were updated to the expected value. 80 set next_insn_addr 0x[format %08X $next_insn_addr] 81 gdb_test "x/1wx 0x[format %x $sp]" "$hex:\\s+$next_insn_addr" \ 82 "check return address was updated correctly" 83