xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.base/jit-reader.exp (revision 33881f779a77dce6440bdc44610d94de75bebefe)
1# Copyright 2012-2017 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
16standard_testfile jithost.c
17
18if { (![istarget x86_64-*-*] && ![istarget i?86-*-*]) || ![is_lp64_target] } {
19    return -1;
20}
21
22if {[skip_shlib_tests]} {
23    return -1
24}
25
26if { ![isnative] } {
27    return -1
28}
29
30if {[get_compiler_info]} {
31    untested "could not get compiler info"
32    return 1
33}
34
35set jit_host_src $srcfile
36set 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.
41set jit_reader_header [standard_output_file "../../../../../gdb/jit-reader.h"]
42set jit_reader_flag "-DJIT_READER_H=\"$jit_reader_header\""
43
44if  { [gdb_compile "${srcdir}/${subdir}/${jit_host_src}" "${jit_host_bin}" \
45       executable  [list debug additional_flags=$jit_reader_flag]] != "" } {
46    untested "failed to compile"
47    return -1
48}
49
50set jit_reader jitreader
51set jit_reader_src ${jit_reader}.c
52set jit_reader_bin [standard_output_file ${jit_reader}.so]
53
54if { [gdb_compile_shlib "${srcdir}/${subdir}/${jit_reader_src}" "${jit_reader_bin}" \
55	  [list debug additional_flags=$jit_reader_flag]] != "" } {
56    untested "failed to compile"
57    return -1
58}
59
60# Test "info registers" in the current frame, expecting RSP's value to
61# be SP.
62
63proc 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
97proc jit_reader_test {} {
98    global jit_host_bin
99    global jit_reader_bin
100    global 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 {$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_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    }
249}
250
251jit_reader_test
252