amd64-disp-step-avx.exp revision 1.1.1.4 1 # Copyright 2009-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.
17
18 # Test displaced stepping over VEX-encoded RIP-relative AVX
19 # instructions.
20
21 require is_x86_64_m64_target have_avx
22
23 standard_testfile .S
24
25 set options [list debug nopie]
26 if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} $options] } {
27 return -1
28 }
29
30 # Get things started.
31
32 gdb_test "set displaced-stepping on" ""
33 gdb_test "show displaced-stepping" ".* displaced stepping .* is on.*"
34
35 if {![runto_main]} {
36 return 0
37 }
38
39 # GDB picks a spare register from this list to hold the RIP-relative
40 # address.
41 set rip_regs { "rax" "rbx" "rcx" "rdx" "rbp" "rsi" "rdi" }
42
43 # Assign VAL to all the RIP_REGS.
44
45 proc set_regs { val } {
46 global gdb_prompt
47 global rip_regs
48
49 foreach reg ${rip_regs} {
50 gdb_test_no_output "set \$${reg} = ${val}"
51 }
52 }
53
54 # Verify all RIP_REGS print as HEX_VAL_RE in hex.
55
56 proc verify_regs { hex_val_re } {
57 global rip_regs
58
59 foreach reg ${rip_regs} {
60 gdb_test "p /x \$${reg}" " = ${hex_val_re}" "${reg} expected value"
61 }
62 }
63
64 # Set a break at FUNC, which starts with a RIP-relative instruction
65 # that we want to displaced-step over, and then continue over the
66 # breakpoint, forcing a displaced-stepping sequence.
67
68 proc disp_step_func { func } {
69 global srcfile
70
71 set test_start_label "${func}"
72 set test_end_label "${func}_end"
73
74 gdb_test "break ${test_start_label}" \
75 "Breakpoint.*at.* file .*$srcfile, line.*"
76 gdb_test "break ${test_end_label}" \
77 "Breakpoint.*at.* file .*$srcfile, line.*"
78
79 gdb_test "continue" \
80 "Continuing.*Breakpoint.*, ${test_start_label} ().*" \
81 "continue to ${test_start_label}"
82
83 # GDB picks a spare register to hold the RIP-relative address.
84 # Ensure the spare register value is restored properly (rax-rdi,
85 # sans rsp).
86 set value "0xdeadbeefd3adb33f"
87 set_regs $value
88
89 # Turn "debug displaced" on to make sure a displaced step is actually
90 # executed, not an inline step.
91 gdb_test_no_output "set debug displaced on"
92
93 gdb_test "continue" \
94 "Continuing.*prepared successfully .*Breakpoint.*, ${test_end_label} ().*" \
95 "continue to ${test_end_label}"
96
97 gdb_test_no_output "set debug displaced off"
98
99 verify_regs $value
100 }
101
102 # Test a VEX2-encoded RIP-relative instruction.
103 with_test_prefix "vex2" {
104 # Initialize all XMM registers to 0.
105 for {set i 0 } { $i < 16 } { incr i } {
106 gdb_test_no_output "set \$xmm${i}.uint128 = 0" \
107 "xmm${i} set to zero"
108 }
109
110 disp_step_func "test_rip_vex2"
111
112 # Confirm the instruction's expected side effects. It should have
113 # modified xmm0.
114 gdb_test "p /x \$xmm0.uint128" " = 0x1122334455667788" \
115 "xmm0 has expected value after"
116
117 # And all of the other XMM register should still be 0.
118 for {set i 1 } { $i < 16 } { incr i } {
119 gdb_test "p /x \$xmm${i}.uint128" " = 0x0" \
120 "xmm${i} has expected value after"
121 }
122 }
123
124 # Test a VEX3-encoded RIP-relative instruction.
125 with_test_prefix "vex3" {
126 # This case writes to the 'var128' variable. Confirm the
127 # variable's value is what we believe it is before the AVX
128 # instruction runs.
129 gdb_test "p /x (unsigned long long \[2\]) var128" \
130 " = \\{0xaa55aa55aa55aa55, 0x55aa55aa55aa55aa\\}" \
131 "var128 has expected value before"
132
133 # Run the AVX instruction.
134 disp_step_func "test_rip_vex3"
135
136 # Confirm the instruction's expected side effects. It should have
137 # modifed the 'var128' variable.
138 gdb_test "p /x (unsigned long long \[2\]) var128" \
139 " = \\{0x1122334455667788, 0x0\\}" \
140 "var128 has expected value after"
141 }
142
143 # Done, run program to exit.
144 gdb_continue_to_end "amd64-disp-step-avx"
145