1# Expect script for LD Bootstrap Tests
2#   Copyright (C) 1993-2014 Free Software Foundation, Inc.
3#
4# This file is part of the GNU Binutils.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19# MA 02110-1301, USA.
20#
21# Written by Jeffrey Wheat (cassidy@cygnus.com)
22# Rewritten by Ian Lance Taylor (ian@cygnus.com)
23#
24
25# Make sure that ld can bootstrap itself.
26
27# This test can only be run if ld generates native executables.
28if ![isnative] {
29    return
30}
31
32# Determine if plugin support is present.
33remote_exec host "$nm --help" "" "/dev/null" "plugin-support"
34set tmp [file_contents "plugin-support"]
35regexp ".*\(--plugin\).*\n" $tmp foo plugins
36if [info exists plugins] then {
37    set plugins "yes"
38} else {
39    set plugins "no"
40}
41
42# LD can have plugin support even if BFD does not.
43if [check_plugin_api_available] {
44    set plugins "yes"
45}
46
47# Bootstrap ld.  First link the object files together using -r, in
48# order to test -r.  Then link the result into an executable, ld1, to
49# really test -r.  Use ld1 to link a fresh ld, ld2.  Use ld2 to link a
50# new ld, ld3.  ld2 and ld3 should be identical.
51set test_flags {"" "strip" "--static" "--traditional-format"
52		"--no-keep-memory" "--relax"}
53if { [istarget "powerpc-*-*"] } {
54    lappend test_flags "--ppc476-workaround"
55}
56
57foreach flags $test_flags {
58    set do_strip "no"
59    if {"$flags" == "strip"} {
60	set testname "bootstrap with $flags"
61        set flags ""
62	set do_strip "yes"
63    } else { if {"$flags" != ""} {
64	set testname "bootstrap with $flags"
65    } else {
66	set testname "bootstrap"
67    }}
68
69    # --static is meaningless and --relax is incompatible with -r.
70    set partial_flags "$flags"
71    if { "$flags" == "--static" || "$flags" == "--relax" } {
72	set partial_flags ""
73    }
74
75    if { $partial_flags == "--ppc476-workaround" } {
76	append partial_flags " -T $srcdir/$subdir/ppc476.t"
77    }
78
79    # This test can only be run if we have the ld build directory,
80    # since we need the object files.
81    if {$ld != "$objdir/ld-new"} {
82	untested $testname
83	continue
84    }
85
86    # Plugin support requires linking with a dynamic library which
87    # means that these tests will fail.
88    if { $flags == "--static" && $plugins == "yes" } then {
89	untested $testname
90	continue
91    }
92
93    # If we only have a shared libbfd, we probably can't run the
94    # --static test.
95    if { $flags == "--static" && ! [string match "*libbfd.a*" $BFDLIB] } then {
96	untested $testname
97	continue
98    }
99
100    if ![ld_relocate $ld tmpdir/ld-partial.o "$partial_flags $OFILES"] {
101	fail $testname
102	continue
103    }
104
105    # On AIX, you need to specify an import list when using --static.
106    # You only want the import list when creating the final
107    # executable.
108    if { [istarget "*-*-aix*"]
109         && ![istarget "ia64-*-aix*"]} {
110	if {"$flags" == "--static"} {
111	    set flags "--static -bI:/lib/syscalls.exp"
112	}
113    }
114
115    # On Cygwin, -lintl may require -liconv when linking statically.
116    set extralibs ""
117    if { [istarget "*-*-cygwin*"]} {
118	if {"$flags" == "--static"} {
119	    set extralibs "-liconv"
120	}
121    }
122
123    # Plugin support requires linking with libdl.
124    if { $plugins == "yes" } {
125	if { ![istarget "*-*-freebsd*"]} {
126	    set extralibs "$extralibs -ldl"
127	}
128    }
129
130    # On Irix 5, linking with --static only works if all the files are
131    # compiled using -non_shared.
132    if {"$flags" == "--static"} {
133	setup_xfail "mips*-*-irix5*"
134    }
135
136    if ![ld_link $ld tmpdir/ld1 "$flags tmpdir/ld-partial.o $BFDLIB $LIBIBERTY $extralibs"] {
137	fail $testname
138	continue
139    }
140
141    if {"$do_strip" == "yes"} {
142	verbose -log "$strip tmpdir/ld1"
143	catch "exec $strip tmpdir/ld1" exec_output
144	if ![string match "" $exec_output] then {
145	    verbose -log "$exec_output"
146	    fail $testname
147	    continue
148	}
149    }
150
151    if ![ld_link tmpdir/ld1 tmpdir/ld2 "$flags $OFILES $BFDLIB $LIBIBERTY $extralibs"] {
152	fail $testname
153	continue
154    }
155
156    if ![ld_link tmpdir/ld2 tmpdir/ld3 "$flags $OFILES $BFDLIB $LIBIBERTY $extralibs"] {
157	fail $testname
158	continue
159    }
160
161    if {"$flags" == "--static"} {
162	if { [istarget ia64-*-elf*]
163	     || [istarget ia64-*-linux*] } {
164	    # On ia64, tmpdir/ld2 != tmpdir/ld3 is normal since they are
165	    # generated by different linkers, tmpdir/ld1 and tmpdir/ld2.
166	    # So we rebuild tmpdir/ld2 with tmpdir/ld3.
167	    if ![ld_link tmpdir/ld3 tmpdir/ld2 "$flags $OFILES $BFDLIB $LIBIBERTY $extralibs"] {
168		fail $testname
169		continue
170	    }
171	}
172    } else {
173	if { [istarget mips*-*-linux*] } {
174	    # On Linux/mips, tmpdir/ld2 != tmpdir/ld3 is normal since
175	    # they are generated by different linkers, tmpdir/ld1 and
176	    # tmpdir/ld2. So we rebuild tmpdir/ld2 with tmpdir/ld3.
177	    if ![ld_link tmpdir/ld3 tmpdir/ld2 "$flags $OFILES $BFDLIB $LIBIBERTY $extralibs"] {
178		fail $testname
179		continue
180	    }
181	}
182    }
183
184    if {[istarget "*-*-pe"]
185	|| [istarget "*-*-wince"]
186	|| [istarget "*-*-cygwin*"]
187	|| [istarget "*-*-winnt*"]
188	|| [istarget "*-*-mingw*"]
189	|| [istarget "*-*-interix*"]
190	|| [istarget "*-*-beospe*"]
191	|| [istarget "*-*-netbsdpe*"]} {
192	# Trim off the date present in PE binaries by only looking
193	#   at the ends of the files
194	# Although this works, a way to set the date would be better.
195	# Removing or zeroing the date stamp in the binary produced by
196	# the linker is not possible as it is required by the target OS.
197	set do_compare [string map {16 220 f1 tmpdir/ld2 f2 tmpdir/ld3 tmp-foo1 tmpdir/ld2tail tmp-foo2 tmpdir/ld3tail} $DO_COMPARE]
198	send_log "$do_compare\n"
199	verbose  "$do_compare"
200	catch "exec sh -c [list $do_compare]" exec_output
201    } else {
202	send_log "cmp tmpdir/ld2 tmpdir/ld3\n"
203	verbose  "cmp tmpdir/ld2 tmpdir/ld3"
204	catch "exec cmp tmpdir/ld2 tmpdir/ld3" exec_output
205    }
206    set exec_output [prune_warnings $exec_output]
207
208    if [string match "" $exec_output] then {
209	pass $testname
210    } else {
211	send_log "$exec_output\n"
212	verbose "$exec_output" 1
213
214	fail $testname
215    }
216}
217
218catch "exec rm -f tmpdir/ld-partial.o tmpdir/ld1 tmpdir/ld2 tmpdir/ld3" status
219catch "exec rm -f tmpdir/ld2tail tmpdir/ld3tail" status
220