342 lines
10 KiB
Plaintext
342 lines
10 KiB
Plaintext
# Copyright (C) 2016-2018 Free Software Foundation, Inc.
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
# This file is part of the gdb testsuite.
|
|
|
|
# Test manually setting _all_ combinations of all supported bfd
|
|
# architectures and OS ABIs. This ensures that gdbarch initialization
|
|
# routines handle unusual combinations gracefully, at least without
|
|
# crashing.
|
|
|
|
# While at it, because the number of possible combinations is quite
|
|
# large, embed other checks that might be useful to do with all
|
|
# supported archs.
|
|
|
|
# One such test is ensuring that printing float, double and long
|
|
# double types works in cross/bi-arch scenarios. Some of GDB's float
|
|
# format conversion routines used to fail to consider that even if
|
|
# host and target floating formats match, their sizes may still
|
|
# differ. E.g., on x86, long double is 80-bit extended precision on
|
|
# both 32-bit vs 64-bit, but it's stored as 96 bit on 32-bit, and 128
|
|
# bit on 64-bit. This resulted in GDB accessing memory out of bounds.
|
|
# This test catches the issue when run against gdb linked with
|
|
# libmcheck, or run under Valgrind.
|
|
|
|
# Note: this test is actually split in several driver .exp files, in
|
|
# order to be able to parallelize the work. Each driver .exp file
|
|
# exercises a different slice of the supported architectures. See
|
|
# all-architectures-*.exp and the TEST_SLICE variable.
|
|
|
|
clean_restart
|
|
|
|
# By default, preparation steps don't output a PASS message. This is
|
|
# because the testcase has several thousand such steps.
|
|
set want_tests_messages 0
|
|
|
|
# Call this when an "internal" preparation-like step test passed.
|
|
# Logs the pass in gdb.log, but not in gdb.sum.
|
|
|
|
proc internal_pass {message} {
|
|
global want_tests_messages
|
|
|
|
if {$want_tests_messages} {
|
|
pass $message
|
|
} else {
|
|
# Skip the sum file, but still log an internal pass in the log
|
|
# file.
|
|
global pf_prefix
|
|
|
|
verbose -log "IPASS: $pf_prefix $message"
|
|
}
|
|
}
|
|
|
|
# The number of times gdb_test_internal was called, and the number of
|
|
# time that resulted in an internal pass. If these don't match, then
|
|
# some test failed.
|
|
set test_count 0
|
|
set internal_pass_count 0
|
|
|
|
# Like gdb_test, but calls internal_pass instead of pass, on success.
|
|
|
|
proc gdb_test_internal {cmd pattern {message ""}} {
|
|
global test_count internal_pass_count
|
|
global gdb_prompt
|
|
|
|
incr test_count
|
|
|
|
if {$message == ""} {
|
|
set message $cmd
|
|
}
|
|
|
|
gdb_test_multiple $cmd $message {
|
|
-re "$pattern\r\n$gdb_prompt $" {
|
|
internal_pass $message
|
|
incr internal_pass_count
|
|
}
|
|
}
|
|
}
|
|
|
|
gdb_test_internal "set max-completions unlimited" \
|
|
"^set max-completions unlimited"
|
|
|
|
# Return a list of all the accepted values of "set WHAT".
|
|
|
|
proc get_set_option_choices {what} {
|
|
global gdb_prompt
|
|
|
|
set values {}
|
|
|
|
set test "complete set $what"
|
|
gdb_test_multiple "complete set $what " "$test" {
|
|
-re "set $what (\[^\r\n\]+)\r\n" {
|
|
lappend values $expect_out(1,string)
|
|
exp_continue
|
|
}
|
|
-re "$gdb_prompt " {
|
|
internal_pass $test
|
|
}
|
|
}
|
|
return $values
|
|
}
|
|
|
|
set supported_archs [get_set_option_choices "architecture"]
|
|
# There should be at least one more than "auto".
|
|
gdb_assert {[llength $supported_archs] > 1} "at least one architecture"
|
|
|
|
set supported_osabis [get_set_option_choices "osabi"]
|
|
# There should be at least one more than "auto" and "default".
|
|
gdb_assert {[llength $supported_osabis] > 2} "at least one osabi"
|
|
|
|
if {[lsearch $supported_archs "mips"] >= 0} {
|
|
set supported_mipsfpu [get_set_option_choices "mipsfpu"]
|
|
set supported_mips_abi [get_set_option_choices "mips abi"]
|
|
|
|
gdb_assert {[llength $supported_mipsfpu] != 0} "at least one mipsfpu"
|
|
gdb_assert {[llength $supported_mips_abi] != 0} "at least one mips abi"
|
|
}
|
|
|
|
if {[lsearch $supported_archs "arm"] >= 0} {
|
|
set supported_arm_fpu [get_set_option_choices "arm fpu"]
|
|
set supported_arm_abi [get_set_option_choices "arm abi"]
|
|
|
|
gdb_assert {[llength $supported_arm_fpu] != 0} "at least one arm fpu"
|
|
gdb_assert {[llength $supported_arm_abi] != 0} "at least one arm abi"
|
|
}
|
|
|
|
# Exercise printing float, double and long double.
|
|
|
|
proc print_floats {} {
|
|
gdb_test_internal "ptype 1.0L" "type = long double" "ptype, long double"
|
|
gdb_test_internal "print 1.0L" " = 1" "print, long double"
|
|
|
|
gdb_test_internal "ptype 1.0" "type = double" "ptype, double"
|
|
gdb_test_internal "print 1.0" " = 1" "print, double"
|
|
|
|
gdb_test_internal "ptype 1.0f" "type = float" "ptype, float"
|
|
gdb_test_internal "print 1.0f" " = 1" "print, float"
|
|
}
|
|
|
|
# Run tests on the current architecture.
|
|
|
|
proc do_arch_tests {} {
|
|
print_floats
|
|
|
|
# GDB can't access memory because there is no loaded executable
|
|
# nor live inferior.
|
|
gdb_test_internal "disassemble 0x0,+4" \
|
|
"Cannot access memory at address 0x0"
|
|
}
|
|
|
|
# Given we can't change arch, osabi, endianness, etc. atomically, we
|
|
# need to silently ignore the case of the current OS ABI (not the one
|
|
# we'll switch to) not having a handler for the arch.
|
|
set osabi_warning \
|
|
[multi_line \
|
|
"warning: A handler for the OS ABI .* is not built into this configuration" \
|
|
"of GDB. Attempting to continue with the default .* settings." \
|
|
"" \
|
|
"" \
|
|
]
|
|
|
|
set endian_warning "(Little|Big) endian target not supported by GDB\r\n"
|
|
|
|
# Like gdb_test_no_output, but use internal_pass instead of pass, and
|
|
# ignore "no handler for OS ABI" warnings.
|
|
|
|
proc gdb_test_no_output_osabi {cmd test} {
|
|
global osabi_warning
|
|
global gdb_prompt
|
|
|
|
gdb_test_multiple "$cmd" $test {
|
|
-re "^${cmd}\r\n(${osabi_warning})?$gdb_prompt $" {
|
|
internal_pass $test
|
|
}
|
|
}
|
|
}
|
|
|
|
# It'd be nicer/safer to restart GDB on each iteration, but, that
|
|
# increases the testcase's run time several times fold. At the time
|
|
# of writting, it'd jump from 20s to 4min on x86-64 GNU/Linux with
|
|
# --enable-targets=all.
|
|
|
|
set num_slices 8
|
|
set num_archs [llength $supported_archs]
|
|
set archs_per_slice [expr (($num_archs + $num_slices - 1) / $num_slices)]
|
|
|
|
with_test_prefix "tests" {
|
|
foreach_with_prefix osabi $supported_osabis {
|
|
|
|
gdb_test_no_output_osabi "set osabi $osabi" \
|
|
"set osabi"
|
|
|
|
set arch_count 0
|
|
foreach_with_prefix arch $supported_archs {
|
|
|
|
incr arch_count
|
|
|
|
# Skip architectures outside our slice.
|
|
if {$arch_count < [expr $test_slice * $archs_per_slice]} {
|
|
continue
|
|
}
|
|
if {$arch_count >= [expr ($test_slice + 1) * $archs_per_slice]} {
|
|
continue
|
|
}
|
|
|
|
if {$arch == "auto"} {
|
|
continue
|
|
}
|
|
set default_endian ""
|
|
foreach_with_prefix endian {"auto" "big" "little"} {
|
|
|
|
set test "set endian"
|
|
if {$endian == $default_endian} {
|
|
continue
|
|
} elseif {$endian == "auto"} {
|
|
gdb_test_multiple "set endian $endian" $test {
|
|
-re "^set endian $endian\r\n(${osabi_warning})?The target endianness is set automatically \\(currently .* endian\\)\r\n$gdb_prompt $" {
|
|
internal_pass $test
|
|
}
|
|
}
|
|
} else {
|
|
gdb_test_multiple "set endian $endian" $test {
|
|
-re "^set endian $endian\r\n${endian_warning}.*\r\n$gdb_prompt $" {
|
|
internal_pass $test
|
|
continue
|
|
}
|
|
-re "^set endian $endian\r\n(${osabi_warning})?The target is assumed to be $endian endian\r\n$gdb_prompt $" {
|
|
internal_pass $test
|
|
}
|
|
}
|
|
}
|
|
|
|
# Skip setting the same architecture again.
|
|
if {$endian == "auto"} {
|
|
set arch_re [string_to_regexp $arch]
|
|
set test "set architecture $arch"
|
|
gdb_test_multiple $test $test {
|
|
-re "^set architecture $arch_re\r\n(${osabi_warning})?The target architecture is assumed to be $arch_re\r\n$gdb_prompt $" {
|
|
internal_pass $test
|
|
}
|
|
-re "Architecture .* not recognized.*$gdb_prompt $" {
|
|
# GDB is missing support for a few
|
|
# machines that bfd supports.
|
|
if {$arch == "powerpc:EC603e"
|
|
|| $arch == "powerpc:e500mc"
|
|
|| $arch == "powerpc:e500mc64"
|
|
|| $arch == "powerpc:vle"
|
|
|| $arch == "powerpc:titan"
|
|
|| $arch == "powerpc:e5500"
|
|
|| $arch == "powerpc:e6500"} {
|
|
if {$want_tests_messages} {
|
|
kfail $test "gdb/19797"
|
|
}
|
|
} else {
|
|
fail "$test (arch not recognized)"
|
|
}
|
|
continue
|
|
}
|
|
}
|
|
|
|
# Record what is the default endianess. As an
|
|
# optimization, we'll skip testing the manual "set
|
|
# endian DEFAULT" case.
|
|
set test "show endian"
|
|
gdb_test_multiple "show endian" $test {
|
|
-re "currently little endian.*$gdb_prompt $" {
|
|
set default_endian "little"
|
|
internal_pass $test
|
|
}
|
|
-re "currently big endian.*$gdb_prompt $" {
|
|
set default_endian "big"
|
|
internal_pass $test
|
|
}
|
|
}
|
|
}
|
|
|
|
# Some architectures have extra settings that affect
|
|
# the ABI. Specify the extra testing axes in a
|
|
# declarative form.
|
|
#
|
|
# A list of {COMMAND, VAR, OPTIONS-LIST} elements.
|
|
set all_axes {}
|
|
|
|
if {$arch == "mips"} {
|
|
lappend all_axes [list "set mips abi" mips_abi $supported_mips_abi]
|
|
lappend all_axes [list "set mipsfpu" mipsfpu $supported_mipsfpu]
|
|
} elseif {$arch == "arm"} {
|
|
lappend all_axes [list "set arm abi" arm_abi $supported_arm_abi]
|
|
lappend all_axes [list "set arm fpu" arm_fpu $supported_arm_fpu]
|
|
}
|
|
|
|
# Run testing axis CUR_AXIS. This is a recursive
|
|
# procedure that tries all combinations of options of
|
|
# all the testing axes.
|
|
proc run_axis {all_axes cur_axis} {
|
|
if {$cur_axis == [llength $all_axes]} {
|
|
do_arch_tests
|
|
return
|
|
}
|
|
|
|
# Unpack the axis.
|
|
set axis [lindex $all_axes $cur_axis]
|
|
set cmd [lindex $axis 0]
|
|
set var [lindex $axis 1]
|
|
set options [lindex $axis 2]
|
|
|
|
foreach v $options {
|
|
with_test_prefix "$var=$v" {
|
|
gdb_test_no_output_osabi "$cmd $v" "$cmd"
|
|
run_axis $all_axes [expr $cur_axis + 1]
|
|
}
|
|
}
|
|
}
|
|
|
|
run_axis $all_axes 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# A test that:
|
|
#
|
|
# - ensures there's a PASS if all internal tests actually passed
|
|
#
|
|
# - ensures there's at least one test that is interpreted as a
|
|
# regression (a matching PASS->FAIL) if some of the internal tests
|
|
# failed, instead of looking like it could be a new FAIL that could
|
|
# be ignored.
|
|
#
|
|
gdb_assert {$internal_pass_count == $test_count} "all passed"
|