Home | History | Annotate | Line # | Download | only in gdb.arch
      1  1.1  christos # Copyright 2023-2024 Free Software Foundation, Inc.
      2  1.1  christos 
      3  1.1  christos # This program is free software; you can redistribute it and/or modify
      4  1.1  christos # it under the terms of the GNU General Public License as published by
      5  1.1  christos # the Free Software Foundation; either version 3 of the License, or
      6  1.1  christos # (at your option) any later version.
      7  1.1  christos #
      8  1.1  christos # This program is distributed in the hope that it will be useful,
      9  1.1  christos # but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  1.1  christos # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11  1.1  christos # GNU General Public License for more details.
     12  1.1  christos #
     13  1.1  christos # You should have received a copy of the GNU General Public License
     14  1.1  christos # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15  1.1  christos 
     16  1.1  christos # Test i386 displaced stepping over a call instruction that calls to
     17  1.1  christos # itself.  This is pretty unlikely to be seen in the wild, but does
     18  1.1  christos # test a corner case of our displaced step handling.
     19  1.1  christos 
     20  1.1  christos require is_x86_like_target
     21  1.1  christos 
     22  1.1  christos set newline "\[\r\n\]*"
     23  1.1  christos 
     24  1.1  christos set opts {debug nopie}
     25  1.1  christos standard_testfile .S -alarm.c
     26  1.1  christos 
     27  1.1  christos if { [prepare_for_testing "failed to prepare" $testfile "$srcfile $srcfile2" $opts] } {
     28  1.1  christos     return -1
     29  1.1  christos }
     30  1.1  christos 
     31  1.1  christos gdb_test "set displaced-stepping on" ""
     32  1.1  christos gdb_test "show displaced-stepping" ".* displaced stepping .* is on.*"
     33  1.1  christos 
     34  1.1  christos if {![runto_main]} {
     35  1.1  christos     return 0
     36  1.1  christos }
     37  1.1  christos 
     38  1.1  christos # Proceed to the test function.
     39  1.1  christos gdb_breakpoint "test_call"
     40  1.1  christos gdb_continue_to_breakpoint "test_call"
     41  1.1  christos 
     42  1.1  christos # Get the current stack pointer value.
     43  1.1  christos set sp [get_hexadecimal_valueof "\$sp" "*UNKNOWN*"]
     44  1.1  christos 
     45  1.1  christos # Get the address of the next instruction.
     46  1.1  christos set next_insn_addr ""
     47  1.1  christos gdb_test_multiple "x/2i \$pc" "get address of next insn" {
     48  1.1  christos     -re "\r\n=> $hex \[^\r\n\]+\r\n" {
     49  1.1  christos 	exp_continue
     50  1.1  christos     }
     51  1.1  christos     -re "^   ($hex) \[^\r\n\]+\r\n" {
     52  1.1  christos 	set next_insn_addr $expect_out(1,string)
     53  1.1  christos 	exp_continue
     54  1.1  christos     }
     55  1.1  christos     -re "^$::gdb_prompt $" {
     56  1.1  christos 	gdb_assert {![string equal $next_insn_addr ""]} \
     57  1.1  christos 	    $gdb_test_name
     58  1.1  christos     }
     59  1.1  christos }
     60  1.1  christos 
     61  1.1  christos # Clear the slot on the stack and confirm it was set to zero.
     62  1.1  christos set sp [expr $sp - 0x4]
     63  1.1  christos gdb_test_no_output "set {unsigned int} $sp = 0" \
     64  1.1  christos     "clear stack slot"
     65  1.1  christos set zero_val 0x[format %08x 0]
     66  1.1  christos gdb_test "x/1wx 0x[format %x $sp]" "$hex:\\s+${zero_val}" \
     67  1.1  christos     "check return address slot was set to zero"
     68  1.1  christos 
     69  1.1  christos # Single step.
     70  1.1  christos gdb_test "stepi" \
     71  1.1  christos     "Breakpoint $decimal, test_call \\(\\) at .*"
     72  1.1  christos 
     73  1.1  christos # Check stack pointer was updated to the expected value.
     74  1.1  christos set new_sp [get_hexadecimal_valueof "\$sp" "*UNKNOWN*" \
     75  1.1  christos 	       "get stack pointer after step"]
     76  1.1  christos gdb_assert {[expr $sp == $new_sp]} \
     77  1.1  christos     "check stack pointer was updated as expected"
     78  1.1  christos 
     79  1.1  christos # Check the contents of the stack were updated to the expected value.
     80  1.1  christos set next_insn_addr 0x[format %08X $next_insn_addr]
     81  1.1  christos gdb_test "x/1wx 0x[format %x $sp]" "$hex:\\s+$next_insn_addr" \
     82  1.1  christos     "check return address was updated correctly"
     83