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 amd64 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 20require is_x86_64_m64_target 21 22set newline "\[\r\n\]*" 23 24set opts {debug nopie} 25standard_testfile .S -alarm.c 26 27if { [prepare_for_testing "failed to prepare" $testfile "$srcfile $srcfile2" $opts] } { 28 return -1 29} 30 31gdb_test "set displaced-stepping on" "" 32gdb_test "show displaced-stepping" ".* displaced stepping .* is on.*" 33 34if {![runto_main]} { 35 return 0 36} 37 38# Proceed to the test function. 39gdb_breakpoint "test_call" 40gdb_continue_to_breakpoint "test_call" 41 42# Get the current stack pointer value. 43set sp [get_hexadecimal_valueof "\$sp" "*UNKNOWN*"] 44 45# Get the address of the next instruction. 46set next_insn_addr "" 47gdb_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. 62set sp [expr $sp - 0x8] 63gdb_test_no_output "set {unsigned long long} $sp = 0" \ 64 "clear stack slot" 65set zero_val 0x[format %016x 0] 66gdb_test "x/1gx 0x[format %x $sp]" "$hex:\\s+${zero_val}" \ 67 "check return address slot was set to zero" 68 69# Single step. 70gdb_test "stepi" \ 71 "Breakpoint $decimal, test_call \\(\\) at .*" 72 73# Check stack pointer was updated to the expected value. 74set new_sp [get_hexadecimal_valueof "\$sp" "*UNKNOWN*" \ 75 "get stack pointer after step"] 76gdb_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. 80set next_insn_addr 0x[format %016X $next_insn_addr] 81gdb_test "x/1gx 0x[format %x $sp]" "$hex:\\s+$next_insn_addr" \ 82 "check return address was updated correctly" 83