ChangeLog rotatation and copyright year update
[deliverable/binutils-gdb.git] / ld / testsuite / lib / ld-lib.exp
index 369dc1f7a1bc16617040ff1eda3073db99a88a41..b968b6b467d1b0bc9ca3df8d612c4a966260703a 100644 (file)
@@ -1,5 +1,5 @@
 # Support routines for LD testsuite.
-#   Copyright (C) 1994-2014 Free Software Foundation, Inc.
+#   Copyright (C) 1994-2015 Free Software Foundation, Inc.
 #
 # This file is part of the GNU Binutils.
 #
@@ -79,14 +79,33 @@ proc default_ld_version { ld } {
 
 proc run_host_cmd { prog command } {
     global link_output
+    global gcc_B_opt
+    global ld_L_opt
 
     if { ![is_remote host] && [which "$prog"] == 0 } then {
        perror "$prog does not exist"
        return 0
     }
 
-    verbose -log "$prog $command"
-    set status [remote_exec host [concat sh -c [list "$prog $command 2>&1"]] "" "/dev/null" "ld.tmp"]
+    # If we are compiling with gcc, we want to add gcc_B_opt and
+    # ld_L_opt to flags.  However, if $prog already has -B options,
+    # which might be the case when running gcc out of a build
+    # directory, we want our -B options to come first.
+    set gccexe $prog
+    set gccparm [string first " " $gccexe]
+    set gccflags ""
+    if { $gccparm > 0 } then {
+       set gccflags [string range $gccexe $gccparm end]
+       set gccexe [string range $gccexe 0 $gccparm]
+       set prog $gccexe
+    }
+    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"
+    }
+
+    verbose -log "$prog $gccflags $command"
+    set status [remote_exec host [concat sh -c [list "$prog $gccflags $command 2>&1"]] "" "/dev/null" "ld.tmp"]
     remote_upload host "ld.tmp"
     set link_output [file_contents "ld.tmp"]
     regsub "\n$" $link_output "" link_output
@@ -208,45 +227,22 @@ proc default_ld_link { ld target objects } {
 #
 proc default_ld_simple_link { ld target objects } {
     global host_triplet
-    global gcc_ld_flag
     global exec_output
 
+    set flags ""
     if [is_endian_output_format $objects] then {
        set flags [big_or_little_endian]
-    } else {
-       set flags ""
-    }
-
-    # If we are compiling with gcc, we want to add gcc_ld_flag to
-    # flags.  Rather than determine this in some complex way, we guess
-    # 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 ldflags "$gcc_ld_flag $ldflags"
     }
 
     remote_file host delete $target
-
-    set exec_output [run_host_cmd "$ld" "$ldflags $flags -o $target $objects"]
+    set exec_output [run_host_cmd "$ld" "$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
     # symbol, since the default linker script might use ENTRY.
     regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
 
-    if [string match "" $exec_output] then {
-       return 1
-    } else {
-       return 0
-    }
+    return [string match "" $exec_output]
 }
 
 # Compile an object using cc.
@@ -257,7 +253,7 @@ proc default_ld_compile { cc source object } {
     global srcdir
     global subdir
     global host_triplet
-    global gcc_gas_flag
+    global gcc_B_opt
 
     set cc_prog $cc
     if {[llength $cc_prog] > 1} then {
@@ -271,11 +267,12 @@ proc default_ld_compile { cc source object } {
     remote_file build delete "$object"
     remote_file host delete "$object"
 
-    set flags "-I$srcdir/$subdir"
+    set flags "$gcc_B_opt -I$srcdir/$subdir"
 
-    # If we are compiling with gcc, we want to add gcc_gas_flag to
-    # flags.  Rather than determine this in some complex way, we guess
-    # based on the name of the compiler.
+    # If we are compiling with gcc, we want to add gcc_B_opt to flags.
+    # However, if $prog already has -B options, which might be the
+    # case when running gcc out of a build directory, we want our -B
+    # options to come first.
     set ccexe $cc
     set ccparm [string first " " $cc]
     set ccflags ""
@@ -284,15 +281,12 @@ proc default_ld_compile { cc source object } {
        set ccexe [string range $cc 0 $ccparm]
        set cc $ccexe
     }
-    set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""]
-    if {[string match "*gcc*" $ccexe] || [string match "*++*" $ccexe]} then {
-       set flags "$gcc_gas_flag $flags"
-    }
 
+    set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""]
     if {[string match "*++*" $ccexe]} {
-       set flags "$flags $CXXFLAGS"
+       append flags " $CXXFLAGS"
     } else {
-       set flags "$flags $CFLAGS"
+       append flags " $CFLAGS"
     }
 
     if [board_info [target_info name] exists cflags] {
@@ -303,9 +297,10 @@ proc default_ld_compile { cc source object } {
        append flags " [board_info [target_info name] multilib_flags]"
     }
 
-    verbose -log "$cc $flags $ccflags -c $source -o $object"
+    set cmd "$cc $flags $ccflags -c $source -o $object"
+    verbose -log "$cmd"
 
-    set status [remote_exec host [concat sh -c [list "$cc $flags $ccflags -c $source -o $object 2>&1"]] "" "/dev/null" "ld.tmp"]
+    set status [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
     remote_upload host "ld.tmp"
     set exec_output [file_contents "ld.tmp"]
     remote_file build delete "ld.tmp"
@@ -415,9 +410,9 @@ proc ld_simple_link_defsyms {} {
         append flags " --defsym __gccmain=0"
     }
 
-    # Windows targets need __main, prefixed with underscore.
+    # Windows targets need __main, some prefixed with underscore.
     if {[istarget *-*-cygwin* ] || [istarget *-*-mingw*]} {
-        append flags " --defsym ___main=0"
+        append flags " --defsym __main=0 --defsym ___main=0"
     }
 
     # PowerPC EABI code calls __eabi.
@@ -497,6 +492,11 @@ proc ld_simple_link_defsyms {} {
 #   ld_after_inputfiles: FLAGS
 #       Similar to "ld", but put after all input files.
 #
+#   objcopy_objects: FLAGS
+#      Run objcopy with the specified flags after assembling any source
+#      that has the special marker RUN_OBJCOPY in the source specific
+#      flags.
+#
 #   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
@@ -605,6 +605,7 @@ proc run_dump_test { name {extra_options {}} } {
     set opts(error) {}
     set opts(warning) {}
     set opts(objcopy_linked_file) {}
+    set opts(objcopy_objects) {}
 
     foreach i $opt_array {
        set opt_name [lindex $i 0]
@@ -784,6 +785,12 @@ proc run_dump_test { name {extra_options {}} } {
     for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
        set sourcefile [lindex $sourcefiles $i]
        set sourceasflags [lindex $asflags $i]
+       set run_objcopy_objects 0
+
+       if { [string match "*RUN_OBJCOPY*" $sourceasflags] } {
+           set run_objcopy_objects 1
+       }
+       regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
 
        set objfile "tmpdir/dump$i.o"
        catch "exec rm -f $objfile" exec_output
@@ -807,6 +814,30 @@ proc run_dump_test { name {extra_options {}} } {
            fail $testname
            return
        }
+
+       if { $run_objcopy_objects } {
+           set cmd "$OBJCOPY $opts(objcopy_objects) $objfile"
+
+           send_log "$cmd\n"
+           set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \
+                       "" "/dev/null" "objcopy.tmp"]
+           remote_upload host "objcopy.tmp"
+           set comp_output [prune_warnings [file_contents "objcopy.tmp"]]
+           remote_file host delete "objcopy.tmp"
+           remote_file build delete "objcopy.tmp"
+
+           if { [lindex $cmdret 0] != 0 \
+                 || ![string match "" $comp_output] } {
+               send_log "$comp_output\n"
+               verbose "$comp_output" 3
+
+               set exitstat "succeeded"
+               if { $cmdret != 0 } { set exitstat "failed" }
+               verbose -log "$exitstat with: <$comp_output>"
+               fail $testname
+               return
+           }
+       }
     }
 
     set expmsg $opts(error)
@@ -1095,7 +1126,9 @@ proc run_ld_link_tests { ldtests } {
            continue
        }
 
-       if { [regexp ".*\\.a$" $binfile] } {
+       if { $binfile eq "tmpdir/" } {
+           # compile only
+       } elseif { [regexp ".*\\.a$" $binfile] } {
            if { ![ar_simple_create $ar $ld_options $binfile "$objfiles $ld_after"] } {
                set failed 1
            }
@@ -1298,10 +1331,12 @@ proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
            set link_cmd $ld
        }
 
-       if ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
+       if { $binfile eq "tmpdir/" } {
+           # compile only
+           pass $testname
+           continue;
+       } elseif ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
            set failed 1
-       } else {
-           set failed 0
        }
 
        # Check if exec_output is expected.
@@ -1375,6 +1410,13 @@ proc run_cc_link_tests { ldtests } {
     global CXXFLAGS
     global ar
     global exec_output
+    global board_cflags
+
+    if [board_info [target_info name] exists cflags] {
+        set board_cflags " [board_info [target_info name] cflags]"
+    } else {
+       set board_cflags ""
+    }
 
     foreach testitem $ldtests {
        set testname [lindex $testitem 0]
@@ -1389,6 +1431,15 @@ proc run_cc_link_tests { ldtests } {
        set is_unresolved 0
        set failed 0
 
+       #verbose -log "testname  is $testname"
+       #verbose -log "ldflags   is $ldflags"
+       #verbose -log "cflags    is $cflags"
+       #verbose -log "src_files is $src_files"
+       #verbose -log "actions   is $actions"
+       #verbose -log "binfile   is $binfile"
+       #verbose -log "lang      is $lang"
+       #verbose -log "warnings  is $warnings"
+
        # Compile each file in the test.
        foreach src_file $src_files {
            set fileroot "[file rootname [file tail $src_file]]"
@@ -1414,18 +1465,16 @@ proc run_cc_link_tests { ldtests } {
            set cc_cmd $CC
        }
 
-       if { [regexp ".*\\.a$" $binfile] } {
+       if { $binfile eq "tmpdir/" } {
+           # compile only
+       } elseif { [regexp ".*\\.a$" $binfile] } {
            if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
                fail $testname
                set failed 1
-           } else {
-               set failed 0
            }
        } else {
-           if { ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] } {
+           if { ![ld_simple_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"] } {
                set failed 1
-           } else {
-               set failed 0
            }
 
            # Check if exec_output is expected.
@@ -1499,16 +1548,13 @@ proc run_cc_link_tests { ldtests } {
                    }
                }
            }
-
-           if { $failed != 0 } {
-               fail $testname
-           } else { if { $is_unresolved == 0 } {
-               pass $testname
-           } }
        }
 
-       # Catch action errors.
-       if { $is_unresolved != 0 } {
+       if { $failed != 0 } {
+           fail $testname
+       } elseif { $is_unresolved == 0 } {
+           pass $testname
+       } else {
            unresolved $testname
            continue
        }
@@ -1606,6 +1652,7 @@ proc check_shared_lib_support { } {
         && ![istarget rx-*-*]
         && ![istarget spu-*-*]
         && ![istarget v850*-*-*]
+        && ![istarget visium-*-*]
         && ![istarget xstormy16-*-*]
         && ![istarget *-*-irix*]
         && ![istarget *-*-rtems] } {
@@ -1621,7 +1668,7 @@ proc check_plugin_api_available { } {
     if {![info exists plugin_api_available_saved]} {
        # Check if the ld used by gcc supports --plugin.
        set ld_output [remote_exec host $ld "--help"]
-       if { [ string first "-plugin" $ld_output ] >= 0 } {
+       if { [ string first "-plugin PLUGIN" $ld_output ] >= 0 } {
            set plugin_api_available_saved 1
        } else {
            set plugin_api_available_saved 0
@@ -1630,80 +1677,120 @@ proc check_plugin_api_available { } {
     return $plugin_api_available_saved
 }
 
+# Sets ld_sysroot to the current sysroot (empty if not supported) and
+# returns true if the target ld supports sysroot.
+proc check_sysroot_available { } {
+    global ld_sysroot_available_saved ld ld_sysroot
+    if {![info exists ld_sysroot_available_saved]} {
+       # Check if ld supports --sysroot *other* than empty.
+       set ld_sysroot [string trimright [lindex [remote_exec host $ld "--print-sysroot"] 1]]
+       if { $ld_sysroot == "" } {
+           set ld_sysroot_available_saved 0
+       } else {
+           set ld_sysroot_available_saved 1
+       }
+    }
+    return $ld_sysroot_available_saved
+}
+
 # Returns true if the target compiler supports LTO
 proc check_lto_available { } {
     global lto_available_saved
     global CC
 
-    set flags ""
-
-    if [board_info [target_info name] exists cflags] {
-        append flags " [board_info [target_info name] cflags]"
-    }
-
-    if [board_info [target_info name] exists ldflags] {
-        append flags " [board_info [target_info name] ldflags]"
-    }
-
     if {![info exists lto_available_saved]} {
-       # Check if gcc supports -flto -fuse-linker-plugin
-       if { [which $CC] == 0 } {
+        if { [which $CC] == 0 } {
            set lto_available_saved 0
            return 0
        }
-       set basename "lto"
-       set src ${basename}[pid].c
-       set output ${basename}[pid].out
+       # Check if gcc supports -flto -fuse-linker-plugin
+       set flags ""
+       if [board_info [target_info name] exists cflags] {
+           append flags " [board_info [target_info name] cflags]"
+       }
+       if [board_info [target_info name] exists ldflags] {
+           append flags " [board_info [target_info name] ldflags]"
+       }
+
+       set basename "tmpdir/lto[pid]"
+       set src ${basename}.c
+       set output ${basename}.out
        set f [open $src "w"]
        puts $f "int main() { return 0; }"
        close $f
-       set status [remote_exec host $CC "$flags -B[pwd]/tmpdir/ld/ -flto -ffat-lto-objects -fuse-linker-plugin $src -o $output"]
-       if { [lindex $status 0] == 0 } {
-           set lto_available_saved 1
-       } else {
-           set lto_available_saved 0
-       }
+       remote_download host $src
+       set lto_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -fuse-linker-plugin $src -o $output"]
+       remote_file host delete $src
+       remote_file host delete $output
        file delete $src
-       file delete $output
     }
     return $lto_available_saved
 }
 
-# Returns true if the target compiler supports LTO and -shared
-proc check_lto_shared_available { } {
-    global lto_shared_available_saved
+# Returns true if the target compiler supports LTO  -ffat-lto-objects
+proc check_lto_fat_available { } {
+    global lto_fat_available_saved
     global CC
 
-    set flags ""
+    if {![info exists lto_fat_available_saved]} {
+        if { [which $CC] == 0 } {
+           set lto_fat_available_saved 0
+           return 0
+       }
+       # Check if gcc supports -flto -fuse-linker-plugin
+       set flags ""
+       if [board_info [target_info name] exists cflags] {
+           append flags " [board_info [target_info name] cflags]"
+       }
+       if [board_info [target_info name] exists ldflags] {
+           append flags " [board_info [target_info name] ldflags]"
+       }
 
-    if [board_info [target_info name] exists cflags] {
-        append flags " [board_info [target_info name] cflags]"
+       set basename "tmpdir/lto[pid]"
+       set src ${basename}.c
+       set output ${basename}.out
+       set f [open $src "w"]
+       puts $f "int main() { return 0; }"
+       close $f
+       remote_download host $src
+       set lto_fat_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -ffat-lto-objects -fuse-linker-plugin $src -o $output"]
+       remote_file host delete $src
+       remote_file host delete $output
+       file delete $src
     }
+    return $lto_fat_available_saved
+}
 
-    if [board_info [target_info name] exists ldflags] {
-        append flags " [board_info [target_info name] ldflags]"
-    }
+# Returns true if the target compiler supports LTO and -shared
+proc check_lto_shared_available { } {
+    global lto_shared_available_saved
+    global CC
 
     if {![info exists lto_shared_available_saved]} {
-       # Check if gcc supports -flto -fuse-linker-plugin -shared
-       if { [which $CC] == 0 } {
+        if { [which $CC] == 0 } {
            set lto_shared_available_saved 0
            return 0
        }
-       set basename "lto_shared"
-       set src ${basename}[pid].c
-       set output ${basename}[pid].so
+       # Check if gcc supports -flto -fuse-linker-plugin -shared
+       set flags ""
+       if [board_info [target_info name] exists cflags] {
+           append flags " [board_info [target_info name] cflags]"
+       }
+       if [board_info [target_info name] exists ldflags] {
+           append flags " [board_info [target_info name] ldflags]"
+       }
+
+       set basename "tmpdir/lto_shared[pid]"
+       set src ${basename}.c
+       set output ${basename}.so
        set f [open $src "w"]
        puts $f ""
        close $f
-       set status [remote_exec host $CC "$flags -shared -fPIC -B[pwd]/tmpdir/ld/ -flto -fuse-linker-plugin $src -o $output"]
-       if { [lindex $status 0] == 0 } {
-           set lto_shared_available_saved 1
-       } else {
-           set lto_shared_available_saved 0
-       }
+       remote_download host $src
+       set lto_shared_available_saved [run_host_cmd_yesno "$CC" "$flags -shared -fPIC -flto -fuse-linker-plugin $src -o $output"]
+       remote_file host delete $src
+       remote_file host delete $output
        file delete $src
-       file delete $output
     }
     return $lto_shared_available_saved
 }
@@ -1734,6 +1821,53 @@ proc check_as_cfi { } {
     return $success
 }
 
+# Returns true if IFUNC works.
+
+proc check_ifunc_available { } {
+    global ifunc_available_saved
+    global CC
+
+    if {![info exists ifunc_available_saved]} {
+        if { [which $CC] == 0 } {
+           set ifunc_available_saved 0
+           return 0
+       }
+       # Check if gcc supports -flto -fuse-linker-plugin
+       set flags ""
+       if [board_info [target_info name] exists cflags] {
+           append flags " [board_info [target_info name] cflags]"
+       }
+       if [board_info [target_info name] exists ldflags] {
+           append flags " [board_info [target_info name] ldflags]"
+       }
+
+       set basename "tmpdir/ifunc[pid]"
+       set src ${basename}.c
+       set output ${basename}.out
+       set f [open $src "w"]
+       puts $f "extern int library_func2 (void);"
+       puts $f "int main (void)"
+       puts $f "{"
+       puts $f "  if (library_func2 () != 2) __builtin_abort ();"
+       puts $f "  return 0; "
+       puts $f "}"
+       puts $f "static int library_func1 (void) {return 2; }"
+       puts $f "void *foo (void) __asm__ (\"library_func2\");"
+       puts $f "void *foo (void) { return library_func1; }"
+       puts $f "__asm__(\".type library_func2, %gnu_indirect_function\");"
+       close $f
+       remote_download host $src
+       set ifunc_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
+       if { $ifunc_available_saved == 1 } {
+         set ifunc_available_saved [run_host_cmd_yesno "$output" ""]
+       }
+       remote_file host delete $src
+       remote_file host delete $output
+       file delete $src
+    }
+    return $ifunc_available_saved
+}
+
 # Provide virtual target "cfi" for targets supporting CFI.
 
 rename "istarget" "istarget_ld"
This page took 0.030665 seconds and 4 git commands to generate.