diff options
Diffstat (limited to 'libctf/testsuite/lib')
-rw-r--r-- | libctf/testsuite/lib/ctf-lib.exp | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/libctf/testsuite/lib/ctf-lib.exp b/libctf/testsuite/lib/ctf-lib.exp new file mode 100644 index 0000000..796342b --- /dev/null +++ b/libctf/testsuite/lib/ctf-lib.exp @@ -0,0 +1,409 @@ +# Support routines for libctf testsuite. +# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# +# This file is part of the GNU Binutils. +# +# This file 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. + +proc load_common_lib { name } { + global srcdir + load_file $srcdir/../../binutils/testsuite/lib/$name +} + +load_common_lib binutils-common.exp + +proc run_native_host_cmd { command } { + global link_output + global ld + + verbose -log "$command" + set run_output "" + try { + set run_output [exec "sh" "-c" "$command" "2>@1"] + set status 0 + } trap CHILDSTATUS {results options} { + set status [lindex [dict get $options -errorcode] 2] + set run_output $results + } + regsub "\n$" $run_output "" run_output + if { [lindex $status 0] != 0 && [string match "" $run_output] } then { + append run_output "child process exited abnormally" + } + + if [string match "" $run_output] then { + return "" + } + + verbose -log "$run_output" + return "$run_output" +} + +proc run_host_cmd { prog command } { + global link_output + global gcc_B_opt + global gcc_ld_B_opt_tested + global ld + + if { ![is_remote host] && [which "$prog"] == 0 } then { + perror "$prog does not exist" + return 0 + } + + # If we are compiling with gcc, we want to add gcc_B_opt to flags. However, + # if $prog already has -B options, which might be the case when running gcc + # out of a build directory, we want our -B options to come first. + set gccexe $prog + set gccparm [string first " " $gccexe] + set gccflags "" + if { $gccparm > 0 } then { + set gccflags [string range $gccexe $gccparm end] + set gccexe [string range $gccexe 0 $gccparm] + set prog $gccexe + } + set gccexe [string replace $gccexe 0 [string last "/" $gccexe] ""] + if {[string match "*cc*" $gccexe] || [string match "*++*" $gccexe]} then { + set gccflags "$gcc_B_opt $gccflags" + if {![info exists gcc_ld_B_opt_tested]} { + set gcc_ld_B_opt_tested 1 + set ld_version_message [run_host_cmd "$ld" "--version"] + set gcc_ld_version_message [run_host_cmd "$prog" "$gccflags -Wl,--version"] + if {[string first $ld_version_message $gcc_ld_version_message] < 0} { + perror "************************************************************************" + perror "Your compiler driver ignores -B when choosing ld." + perror "You will not be testing the new ld in many of the following tests." + set gcc_ld_version [run_host_cmd "$prog" "$gccflags --print-prog-name=ld"] + if {![string match "" $gcc_ld_version] && ![string match "ld" $gcc_ld_version]} { + perror "It seems you will be testing $gcc_ld_version instead." + } + perror "************************************************************************" + } + } + } + + verbose -log "$prog $gccflags $command" + set status [remote_exec host [concat sh -c [list "$prog $gccflags $command 2>&1"]] "" "/dev/null" "libctf.tmp"] + remote_upload host "libctf.tmp" + set run_output [file_contents "libctf.tmp"] + regsub "\n$" $run_output "" run_output + if { [lindex $status 0] != 0 && [string match "" $run_output] } then { + append run_output "child process exited abnormally" + } + remote_file build delete libctf.tmp + remote_file host delete libctf.tmp + + if [string match "" $run_output] then { + return "" + } + + verbose -log "$run_output" + return "$run_output" +} + +proc run_host_cmd_yesno { prog command } { + global exec_output + global errcnt warncnt + + set exec_output [prune_warnings [run_host_cmd "$prog" "$command"]] + # Ignore error and warning. + set errcnt 0 + set warncnt 0 + if [string match "" $exec_output] then { + return 1; + } + return 0; +} + +# Return true if we can build a program with the compiler. +# On some targets, CC might be defined, but libraries and startup +# code might be missing or require special options that the ld test +# harness doesn't know about. + +proc check_compiler_available { } { + global compiler_available_saved + global CC + + if {![info exists compiler_available_saved]} { + if { [which $CC] == 0 } { + set compiler_available_saved 0 + return 0 + } + + set flags "" + if [board_info [target_info name] exists cflags] { + append flags " [board_info [target_info name] cflags]" + } + if [board_info [target_info name] exists ldflags] { + append flags " [board_info [target_info name] ldflags]" + } + + set basename "tmpdir/compiler[pid]" + set src ${basename}.c + set output ${basename}.out + set f [open $src "w"] + puts $f "int main (void)" + puts $f "{" + puts $f " return 0; " + puts $f "}" + close $f + if [is_remote host] { + set src [remote_download host $src] + } + set compiler_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"] + remote_file host delete $src + remote_file host delete $output + file delete $src + } + return $compiler_available_saved +} + +# Compile and link a C source file for execution on the host. +proc compile_link_one_host_cc { src output additional_args } { + global CC_FOR_HOST + global CFLAGS + + return [run_native_host_cmd "./libtool --quiet --tag=CC --mode=link $CC_FOR_HOST $CFLAGS $src -o $output $additional_args" ] +} + +# Compile a C source file, with the specified additional_flags. +proc compile_one_cc { src output additional_flags } { + global CC + global CFLAGS + + set flags "" + if [board_info [target_info name] exists cflags] { + append flags " [board_info [target_info name] cflags]" + } + if [board_info [target_info name] exists ldflags] { + append flags " [board_info [target_info name] ldflags]" + } + + if [is_remote host] { + set src [remote_download host $src] + } + return [run_host_cmd "$CC" "$flags $CFLAGS $additional_flags $src -o $output"] +} + +# run_lookup_test FILE +# +# Compile with the host compiler and link a .c file into a "lookup" binary, then +# compile and optionally link together a bunch of .s or .c files with CTF info +# and pass the name of the resulting binary to the "lookup" binary and check the +# output. (If none is specified, the binary is expected to generate its own CTF +# for testing purposes.) +# +# As with run_dump_test, this is all driven by a file (in this case, a .lk file) +# beginning with zero or more option lines, which specify the names of the +# lookup binary's source file, the source file(s) with CTF info to compile +# together, and whether to link them. The optional lines have the syntax: +# +# # OPTION: VALUE +# +# OPTION is the name of some option, like "name" or "lookup", and +# VALUE is OPTION's value. The valid options are described below. +# Whitespace is ignored everywhere, except within VALUE. The option +# list ends with the first line that doesn't match the above syntax. +# However, a line within the options that begins with a #, but doesn't +# have a recognizable option name followed by a colon, is considered a +# comment and entirely ignored. +# +# The interesting options are: +# +# name: TEST-NAME +# The name of this test, passed to DejaGNU's `pass' and `fail' +# commands. If omitted, this defaults to FILE, the root of the +# lookup .c file's name. +# +# lookup: SOURCE +# Compile the file SOURCE.c. If omitted, the lookup source defaults +# to FILE.c. +# +# source: SOURCE +# Assemble the file SOURCE.c and pass it to the LOOKUP program. +# +# link: +# If set, link the SOURCE together even if only one file is specified. +# +# link_flags: +# If set, extra flags to pass to the linker. +# +# xfail: GLOB|PROC ... +# This test is expected to fail on a specified list of targets. +# +# Each option may occur at most once unless otherwise mentioned. +# +# After the option lines come regexp lines. run_lookup_test calls +# regexp_diff to compare the output of the lookup program against the +# regexps in FILE.d. +# +proc run_lookup_test { name } { + global CC CFLAGS LIBS + global copyfile env runtests srcdir subdir verbose + + if ![runtest_file_p $runtests $name] then { + return + } + + if [string match "*/*" $name] { + set file $name + set name [file tail $name] + } else { + set file "$srcdir/$subdir/$name" + } + + set opt_array [slurp_options "${file}.lk"] + if { $opt_array == -1 } { + perror "error reading options from $file.lk" + unresolved $subdir/$name + return + } + set run_ld 0 + set opts(link) {} + set opts(link_flags) {} + set opts(lookup) {} + set opts(name) {} + set opts(source) {} + set opts(xfail) {} + + foreach i $opt_array { + set opt_name [lindex $i 0] + set opt_val [lindex $i 1] + if { $opt_name == "" } { + set in_extra 1 + continue + } + if ![info exists opts($opt_name)] { + perror "unknown option $opt_name in file $file.lk" + unresolved $subdir/$name + return + } + + set opts($opt_name) [concat $opts($opt_name) $opt_val] + } + + if { [llength $opts(lookup)] == 0 } { + set opts(lookup) "$file.c" + } else { + set opts(lookup) "[file dirname $file]/$opts(lookup)" + } + + if { [llength $opts(name)] == 0 } { + set opts(name) $opts(lookup) + } + + if { [llength $opts(link)] != 0 + || [llength $opts(source)] > 1 } { + set run_ld 1 + } + + set testname $opts(name) + if { $opts(name) == "" } { + set testname "$subdir/$name" + } + + # Compile and link the lookup program. + set comp_output [compile_link_one_host_cc $opts(lookup) "tmpdir/lookup" "libctf.la"] + + if { $comp_output != ""} { + send_log "compilation of lookup program $opts(lookup) failed with <$comp_output>" + perror "compilation of lookup program $opts(lookup) failed" + fail $testname + return 0 + } + + # Compile the inputs and posibly link them together. + + set lookup_output "" + if { [llength $opts(source)] > 0 } { + set lookup_flags "" + if { $run_ld } { + set lookup_output "tmpdir/out.so" + set lookup_flags "-gt -fPIC -shared $opts(link_flags)" + } else { + set lookup_output "tmpdir/out.o" + set lookup_flags "-gt -fPIC -c" + } + if [board_info [target_info name] exists cflags] { + append lookup_flags " [board_info [target_info name] cflags]" + } + if [board_info [target_info name] exists ldflags] { + append lookup_flags " [board_info [target_info name] ldflags]" + } + set src {} + foreach sfile $opts(source) { + if [is_remote host] { + lappend src [remote_download host [file join [file dirname $file] $sfile]] + } else { + lappend src [file join [file dirname $file] $sfile] + } + } + + set comp_output [run_host_cmd "$CC" "$CFLAGS $lookup_flags [concat $src] -o $lookup_output"] + + if { $comp_output != ""} { + send_log "compilation of CTF program [concat $src] failed with <$comp_output>" + fail $testname + return 0 + } + } + + # Time to setup xfailures. + foreach targ $opts(xfail) { + if [match_target $targ] { + setup_xfail "*-*-*" + break + } + } + + # Invoke the lookup program on the outputs. + + set results [run_host_cmd tmpdir/lookup $lookup_output] + + set f [open "tmpdir/lookup.out" "w"] + puts $f $results + close $f + + if { [regexp_diff "tmpdir/lookup.out" "${file}.lk"] } then { + fail $testname + if { $verbose == 2 } then { verbose "output is [file_contents tmpdir/lookup.out]" 2 } + return 0 + } + + pass $testname + return 0 +} + +# Returns true if the target compiler supports -gt +proc check_ctf_available { } { + global ctf_available_saved + + if {![info exists ctf_available_saved]} { + if { ![check_compiler_available] } { + set ctf_available_saved 0 + } else { + set basename "tmpdir/ctf_available[pid]" + set src ${basename}.c + set output ${basename}.o + set f [open $src "w"] + puts $f "int main() { return 0; }" + close $f + set ctf_available_saved [compile_one_cc $src $output "-gt -c"] + remote_file host delete $src + remote_file host delete $output + file delete $src + } + } + return $ctf_available_saved +} |