mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-06 12:09:26 +08:00
f63dcaf808
This commit changes the output of 'show endian'. Here is a session before this commit: (gdb) show endian The target endianness is set automatically (currently little endian) (gdb) set endian big The target is assumed to be big endian (gdb) show endian The target is assumed to be big endian (gdb) After this commit the session now looks like this: (gdb) show endian The target endianness is set automatically (currently little endian). (gdb) set endian big The target is set to big endian. (gdb) show endian The target is set to big endian. (gdb) The changes are: 1. Each line ends with '.', and 2. After setting the endianness GDB is now a little more assertive; 'target is set to' not 'target is assumed to be', the user did just tell us after all!
342 lines
10 KiB
Tcl
342 lines
10 KiB
Tcl
# Copyright (C) 2016-2020 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 set to $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 set to \"$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"
|