return -1
}
-proc disp_step_cross_syscall { syscall } {
- with_test_prefix "$syscall" {
- global syscall_insn
- global gdb_prompt
+proc check_pc_after_cross_syscall { syscall syscall_insn_next_addr } {
+ set syscall_insn_next_addr_found [get_hexadecimal_valueof "\$pc" "0"]
+
+ set test "single step over $syscall final pc"
+ if {$syscall_insn_next_addr != 0
+ && $syscall_insn_next_addr == $syscall_insn_next_addr_found} {
+ pass $test
+ } else {
+ fail $test
+ }
+}
- set testfile "disp-step-$syscall"
+# Restart GDB and set up the test. Return a list in which the first one
+# is the address of syscall instruction and the second one is the address
+# of the next instruction address of syscall instruction. If anything
+# wrong, the two elements of list are -1.
- if [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.c {debug}] {
- untested ${testfile}.exp
- return -1
- }
+proc setup { syscall } {
+ global gdb_prompt syscall_insn
- if { ![runto main] } then {
- fail "run to main ($syscall)"
- return
- }
+ set testfile "disp-step-$syscall"
- # Delete the breakpoint on main.
- gdb_test_no_output "delete break 1"
+ clean_restart $testfile
- gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
- gdb_test_no_output "set displaced-stepping off"
+ if { ![runto main] } then {
+ fail "run to main ($syscall)"
+ return -1
+ }
- set syscall_bp 0
- gdb_test_multiple "break $syscall" "break $syscall" {
- -re "Breakpoint (\[0-9\]*) at .*$gdb_prompt $" {
- set syscall_bp $expect_out(1,string)
- pass "break $syscall"
- }
- }
+ # Delete the breakpoint on main.
+ gdb_test_no_output "delete break 1"
- gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
- "continue to $syscall (1st time)"
- # Hit the breakpoint on $syscall for the first time. In this time, we will let PLT
- # resolution done, and the number single steps we will do later will be
- # reduced.
+ gdb_test_no_output "set displaced-stepping off"
- gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
- "continue to $syscall (2nd time)"
- # Hit the breakpoint on $syscall for the second time. In this time, the address
- # of syscall insn and next insn of syscall are recorded.
+ gdb_test "break $syscall" "Breakpoint \[0-9\]* at .*"
- gdb_test "display/i \$pc" ".*"
+ gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
+ "continue to $syscall (1st time)"
+ # Hit the breakpoint on $syscall for the first time. In this time,
+ # we will let PLT resolution done, and the number single steps we will
+ # do later will be reduced.
+ gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
+ "continue to $syscall (2nd time)"
+ # Hit the breakpoint on $syscall for the second time. In this time,
+ # the address of syscall insn and next insn of syscall are recorded.
- # Single step until we see a syscall insn or we reach the
- # upper bound of loop iterations.
- set msg "find syscall insn in $syscall"
- set steps 0
- set max_steps 1000
- gdb_test_multiple "stepi" $msg {
- -re ".*$syscall_insn.*$gdb_prompt $" {
- pass $msg
- }
- -re "x/i .*=>.*\r\n$gdb_prompt $" {
- incr steps
- if {$steps == $max_steps} {
- fail $msg
- } else {
- send_gdb "stepi\n"
- exp_continue
- }
+ gdb_test "display/i \$pc" ".*"
+
+ # Single step until we see a syscall insn or we reach the
+ # upper bound of loop iterations.
+ set msg "find syscall insn in $syscall"
+ set steps 0
+ set max_steps 1000
+ gdb_test_multiple "stepi" $msg {
+ -re ".*$syscall_insn.*$gdb_prompt $" {
+ pass $msg
+ }
+ -re "x/i .*=>.*\r\n$gdb_prompt $" {
+ incr steps
+ if {$steps == $max_steps} {
+ fail $msg
+ } else {
+ send_gdb "stepi\n"
+ exp_continue
}
}
+ }
+
+ if {$steps == $max_steps} {
+ return { -1, -1 }
+ }
+
+ set syscall_insn_addr [get_hexadecimal_valueof "\$pc" "0"]
+ if {[gdb_test "stepi" "x/i .*=>.*" "stepi $syscall insn"] != 0} {
+ return { -1, -1 }
+ }
+ return [list $syscall_insn_addr [get_hexadecimal_valueof "\$pc" "0"]]
+}
- if {$steps == $max_steps} {
+proc disp_step_cross_syscall { syscall } {
+ with_test_prefix "$syscall" {
+ global syscall_insn
+ global gdb_prompt
+
+ set testfile "disp-step-$syscall"
+
+ if [build_executable ${testfile}.exp ${testfile} ${testfile}.c {debug}] {
+ untested ${testfile}.exp
return -1
}
- set syscall_insn_addr [get_hexadecimal_valueof "\$pc" "0"]
- if {[gdb_test "stepi" "x/i .*=>.*" "stepi $syscall insn"] != 0} {
+ set ret [setup $syscall]
+
+ set syscall_insn_addr [lindex $ret 0]
+ set syscall_insn_next_addr [lindex $ret 1]
+ if { $syscall_insn_addr == -1 } {
return -1
}
- set syscall_insn_next_addr [get_hexadecimal_valueof "\$pc" "0"]
gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in |__libc_|)$syscall \\(\\).*" \
"continue to $syscall (3rd time)"
pass "break on syscall insns"
}
}
- gdb_test_no_output "delete $syscall_bp" "delete break $syscall"
gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, .*" \
"continue to syscall insn $syscall"
return -1
}
- set syscall_insn_next_addr_found [get_hexadecimal_valueof "\$pc" "0"]
-
- set test "single step over $syscall final pc"
- if {$syscall_insn_next_addr != 0
- && $syscall_insn_next_addr == $syscall_insn_next_addr_found} {
- pass $test
- } else {
- fail $test
- }
+ check_pc_after_cross_syscall $syscall $syscall_insn_next_addr
# Delete breakpoint syscall insns to avoid interference to other syscalls.
- gdb_test_no_output "delete $syscall_insn_bp" "delete break $syscall insn"
+ delete_breakpoints
+ gdb_test "break marker" "Breakpoint.*at.* file .*${testfile}.c, line.*"
gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker \\(\\) at.*" \
"continue to marker ($syscall)"
}