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