[PATCH 5/57][Arm][GAS] Add support for MVE instructions: vmull{b,t}
[binutils-gdb.git] / gdb / testsuite / gdb.base / step-over-syscall.exp
blob8daf65b2d0dbe7ef7722ed2dfd46b406a7e61394
1 # This testcase is part of GDB, the GNU debugger.
3 # Copyright 2011-2019 Free Software Foundation, Inc.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 set syscall_insn ""
20 # Define the syscall instruction for each target.
22 if { [istarget "i\[34567\]86-*-linux*"] || [istarget "x86_64-*-linux*"] } {
23     set syscall_insn "\[ \t\](int|syscall|sysenter)\[ \t\]"
24 } elseif { [istarget "aarch64*-*-linux*"] || [istarget "arm*-*-linux*"] } {
25     set syscall_insn "\[ \t\](swi|svc)\[ \t\]"
26 } else {
27     return -1
30 proc check_pc_after_cross_syscall { syscall syscall_insn_next_addr } {
31     set syscall_insn_next_addr_found [get_hexadecimal_valueof "\$pc" "0"]
33     set test "single step over $syscall final pc"
34     if {$syscall_insn_next_addr != 0
35         && $syscall_insn_next_addr == $syscall_insn_next_addr_found} {
36         pass $test
37     } else {
38         fail $test
39     }
42 # Restart GDB and set up the test.  Return a list in which the first one
43 # is the address of syscall instruction and the second one is the address
44 # of the next instruction address of syscall instruction.  If anything
45 # wrong, the two elements of list are -1.
47 proc setup { syscall } {
48     global gdb_prompt syscall_insn
50     set testfile "step-over-$syscall"
52     clean_restart $testfile
54     if { ![runto main] } then {
55         fail "run to main ($syscall)"
56         return -1
57     }
59     # Delete the breakpoint on main.
60     gdb_test_no_output "delete break 1"
62     gdb_test_no_output "set displaced-stepping off"
64     gdb_test "break $syscall" "Breakpoint \[0-9\]* at .*"
66     gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
67         "continue to $syscall (1st time)"
68     # Hit the breakpoint on $syscall for the first time.  In this time,
69     # we will let PLT resolution done, and the number single steps we will
70     # do later will be reduced.
72     gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
73         "continue to $syscall (2nd time)"
74     # Hit the breakpoint on $syscall for the second time.  In this time,
75     # the address of syscall insn and next insn of syscall are recorded.
77     gdb_test "display/i \$pc" ".*"
79     # Single step until we see a syscall insn or we reach the
80     # upper bound of loop iterations.
81     set msg "find syscall insn in $syscall"
82     set steps 0
83     set max_steps 1000
84     gdb_test_multiple "stepi" $msg {
85         -re ".*$syscall_insn.*$gdb_prompt $" {
86             pass $msg
87         }
88         -re "x/i .*=>.*\r\n$gdb_prompt $" {
89             incr steps
90             if {$steps == $max_steps} {
91                 fail $msg
92             } else {
93                 send_gdb "stepi\n"
94                 exp_continue
95             }
96         }
97     }
99     if {$steps == $max_steps} {
100         return { -1, -1 }
101     }
103     set syscall_insn_addr [get_hexadecimal_valueof "\$pc" "0"]
104     if {[gdb_test "stepi" "x/i .*=>.*" "stepi $syscall insn"] != 0} {
105         return { -1, -1 }
106     }
107     return [list $syscall_insn_addr [get_hexadecimal_valueof "\$pc" "0"]]
110 proc step_over_syscall { syscall } {
111     with_test_prefix "$syscall" {
112         global syscall_insn
113         global gdb_prompt
115         set testfile "step-over-$syscall"
117         if [build_executable ${testfile}.exp ${testfile} ${testfile}.c {debug}] {
118             untested "failed to compile"
119             return -1
120         }
122         foreach_with_prefix displaced {"off" "on"} {
123             if {$displaced == "on" && ![support_displaced_stepping]} {
124                 continue
125             }
127             if { $displaced == "on" && $syscall == "clone" } {
128                 # GDB doesn't support stepping over clone syscall with
129                 # displaced stepping.
130                 kfail "gdb/19675" "single step over clone"
131                 continue
132             }
134             set ret [setup $syscall]
136             set syscall_insn_addr [lindex $ret 0]
137             set syscall_insn_next_addr [lindex $ret 1]
138             if { $syscall_insn_addr == -1 } {
139                 return -1
140             }
142             gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
143                 "continue to $syscall (3rd time)"
145             # Hit the breakpoint on $syscall for the third time.  In this time, we'll set
146             # breakpoint on the syscall insn we recorded previously, and single step over it.
148             set syscall_insn_bp 0
149             gdb_test_multiple "break \*$syscall_insn_addr"  "break on syscall insn" {
150                 -re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
151                     set syscall_insn_bp $expect_out(1,string)
152                     pass "break on syscall insns"
153                 }
154             }
156             gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .*" \
157                 "continue to syscall insn $syscall"
159             gdb_test_no_output "set displaced-stepping $displaced"
161             # Check the address of next instruction of syscall.
162             if {[gdb_test "stepi" "x/i .*=>.*" "single step over $syscall"] != 0} {
163                 return -1
164             }
165             check_pc_after_cross_syscall $syscall $syscall_insn_next_addr
167             # Delete breakpoint syscall insns to avoid interference to other syscalls.
168             delete_breakpoints
170             gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
171             gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
172                 "continue to marker ($syscall)"
173         }
174     }
177 # Set a breakpoint with a condition that evals false on syscall
178 # instruction.  In fact, it tests GDBserver steps over syscall
179 # instruction.  SYSCALL is the syscall the program calls.
180 # FOLLOW_FORK is either "parent" or "child".  DETACH_ON_FORK is
181 # "on" or "off".
183 proc break_cond_on_syscall { syscall follow_fork detach_on_fork } {
184     with_test_prefix "break cond on target : $syscall" {
185         set testfile "step-over-$syscall"
187         set ret [setup $syscall]
189         set syscall_insn_addr [lindex $ret 0]
190         set syscall_insn_next_addr [lindex $ret 1]
191         if { $syscall_insn_addr == -1 } {
192             return -1
193         }
195         gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
196             "continue to $syscall"
197         # Delete breakpoint syscall insns to avoid interference with other syscalls.
198         delete_breakpoints
200         gdb_test "set follow-fork-mode $follow_fork"
201         gdb_test "set detach-on-fork $detach_on_fork"
203         # Create a breakpoint with a condition that evals false.
204         gdb_test "break \*$syscall_insn_addr if main == 0" \
205             "Breakpoint \[0-9\]* at .*"
207         if { $syscall == "clone" } {
208             # Create a breakpoint in the child with the condition that
209             # evals false, so that GDBserver can get the event from the
210             # child but GDB doesn't see it.  In this way, we don't have
211             # to adjust the test flow for "clone".
212             # This is a regression test for PR server/19736.  In this way,
213             # we can test that GDBserver gets an event from the child and
214             # set suspend count correctly while the parent is stepping over
215             # the breakpoint.
216             gdb_test "break clone_fn if main == 0"
217         }
219         if { $syscall == "clone" } {
220             # follow-fork and detach-on-fork only make sense to
221             # fork and vfork.
222             gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
223             gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
224                 "continue to marker"
225         } else {
226             if { $follow_fork == "child" } {
227                 gdb_test "continue" "exited normally.*" "continue to end of inf 2"
228                 if { $detach_on_fork == "off" } {
229                     gdb_test "inferior 1"
230                     gdb_test "break marker" "Breakpoint.*at.*"
231                     gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
232                         "continue to marker"
233                 }
234             } else {
235                 gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
236                 gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
237                     "continue to marker"
238             }
239         }
240     }
243 step_over_syscall "fork"
244 step_over_syscall "vfork"
245 step_over_syscall "clone"
247 set testfile "step-over-fork"
248 clean_restart $testfile
249 if { ![runto main] } then {
250     fail "run to main"
251     return -1
254 set cond_bp_target 1
256 set test "set breakpoint condition-evaluation target"
257 gdb_test_multiple $test $test {
258     -re "warning: Target does not support breakpoint condition evaluation.\r\nUsing host evaluation mode instead.\r\n$gdb_prompt $" {
259         # Target doesn't support breakpoint condition
260         # evaluation on its side.
261         set cond_bp_target 0
262     }
263     -re "^$test\r\n$gdb_prompt $" {
264     }
267 if { $cond_bp_target } {
269     foreach_with_prefix detach-on-fork {"on" "off"} {
270         foreach_with_prefix follow-fork {"parent" "child"} {
271             foreach syscall { "fork" "vfork" "clone" } {
273                 if { $syscall == "vfork"
274                      && ${follow-fork} == "parent"
275                      && ${detach-on-fork} == "off" } {
276                     # Both vforked child process and parent process are
277                     # under GDB's control, but GDB follows the parent
278                     # process only, which can't be run until vforked child
279                     # finishes.  Skip the test in this scenario.
280                     continue
281                 }
282                 break_cond_on_syscall $syscall ${follow-fork} ${detach-on-fork}
283             }
284         }
285     }