# Support routines for LD testsuite.
-# Copyright (C) 1994-2016 Free Software Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
return $flags
}
-# Link a program using ld.
+# Link a program using ld
#
proc default_ld_link { ld target objects } {
- global HOSTING_EMU
- global HOSTING_CRT0
- global HOSTING_SCRT0
- global HOSTING_LIBS
- global HOSTING_SLIBS
- global LIBS
- global host_triplet
- global link_output
- global exec_output
-
- if { [ string match "* -pie *" $objects ] } {
- set objs "$HOSTING_SCRT0 $objects"
- set libs "$LIBS $HOSTING_SLIBS"
- } else {
- set objs "$HOSTING_CRT0 $objects"
- set libs "$LIBS $HOSTING_LIBS"
- }
-
- if [is_endian_output_format $objects] then {
- set flags [big_or_little_endian]
- } else {
- set flags ""
- }
-
- remote_file host delete $target
-
- return [run_host_cmd_yesno "$ld" "$HOSTING_EMU $flags -o $target $objs $libs"]
-}
-
-# Link a program using ld, without including any libraries.
-#
-proc default_ld_simple_link { ld target objects } {
global host_triplet
global exec_output
# Define various symbols needed when not linking against all
# target libs.
-proc ld_simple_link_defsyms {} {
+proc ld_link_defsyms {} {
set flags "--defsym __stack_chk_fail=0"
set dumpfile tmpdir/dump.out
set run_ld 0
set run_objcopy 0
+ set objfile_names {}
set opts(as) {}
set opts(ld) {}
set opts(ld_after_inputfiles) {}
} else {
lappend asflags {}
}
+
+ # Create the object file name based on nothing but the source
+ # file name.
+ set new_objfile \
+ [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]].o]
+ # But, sometimes, we have the exact same source filename in
+ # different directories (foo/src.s bar/src.s) which would lead
+ # us to try and create two src.o files. We detect this
+ # conflict here, and instead create src.o and src1.o.
+ set j 0
+ while { [lsearch $objfile_names $new_objfile] != -1 } {
+ incr j
+ set new_objfile \
+ [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]]${j}.o]
+ }
+ lappend objfile_names $new_objfile
}
default {
if [string length $opts($opt_name)] {
if { $opts(source) == "" } {
set sourcefiles [list ${file}.s]
set asflags [list ""]
+ set objfile_names [list tmpdir/[file tail ${file}].o]
} else {
set sourcefiles {}
foreach sf $opts(source) {
}
regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
- set objfile "tmpdir/dump$i.o"
+ set objfile [lindex $objfile_names $i]
catch "exec rm -f $objfile" exec_output
lappend objfiles $objfile
set cmd "$AS $ASFLAGS $opts(as) $sourceasflags -o $objfile $sourcefile"
remote_file build delete "ld.tmp"
if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
- send_log "$comp_output\n"
+ send_log -- "$comp_output\n"
verbose "$comp_output" 3
set exitstat "succeeded"
if { [lindex $cmdret 0] != 0 \
|| ![string match "" $comp_output] } {
- send_log "$comp_output\n"
+ send_log -- "$comp_output\n"
verbose "$comp_output" 3
set exitstat "succeeded"
} else {
verbose -log "$exitstat with: <$comp_output>, no expected output"
}
- send_log "$comp_output\n"
+ send_log -- "$comp_output\n"
verbose "$comp_output" 3
if { (($check_ld(source) == "") == ($comp_output == "")) \
}
}
} else {
- set objfile "tmpdir/dump0.o"
+ set objfile [lindex $objfiles 0]
}
# We must not have expected failure if we get here.
if { ![ar_simple_create $ar $ld_options $binfile "$objfiles $ld_after"] } {
set failed 1
}
- } elseif { ![ld_simple_link $ld $binfile "$ld_extra_opt -L$srcdir/$subdir $ld_options $objfiles $ld_after"] } {
+ } elseif { ![ld_link $ld $binfile "$ld_extra_opt -L$srcdir/$subdir $ld_options $objfiles $ld_after"] } {
set maybe_failed 1
set ld_output "$exec_output"
}
global CXXFLAGS
global errcnt
global exec_output
+ global board_cflags
+
+ # When using GCC as the linker driver, we need to specify board cflags when
+ # linking because cflags may contain linker options. For example when
+ # linker options are included in GCC spec files then we need the -specs
+ # option.
+ if [board_info [target_info name] exists cflags] {
+ set board_cflags " [board_info [target_info name] cflags]"
+ } else {
+ set board_cflags ""
+ }
foreach testitem $ldtests {
foreach target $args {
# incorrect section attributes and the assembler will warn
# them.
if { [ string match "c++" $lang ] } {
- ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
+ set cmd "$CXX -c $CXXFLAGS $cflags"
} else {
- ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
+ set cmd "$CC -c $CFLAGS $cflags"
+ }
+ if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] {
+ set failed 1
+ break
}
}
+ if { $failed != 0 } {
+ unresolved $testname
+ continue
+ }
- # We have to use $CC to build PIE and shared library.
- if { [ string match "c" $lang ] } {
- set link_proc ld_simple_link
- set link_cmd $CC
- } elseif { [ string match "c++" $lang ] } {
- set link_proc ld_simple_link
+ if { [ string match "c++" $lang ] } {
+ set link_proc ld_link
set link_cmd $CXX
- } elseif { [ string match "-shared" $ld_options ] \
- || [ string match "-pie" $ld_options ] } {
- set link_proc ld_simple_link
- set link_cmd $CC
} else {
set link_proc ld_link
- set link_cmd $ld
+ set link_cmd $CC
}
if { $binfile eq "tmpdir/" } {
# compile only
pass $testname
continue;
- } elseif ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
+ } elseif ![$link_proc $link_cmd $binfile "$board_cflags -L$srcdir/$subdir $ld_options $objfiles"] {
set failed 1
}
}
}
- if { $failed == 0 } {
+ if { $failed == 0 && [isnative] } {
send_log "Running: $binfile > $binfile.out\n"
verbose "Running: $binfile > $binfile.out"
catch "exec $binfile > $binfile.out" exec_output
if { $failed != 0 } {
fail $testname
+ } elseif ![isnative] {
+ unsupported $testname
} else {
set errcnt 0
pass $testname
# incorrect section attributes and the assembler will warn
# them.
if { [ string match "c++" $lang ] } {
- ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
+ set cmd "$CXX -c $CXXFLAGS $cflags"
} else {
- ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
+ set cmd "$CC -c $CFLAGS $cflags"
+ }
+ if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] {
+ set failed 1
+ break
}
}
+ if { $failed != 0 } {
+ unresolved $testname
+ continue
+ }
# Clear error and warning counts.
reset_vars
set failed 1
}
} else {
- if { ![ld_simple_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"] } {
+ if { ![ld_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"] } {
set failed 1
}
|| [istarget dlx-*-*]
|| [istarget i960-*-*]
|| [istarget pj*-*-*]
+ || [istarget pru*-*-*]
|| [istarget alpha-*-*]
|| [istarget hppa*64-*-*]
|| [istarget i370-*-*]
&& ![istarget nds32*-*-*]
&& ![istarget or1k*-*-*]
&& ![istarget pj-*-*]
+ && ![istarget pru-*-*]
&& ![istarget rl78-*-*]
&& ![istarget rx-*-*]
&& ![istarget spu-*-*]
&& ![istarget v850*-*-*]
&& ![istarget visium-*-*]
+ && ![istarget xc16x-*-elf]
&& ![istarget xgate-*-*]
&& ![istarget xstormy16-*-*]
&& ![istarget *-*-irix*]
return 0
}
+# Return true if target uses genelf.em (assuming it is ELF).
+proc is_generic_elf { } {
+ if { [istarget "d30v-*-*"]
+ || [istarget "dlx-*-*"]
+ || [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*-*-*"] } {
+ return 1;
+ }
+ return 0;
+}
+
# Returns true if the target ld supports the plugin API.
proc check_plugin_api_available { } {
global plugin_api_available_saved