Commit | Line | Data |
---|---|---|
b811d2c2 | 1 | # Copyright 2012-2020 Free Software Foundation, Inc. |
2838cc1d SD |
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 | ||
922a7c7c | 16 | standard_testfile jit-reader-host.c |
2838cc1d SD |
17 | |
18 | if { (![istarget x86_64-*-*] && ![istarget i?86-*-*]) || ![is_lp64_target] } { | |
19 | return -1; | |
20 | } | |
21 | ||
22 | if {[skip_shlib_tests]} { | |
23 | return -1 | |
24 | } | |
25 | ||
26 | if { ![isnative] } { | |
27 | return -1 | |
28 | } | |
29 | ||
30 | if {[get_compiler_info]} { | |
31 | untested "could not get compiler info" | |
32 | return 1 | |
33 | } | |
34 | ||
5144dfba TV |
35 | |
36 | # Increase this to see more detail. | |
37 | set test_verbose 0 | |
38 | ||
2838cc1d SD |
39 | set jit_host_src $srcfile |
40 | set jit_host_bin $binfile | |
41 | ||
42 | # We inject the complete path to jit-reader.h into the source file | |
43 | # lest we end up (incorrectly) building against a system-installed | |
44 | # version. | |
45 | set jit_reader_header [standard_output_file "../../../../../gdb/jit-reader.h"] | |
46 | set jit_reader_flag "-DJIT_READER_H=\"$jit_reader_header\"" | |
47 | ||
48 | if { [gdb_compile "${srcdir}/${subdir}/${jit_host_src}" "${jit_host_bin}" \ | |
49 | executable [list debug additional_flags=$jit_reader_flag]] != "" } { | |
5b362f04 | 50 | untested "failed to compile" |
2838cc1d SD |
51 | return -1 |
52 | } | |
53 | ||
922a7c7c | 54 | set jit_reader jit-reader |
2838cc1d SD |
55 | set jit_reader_src ${jit_reader}.c |
56 | set jit_reader_bin [standard_output_file ${jit_reader}.so] | |
57 | ||
58 | if { [gdb_compile_shlib "${srcdir}/${subdir}/${jit_reader_src}" "${jit_reader_bin}" \ | |
59 | [list debug additional_flags=$jit_reader_flag]] != "" } { | |
5b362f04 | 60 | untested "failed to compile" |
2838cc1d SD |
61 | return -1 |
62 | } | |
63 | ||
20aa2c60 PA |
64 | # Test "info registers" in the current frame, expecting RSP's value to |
65 | # be SP. | |
66 | ||
67 | proc info_registers_current_frame {sp} { | |
68 | global hex decimal | |
69 | ||
70 | set any "\[^\r\n\]*" | |
71 | ||
b17fcc10 | 72 | set neg_decimal "-?$decimal" |
f49c464f MS |
73 | |
74 | set expected \ | |
20aa2c60 | 75 | [multi_line \ |
b17fcc10 TV |
76 | "rax $hex +$neg_decimal" \ |
77 | "rbx $hex +$neg_decimal" \ | |
78 | "rcx $hex +$neg_decimal" \ | |
79 | "rdx $hex +$neg_decimal" \ | |
80 | "rsi $hex +$neg_decimal" \ | |
81 | "rdi $hex +$neg_decimal" \ | |
6d72d289 SM |
82 | "rbp $hex +$hex" \ |
83 | "rsp $sp +$sp" \ | |
b17fcc10 TV |
84 | "r8 $hex +$neg_decimal" \ |
85 | "r9 $hex +$neg_decimal" \ | |
86 | "r10 $hex +$neg_decimal" \ | |
87 | "r11 $hex +$neg_decimal" \ | |
88 | "r12 $hex +$neg_decimal" \ | |
89 | "r13 $hex +$neg_decimal" \ | |
90 | "r14 $hex +$neg_decimal" \ | |
91 | "r15 $hex +$neg_decimal" \ | |
6d72d289 SM |
92 | "rip $hex +$hex$any" \ |
93 | "eflags $hex +\\\[$any\\\]" \ | |
b17fcc10 TV |
94 | "cs $hex +$neg_decimal" \ |
95 | "ss $hex +$neg_decimal" \ | |
96 | "ds $hex +$neg_decimal" \ | |
97 | "es $hex +$neg_decimal" \ | |
98 | "fs $hex +$neg_decimal" \ | |
99 | "gs $hex +$neg_decimal" \ | |
20aa2c60 | 100 | ] |
f49c464f MS |
101 | |
102 | # There may be more registers. | |
103 | append expected ".*" | |
104 | ||
105 | gdb_test "info registers" $expected | |
20aa2c60 PA |
106 | } |
107 | ||
2838cc1d SD |
108 | proc jit_reader_test {} { |
109 | global jit_host_bin | |
110 | global jit_reader_bin | |
5144dfba | 111 | global test_verbose |
20aa2c60 PA |
112 | global hex decimal |
113 | ||
114 | set any "\[^\r\n\]*" | |
2838cc1d SD |
115 | |
116 | clean_restart $jit_host_bin | |
117 | gdb_load_shlib $jit_reader_bin | |
118 | ||
5144dfba | 119 | if {$test_verbose > 0} { |
2838cc1d SD |
120 | gdb_test_no_output "set debug jit 1" |
121 | } | |
122 | ||
123 | gdb_test_no_output "jit-reader-load ${jit_reader_bin}" "jit-reader-load" | |
124 | gdb_run_cmd | |
125 | gdb_test "" "Program received signal SIGTRAP, .*" "expect SIGTRAP" | |
126 | ||
20aa2c60 PA |
127 | # Test the JIT reader unwinder. |
128 | with_test_prefix "with jit-reader" { | |
129 | ||
130 | with_test_prefix "before mangling" { | |
131 | gdb_test "bt" \ | |
132 | [multi_line \ | |
d043f8c8 | 133 | "#0 ${any} in jit_function_stack_mangle ${any}" \ |
20aa2c60 PA |
134 | "#1 ${any} in main ${any}" \ |
135 | ] \ | |
136 | "bt works" | |
137 | ||
138 | set sp_before_mangling \ | |
139 | [get_hexadecimal_valueof "\$sp" 0 "get sp"] | |
140 | ||
d043f8c8 | 141 | gdb_test "up" "#1 $any in main $any\r\n$any function_stack_mangle $any" \ |
20aa2c60 PA |
142 | "move up to caller" |
143 | ||
144 | set caller_sp \ | |
145 | [get_hexadecimal_valueof "\$sp" 0 "get caller sp"] | |
146 | } | |
147 | ||
148 | # Step over the instruction that mangles the stack pointer. | |
149 | # While that confuses GDB's built-in unwinder, the JIT | |
150 | # reader's unwinder understands the mangling and should thus | |
151 | # be able to unwind at that location. | |
152 | with_test_prefix "after mangling" { | |
d043f8c8 | 153 | gdb_test "si" "in jit_function_stack_mangle .*" "step over stack mangling" |
20aa2c60 PA |
154 | |
155 | set sp_after_mangling \ | |
156 | [get_hexadecimal_valueof "\$sp" 0 "get sp"] | |
157 | ||
158 | gdb_assert {$sp_before_mangling != $sp_after_mangling} \ | |
159 | "sp is mangled" | |
160 | ||
161 | # Check that the jit unwinder manages to backtrace through | |
162 | # the mangled stack pointer. | |
163 | gdb_test "bt" \ | |
164 | [multi_line \ | |
d043f8c8 | 165 | "#0 ${any} in jit_function_stack_mangle ${any}" \ |
20aa2c60 PA |
166 | "#1 ${any} in main ${any}" \ |
167 | ] \ | |
168 | "bt works" | |
169 | ||
170 | with_test_prefix "current frame" { | |
171 | info_registers_current_frame $sp_after_mangling | |
172 | ||
173 | gdb_test "info frame" \ | |
d043f8c8 | 174 | "Stack level 0, frame at $sp_before_mangling.*in jit_function_stack_mangle.*" |
20aa2c60 PA |
175 | } |
176 | ||
177 | with_test_prefix "caller frame" { | |
d043f8c8 | 178 | gdb_test "up" "#1 $any in main $any\r\n$any function_stack_mangle $any" \ |
20aa2c60 PA |
179 | "up to caller" |
180 | ||
181 | # Since the JIT unwinder only provides RIP/RSP/RBP, | |
182 | # all other registers should show as "<not saved>". | |
f49c464f MS |
183 | |
184 | set expected \ | |
20aa2c60 PA |
185 | [multi_line \ |
186 | "rax <not saved>" \ | |
187 | "rbx <not saved>" \ | |
188 | "rcx <not saved>" \ | |
189 | "rdx <not saved>" \ | |
190 | "rsi <not saved>" \ | |
191 | "rdi <not saved>" \ | |
6d72d289 SM |
192 | "rbp $hex +$hex" \ |
193 | "rsp $caller_sp +$caller_sp" \ | |
20aa2c60 PA |
194 | "r8 <not saved>" \ |
195 | "r9 <not saved>" \ | |
196 | "r10 <not saved>" \ | |
197 | "r11 <not saved>" \ | |
198 | "r12 <not saved>" \ | |
199 | "r13 <not saved>" \ | |
200 | "r14 <not saved>" \ | |
201 | "r15 <not saved>" \ | |
6d72d289 | 202 | "rip $hex +$hex $any" \ |
20aa2c60 PA |
203 | "eflags <not saved>" \ |
204 | "cs <not saved>" \ | |
205 | "ss <not saved>" \ | |
206 | "ds <not saved>" \ | |
207 | "es <not saved>" \ | |
208 | "fs <not saved>" \ | |
209 | "gs <not saved>" \ | |
210 | ] | |
211 | ||
f49c464f MS |
212 | # There may be more registers. |
213 | append expected ".*" | |
214 | ||
215 | gdb_test "info registers" $expected | |
216 | ||
20aa2c60 PA |
217 | # Make sure that "info frame" doesn't crash. |
218 | gdb_test "info frame" "Stack level 1, .*in main.*" | |
219 | ||
220 | # ... and that neither does printing a pseudo | |
221 | # register. | |
222 | gdb_test "print /x \$ebp" " = $hex" "print pseudo register" | |
223 | ||
224 | # There's no way for the JIT reader API to support | |
225 | # modifyiable values. | |
226 | gdb_test "print \$rbp = -1" \ | |
227 | "Attempt to assign to an unmodifiable value\." \ | |
228 | "cannot assign to register" | |
229 | } | |
230 | } | |
231 | } | |
232 | ||
233 | # Now unload the jit reader, and ensure that backtracing really | |
234 | # doesn't work without it. | |
235 | with_test_prefix "without jit-reader" { | |
236 | gdb_test_no_output "jit-reader-unload ${jit_reader_bin}" \ | |
237 | "jit-reader-unload" | |
238 | ||
239 | # Check that we're no longer using the JIT unwinder, and that | |
240 | # the built-in unwinder cannot backtrace through the mangled | |
241 | # stack pointer. | |
242 | gdb_test "bt" \ | |
243 | [multi_line \ | |
244 | "Backtrace stopped: Cannot access memory at address $sp_after_mangling" \ | |
245 | ] \ | |
246 | "bt shows error" | |
247 | ||
248 | gdb_test "info frame" "Cannot access memory at address.*" \ | |
249 | "info frame shows error" | |
250 | info_registers_current_frame $sp_after_mangling | |
251 | gdb_test "up" "Initial frame selected; you cannot go up\\." \ | |
252 | "cannot go up" | |
253 | } | |
254 | ||
255 | with_test_prefix "with jit-reader again" { | |
256 | gdb_test_no_output "jit-reader-load ${jit_reader_bin}" "jit-reader-load" | |
257 | ||
258 | # Check that the jit unwinder manages to backtrace through | |
259 | # the mangled stack pointer. | |
260 | gdb_test "bt" \ | |
261 | [multi_line \ | |
d043f8c8 | 262 | "#0 ${any} in jit_function_stack_mangle ${any}" \ |
20aa2c60 PA |
263 | "#1 ${any} in main ${any}" \ |
264 | ] | |
265 | } | |
2838cc1d SD |
266 | } |
267 | ||
268 | jit_reader_test |