1 # Copyright 2008-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 # This file is part of the GDB testsuite. It tests reverse stepping. 17 # Lots of code borrowed from "step-test.exp". 18 19 # The reverse finish command should return from a function and stop on 20 # the first instruction of the source line where the function call is made. 21 # Specifically, the behavior should match doing a reverse next from the 22 # first instruction in the function. GDB should only take one reverse step 23 # or next statement to reach the previous source code line. 24 25 # This testcase verifies the reverse-finish command stops at the first 26 # instruction in the source code line where the function was called. There 27 # are two scenarios that must be checked: 28 # 1) gdb is at the entry point instruction for the function 29 # 2) gdb is in the body of the function. 30 31 # This test verifies the fix for gdb bugzilla: 32 # https://sourceware.org/bugzilla/show_bug.cgi?id=29927 33 34 # PowerPC supports two entry points to a function. The normal entry point 35 # is called the local entry point (LEP). The alternate entry point is called 36 # the global entry point (GEP). A function call via a function pointer 37 # will entry via the GEP. A normal function call will enter via the LEP. 38 # 39 # This test has been expanded to include tests to verify the reverse-finish 40 # command works properly if the function is called via the GEP. The original 41 # test only verified the reverse-finish command for a normal call that used 42 # the LEP. 43 44 if ![supports_reverse] { 45 return 46 } 47 48 standard_testfile 49 50 if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { 51 return -1 52 } 53 54 runto_main 55 56 if [supports_process_record] { 57 # Activate process record/replay. 58 gdb_test_no_output "record" "turn on process record for test1" 59 } 60 61 62 ### TEST 1: reverse finish from the entry point instruction (LEP) in 63 ### function1 when called using the normal entry point (LEP). 64 65 # Set breakpoint at call to function1 in main. 66 set bp_LEP_test [gdb_get_line_number "CALL VIA LEP" $srcfile] 67 gdb_breakpoint $srcfile:$bp_LEP_test temporary 68 69 # Continue to break point at function1 call in main. 70 gdb_continue_to_breakpoint \ 71 "stopped at function1 entry point instruction to stepi into function" \ 72 ".*$srcfile:$bp_LEP_test\r\n.*" 73 74 # stepi until we see "{" indicating we entered function1 75 repeat_cmd_until "stepi" "CALL VIA LEP" "{" "stepi into function1 call" "100" 76 77 # The reverse-finish command should stop on the function call instruction 78 # which is the last instruction in the source code line. Another reverse-next 79 # instruction stops at the previous source code line. 80 gdb_test "reverse-finish" ".*function1 \\(a, b\\); // CALL VIA LEP.*" \ 81 "reverse-finish function1 LEP call from LEP " 82 gdb_test "reverse-next" ".*b = 5;.*" "reverse next 2, at b = 5, call from LEP" 83 84 85 gdb_test "reverse-continue" ".*" "setup for test 2" 86 87 # Turn off record to clear logs and turn on again 88 gdb_test "record stop" "Process record is stopped.*" \ 89 "turn off process record for test1" 90 gdb_test_no_output "record" "turn on process record for test2" 91 92 93 ### TEST 2: reverse finish from the body of function1. 94 95 # Set breakpoint at call to function1 in main. 96 gdb_breakpoint $srcfile:$bp_LEP_test temporary 97 98 # Continue to break point at function1 call in main. 99 gdb_continue_to_breakpoint \ 100 "at function1 entry point instruction to step to body of function" \ 101 ".*$srcfile:$bp_LEP_test\r\n.*" 102 103 # do a step instruction to get to the body of the function 104 gdb_test "step" ".*int ret = 0;.*" "step test 1" 105 106 # The reverse-finish command should stop on the function call instruction 107 # which is the last instruction in the source code line. Another reverse-next 108 # instruction stops at the previous source code line. 109 gdb_test "reverse-finish" ".*function1 \\(a, b\\); // CALL VIA LEP.*" \ 110 "reverse-finish function1 LEP call from function body" 111 gdb_test "reverse-next" ".*b = 5;.*" \ 112 "reverse next 2 at b = 5, from function body" 113 114 gdb_test "reverse-continue" ".*" "setup for test 3" 115 116 # Turn off record to clear logs and turn on again 117 gdb_test "record stop" "Process record is stopped.*" \ 118 "turn off process record for test2" 119 gdb_test_no_output "record" "turn on process record for test3" 120 121 122 ### TEST 3: reverse finish from the alternate entry point instruction (GEP) in 123 ### function1 when called using the alternate entry point (GEP). 124 125 # Set breakpoint at call to funp in main. 126 set bp_GEP_test [gdb_get_line_number "CALL VIA GEP" $srcfile] 127 gdb_breakpoint $srcfile:$bp_GEP_test temporary 128 129 # Continue to break point at funp call in main. 130 gdb_continue_to_breakpoint \ 131 "stopped at function1 entry point instruction to stepi into funp" \ 132 ".*$srcfile:$bp_GEP_test\r\n.*" 133 134 # stepi until we see "{" indicating we entered function. 135 repeat_cmd_until "stepi" "CALL VIA GEP" "{" "stepi into funp call" 136 137 # The reverse-finish command should stop on the function call instruction 138 # which is the last instruction in the source code line. Another reverse-next 139 # instruction stops at the previous source code line. 140 gdb_test "reverse-finish" ".*funp \\(a, b\\);.*" \ 141 "function1 GEP call call from GEP" 142 gdb_test "reverse-next" ".*b = 50;.*" "reverse next 2 at b = 50, call from GEP" 143 144 gdb_test "reverse-continue" ".*" "setup for test 4" 145 146 # Turn off record to clear logs and turn on again 147 gdb_test "record stop" "Process record is stopped.*" \ 148 "turn off process record for test3" 149 gdb_test_no_output "record" "turn on process record for test4" 150 151 ### TEST 4: reverse finish from between the GEP and LEP in 152 ### function1 when called using the alternate entry point (GEP). 153 154 # Set breakpoint at call to funp in main. 155 set bp_GEP_test [gdb_get_line_number "CALL VIA GEP" $srcfile] 156 gdb_breakpoint $srcfile:$bp_GEP_test temporary 157 158 # Continue to break point at funp call in main. 159 gdb_continue_to_breakpoint \ 160 "stopped at function1 entry point instruction to stepi into funp again" \ 161 ".*$srcfile:$bp_GEP_test\r\n.*" 162 163 # stepi until we see "{" indicating we entered function. 164 repeat_cmd_until "stepi" "CALL VIA GEP" "{" "stepi into funp call again" 165 166 # do one more stepi so we are between the GEP and LEP. 167 gdb_test "stepi" "{" "stepi to between GEP and LEP" 168 169 # The reverse-finish command should stop on the function call instruction 170 # which is the last instruction in the source code line. Another reverse-next 171 # instruction stops at the previous source code line. 172 gdb_test "reverse-finish" ".*funp \\(a, b\\);.*" \ 173 "function1 GEP call call from GEP again" 174 gdb_test "reverse-next" ".*b = 50;.*" \ 175 "reverse next 2 at b = 50, call from GEP again" 176 177 gdb_test "reverse-continue" ".*" "setup for test 5" 178 179 # Turn off record to clear logs and turn on again 180 gdb_test "record stop" "Process record is stopped.*" \ 181 "turn off process record for test4" 182 gdb_test_no_output "record" "turn on process record for test5" 183 184 185 ### TEST 5: reverse finish from the body of function 1 when calling using the 186 ### alternate entrypoint (GEP). 187 gdb_breakpoint $srcfile:$bp_GEP_test temporary 188 189 # Continue to break point at funp call. 190 gdb_continue_to_breakpoint \ 191 "at function1 entry point instruction to step to body of funp call" \ 192 ".*$srcfile:$bp_GEP_test\r\n.*" 193 194 # Step into body of funp, called via GEP. 195 gdb_test "step" ".*int ret = 0;.*" "step test 2" 196 197 # The reverse-finish command should stop on the function call instruction 198 # which is the last instruction in the source code line. Another reverse-next 199 # instruction stops at the previous source code line. 200 gdb_test "reverse-finish" ".*funp \\(a, b\\);.*" \ 201 "reverse-finish function1 GEP call, from function body " 202 gdb_test "reverse-next" ".*b = 50;.*" \ 203 "reverse next 2 at b = 50 from function body" 204