diff options
Diffstat (limited to 'ld/testsuite/ld-plugin/lto-binutils.exp')
-rw-r--r-- | ld/testsuite/ld-plugin/lto-binutils.exp | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/ld/testsuite/ld-plugin/lto-binutils.exp b/ld/testsuite/ld-plugin/lto-binutils.exp new file mode 100644 index 0000000..88d3517 --- /dev/null +++ b/ld/testsuite/ld-plugin/lto-binutils.exp @@ -0,0 +1,357 @@ +# Expect script for binutils tests with LTO +# Copyright (C) 2025 Free Software Foundation, Inc. +# +# This file is part of the GNU Binutils. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +# Make sure that binutils can correctly handle LTO IR in ELF. + +if { !([istarget *-*-linux*] + || [istarget arm*-*-uclinuxfdpiceabi] + || [istarget *-*-gnu*]) || [istarget *ecoff] } then { + return +} + +# Check to see if the C and C++ compilers work +if { ![check_compiler_available] || [which $CXX_FOR_TARGET] == 0 } { + return +} + +# These tests require plugin and LTO. +if { ![check_plugin_api_available] + || ![check_lto_available] } { + return +} + +set lto_fat "" +set lto_no_fat "" +if { [check_lto_fat_available] } { + set lto_fat "-ffat-lto-objects" + set lto_no_fat "-fno-fat-lto-objects" + set no_lto "-fno-lto" +} + +# List contains test-items: +# 0:program name +# 1:program options +# 2:input file +# 3:output file +# 4:action list (optional) +# +proc run_lto_binutils_test { lto_tests } { + global srcdir + global subdir + global nm + global objcopy + global objdump + global READELF + global strip + global plug_opt + + foreach testitem $lto_tests { + set prog_name [lindex $testitem 0] + set prog_options [lindex $testitem 1] + set input tmpdir/[lindex $testitem 2] + set output tmpdir/[lindex $testitem 3] + set actions [lindex $testitem 4] + set objfiles {} + set is_unresolved 0 + set failed 0 + +# eval set prog \$$prog_name + switch -- $prog_name { + objcopy + { + set prog $objcopy + set prog_output "$output" + } + strip + { + set prog $strip + set prog_output "-o $output" + } + default + { + perror "Unrecognized action $action" + set is_unresolved 1 + break + } + } + + # Don't leave previous output around + if { $output ne "tmpdir/" } { + remote_file host delete $output + } + + append prog_options " $plug_opt" + + set cmd_options "$prog_options $prog_output $input" + set test_name "$prog_name $cmd_options" + + set cmd "$prog $cmd_options" + send_log "$cmd\n" + set got [remote_exec host "$cmd"] + if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { + send_log "$got\n" + fail "$test_name" + continue + } + + if { $failed == 0 } { + foreach actionlist $actions { + set action [lindex $actionlist 0] + set progopts [lindex $actionlist 1] + + # There are actions where we run regexp_diff on the + # output, and there are other actions (presumably). + # Handling of the former look the same. + set dump_prog "" + switch -- $action { + objdump + { set dump_prog $objdump } + nm + { set dump_prog $nm } + readelf + { set dump_prog $READELF } + default + { + perror "Unrecognized action $action" + set is_unresolved 1 + break + } + } + + if { $dump_prog != "" } { + set dumpfile [lindex $actionlist 2] + set binary $dump_prog + + # Ensure consistent sorting of symbols + if {[info exists env(LC_ALL)]} { + set old_lc_all $env(LC_ALL) + } + set env(LC_ALL) "C" + set cmd "$binary $progopts $output > tmpdir/dump.out" + send_log "$cmd\n" + catch "exec $cmd" comp_output + if {[info exists old_lc_all]} { + set env(LC_ALL) $old_lc_all + } else { + unset env(LC_ALL) + } + set comp_output [prune_warnings $comp_output] + + if ![string match "" $comp_output] then { + send_log "$comp_output\n" + set failed 1 + break + } + + if { [regexp_diff "tmpdir/dump.out" "$srcdir/$subdir/$dumpfile"] } then { + verbose -log "output is [file_contents "tmpdir/dump.out"]" 2 + set failed 1 + break + } + } + } + } + + if { $failed } { + fail $test_name + } elseif { $is_unresolved } { + unresolved $test_name + } else { + pass $test_name + } + } +} + +run_cc_link_tests [list \ + [list \ + "Build strip-1a.o" \ + "" \ + "-O2 -flto $lto_no_fat" \ + { strip-1a.c } \ + ] \ + [list \ + "Build libstrip-1a.a" \ + "$plug_opt" \ + "-O2 -flto $lto_no_fat" \ + { strip-1a.c } \ + {} \ + "libstrip-1a.a" \ + ] \ + [list \ + "Build strip-1a-fat.o" \ + "" \ + "-O2 -flto $lto_fat" \ + { strip-1a-fat.c } \ + ] \ + [list \ + "Build libstrip-1a-fat.a" \ + "$plug_opt" \ + "-O2 -flto $lto_fat" \ + { strip-1a-fat.c } \ + {} \ + "libstrip-1a-fat.a" \ + ] \ +] + +run_lto_binutils_test [list \ + [list \ + "strip" \ + "--strip-unneeded" \ + "libstrip-1a.a" \ + "libstrip-1a-s.a" \ + ] \ + [list \ + "strip" \ + "--strip-unneeded" \ + "strip-1a.o" \ + "strip-1a-s.o" \ + ] \ + [list \ + "strip" \ + "--strip-unneeded -R .gnu.*lto_* -N __gnu_lto_v1" \ + "libstrip-1a-fat.a" \ + "libstrip-1a-fat-s.a" \ + {{readelf -SW strip-1a-fat.rd}} \ + ] \ + [list \ + "strip" \ + "--strip-unneeded -R .gnu.*lto_* -N __gnu_lto_v1" \ + "strip-1a-fat.o" \ + "strip-1a-fat-s.o" \ + {{readelf -SW strip-1a-fat.rd}} \ + ] \ + [list \ + "strip" \ + "--strip-unneeded -R .gnu.debuglto_*" \ + "libstrip-1a-fat.a" \ + "libstrip-1b-fat-s.a" \ + {{readelf -SW strip-1b-fat.rd}} \ + ] \ + [list \ + "strip" \ + "--strip-unneeded -R .gnu.debuglto_*" \ + "strip-1a-fat.o" \ + "strip-1b-fat-s.o" \ + {{readelf -SW strip-1b-fat.rd}} \ + ] \ +] + +if { [check_lto_fat_available] } { + run_lto_binutils_test [list \ + [list \ + "strip" \ + "-R .gnu.*lto_* -N __gnu_lto_v1" \ + "strip-1a.o" \ + "strip-1a-s-all.o" \ + {{nm -n strip-1a-s-all.nd}} \ + ] \ + [list \ + "strip" \ + "-R .gnu.*lto_* -N __gnu_lto_v1" \ + "libstrip-1a.a" \ + "libstrip-1a-s-all.a" \ + {{nm -n strip-1a-s-all.nd}} \ + ] \ + ] +} + +run_cc_link_tests [list \ + [list \ + "Build strip-1a (strip-1a.o)" \ + "" \ + "-O2 -flto $lto_no_fat" \ + { strip-1b.c } \ + {} \ + "libstrip-1a" \ + "C" \ + "tmpdir/strip-1a.o" \ + ] \ + [list \ + "Build strip-1b (strip-1a-s.o)" \ + "" \ + "-O2 -flto $lto_no_fat" \ + { strip-1b.c } \ + {} \ + "libstrip-1b" \ + "C" \ + "tmpdir/strip-1a-s.o" \ + ] \ + [list \ + "Build strip-1c (libstrip-1a.a)" \ + "" \ + "-O2 -flto $lto_no_fat" \ + { strip-1b.c } \ + {} \ + "libstrip-1c" \ + "C" \ + "tmpdir/libstrip-1a.a" \ + ] \ + [list \ + "Build strip-1d (libstrip-1a-s.a)" \ + "" \ + "-O2 -flto $lto_no_fat" \ + { strip-1b.c } \ + {} \ + "libstrip-1d" \ + "C" \ + "tmpdir/libstrip-1a-s.a" \ + ] \ + [list \ + "Build strip-1e (strip-1a-fat-s.o)" \ + "" \ + "-O2 -flto $lto_fat" \ + { strip-1b-fat.c } \ + {} \ + "libstrip-1e" \ + "C" \ + "tmpdir/strip-1a-fat-s.o" \ + ] \ + [list \ + "Build strip-1f (libstrip-1a-fat-s.a)" \ + "" \ + "-O2 -flto $lto_fat" \ + { strip-1b-fat.c } \ + {} \ + "libstrip-1f" \ + "C" \ + "tmpdir/libstrip-1a-fat-s.a" \ + ] \ + [list \ + "Build strip-1g (strip-1b-fat-s.o)" \ + "" \ + "-O2 -flto $lto_fat" \ + { strip-1b-fat.c } \ + {} \ + "libstrip-1g" \ + "C" \ + "tmpdir/strip-1b-fat-s.o" \ + ] \ + [list \ + "Build strip-1h (libstrip-1b-fat-s.a)" \ + "" \ + "-O2 -flto $lto_fat" \ + { strip-1b-fat.c } \ + {} \ + "libstrip-1h" \ + "C" \ + "tmpdir/libstrip-1b-fat-s.a" \ + ] \ +] |