mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-11 13:02:10 +08:00
ERROR should really be reserved for errors in the testsuite framework, not just normal errors from the tools under test. Removing use of perror has been suggested before but without action, over concerns that some test failures might be missed. This patch removes uses of perror in ld_assemble, ld_compile and ld_nm, and updates numerous places that ignored the result of these functions by inappropriately returning an "unresolved" test status. Net result over my large set of targets look good, in some cases improving the diagnostics, eg: i386-msdos -ERROR: tmpdir/script: nm failed i386-msdos -ERROR: tmpdir/script: nm failed i386-msdos -ERROR: tmpdir/script: nm failed i386-msdos -ERROR: tmpdir/script: nm failed i386-msdos +FAIL: script i386-msdos +FAIL: MRI script i386-msdos +FAIL: MEMORY i386-msdos +FAIL: MEMORY with symbols * testsuite/lib/ld-lib.exp (default_ld_compile): Don't perror on a compiler error. (default_ld_assemble): Similarly for an assembler error. (default_ld_nm): Similarly for an nm error. (run_ld_link_tests): Report ld_assemble errors as a fail. (check_as_cfi): Remove now unnecessary perror substitution. * testsuite/ld-elf/exclude.exp: Report ld_nm error return as test fails rather then unresolved. * testsuite/ld-gc/gc.exp: Likewise. * testsuite/ld-scripts/alignof.exp: Likewise. * testsuite/ld-scripts/defined.exp: Likewise. * testsuite/ld-scripts/script.exp: Likewise. * testsuite/ld-scripts/sizeof.exp: Likewise. * testsuite/ld-selective/selective.exp: Likewise. * testsuite/ld-scripts/extern.exp: Likewise. Return on ld_link failure. * testsuite/ld-elfweak/elfweak.exp: Report compiler errors as test unresolved. * testsuite/ld-fastcall/fastcall.exp: Report assember errors as test fails. * testsuite/ld-i386/i386.exp (iamcu_tests): Likewise. * testsuite/ld-ia64/line.exp: Likewise. * testsuite/ld-mep/mep.exp: Likewise. * testsuite/ld-mips-elf/mips-elf-flags.exp: Likewise. * testsuite/ld-nios2/nios2.exp: Likewise. * testsuite/ld-scripts/alignof.exp: Likewise. * testsuite/ld-x86-64/line.exp: Likewise. * testsuite/ld-x86-64/x86-64.exp: Likewise. * testsuite/ld-scripts/log2.exp: Formatting. * testsuite/ld-tic6x/tic6x.exp: Report ld_link errors as a test fail.
450 lines
14 KiB
Plaintext
450 lines
14 KiB
Plaintext
# Expect script for ld-weak tests
|
|
# Copyright (C) 2001-2020 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
|
|
global NOSANTIZE_CFLAGS
|
|
|
|
set files ""
|
|
foreach obj $objs {
|
|
set files "$files $tmpdir/$obj"
|
|
}
|
|
|
|
if {![ld_link $CC $tmpdir/$execname "$flags $NOSANTIZE_CFLAGS $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]} then {
|
|
unresolved "ELF weak"
|
|
} elseif {![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 $NOSANTIZE_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 "" ""
|
|
}
|