]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/testsuite/gdb.base/jit-reader.exp
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.base / jit-reader.exp
1 # Copyright 2012-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 # Optionally test a Python API here as well.
17 load_lib gdb-python.exp
18
19 standard_testfile jit-reader-host.c
20
21 require {is_any_target "i?86-*-*" "x86_64-*-*"} is_lp64_target
22
23 require allow_shlib_tests isnative
24
25 # Increase this to see more detail.
26 set test_verbose 0
27
28 set jit_host_src $srcfile
29 set jit_host_bin $binfile
30
31 # We inject the complete path to jit-reader.h into the source file
32 # lest we end up (incorrectly) building against a system-installed
33 # version.
34 set jit_reader_header [standard_output_file "../../../../../gdb/jit-reader.h"]
35 set jit_reader_flag "-DJIT_READER_H=\"$jit_reader_header\""
36
37 if { [gdb_compile "${srcdir}/${subdir}/${jit_host_src}" "${jit_host_bin}" \
38 executable [list debug additional_flags=$jit_reader_flag]] != "" } {
39 untested "failed to compile"
40 return -1
41 }
42
43 set jit_reader jit-reader
44 set jit_reader_src ${jit_reader}.c
45 set jit_reader_bin [standard_output_file ${jit_reader}.so]
46
47 if { [gdb_compile_shlib "${srcdir}/${subdir}/${jit_reader_src}" "${jit_reader_bin}" \
48 [list debug additional_flags=$jit_reader_flag]] != "" } {
49 untested "failed to compile"
50 return -1
51 }
52
53 # Test "info registers" in the current frame, expecting RSP's value to
54 # be SP.
55
56 proc info_registers_current_frame {sp} {
57 global hex decimal
58
59 set any "\[^\r\n\]*"
60
61 set neg_decimal "-?$decimal"
62
63 set expected \
64 [multi_line \
65 "rax $hex +$neg_decimal" \
66 "rbx $hex +$neg_decimal" \
67 "rcx $hex +$neg_decimal" \
68 "rdx $hex +$neg_decimal" \
69 "rsi $hex +$neg_decimal" \
70 "rdi $hex +$neg_decimal" \
71 "rbp $hex +$hex" \
72 "rsp $sp +$sp" \
73 "r8 $hex +$neg_decimal" \
74 "r9 $hex +$neg_decimal" \
75 "r10 $hex +$neg_decimal" \
76 "r11 $hex +$neg_decimal" \
77 "r12 $hex +$neg_decimal" \
78 "r13 $hex +$neg_decimal" \
79 "r14 $hex +$neg_decimal" \
80 "r15 $hex +$neg_decimal" \
81 "rip $hex +$hex$any" \
82 "eflags $hex +\\\[$any\\\]" \
83 "cs $hex +$neg_decimal" \
84 "ss $hex +$neg_decimal" \
85 "ds $hex +$neg_decimal" \
86 "es $hex +$neg_decimal" \
87 "fs $hex +$neg_decimal" \
88 "gs $hex +$neg_decimal" \
89 ]
90
91 # There may be more registers.
92 append expected ".*"
93
94 gdb_test "info registers" $expected
95 }
96
97 proc jit_reader_test {} {
98 global jit_host_bin
99 global jit_reader_bin
100 global test_verbose
101 global hex decimal
102
103 set any "\[^\r\n\]*"
104
105 clean_restart $jit_host_bin
106 gdb_load_shlib $jit_reader_bin
107
108 if {$test_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
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_stack_mangle ${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_stack_mangle $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_stack_mangle .*" "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_stack_mangle ${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_stack_mangle.*"
164 }
165
166 with_test_prefix "caller frame" {
167 gdb_test "up" "#1 $any in main $any\r\n$any function_stack_mangle $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
173 set expected \
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>" \
181 "rbp $hex +$hex" \
182 "rsp $caller_sp +$caller_sp" \
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>" \
191 "rip $hex +$hex $any" \
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 # There may be more registers.
202 append expected ".*"
203
204 gdb_test "info registers" $expected
205
206 # Make sure that "info frame" doesn't crash.
207 gdb_test "info frame" "Stack level 1, .*in main.*"
208
209 # ... and that neither does printing a pseudo
210 # register.
211 gdb_test "print /x \$ebp" " = $hex" "print pseudo register"
212
213 # There's no way for the JIT reader API to support
214 # modifyiable values.
215 gdb_test "print \$rbp = -1" \
216 "Attempt to assign to an unmodifiable value\." \
217 "cannot assign to register"
218 }
219
220 if { [allow_python_tests] } {
221 gdb_test "python print(gdb.objfiles())" \
222 "$any<gdb.Objfile filename=<< JIT compiled code at $hex >>>$any" \
223 "python gdb.Objfile.__repr__ ()"
224
225 gdb_test "python print(list(map(lambda objf : objf.filename, gdb.objfiles())))" \
226 "$any'<< JIT compiled code at $hex >>'$any" \
227 "python gdb.Objfile.filename"
228
229 gdb_test "python print( \[o for o in gdb.objfiles() if o.filename.startswith('<< JIT compiled code')\]\[0\].build_id )" \
230 "None" \
231 "python gdb.Objfile.build_id"
232 }
233 }
234 }
235
236 # Now unload the jit reader, and ensure that backtracing really
237 # doesn't work without it.
238 with_test_prefix "without jit-reader" {
239 gdb_test_no_output "jit-reader-unload ${jit_reader_bin}" \
240 "jit-reader-unload"
241
242 # Check that we're no longer using the JIT unwinder, and that
243 # the built-in unwinder cannot backtrace through the mangled
244 # stack pointer.
245 gdb_test "bt" \
246 "Backtrace stopped: Cannot access memory at address $sp_after_mangling" \
247 "bt shows error"
248
249 gdb_test "info frame" "Cannot access memory at address.*" \
250 "info frame shows error"
251 info_registers_current_frame $sp_after_mangling
252 gdb_test "up" "Initial frame selected; you cannot go up\\." \
253 "cannot go up"
254 }
255
256 with_test_prefix "with jit-reader again" {
257 gdb_test_no_output "jit-reader-load ${jit_reader_bin}" "jit-reader-load"
258
259 # Check that the jit unwinder manages to backtrace through
260 # the mangled stack pointer.
261 gdb_test "bt" \
262 [multi_line \
263 "#0 ${any} in jit_function_stack_mangle ${any}" \
264 "#1 ${any} in main ${any}" \
265 ]
266 }
267
268 if {[allow_python_tests]} {
269 gdb_test "python print(any(\[not x.is_file for x in gdb.objfiles()\]))" \
270 "True" \
271 "at least one non-file objfile"
272 gdb_test "python print(any(\[x.is_file for x in gdb.objfiles()\]))" \
273 "True" \
274 "at least one file-based objfile"
275 }
276
277 with_test_prefix "test dwarf unwinder" {
278 # Check that the DWARF unwinder does not crash in presence of
279 # JIT objfiles.
280 gdb_test "up"
281 gdb_breakpoint "*function_add" temporary
282 gdb_test "cont" ".*Temporary breakpoint ${any} in jit_function_add .*"
283 gdb_test "bt" \
284 [multi_line \
285 "#0 ${any} in jit_function_add ${any}" \
286 "#1 ${any} in main ${any}" \
287 ]
288 }
289 }
290
291 jit_reader_test