# Support routines for LD testsuite.
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-# 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+# 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
# based on the name of the compiler.
set ldexe $ld
set ldparm [string first " " $ld]
+ set ldflags ""
if { $ldparm > 0 } then {
+ set ldflags [string range $ld $ldparm end]
set ldexe [string range $ld 0 $ldparm]
+ set ld $ldexe
}
set ldexe [string replace $ldexe 0 [string last "/" $ldexe] ""]
if {[string match "*gcc*" $ldexe] || [string match "*++*" $ldexe]} then {
- set flags "$gcc_ld_flag $flags"
+ set ldflags "$gcc_ld_flag $ldflags"
}
remote_file host delete $target
- set exec_output [run_host_cmd "$ld" "$flags -o $target $objects"]
+ set exec_output [run_host_cmd "$ld" "$ldflags $flags -o $target $objects"]
set exec_output [prune_warnings $exec_output]
# We don't care if we get a warning about a non-existent start
}
}
+# Define various symbols needed when not linking against all
+# target libs.
+proc ld_simple_link_defsyms {} {
+
+ set flags "--defsym __stack_chk_fail=0"
+
+ # ARM targets call __gccmain
+ if {[istarget arm*-*-*] || \
+ [istarget strongarm*-*-*] || \
+ [istarget xscale*-*-*] || \
+ [istarget thumb-*-*] } {
+ append flags " --defsym __gccmain=0"
+ }
+
+ # PowerPC EABI code calls __eabi.
+ if {[istarget powerpc*-*-eabi*] || [istarget powerpc*-*-rtems*]} {
+ append flags " --defsym __eabi=0"
+ }
+
+ # mn10200 code calls __truncsipsi2_d0_d2.
+ if {[istarget mn10200*-*-*]} then {
+ append flags " --defsym __truncsipsi2_d0_d2=0"
+ }
+
+ # m6811/m6812 code has references to soft registers.
+ if {[istarget m6811-*-*] || [istarget m6812-*-*]} {
+ append flags " --defsym _.frame=0 --defsym _.d1=0 --defsym _.d2=0"
+ append flags " --defsym _.d3=0 --defsym _.d4=0"
+ append flags " --defsym _.tmp=0 --defsym _.xy=0 --defsym _.z=0"
+ }
+
+ # Some OpenBSD targets have ProPolice and reference __guard and
+ # __stack_smash_handler.
+ if [istarget *-*-openbsd*] {
+ append flags " --defsym __guard=0"
+ append flags " --defsym __stack_smash_handler=0"
+ }
+
+ return $flags
+}
+
# True if the object format is known to be ELF.
#
proc is_elf_format {} {
&& ![istarget hppa*64*-*-hpux*] \
&& ![istarget *-*-linux*] \
&& ![istarget frv-*-uclinux*] \
+ && ![istarget bfin-*-uclinux] \
+ && ![istarget sh*-*-uclinux*] \
&& ![istarget *-*-irix5*] \
&& ![istarget *-*-irix6*] \
&& ![istarget *-*-netbsd*] \
proc is_pecoff_format {} {
if { ![istarget *-*-mingw*] \
&& ![istarget *-*-cygwin*] \
+ && ![istarget *-*-cegcc*] \
&& ![istarget *-*-pe*] } {
return 0
}
# Link assembled files using FLAGS, in the order of the "source"
# directives, when using multiple files.
#
+# ld_after_inputfiles: FLAGS
+# Similar to "ld", but put after all input files.
+#
# objcopy_linked_file: FLAGS
# Run objcopy on the linked file with the specified flags.
# This lets you transform the linked file using objcopy, before the
#
# target: TARGET
# Only run the test for TARGET. This may occur more than once; the
-# target being tested must match at least one.
+# target being tested must match at least one. You may provide target
+# name "cfi" for any target supporting the CFI statements.
#
# notarget: TARGET
# Do not run the test for TARGET. This may occur more than once;
# error: REGEX
# An error with message matching REGEX must be emitted for the test
# to pass. The PROG, objdump, nm and objcopy options have no
-# meaning and need not supplied if this is present.
+# meaning and need not supplied if this is present. Multiple "error"
+# directives append to the expected linker error message.
#
# warning: REGEX
# Expect a linker warning matching REGEX. It is an error to issue
-# both "error" and "warning".
+# both "error" and "warning". Multiple "warning" directives
+# append to the expected linker warning message.
#
# Each option may occur at most once unless otherwise mentioned.
#
global OBJDUMP NM AS OBJCOPY READELF LD
global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
global host_triplet runtests
- global env
+ global env verbose
if [string match "*/*" $name] {
set file $name
set run_objcopy 0
set opts(as) {}
set opts(ld) {}
+ set opts(ld_after_inputfiles) {}
set opts(xfail) {}
set opts(target) {}
set opts(notarget) {}
xfail {}
target {}
notarget {}
+ warning {}
+ error {}
source {
# Move any source-specific as-flags to a separate array to
# simplify processing.
# Add -L$srcdir/$subdir so that the linker command can use
# linker scripts in the source directory.
set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
- $opts(ld) -o $objfile $objfiles"
+ $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
send_log "$cmd\n"
set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
remote_upload host "ld.tmp"
- set comp_output [prune_warnings [file_contents "ld.tmp"]]
+ set comp_output [file_contents "ld.tmp"]
remote_file host delete "ld.tmp"
remote_file build delete "ld.tmp"
set cmdret [lindex $cmdret 0]
send_log "$cmd\n"
set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
remote_upload host "ld.tmp"
- append comp_output [prune_warnings [file_contents "ld.tmp"]]
+ append comp_output [file_contents "ld.tmp"]
remote_file host delete "ld.tmp"
remote_file build delete "ld.tmp"
set cmdret [lindex $cmdret 0]
send_log "$comp_output\n"
verbose "$comp_output" 3
- if { [regexp $expmsg $comp_output] \
- && (($cmdret == 0) == ($opts(warning) != "")) } {
+ if { ($expmsg == "") == ($comp_output == "") \
+ && [regexp $expmsg $comp_output] \
+ && (($cmdret == 0) == ($opts(error) == "")) } {
# We have the expected output from ld.
if { $opts(error) != "" || $program == "" } {
pass $testname
set env(LC_ALL) "C"
send_log "$cmd\n"
set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
+ set cmdret [lindex $cmdret 0]
remote_upload host "ld.tmp"
set comp_output [prune_warnings [file_contents "ld.tmp"]]
remote_file host delete "ld.tmp"
} else {
unset env(LC_ALL)
}
- if ![string match "" $comp_output] then {
- send_log "$comp_output\n"
+ if { $cmdret != 0 || $comp_output != "" } {
+ send_log "exited abnormally with $cmdret, output:$comp_output\n"
fail $testname
return
}
- verbose_eval {[file_contents $dumpfile]} 3
+ if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
if { [regexp_diff $dumpfile "${file}.d"] } then {
fail $testname
- verbose "output is [file_contents $dumpfile]" 2
+ if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
return
}
set end_2 0
set differences 0
set diff_pass 0
+ set fail_if_match 0
if [file exists $file_1] then {
set file_a [open $file_1 r]
set end_2 1
set diff_pass 1
break
+ } elseif [ string match "#failif" $line_b ] {
+ send_log "fail if no difference\n"
+ verbose "fail if no difference" 3
+ set fail_if_match 1
} elseif [ string match "#..." $line_b ] {
if { [gets $file_b line_b] == $eof } {
set end_2 1
set differences 1
}
+ if { $fail_if_match } {
+ if { $differences == 0 } {
+ set differences 1
+ } else {
+ set differences 0
+ }
+ }
+
close $file_a
close $file_b
return $contents
}
+# Create an archive using ar
+#
+proc ar_simple_create { ar aropts target objects } {
+ remote_file host delete $target
+
+ set exec_output [run_host_cmd "$ar" "$aropts rc $target $objects"]
+ set exec_output [prune_warnings $exec_output]
+
+ if [string match "" $exec_output] then {
+ send_log "$exec_output\n"
+ return 1
+ } else {
+ return 0
+ }
+}
+
# List contains test-items with 3 items followed by 2 lists, one item and
# one optional item:
-# 0:name 1:ld options 2:assembler options
+# 0:name 1:ld/ar options 2:assembler options
# 3:filenames of assembler files 4: action and options. 5: name of output file
# 6:compiler flags (optional)
#
global ld
global as
global nm
+ global ar
global objdump
global READELF
global srcdir
global env
global CC
global CFLAGS
+ global runtests
foreach testitem $ldtests {
set testname [lindex $testitem 0]
+
+ if ![runtest_file_p $runtests $testname] then {
+ continue
+ }
+
set ld_options [lindex $testitem 1]
set as_options [lindex $testitem 2]
set src_files [lindex $testitem 3]
continue
}
- if ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
+ if { [regexp ".*\\.a$" $binfile] } {
+ if { ![ar_simple_create $ar $ld_options $binfile "$objfiles"] } {
+ fail $testname
+ set failed 1
+ } else {
+ set failed 0
+ }
+ } elseif { ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] } {
fail $testname
+ set failed 1
} else {
set failed 0
+ }
+
+ if { $failed == 0 } {
foreach actionlist $actions {
set action [lindex $actionlist 0]
set progopts [lindex $actionlist 1]
}
}
-
-proc verbose_eval { expr { level 1 } } {
- global verbose
- if $verbose>$level then { eval verbose "$expr" $level }
-}
-
# This definition is taken from an unreleased version of DejaGnu. Once
# that version gets released, and has been out in the world for a few
# months at least, it may be safe to delete this copy.
# List contains test-items with 3 items followed by 2 lists, one item and
# one optional item:
# 0:name
-# 1:link options
+# 1:ld or ar options
# 2:compile options
# 3:filenames of source files
# 4:action and options.
global CXX
global CFLAGS
global CXXFLAGS
+ global ar
foreach testitem $ldtests {
set testname [lindex $testitem 0]
set cc_cmd $CC
}
- if ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] {
+ if { [regexp ".*\\.a$" $binfile] } {
+ if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
+ fail $testname
+ set failed 1
+ } else {
+ set failed 0
+ }
+ } elseif { ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] } {
fail $testname
+ set failed 1
} else {
set failed 0
+ }
+
+ if { $failed == 0 } {
foreach actionlist $actions {
set action [lindex $actionlist 0]
set progopts [lindex $actionlist 1]
if {![info exists gc_sections_available_saved]} {
# Some targets don't support gc-sections despite whatever's
# advertised by ld's options.
- if { [istarget alpha*-*-*]
- || [istarget ia64-*-*] } {
+ if {[istarget arc-*-*]
+ || [istarget d30v-*-*]
+ || [istarget dlx-*-*]
+ || [istarget i960-*-*]
+ || [istarget or32-*-*]
+ || [istarget pj*-*-*]
+ || [istarget alpha-*-*]
+ || [istarget hppa64-*-*]
+ || [istarget i370-*-*]
+ || [istarget i860-*-*]
+ || [istarget ia64-*-*]
+ || [istarget mep-*-*]
+ || [istarget mn10200-*-*]
+ || [istarget *-*-cygwin]
+ || [istarget *-*-mingw*] } {
set gc_sections_available_saved 0
return 0
}
return 0
}
- # VxWorks kernel modules are relocatable objects linked with -r,
- # while RTP executables are linked with -q (--emit-relocs).
- # Both of these options are incompatible with --gc-sections.
- if { [istarget *-*-vxworks*] } {
- set gc_sections_available_saved 0
- return 0
- }
-
# Check if the ld used by gcc supports --gc-sections.
set ld_output [remote_exec host $ld "--help"]
if { [ string first "--gc-sections" $ld_output ] >= 0 } {
}
return $gc_sections_available_saved
}
+
+# Check if the assembler supports CFI statements.
+
+proc check_as_cfi { } {
+ global check_as_cfi_result
+ global as
+ if [info exists check_as_cfi_result] {
+ return $check_as_cfi_result
+ }
+ set as_file "tmpdir/check_as_cfi.s"
+ set as_fh [open $as_file w 0666]
+ puts $as_fh "# Generated file. DO NOT EDIT"
+ puts $as_fh "\t.cfi_startproc"
+ puts $as_fh "\t.cfi_endproc"
+ close $as_fh
+ remote_download host $as_file
+ verbose -log "Checking CFI support:"
+ rename "perror" "check_as_cfi_perror"
+ proc perror { args } { }
+ set success [ld_assemble $as $as_file "/dev/null"]
+ rename "perror" ""
+ rename "check_as_cfi_perror" "perror"
+ #remote_file host delete $as_file
+ set check_as_cfi_result $success
+ return $success
+}
+
+# Provide virtual target "cfi" for targets supporting CFI.
+
+rename "istarget" "istarget_ld"
+proc istarget { target } {
+ if {$target == "cfi"} {
+ return [check_as_cfi]
+ }
+ return [istarget_ld $target]
+}