binutils-gdb/ld/testsuite/ld-elfweak/elfweak.exp
Sandra Loosemore 44ed80923a Use better test for usable compiler in ld testsuite.
The ld testsuite includes numerous tests that depend on being able to
compile and link programs with the C compiler.  Some of these tests
use [which $CC] to check for the presence of the compiler before
proceeding with the test, but run_ld_link_exec_tests and run_cc_link_tests
give ERRORs if compilation fails.  Also, even if $CC is defined and present,
it may not be usable due to missing libraries, etc.

This patch adds a new procedure check_compiler_available that attempts
to build an empty program and caches the result.  Uses of [which $CC]
are replaced with calls to this procedure, and run_ld_link_exec_tests
and run_cc_link_tests now also guard attempts to use $CC.

2019-04-24  Sandra Loosemore  <sandra@codesourcery.com>

	ld/
	* testsuite/config/default.exp: Use [check_compiler_available]
	instead of [which $CC].
	* testsuite/ld-auto-import/auto-import.exp: Likewise.
	* testsuite/ld-cygwin/exe-export.exp: Likewise.
	* testsuite/ld-elf/audit.exp: Likewise.
	* testsuite/ld-elf/compress.exp: Likewise.
	* testsuite/ld-elf/dwarf.exp: Likewise.
	* testsuite/ld-elf/elf.exp: Likewise.
	* testsuite/ld-elf/indirect.exp: Likewise.
	* testsuite/ld-elf/linux-x86.exp: Likewise.
	* testsuite/ld-elf/shared.exp: Likewise.
	* testsuite/ld-elf/tls.exp: Likewise.
	* testsuite/ld-elf/wrap.exp: Likewise.
	* testsuite/ld-elfcomm/elfcomm.exp: Likewise.
	* testsuite/ld-elfvers/vers.exp: Likewise.
	* testsuite/ld-elfvsb/elfvsb.exp: Likewise.
	* testsuite/ld-elfweak/elfweak.exp: Likewise.
	* testsuite/ld-gc/gc.exp: Likewise.
	* testsuite/ld-i386/i386.exp: Likewise.
	* testsuite/ld-i386/no-plt.exp: Likewise.
	* testsuite/ld-i386/tls.exp: Likewise.
	* testsuite/ld-ifunc/ifunc.exp: Likewise.
	* testsuite/ld-mn10300/mn10300.exp: Likewise.
	* testsuite/ld-pe/pe-compile.exp: Likewise.
	* testsuite/ld-pe/pe-run.exp: Likewise.
	* testsuite/ld-pe/pe-run2.exp: Likewise.
	* testsuite/ld-pie/pie.exp: Likewise.
	* testsuite/ld-plugin/lto.exp: Likewise.
	* testsuite/ld-plugin/plugin.exp: Likewise.
	* testsuite/ld-scripts/crossref.exp: Likewise.
	* testsuite/ld-sh/sh.exp: Likewise.
	* testsuite/ld-shared/shared.exp: Likewise.
	* testsuite/ld-size/size.exp: Likewise.
	* testsuite/ld-srec/srec.exp: Likewise.
	* testsuite/ld-undefined/undefined.exp: Likewise.
	* testsuite/ld-unique/unique.exp: Likewise.
	* testsuite/ld-x86-64/mpx.exp: Likewise.
	* testsuite/ld-x86-64/no-plt.exp: Likewise.
	* testsuite/ld-x86-64/tls.exp: Likewise.
	* testsuite/ld-x86-64/x86-64.exp: Likewise.
	* testsuite/lib/ld-lib.exp (run_ld_link_exec_tests): Call
	check_compiler_available before trying to use the compiler.
	(run_cc_link_tests): Likewise.
	(check_compiler_available): New.  Use it instead of [which $CC].
2019-04-24 12:14:56 -07:00

449 lines
14 KiB
Plaintext

