Commit | Line | Data |
---|---|---|
b811d2c2 | 1 | # Copyright (C) 2016-2020 Free Software Foundation, Inc. |
f1b5deee PA |
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 | # This file is part of the gdb testsuite. | |
17 | ||
18 | # Test manually setting _all_ combinations of all supported bfd | |
19 | # architectures and OS ABIs. This ensures that gdbarch initialization | |
20 | # routines handle unusual combinations gracefully, at least without | |
21 | # crashing. | |
22 | ||
23 | # While at it, because the number of possible combinations is quite | |
24 | # large, embed other checks that might be useful to do with all | |
25 | # supported archs. | |
26 | ||
27 | # One such test is ensuring that printing float, double and long | |
28 | # double types works in cross/bi-arch scenarios. Some of GDB's float | |
29 | # format conversion routines used to fail to consider that even if | |
30 | # host and target floating formats match, their sizes may still | |
31 | # differ. E.g., on x86, long double is 80-bit extended precision on | |
32 | # both 32-bit vs 64-bit, but it's stored as 96 bit on 32-bit, and 128 | |
33 | # bit on 64-bit. This resulted in GDB accessing memory out of bounds. | |
34 | # This test catches the issue when run against gdb linked with | |
35 | # libmcheck, or run under Valgrind. | |
36 | ||
37 | # Note: this test is actually split in several driver .exp files, in | |
38 | # order to be able to parallelize the work. Each driver .exp file | |
39 | # exercises a different slice of the supported architectures. See | |
40 | # all-architectures-*.exp and the TEST_SLICE variable. | |
41 | ||
42 | clean_restart | |
43 | ||
44 | # By default, preparation steps don't output a PASS message. This is | |
45 | # because the testcase has several thousand such steps. | |
46 | set want_tests_messages 0 | |
47 | ||
48 | # Call this when an "internal" preparation-like step test passed. | |
49 | # Logs the pass in gdb.log, but not in gdb.sum. | |
50 | ||
51 | proc internal_pass {message} { | |
52 | global want_tests_messages | |
53 | ||
54 | if {$want_tests_messages} { | |
55 | pass $message | |
56 | } else { | |
57 | # Skip the sum file, but still log an internal pass in the log | |
58 | # file. | |
59 | global pf_prefix | |
60 | ||
61 | verbose -log "IPASS: $pf_prefix $message" | |
62 | } | |
63 | } | |
64 | ||
65 | # The number of times gdb_test_internal was called, and the number of | |
66 | # time that resulted in an internal pass. If these don't match, then | |
67 | # some test failed. | |
68 | set test_count 0 | |
69 | set internal_pass_count 0 | |
70 | ||
71 | # Like gdb_test, but calls internal_pass instead of pass, on success. | |
72 | ||
73 | proc gdb_test_internal {cmd pattern {message ""}} { | |
74 | global test_count internal_pass_count | |
75 | global gdb_prompt | |
76 | ||
77 | incr test_count | |
78 | ||
79 | if {$message == ""} { | |
80 | set message $cmd | |
81 | } | |
82 | ||
83 | gdb_test_multiple $cmd $message { | |
84 | -re "$pattern\r\n$gdb_prompt $" { | |
85 | internal_pass $message | |
86 | incr internal_pass_count | |
87 | } | |
88 | } | |
89 | } | |
90 | ||
91 | gdb_test_internal "set max-completions unlimited" \ | |
92 | "^set max-completions unlimited" | |
93 | ||
94 | # Return a list of all the accepted values of "set WHAT". | |
95 | ||
96 | proc get_set_option_choices {what} { | |
97 | global gdb_prompt | |
98 | ||
99 | set values {} | |
100 | ||
101 | set test "complete set $what" | |
102 | gdb_test_multiple "complete set $what " "$test" { | |
103 | -re "set $what (\[^\r\n\]+)\r\n" { | |
104 | lappend values $expect_out(1,string) | |
105 | exp_continue | |
106 | } | |
107 | -re "$gdb_prompt " { | |
108 | internal_pass $test | |
109 | } | |
110 | } | |
111 | return $values | |
112 | } | |
113 | ||
114 | set supported_archs [get_set_option_choices "architecture"] | |
115 | # There should be at least one more than "auto". | |
116 | gdb_assert {[llength $supported_archs] > 1} "at least one architecture" | |
117 | ||
118 | set supported_osabis [get_set_option_choices "osabi"] | |
119 | # There should be at least one more than "auto" and "default". | |
120 | gdb_assert {[llength $supported_osabis] > 2} "at least one osabi" | |
121 | ||
122 | if {[lsearch $supported_archs "mips"] >= 0} { | |
123 | set supported_mipsfpu [get_set_option_choices "mipsfpu"] | |
124 | set supported_mips_abi [get_set_option_choices "mips abi"] | |
125 | ||
126 | gdb_assert {[llength $supported_mipsfpu] != 0} "at least one mipsfpu" | |
127 | gdb_assert {[llength $supported_mips_abi] != 0} "at least one mips abi" | |
128 | } | |
129 | ||
130 | if {[lsearch $supported_archs "arm"] >= 0} { | |
131 | set supported_arm_fpu [get_set_option_choices "arm fpu"] | |
132 | set supported_arm_abi [get_set_option_choices "arm abi"] | |
133 | ||
134 | gdb_assert {[llength $supported_arm_fpu] != 0} "at least one arm fpu" | |
135 | gdb_assert {[llength $supported_arm_abi] != 0} "at least one arm abi" | |
136 | } | |
137 | ||
138 | # Exercise printing float, double and long double. | |
139 | ||
140 | proc print_floats {} { | |
141 | gdb_test_internal "ptype 1.0L" "type = long double" "ptype, long double" | |
142 | gdb_test_internal "print 1.0L" " = 1" "print, long double" | |
143 | ||
144 | gdb_test_internal "ptype 1.0" "type = double" "ptype, double" | |
145 | gdb_test_internal "print 1.0" " = 1" "print, double" | |
146 | ||
147 | gdb_test_internal "ptype 1.0f" "type = float" "ptype, float" | |
148 | gdb_test_internal "print 1.0f" " = 1" "print, float" | |
149 | } | |
150 | ||
151 | # Run tests on the current architecture. | |
152 | ||
153 | proc do_arch_tests {} { | |
154 | print_floats | |
d8b49cf0 YQ |
155 | |
156 | # GDB can't access memory because there is no loaded executable | |
157 | # nor live inferior. | |
158 | gdb_test_internal "disassemble 0x0,+4" \ | |
159 | "Cannot access memory at address 0x0" | |
f1b5deee PA |
160 | } |
161 | ||
162 | # Given we can't change arch, osabi, endianness, etc. atomically, we | |
163 | # need to silently ignore the case of the current OS ABI (not the one | |
164 | # we'll switch to) not having a handler for the arch. | |
165 | set osabi_warning \ | |
166 | [multi_line \ | |
167 | "warning: A handler for the OS ABI .* is not built into this configuration" \ | |
168 | "of GDB. Attempting to continue with the default .* settings." \ | |
169 | "" \ | |
170 | "" \ | |
171 | ] | |
172 | ||
173 | set endian_warning "(Little|Big) endian target not supported by GDB\r\n" | |
174 | ||
175 | # Like gdb_test_no_output, but use internal_pass instead of pass, and | |
176 | # ignore "no handler for OS ABI" warnings. | |
177 | ||
178 | proc gdb_test_no_output_osabi {cmd test} { | |
179 | global osabi_warning | |
180 | global gdb_prompt | |
181 | ||
182 | gdb_test_multiple "$cmd" $test { | |
183 | -re "^${cmd}\r\n(${osabi_warning})?$gdb_prompt $" { | |
184 | internal_pass $test | |
185 | } | |
186 | } | |
187 | } | |
188 | ||
189 | # It'd be nicer/safer to restart GDB on each iteration, but, that | |
190 | # increases the testcase's run time several times fold. At the time | |
191 | # of writting, it'd jump from 20s to 4min on x86-64 GNU/Linux with | |
192 | # --enable-targets=all. | |
193 | ||
194 | set num_slices 8 | |
195 | set num_archs [llength $supported_archs] | |
196 | set archs_per_slice [expr (($num_archs + $num_slices - 1) / $num_slices)] | |
197 | ||
198 | with_test_prefix "tests" { | |
199 | foreach_with_prefix osabi $supported_osabis { | |
200 | ||
201 | gdb_test_no_output_osabi "set osabi $osabi" \ | |
202 | "set osabi" | |
203 | ||
204 | set arch_count 0 | |
205 | foreach_with_prefix arch $supported_archs { | |
206 | ||
207 | incr arch_count | |
208 | ||
209 | # Skip architectures outside our slice. | |
210 | if {$arch_count < [expr $test_slice * $archs_per_slice]} { | |
211 | continue | |
212 | } | |
213 | if {$arch_count >= [expr ($test_slice + 1) * $archs_per_slice]} { | |
214 | continue | |
215 | } | |
216 | ||
f1b5deee PA |
217 | if {$arch == "auto"} { |
218 | continue | |
219 | } | |
220 | set default_endian "" | |
221 | foreach_with_prefix endian {"auto" "big" "little"} { | |
222 | ||
223 | set test "set endian" | |
224 | if {$endian == $default_endian} { | |
225 | continue | |
226 | } elseif {$endian == "auto"} { | |
227 | gdb_test_multiple "set endian $endian" $test { | |
f63dcaf8 | 228 | -re "^set endian $endian\r\n(${osabi_warning})?The target endianness is set automatically \\(currently .* endian\\)\\.\r\n$gdb_prompt $" { |
f1b5deee PA |
229 | internal_pass $test |
230 | } | |
231 | } | |
232 | } else { | |
233 | gdb_test_multiple "set endian $endian" $test { | |
234 | -re "^set endian $endian\r\n${endian_warning}.*\r\n$gdb_prompt $" { | |
235 | internal_pass $test | |
236 | continue | |
237 | } | |
f63dcaf8 | 238 | -re "^set endian $endian\r\n(${osabi_warning})?The target is set to $endian endian\\.\r\n$gdb_prompt $" { |
f1b5deee PA |
239 | internal_pass $test |
240 | } | |
241 | } | |
242 | } | |
243 | ||
244 | # Skip setting the same architecture again. | |
245 | if {$endian == "auto"} { | |
246 | set arch_re [string_to_regexp $arch] | |
247 | set test "set architecture $arch" | |
248 | gdb_test_multiple $test $test { | |
ccb9eba6 | 249 | -re "^set architecture $arch_re\r\n(${osabi_warning})?The target architecture is set to \"$arch_re\"\\.\r\n$gdb_prompt $" { |
f1b5deee PA |
250 | internal_pass $test |
251 | } | |
252 | -re "Architecture .* not recognized.*$gdb_prompt $" { | |
253 | # GDB is missing support for a few | |
254 | # machines that bfd supports. | |
255 | if {$arch == "powerpc:EC603e" | |
256 | || $arch == "powerpc:e500mc" | |
257 | || $arch == "powerpc:e500mc64" | |
258 | || $arch == "powerpc:vle" | |
259 | || $arch == "powerpc:titan" | |
260 | || $arch == "powerpc:e5500" | |
261 | || $arch == "powerpc:e6500"} { | |
262 | if {$want_tests_messages} { | |
263 | kfail $test "gdb/19797" | |
264 | } | |
265 | } else { | |
266 | fail "$test (arch not recognized)" | |
267 | } | |
268 | continue | |
269 | } | |
270 | } | |
271 | ||
272 | # Record what is the default endianess. As an | |
273 | # optimization, we'll skip testing the manual "set | |
274 | # endian DEFAULT" case. | |
275 | set test "show endian" | |
276 | gdb_test_multiple "show endian" $test { | |
277 | -re "currently little endian.*$gdb_prompt $" { | |
278 | set default_endian "little" | |
279 | internal_pass $test | |
280 | } | |
281 | -re "currently big endian.*$gdb_prompt $" { | |
282 | set default_endian "big" | |
283 | internal_pass $test | |
284 | } | |
285 | } | |
286 | } | |
287 | ||
288 | # Some architectures have extra settings that affect | |
289 | # the ABI. Specify the extra testing axes in a | |
290 | # declarative form. | |
291 | # | |
292 | # A list of {COMMAND, VAR, OPTIONS-LIST} elements. | |
293 | set all_axes {} | |
294 | ||
295 | if {$arch == "mips"} { | |
296 | lappend all_axes [list "set mips abi" mips_abi $supported_mips_abi] | |
297 | lappend all_axes [list "set mipsfpu" mipsfpu $supported_mipsfpu] | |
298 | } elseif {$arch == "arm"} { | |
299 | lappend all_axes [list "set arm abi" arm_abi $supported_arm_abi] | |
300 | lappend all_axes [list "set arm fpu" arm_fpu $supported_arm_fpu] | |
301 | } | |
302 | ||
303 | # Run testing axis CUR_AXIS. This is a recursive | |
304 | # procedure that tries all combinations of options of | |
305 | # all the testing axes. | |
306 | proc run_axis {all_axes cur_axis} { | |
307 | if {$cur_axis == [llength $all_axes]} { | |
308 | do_arch_tests | |
309 | return | |
310 | } | |
311 | ||
312 | # Unpack the axis. | |
313 | set axis [lindex $all_axes $cur_axis] | |
314 | set cmd [lindex $axis 0] | |
315 | set var [lindex $axis 1] | |
316 | set options [lindex $axis 2] | |
317 | ||
318 | foreach v $options { | |
319 | with_test_prefix "$var=$v" { | |
320 | gdb_test_no_output_osabi "$cmd $v" "$cmd" | |
321 | run_axis $all_axes [expr $cur_axis + 1] | |
322 | } | |
323 | } | |
324 | } | |
325 | ||
326 | run_axis $all_axes 0 | |
327 | } | |
328 | } | |
329 | } | |
330 | } | |
331 | ||
332 | # A test that: | |
333 | # | |
334 | # - ensures there's a PASS if all internal tests actually passed | |
335 | # | |
336 | # - ensures there's at least one test that is interpreted as a | |
337 | # regression (a matching PASS->FAIL) if some of the internal tests | |
338 | # failed, instead of looking like it could be a new FAIL that could | |
339 | # be ignored. | |
340 | # | |
341 | gdb_assert {$internal_pass_count == $test_count} "all passed" |