X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=ld%2Ftestsuite%2Flib%2Fld-lib.exp;h=b60fcadf0582357ab6b12d4418b903b9afc06326;hb=6f9dbcd42f2cf034a9a21f46842c08d2e88449db;hp=07ed74735119e698f6b66944b2ee409808c2af8b;hpb=d1f70bdcab6cffce423617c6e081a5128d9dabe0;p=binutils-gdb.git diff --git a/ld/testsuite/lib/ld-lib.exp b/ld/testsuite/lib/ld-lib.exp index 07ed7473511..b60fcadf058 100644 --- a/ld/testsuite/lib/ld-lib.exp +++ b/ld/testsuite/lib/ld-lib.exp @@ -1,5 +1,5 @@ # 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. # @@ -35,9 +35,12 @@ proc at_least_gcc_version { major minor } { set CC [find_gcc] } if { $CC == "" } { - return 0 + return 0 } set state [remote_exec host $CC --version] + if { [lindex $state 0] != 0 } { + return 0; + } set tmp "[lindex $state 1]\n" # Look for (eg) 4.6.1 in the version output. set ver_re "\[^\\.0-9\]+(\[1-9\]\[0-9\]*)\\.(\[0-9\]+)(?:\\.\[0-9\]+)?" @@ -196,41 +199,9 @@ proc big_or_little_endian {} { 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 @@ -311,6 +282,11 @@ proc default_ld_compile { cc source object } { remote_file build delete "ld.tmp" remote_file host delete "ld.tmp" set exec_output [prune_warnings $exec_output] + # Versions of gcc up to and including pre-release gcc-7, at least on + # some targets, generate .section directives with incorrect type. + # Ignore warnings from the assembler about this. + regsub -all "(^|\n)\[^\n\]*: ignoring incorrect section type \[^\n\]*" $exec_output "" exec_output + regsub -all "^\[^\n\]*: Assembler messages:\n" $exec_output "" exec_output if [string match "" $exec_output] then { if {![file exists $object]} then { regexp ".*/(\[^/\]*)$" $source all dobj @@ -406,7 +382,7 @@ proc default_ld_nm { nm nmflags object } { # 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" @@ -589,6 +565,13 @@ proc run_dump_test { name {extra_options {}} } { global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS global host_triplet runtests global env verbose + global ld_elf_shared_opt + + if { [is_elf_format] && [check_shared_lib_support] } { + set ld_extra_opt "$ld_elf_shared_opt" + } else { + set ld_extra_opt "" + } if [string match "*/*" $name] { set file $name @@ -610,6 +593,7 @@ proc run_dump_test { name {extra_options {}} } { 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) {} @@ -656,6 +640,22 @@ proc run_dump_test { name {extra_options {}} } { } 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)] { @@ -782,6 +782,7 @@ proc run_dump_test { name {extra_options {}} } { 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) { @@ -816,7 +817,7 @@ proc run_dump_test { name {extra_options {}} } { } 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" @@ -829,7 +830,7 @@ proc run_dump_test { name {extra_options {}} } { 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" @@ -852,7 +853,7 @@ proc run_dump_test { name {extra_options {}} } { 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" @@ -912,7 +913,7 @@ proc run_dump_test { name {extra_options {}} } { # Add -L$srcdir/$subdir so that the linker command can use # linker scripts in the source directory. - set cmd "$LD $LDFLAGS -L$srcdir/$subdir \ + set cmd "$LD $ld_extra_opt $LDFLAGS -L$srcdir/$subdir \ $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)" # If needed then check for, or add a -Map option. @@ -960,7 +961,7 @@ proc run_dump_test { name {extra_options {}} } { set exitstat "succeeded" if { $cmdret != 0 } { set exitstat "failed" } - if { $check_ld(source) == "regexp" } { + if { $check_ld(source) == "regex" } { verbose -log "$exitstat with: <$comp_output>, expected: <$check_ld(regex)>" } elseif { $check_ld(source) == "file" } { verbose -log "$exitstat with: <$comp_output>, expected in file $check_ld(file)" @@ -968,7 +969,7 @@ proc run_dump_test { name {extra_options {}} } { } 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 == "")) \ @@ -1004,7 +1005,7 @@ proc run_dump_test { name {extra_options {}} } { } } } else { - set objfile "tmpdir/dump0.o" + set objfile [lindex $objfiles 0] } # We must not have expected failure if we get here. @@ -1152,7 +1153,9 @@ proc ar_simple_create { ar aropts target objects } { # in all other cases, any output from the linker during linking is # treated as a sign of an error and FAILs the test. # -proc run_ld_link_tests { ldtests } { +# args is an optional list of target triplets to be xfailed. +# +proc run_ld_link_tests { ldtests args } { global ld global as global nm @@ -1166,6 +1169,13 @@ proc run_ld_link_tests { ldtests } { global CFLAGS global runtests global exec_output + global ld_elf_shared_opt + + if { [is_elf_format] && [check_shared_lib_support] } { + set ld_extra_opt "$ld_elf_shared_opt" + } else { + set ld_extra_opt "" + } foreach testitem $ldtests { set testname [lindex $testitem 0] @@ -1174,6 +1184,10 @@ proc run_ld_link_tests { ldtests } { continue } + foreach target $args { + setup_xfail $target + } + set ld_options [lindex $testitem 1] set ld_after [lindex $testitem 2] set as_options [lindex $testitem 3] @@ -1228,7 +1242,7 @@ proc run_ld_link_tests { ldtests } { if { ![ar_simple_create $ar $ld_options $binfile "$objfiles $ld_after"] } { set failed 1 } - } elseif { ![ld_simple_link $ld $binfile "-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" } @@ -1347,7 +1361,6 @@ if ![string length [info proc prune_warnings]] { } } -# targets_to_xfail is a list of target triplets to be xfailed. # ldtests contains test-items with 3 items followed by 1 lists, 2 items # and 3 optional items: # 0:name @@ -1359,8 +1372,9 @@ if ![string length [info proc prune_warnings]] { # 6:compiler flags (optional) # 7:language (optional) # 8:linker warning (optional) +# args is an optional list of target triplets to be xfailed. -proc run_ld_link_exec_tests { targets_to_xfail ldtests } { +proc run_ld_link_exec_tests { ldtests args } { global ld global as global srcdir @@ -1372,9 +1386,20 @@ proc run_ld_link_exec_tests { targets_to_xfail ldtests } { 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 $targets_to_xfail { + foreach target $args { setup_xfail $target } set testname [lindex $testitem 0] @@ -1401,37 +1426,34 @@ proc run_ld_link_exec_tests { targets_to_xfail ldtests } { set objfile "tmpdir/$fileroot.o" lappend objfiles $objfile - # We ignore warnings since some compilers may generate - # 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 } @@ -1445,7 +1467,7 @@ proc run_ld_link_exec_tests { targets_to_xfail ldtests } { } } - 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 @@ -1470,6 +1492,8 @@ proc run_ld_link_exec_tests { targets_to_xfail ldtests } { if { $failed != 0 } { fail $testname + } elseif ![isnative] { + unsupported $testname } else { set errcnt 0 pass $testname @@ -1486,12 +1510,15 @@ proc run_ld_link_exec_tests { targets_to_xfail ldtests } { # 4:action and options. # 5:name of output file # 6:language (optional) -# 7:linker warnings (optional) # # Actions: # objdump: Apply objdump options on result. Compare with regex (last arg). # nm: Apply nm options on result. Compare with regex (last arg). # readelf: Apply readelf options on result. Compare with regex (last arg). +# warning: Check linker output against regex (last arg). +# error: Like 'warning' but checking output in error case. +# warning_output: Check linker output against regex in a file (last arg). +# error_output: Like 'warning_output' but checking output in error case. # proc run_cc_link_tests { ldtests } { global nm @@ -1522,10 +1549,11 @@ proc run_cc_link_tests { ldtests } { set actions [lindex $testitem 4] set binfile tmpdir/[lindex $testitem 5] set lang [lindex $testitem 6] - set warnings [lindex $testitem 7] set objfiles {} set is_unresolved 0 set failed 0 + set check_ld(terminal) 0 + set check_ld(source) "" #verbose -log "testname is $testname" #verbose -log "ldflags is $ldflags" @@ -1534,7 +1562,37 @@ proc run_cc_link_tests { ldtests } { #verbose -log "actions is $actions" #verbose -log "binfile is $binfile" #verbose -log "lang is $lang" - #verbose -log "warnings is $warnings" + + foreach actionlist $actions { + set action [lindex $actionlist 0] + set progopts [lindex $actionlist 1] + + # Find actions related to error/warning processing. + switch -- $action { + error + { + set check_ld(source) "regexp" + set check_ld(regexp) $progopts + set check_ld(terminal) 1 + } + warning + { + set check_ld(source) "regexp" + set check_ld(regexp) $progopts + } + error_output + { + set check_ld(source) "file" + set check_ld(file) $progopts + set check_ld(terminal) 1 + } + warning_output + { + set check_ld(source) "file" + set check_ld(file) $progopts + } + } + } # Compile each file in the test. foreach src_file $src_files { @@ -1542,14 +1600,19 @@ proc run_cc_link_tests { ldtests } { set objfile "tmpdir/$fileroot.o" lappend objfiles $objfile - # We ignore warnings since some compilers may generate - # 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. @@ -1565,26 +1628,38 @@ proc run_cc_link_tests { ldtests } { # compile only } elseif { [regexp ".*\\.a$" $binfile] } { if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } { - fail $testname set failed 1 } } else { - if { ![ld_simple_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"] } { - set failed 1 - } + ld_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles" + set ld_output "$exec_output" - # Check if exec_output is expected. - if { $warnings != "" } then { - verbose -log "returned with: <$exec_output>, expected: <$warnings>" - if { [regexp $warnings $exec_output] } then { - set failed 0 - } else { + if { $check_ld(source) == "regexp" } then { + # Match output against regexp argument. + verbose -log "returned with: <$ld_output>, expected: <$check_ld(regexp)>" + if { ![regexp $check_ld(regexp) $ld_output] } then { + set failed 1 + } + } elseif { $check_ld(source) == "file" } then { + # Match output against patterns in a file. + set_file_contents "tmpdir/ld.messages" "$ld_output" + verbose "ld.messages has '[file_contents tmpdir/ld.messages]'" + if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$check_ld(file)"] } then { + verbose "output is $ld_output" 2 set failed 1 } } - if { $failed == 1 } { - fail $testname + if { $check_ld(source) != "" } then { + if { $ld_output == "" } then { + verbose -log "Linker was expected to give error or warning" + set failed 1 + } + } else { + if { $ld_output != "" } then { + verbose -log "Unexpected linker warning or error" + set failed 1 + } } } @@ -1604,6 +1679,10 @@ proc run_cc_link_tests { ldtests } { { set dump_prog $nm } readelf { set dump_prog $READELF } + error {} + warning {} + error_output {} + warning_output {} default { perror "Unrecognized action $action" @@ -1646,13 +1725,12 @@ proc run_cc_link_tests { ldtests } { } } - if { $failed != 0 } { + if { $failed } { fail $testname - } elseif { $is_unresolved == 0 } { - pass $testname - } else { + } elseif { $is_unresolved } { unresolved $testname - continue + } else { + pass $testname } } } @@ -1666,11 +1744,11 @@ proc check_gc_sections_available { } { if {![info exists gc_sections_available_saved]} { # Some targets don't support gc-sections despite whatever's # advertised by ld's options. - if { [istarget arc*-*-*] - || [istarget d30v-*-*] + if { [istarget d30v-*-*] || [istarget dlx-*-*] || [istarget i960-*-*] || [istarget pj*-*-*] + || [istarget pru*-*-*] || [istarget alpha-*-*] || [istarget hppa*64-*-*] || [istarget i370-*-*] @@ -1708,7 +1786,7 @@ proc check_gc_sections_available { } { proc check_shared_lib_support { } { if {![istarget aarch64*-*-elf] - && ![istarget arc*-*-*] + && ![istarget arc*-*-elf*] && ![istarget arm*-*-elf] && ![istarget avr-*-*] && ![istarget cr16-*-*] @@ -1719,8 +1797,8 @@ proc check_shared_lib_support { } { && ![istarget dlx-*-*] && ![istarget epiphany-*-*] && ![istarget fr30-*-*] - && ![istarget ft32-*-*] && ![istarget frv-*-*] + && ![istarget ft32-*-*] && ![istarget h8300-*-*] && ![istarget i860-*-*] && ![istarget i960-*-*] @@ -1741,13 +1819,16 @@ proc check_shared_lib_support { } { && ![istarget msp430-*-*] && ![istarget mt-*-*] && ![istarget nds32*-*-*] + && ![istarget nios2-*-elf] && ![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*] @@ -1757,6 +1838,26 @@ proc check_shared_lib_support { } { 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 @@ -1789,13 +1890,38 @@ proc check_sysroot_available { } { return $ld_sysroot_available_saved } +# Returns 1 if plugin is enabled in gcc. Returns 0 otherwise. +proc check_gcc_plugin_enabled { } { + global CC + + if {![info exists CC]} { + set CC [find_gcc] + } + if { $CC == ""} { + return 0 + } + set state [remote_exec host $CC -v] + if { [lindex $state 0] != 0 } { + return 0; + } + for { set i 1 } { $i < [llength $state] } { incr i } { + set v [lindex $state $i] + if { [ string match "*--disable-plugin*" $v ] } { + verbose "plugin is disabled by $v" + return 0; + } + } + + return 1; +} + # Returns true if the target compiler supports LTO proc check_lto_available { } { global lto_available_saved global CC if {![info exists lto_available_saved]} { - if { [which $CC] == 0 } { + if { ![check_gcc_plugin_enabled] } { set lto_available_saved 0 return 0 } @@ -1838,7 +1964,7 @@ proc check_lto_fat_available { } { global CC if {![info exists lto_fat_available_saved]} { - if { [which $CC] == 0 } { + if { ![check_gcc_plugin_enabled] } { set lto_fat_available_saved 0 return 0 } @@ -1881,7 +2007,7 @@ proc check_lto_shared_available { } { global CC if {![info exists lto_shared_available_saved]} { - if { [which $CC] == 0 } { + if { ![check_gcc_plugin_enabled] } { set lto_shared_available_saved 0 return 0 } @@ -2049,3 +2175,38 @@ proc istarget { target } { } return [istarget_ld $target] } + +# Return true if libdl is supported. + +proc check_libdl_available { } { + global libdl_available_saved + global CC + + if {![info exists libdl_available_saved]} { + if { [which $CC] == 0 } { + set libdl_available_saved 0 + return 0 + } + + set basename "tmpdir/dl_avail_test[pid]" + set src ${basename}.c + set output ${basename}.out + set f [open $src "w"] + # Sample test file. + puts $f "#include " + puts $f "int main (void)" + puts $f "{" + puts $f " dlopen (\"dummy.so\", RTLD_NOW);" + puts $f " return 0; " + puts $f "}" + close $f + if [is_remote host] { + set src [remote_download host $src] + } + set libdl_available_saved [run_host_cmd_yesno "$CC" "$src -o $output -ldl"] + remote_file host delete $src + remote_file host delete $output + file delete $src + } + return $libdl_available_saved +}