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