aboutsummaryrefslogtreecommitdiff
path: root/libctf/testsuite/lib
diff options
context:
space:
mode:
Diffstat (limited to 'libctf/testsuite/lib')
-rw-r--r--libctf/testsuite/lib/ctf-lib.exp409
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
+}