# Expect script for ld-weak tests
# Copyright (C) 2001-2019 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
# MA 02110-1301, USA.
#
# Written by H.J. Lu (hjl@gnu.org)
# Eric Youngdale (eric@andante.jic.com)
#
# Check to see if the C compiler works
if { ![check_compiler_available] } {
return
}
# This test can only be run on a couple of ELF platforms.
# Square bracket expressions seem to confuse istarget.
# This is similar to the test that is used in ld-shared, BTW.
if { ![istarget alpha*-*-linux*]
&& ![istarget arm*-*-linux*]
&& ![istarget hppa*64*-*-hpux*]
&& ![istarget hppa*-*-linux*]
&& ![istarget i?86-*-sysv4*]
&& ![istarget i?86-*-unixware]
&& ![istarget i?86-*-elf*]
&& ![istarget i?86-*-linux*]
&& ![istarget i?86-*-gnu*]
&& ![istarget ia64-*-elf*]
&& ![istarget ia64-*-linux*]
&& ![istarget m68k-*-linux*]
&& ![istarget mips*-*-irix5*]
&& ![istarget mips*-*-linux*]
&& ![istarget powerpc*-*-elf*]
&& ![istarget powerpc*-*-linux*]
&& ![istarget powerpc*-*-sysv4*]
&& ![istarget sh\[34\]*-*-linux*]
&& ![istarget sparc*-*-elf]
&& ![istarget sparc*-*-solaris2*]
&& ![istarget sparc*-*-linux*]
&& ![istarget x86_64-*-linux*]
&& ![istarget *-*-nacl*] } {
return
}
if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
return
}
set diff diff
set tmpdir tmpdir
set DOBJDUMP_FLAGS --dynamic-syms
set SOBJDUMP_FLAGS --syms
set shared "--shared -Wl,--no-as-needed"
#
# objdump_symstuff
# Dump non-dynamic symbol stuff and make sure that it is sane.
#
proc objdump_symstuff { objdump object expectfile } {
global SOBJDUMP_FLAGS
global version_output
global diff
global tmpdir
if ![info exists SOBJDUMP_FLAGS] { set SOBJDUMP_FLAGS "" }
set cmd "$objdump $SOBJDUMP_FLAGS $object | sed -n {s/^\\(\[0-9a-f\]* *\\)\\(\[gw\]\\)\\( *\\)\\(\[FO\]\\)/\\1\\2\\4\\3/;/foo$/p} > $tmpdir/objdump.out"
verbose -log $cmd
catch "exec $cmd" exec_output
set exec_output [prune_warnings $exec_output]
if [string match "" $exec_output] then {
# Now do a line-by-line comparison to effectively diff the darned things
# The stuff coming from the expectfile is actually a regex, so we can
# skip over the actual addresses and so forth. This is currently very
# simpleminded - it expects a one-to-one correspondence in terms of line
# numbers.
if [file exists $expectfile] then {
set file_a [open $expectfile r]
} else {
perror "$expectfile doesn't exist"
return 0
}
if [file exists $tmpdir/objdump.out] then {
set file_b [open $tmpdir/objdump.out r]
} else {
perror "$tmpdir/objdump.out doesn't exist"
return 0
}
verbose "# Diff'ing: $expectfile $tmpdir/objdump.out" 2
set eof -1
set differences 0
while { [gets $file_a line] != $eof } {
if [regexp "^#.*$" $line] then {
continue
} else {
lappend list_a $line
}
}
close $file_a
while { [gets $file_b line] != $eof } {
if [regexp {\.text.* \.[^ ]*$} $line] then {
# Discard defined powerpc64 dot-symbols
continue
} else {
lappend list_b $line
}
}
close $file_b
for { set i 0 } { $i < [llength $list_a] } { incr i } {
set line_a [lindex $list_a $i]
set line_b [lindex $list_b $i]
verbose "\t$expectfile: $i: $line_a" 3
verbose "\t/tmp/objdump.out: $i: $line_b" 3
if [regexp $line_a $line_b] then {
continue
} else {
verbose -log "\t$expectfile: $i: $line_a"
verbose -log "\t$tmpdir/objdump.out: $i: $line_b"
return 0
}
}
if { [llength $list_a] != [llength $list_b] } {
verbose -log "Line count"
return 0
}
if $differences<1 then {
return 1
}
return 0
} else {
verbose -log "$exec_output"
return 0
}
}
#
# objdump_dymsymstuff
# Dump dynamic symbol stuff and make sure that it is sane.
#
proc objdump_dynsymstuff { objdump object expectfile } {
global DOBJDUMP_FLAGS
global version_output
global diff
global tmpdir
if ![info exists DOBJDUMP_FLAGS] { set DOBJDUMP_FLAGS "" }
set cmd "$objdump $DOBJDUMP_FLAGS $object | grep foo$ > $tmpdir/objdump.out"
verbose -log $cmd
catch "exec $cmd" exec_output
set exec_output [prune_warnings $exec_output]
if [string match "" $exec_output] then {
# Now do a line-by-line comparison to effectively diff the darned things
# The stuff coming from the expectfile is actually a regex, so we can
# skip over the actual addresses and so forth. This is currently very
# simpleminded - it expects a one-to-one correspondence in terms of line
# numbers.
if [file exists $expectfile] then {
set file_a [open $expectfile r]
} else {
warning "$expectfile doesn't exist"
return 0
}
if [file exists $tmpdir/objdump.out] then {
set file_b [open $tmpdir/objdump.out r]
} else {
fail "$tmpdir/objdump.out doesn't exist"
return 0
}
verbose "# Diff'ing: $expectfile $tmpdir/objdump.out" 2
set eof -1
set differences 0
while { [gets $file_a line] != $eof } {
if [regexp "^#.*$" $line] then {
continue
} else {
lappend list_a $line
}
}
close $file_a
while { [gets $file_b line] != $eof } {
if [regexp {\.text.* \.[^ ]*$} $line] then {
# Discard defined powerpc64 dot-symbols
continue
} else {
lappend list_b $line
}
}
close $file_b
for { set i 0 } { $i < [llength $list_b] } { incr i } {
set line_b [lindex $list_b $i]
# The tests are rigged so that we should never export a symbol with the
# word 'hide' in it. Thus we just search for it, and bail if we find it.
if [regexp "hide" $line_b] then {
verbose -log "\t$tmpdir/objdump.out: $i: $line_b"
return 0
}
verbose "\t$expectfile: $i: $line_b" 3
# We can't assume that the sort is consistent across
# systems, so we must check each regexp. When we find a
# regexp, we null it out, so we don't match it twice.
for { set j 0 } { $j < [llength $list_a] } { incr j } {
set line_a [lindex $list_a $j]
if [regexp $line_a $line_b] then {
lreplace $list_a $j $j "CAN NOT MATCH"
break
}
}
if { $j >= [llength $list_a] } {
verbose -log "\t$tmpdir/objdump.out: $i: $line_b"
return 0
}
}
if { [llength $list_a] != [llength $list_b] } {
verbose -log "Line count"
return 0
}
if $differences<1 then {
return 1
}
return 0
} else {
verbose -log "$exec_output"
return 0
}
}
proc build_lib {test libname objs dynsymexp} {
global CC
global objdump
global tmpdir
global shared
global srcdir
global subdir
set files ""
foreach obj $objs {
set files "$files $tmpdir/$obj"
}
if {![ld_link $CC $tmpdir/$libname.so "$shared $files"]} {
fail $test
return
}
if {![string match "" $dynsymexp]
&& ![objdump_dynsymstuff $objdump $tmpdir/$libname.so $srcdir/$subdir/$dynsymexp]} {
fail $test
return
}
pass $test
}
proc build_exec { test execname objs flags dat dynsymexp symexp} {
global CC
global objdump
global tmpdir
global srcdir
global subdir
global exec_output
set files ""
foreach obj $objs {
set files "$files $tmpdir/$obj"
}
if {![ld_link $CC $tmpdir/$execname "$flags $files"]} {
fail "$test"
return
}
if {![string match "" $dynsymexp]} then {
if {![objdump_dynsymstuff $objdump $tmpdir/$execname $srcdir/$subdir/$dynsymexp]} {
fail $test
return
}
}
if {![string match "" $symexp]} then {
if {![objdump_symstuff $objdump $tmpdir/$execname $srcdir/$subdir/$symexp]} {
fail $test
return
}
}
if ![isnative] {
unsupported $test
return
}
# Run the resulting program
send_log "$tmpdir/$execname >$tmpdir/$execname.out\n"
verbose "$tmpdir/$execname >$tmpdir/$execname.out"
catch "exec $tmpdir/$execname >$tmpdir/$execname.out" exec_output
if ![string match "" $exec_output] then {
send_log "$exec_output\n"
verbose "$exec_output"
fail $test
return
}
send_log "diff $tmpdir/$execname.out $srcdir/$subdir/$dat.dat\n"
verbose "diff $tmpdir/$execname.out $srcdir/$subdir/$dat.dat"
catch "exec diff $tmpdir/$execname.out $srcdir/$subdir/$dat.dat" exec_output
set exec_output [prune_warnings $exec_output]
if {![string match "" $exec_output]} then {
send_log "$exec_output\n"
verbose "$exec_output"
fail $test
return
}
pass $test
}
# Old version of GCC for MIPS default to enabling -fpic
# and get confused if it is used on the command line.
if { [istarget mips*-*-*] && ! [at_least_gcc_version 4 3] } then {
set picflag ""
} else {
# Unfortunately, the gcc argument is -fpic and the cc argument is
# -KPIC. We have to try both.
set picflag "-fpic"
send_log "$CC $picflag\n"
verbose "$CC $picflag"
catch "exec $CC $picflag" exec_output
send_log "$exec_output\n"
verbose "--" "$exec_output"
if { [string match "*illegal option*" $exec_output]
|| [string match "*option ignored*" $exec_output]
|| [string match "*unrecognized option*" $exec_output]
|| [string match "*passed to ld*" $exec_output] } {
set picflag "-KPIC"
}
}
verbose "Using $picflag to compile PIC code"
if {![ld_compile "$CC $CFLAGS $picflag" $srcdir/$subdir/foo.c $tmpdir/foo.o]
|| ![ld_compile "$CC $CFLAGS $picflag" $srcdir/$subdir/bar.c $tmpdir/bar.o]
|| ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/main.c $tmpdir/main.o]
|| ![ld_link $CC $tmpdir/libbar.so "$shared $tmpdir/bar.o"]
|| ![ld_compile "$CC $CFLAGS $picflag" $srcdir/$subdir/foo1a.c $tmpdir/foo1a.o]
|| ![ld_compile "$CC $CFLAGS $picflag" $srcdir/$subdir/foo1b.c $tmpdir/foo1b.o]
|| ![ld_compile "$CC $CFLAGS $picflag" $srcdir/$subdir/bar1a.c $tmpdir/bar1a.o]
|| ![ld_compile "$CC $CFLAGS $picflag" $srcdir/$subdir/bar1b.c $tmpdir/bar1b.o]
|| ![ld_compile "$CC $CFLAGS $picflag" $srcdir/$subdir/bar1c.c $tmpdir/bar1c.o]
|| ![ld_compile "$CC $CFLAGS $picflag" $srcdir/$subdir/main1.c $tmpdir/main1.o]
|| ![ld_link $CC $tmpdir/libfoo1a.so "$shared $tmpdir/foo1a.o"]
|| ![ld_link $CC $tmpdir/libfoo1b.so "$shared $tmpdir/foo1b.o"]
|| ![ld_link $CC $tmpdir/libbar1a.so "$shared $tmpdir/bar1a.o $tmpdir/libfoo1a.so"]} then {
fail "ELF weak"
} else {
build_lib "ELF DSO weak func first" libfoo "foo.o bar.o" dso.dsym
build_lib "ELF DSO weak func last" libfoo "bar.o foo.o" dso.dsym
build_lib "ELF DSO weak func first DSO" libfoo "foo.o libbar.so" dsow.dsym
build_lib "ELF DSO weak func last DSO" libfoo "libbar.so foo.o" dsow.dsym
build_exec "ELF weak func first" foo "main.o bar.o" "" strong "" strong.sym
build_exec "ELF weak func last" foo "bar.o main.o" "" strong "" strong.sym
build_exec "ELF weak func first DSO" foo "main.o libbar.so" "-Wl,-rpath,.,--no-as-needed" weak weak.dsym ""
build_exec "ELF weak func last DSO" foo "libbar.so main.o" "-Wl,-rpath,.,--no-as-needed" weak weak.dsym ""
build_lib "ELF DSO weak data first" libfoo "bar1a.o foo1a.o" dsodata.dsym
build_lib "ELF DSO weak data last" libfoo "foo1a.o bar1a.o" dsodata.dsym
build_lib "ELF DSO weak data first DSO" libfoo "main1.o libfoo1a.so" dsowdata.dsym
build_lib "ELF DSO weak data last DSO" libfoo "libfoo1a.so main1.o" dsowdata.dsym
build_lib "ELF DSO weak data first DSO common" libfoo "main1.o libfoo1b.so" dsowdata.dsym
build_lib "ELF DSO weak data last DSO common" libfoo "libfoo1b.so main1.o" dsowdata.dsym
build_exec "ELF weak data first" foo "main1.o bar1a.o foo1a.o" "" strongdata "" strongdata.sym
build_exec "ELF weak data last" foo "foo1a.o main1.o bar1a.o" "" strongdata "" strongdata.sym
build_exec "ELF weak data first common" foo "main1.o bar1a.o foo1b.o" "" strongdata "" strongcomm.sym
build_exec "ELF weak data last common" foo "foo1b.o main1.o bar1a.o" "" strongdata "" strongcomm.sym
build_exec "ELF weak data first DSO" foo "main1.o libbar1a.so libfoo1a.so" "-Wl,-rpath,.,--no-as-needed" weakdata weakdata.dsym ""
build_exec "ELF weak data last DSO" foo "libfoo1a.so main1.o libbar1a.so" "-Wl,-rpath,.,--no-as-needed" weakdata weakdata.dsym ""
build_exec "ELF weak data first DSO common" foo "main1.o libbar1a.so libfoo1b.so" "-Wl,--no-as-needed,-rpath,.,-rpath-link,." weakdata weakdata.dsym ""
build_exec "ELF weak data last DSO common" foo "libfoo1b.so main1.o libbar1a.so" "-Wl,--no-as-needed,-rpath,.,-rpath-link,." weakdata weakdata.dsym ""
}
if {![ld_compile "$CC $CFLAGS $picflag" $srcdir/$subdir/size_foo.c $tmpdir/size_foo.o]
|| ![ld_compile "$CC $CFLAGS $picflag" $srcdir/$subdir/size_bar.c $tmpdir/size_bar_s.o]
|| ![ld_compile "$CC $CFLAGS $picflag -DSIZE_BIG" $srcdir/$subdir/size_bar.c $tmpdir/size_bar.o]
|| ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/size_main.c $tmpdir/size_main.o]} then {
unresolved "ELF weak (size)"
} else {
build_lib "ELF DSO small bar (size)" libsize_bar_s "size_bar_s.o" ""
build_lib "ELF DSO foo with small bar (size)" libsize_foo "size_foo.o libsize_bar_s.so" ""
build_lib "ELF DSO big bar (size)" libsize_bar "size_bar.o" ""
build_exec "ELF weak size" size_main "size_main.o libsize_foo.so libsize_bar.so" "-Wl,-rpath=.,-rpath-link=.,--no-as-needed" size "" ""
}
verbose "size2"
run_dump_test $srcdir/$subdir/size2
if {![ld_compile "$CC $CFLAGS $picflag" $srcdir/$subdir/alias.c $tmpdir/alias.o]
|| ![ld_link $CC $tmpdir/alias.so "$shared $tmpdir/alias.o"]
|| ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/aliasmain.c $tmpdir/aliasmain.o]
|| ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/weakref1.c $tmpdir/weakref1.o]
|| ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/weakref2.c $tmpdir/weakref2.o]} then {
unresolved "ELF weak (alias)"
} else {
build_exec "ELF weak (alias)" alias "aliasmain.o weakref1.o weakref2.o alias.so" "-Wl,-rpath=.,--no-as-needed" alias "" ""
}