global link_output
global gcc_B_opt
global ld_L_opt
+ global gcc_ld_B_opt_tested
+ global ld
if { ![is_remote host] && [which "$prog"] == 0 } then {
perror "$prog does not exist"
set gccexe [string replace $gccexe 0 [string last "/" $gccexe] ""]
if {[string match "*cc*" $gccexe] || [string match "*++*" $gccexe]} then {
set gccflags "$gcc_B_opt $gccflags $ld_L_opt"
+ 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"
# once.
#
# target: TARGET
-# Only run the test for TARGET. This may occur more than once; the
-# target being tested must match at least one. You may provide target
-# name "cfi" for any target supporting the CFI statements.
+# Only run the test for TARGET.
+# You may provide target name "cfi" for any target supporting the
+# CFI statements. You may provide target name "shared" for any
+# target supporting shared libraries. Otherwise TARGET is called
+# as a TCL procedure if surrounded by square brackets, or passed
+# to "istarget" if not.
+# This may occur more than once; the target being tested must match
+# at least one. Otherwise the test will be marked unsupported.
+#
+# alltargets: TARGET
+# Only run the test for TARGET.
+# The syntax for TARGET is as with 'target'.
+# This may occur more than once; the target being tested must match
+# all of them. Otherwise the test will be marked unsupported.
#
# notarget: TARGET
-# Do not run the test for TARGET. This may occur more than once;
-# the target being tested must not match any of them.
+# Do not run the test for TARGET.
+# The syntax for TARGET is as with 'target'.
+# This may occur more than once; the target being tested must not
+# match any of them. Otherwise the test will be marked unsupported.
+#
+# skip: TARGET
+# anyskip: TARGET
+# noskip: TARGET
+# These are exactly the same as "notarget", "alltargets" and
+# "target" respectively, except that they do nothing at all if the
+# check fails. They should only be used in groups, to construct a
+# single test which is run on all targets but with variant options
+# or expected output on some targets. (For example, see
+# gas/arm/inst.d and gas/arm/wince_inst.d.)
#
# error: REGEX
# An error with message matching REGEX must be emitted for the test
set opts(ld_after_inputfiles) {}
set opts(xfail) {}
set opts(target) {}
+ set opts(alltargets) {}
set opts(notarget) {}
+ set opts(skip) {}
+ set opts(anyskip) {}
+ set opts(noskip) {}
set opts(objdump) {}
set opts(nm) {}
set opts(objcopy) {}
switch -- $opt_name {
xfail {}
target {}
+ alltargets {}
notarget {}
+ skip {}
+ anyskip {}
+ noskip {}
warning {}
error {}
source {
[big_or_little_endian] opts($opt)
}
+ if { $opts(name) == "" } {
+ set testname "$subdir/$name"
+ } else {
+ set testname $opts(name)
+ }
+
# Decide early whether we should run the test for this target.
+ if { [llength $opts(noskip)] > 0 } {
+ set targmatch 0
+ foreach targ $opts(noskip) {
+ if [match_target $targ] {
+ set targmatch 1
+ break
+ }
+ }
+ if { $targmatch == 0 } {
+ return
+ }
+ }
+ foreach targ $opts(anyskip) {
+ if ![match_target $targ] {
+ return
+ }
+ }
+ foreach targ $opts(skip) {
+ if [match_target $targ] {
+ return
+ }
+ }
if { [llength $opts(target)] > 0 } {
set targmatch 0
foreach targ $opts(target) {
- if [istarget $targ] {
+ if [match_target $targ] {
set targmatch 1
break
}
}
if { $targmatch == 0 } {
+ unsupported $testname
+ return
+ }
+ }
+ foreach targ $opts(alltargets) {
+ if ![match_target $targ] {
+ unsupported $testname
return
}
}
foreach targ $opts(notarget) {
- if [istarget $targ] {
+ if [match_target $targ] {
+ unsupported $testname
return
}
}
readelf { set program readelf }
default
{ perror "unrecognized program option $opts(PROG) in $file.d"
- unresolved $subdir/$name
+ unresolved $testname
return }
}
} else {
if {$opts($p) != ""} {
if {$program != ""} {
perror "ambiguous dump program in $file.d"
- unresolved $subdir/$name
+ unresolved $testname
return
} else {
set program $p
&& $opts(error) == "" \
&& $opts(error_output) == "" } {
perror "dump program unspecified in $file.d"
- unresolved $subdir/$name
+ unresolved $testname
return
}
}
- if { $opts(name) == "" } {
- set testname "$subdir/$name"
- } else {
- set testname $opts(name)
- }
-
if { $opts(source) == "" } {
set sourcefiles [list ${file}.s]
set asflags [list ""]
# ldtests contains test-items with 3 items followed by 1 lists, 2 items
# and 3 optional items:
# 0:name
-# 1:ld options
+# 1:ld leading options, placed before object files
# 2:assembler options
# 3:filenames of source files
# 4:name of output file
# 6:compiler flags (optional)
# 7:language (optional)
# 8:linker warning (optional)
+# 9:ld trailing options, placed after object files (optional)
# args is an optional list of target triplets to be xfailed.
proc run_ld_link_exec_tests { ldtests args } {
global errcnt
global exec_output
global board_cflags
+ global STATIC_LDFLAGS
# When using GCC as the linker driver, we need to specify board cflags when
# linking because cflags may contain linker options. For example when
set cflags [lindex $testitem 6]
set lang [lindex $testitem 7]
set warning [lindex $testitem 8]
+ set ld_after [lindex $testitem 9]
set objfiles {}
set failed 0
continue
}
- if { [ string match "c++" $lang ] } {
+ if { [ string match "asm" $lang ] } {
+ set link_proc ld_link
+ set link_cmd $ld
+ } elseif { [ string match "c++" $lang ] } {
set link_proc ld_link
set link_cmd $CXX
} else {
# compile only
pass $testname
continue;
- } elseif ![$link_proc $link_cmd $binfile "$board_cflags -L$srcdir/$subdir $ld_options $objfiles"] {
- set failed 1
+ } else {
+ if { [string match "" $STATIC_LDFLAGS] \
+ && [regexp -- ".* \[-\]+static .*" " $board_cflags $ld_options $objfiles $ld_after "] } {
+ untested $testname
+ continue
+ }
+ if ![$link_proc $link_cmd $binfile "$board_cflags -L$srcdir/$subdir $ld_options $objfiles $ld_after"] {
+ set failed 1
+ }
}
# Check if exec_output is expected.
global ar
global exec_output
global board_cflags
+ global STATIC_LDFLAGS
if [board_info [target_info name] exists cflags] {
set board_cflags " [board_info [target_info name] cflags]"
set failed 1
}
} else {
+ if { [string match "" $STATIC_LDFLAGS] \
+ && [regexp -- ".* \[-\]+static .*" " $board_cflags $ldflags $objfiles "] } {
+ untested $testname
+ continue
+ }
ld_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"
set ld_output "$exec_output"
if {![info exists gc_sections_available_saved]} {
# Some targets don't support gc-sections despite whatever's
# advertised by ld's options.
- if { [istarget d30v-*-*]
+ if { [istarget alpha-*-*]
+ || [istarget d30v-*-*]
|| [istarget dlx-*-*]
- || [istarget i960-*-*]
- || [istarget pj*-*-*]
- || [istarget pru*-*-*]
- || [istarget alpha-*-*]
|| [istarget hppa*64-*-*]
- || [istarget i370-*-*]
- || [istarget i860-*-*]
|| [istarget ia64-*-*]
|| [istarget mep-*-*]
- || [istarget mn10200-*-*] } {
+ || [istarget mn10200-*-*]
+ || [istarget pj*-*-*]
+ || [istarget pru*-*-*]
+ || [istarget xgate-*-*] } {
set gc_sections_available_saved 0
return 0
}
|| [istarget "fr30-*-*"]
|| ([istarget "frv-*-*"] && ![istarget "frv-*-linux*"])
|| [istarget "ft32-*-*"]
- || [istarget "i860-*-*"]
- || [istarget "i960-*-*"]
|| [istarget "iq2000-*-*"]
|| [istarget "mn10200-*-*"]
|| [istarget "moxie-*-*"]
|| [istarget "msp430-*-*"]
|| [istarget "mt-*-*"]
- || [istarget "pj*-*-*"] } {
+ || [istarget "pj*-*-*"]
+ || [istarget "xgate-*-*"] } {
return 1;
}
return 0;
set src [remote_download host $src]
}
set ifunc_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
- if { $ifunc_available_saved == 1 } {
+ if { [isnative] && $ifunc_available_saved == 1 } {
set ifunc_available_saved [run_host_cmd_yesno "$output" ""]
}
remote_file host delete $src
set src [remote_download host $src]
}
set ifunc_attribute_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
- if { $ifunc_attribute_available_saved == 1 } {
+ if { [isnative] && $ifunc_attribute_available_saved == 1 } {
set ifunc_attribute_available_saved [run_host_cmd_yesno "$output" ""]
}
remote_file host delete $src
if {$target == "cfi"} {
return [check_as_cfi]
}
+ if {$target == "shared"} {
+ return [check_shared_lib_support]
+ }
return [istarget_ld $target]
}