binutils/testsuite/
[platform/upstream/binutils.git] / ld / testsuite / lib / ld-lib.exp
1 # Support routines for LD testsuite.
2 #   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 #    2004, 2005, 2006, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
4 #
5 # This file is part of the GNU Binutils.
6 #
7 # This file is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 # MA 02110-1301, USA.
21
22 proc load_common_lib { name } {
23     global srcdir
24     load_file $srcdir/../../binutils/testsuite/lib/$name
25 }
26
27 load_common_lib binutils-common.exp
28
29 # Extract and print the version number of ld.
30 #
31 proc default_ld_version { ld } {
32     global host_triplet
33
34     if { ![is_remote host] && [which $ld] == 0 } then {
35         perror "$ld does not exist"
36         exit 1
37     }
38
39     remote_exec host "$ld --version" "" "/dev/null" "ld.version"
40     remote_upload host "ld.version"
41     set tmp [prune_warnings [file_contents "ld.version"]]
42     remote_file build delete "ld.version"
43     remote_file host delete "ld.version"
44
45     regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number
46     if [info exists number] then {
47         clone_output "$ld $number\n"
48     }
49 }
50
51 proc run_host_cmd { prog command } {
52     global link_output
53
54     if { ![is_remote host] && [which "$prog"] == 0 } then {
55         perror "$prog does not exist"
56         return 0
57     }
58
59     verbose -log "$prog $command"
60     set status [remote_exec host [concat sh -c [list "$prog $command 2>&1"]] "" "/dev/null" "ld.tmp"]
61     remote_upload host "ld.tmp"
62     set link_output [file_contents "ld.tmp"]
63     regsub "\n$" $link_output "" link_output
64     if { [lindex $status 0] != 0 && [string match "" $link_output] } then {
65         append link_output "child process exited abnormally"
66     }
67     remote_file build delete ld.tmp
68     remote_file host delete ld.tmp
69
70     if [string match "" $link_output] then {
71         return ""
72     }
73
74     verbose -log "$link_output"
75     return "$link_output"
76 }
77
78 proc run_host_cmd_yesno { prog command } {
79     global exec_output
80
81     set exec_output [prune_warnings [run_host_cmd "$prog" "$command"]]
82     if [string match "" $exec_output] then {
83         return 1;
84     }
85     return 0;
86 }
87
88 # Link an object using relocation.
89 #
90 proc default_ld_relocate { ld target objects } {
91     global HOSTING_EMU
92
93     remote_file host delete $target
94     return [run_host_cmd_yesno "$ld" "$HOSTING_EMU -o $target -r $objects"]
95 }
96
97 # Check to see if ld is being invoked with a non-endian output format
98 #
99 proc is_endian_output_format { object_flags } {
100
101     if {[string match "*-oformat binary*" $object_flags] ||      \
102         [string match "*-oformat ieee*" $object_flags] ||        \
103         [string match "*-oformat ihex*" $object_flags] ||        \
104         [string match "*-oformat netbsd-core*" $object_flags] || \
105         [string match "*-oformat srec*" $object_flags] ||        \
106         [string match "*-oformat tekhex*" $object_flags] ||      \
107         [string match "*-oformat trad-core*" $object_flags] } then {
108         return 0
109     } else {
110         return 1
111     }
112 }
113
114 # Look for big-endian or little-endian switches in the multlib
115 # options and translate these into a -EB or -EL switch.  Note
116 # we cannot rely upon proc process_multilib_options to do this
117 # for us because for some targets the compiler does not support
118 # -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
119 # the site.exp file will include the switch "-mbig-endian"
120 # (rather than "big-endian") which is not detected by proc
121 # process_multilib_options.
122 #
123 proc big_or_little_endian {} {
124
125     if [board_info [target_info name] exists multilib_flags] {
126         set tmp_flags " [board_info [target_info name] multilib_flags]"
127
128         foreach x $tmp_flags {
129             case $x in {
130                 {*big*endian eb EB -eb -EB -mb -meb} {
131                     set flags " -EB"
132                     return $flags
133                 }
134                 {*little*endian el EL -el -EL -ml -mel} {
135                     set flags " -EL"
136                     return $flags
137                 }
138             }
139         }
140     }
141
142     set flags ""
143     return $flags
144 }
145
146 # Link a program using ld.
147 #
148 proc default_ld_link { ld target objects } {
149     global HOSTING_EMU
150     global HOSTING_CRT0
151     global HOSTING_LIBS
152     global LIBS
153     global host_triplet
154     global link_output
155     global exec_output
156
157     set objs "$HOSTING_CRT0 $objects"
158     set libs "$LIBS $HOSTING_LIBS"
159
160     if [is_endian_output_format $objects] then {
161         set flags [big_or_little_endian]
162     } else {
163         set flags ""
164     }
165
166     remote_file host delete $target
167
168     return [run_host_cmd_yesno "$ld" "$HOSTING_EMU $flags -o $target $objs $libs"]
169 }
170
171 # Link a program using ld, without including any libraries.
172 #
173 proc default_ld_simple_link { ld target objects } {
174     global host_triplet
175     global gcc_ld_flag
176     global exec_output
177
178     if [is_endian_output_format $objects] then {
179         set flags [big_or_little_endian]
180     } else {
181         set flags ""
182     }
183
184     # If we are compiling with gcc, we want to add gcc_ld_flag to
185     # flags.  Rather than determine this in some complex way, we guess
186     # based on the name of the compiler.
187     set ldexe $ld
188     set ldparm [string first " " $ld]
189     set ldflags ""
190     if { $ldparm > 0 } then {
191         set ldflags [string range $ld $ldparm end]
192         set ldexe [string range $ld 0 $ldparm]
193         set ld $ldexe
194     }
195     set ldexe [string replace $ldexe 0 [string last "/" $ldexe] ""]
196     if {[string match "*gcc*" $ldexe] || [string match "*++*" $ldexe]} then {
197         set ldflags "$gcc_ld_flag $ldflags"
198     }
199
200     remote_file host delete $target
201
202     set exec_output [run_host_cmd "$ld" "$ldflags $flags -o $target $objects"]
203     set exec_output [prune_warnings $exec_output]
204
205     # We don't care if we get a warning about a non-existent start
206     # symbol, since the default linker script might use ENTRY.
207     regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
208
209     if [string match "" $exec_output] then {
210         return 1
211     } else {
212         return 0
213     }
214 }
215
216 # Compile an object using cc.
217 #
218 proc default_ld_compile { cc source object } {
219     global CFLAGS
220     global CXXFLAGS
221     global srcdir
222     global subdir
223     global host_triplet
224     global gcc_gas_flag
225
226     set cc_prog $cc
227     if {[llength $cc_prog] > 1} then {
228         set cc_prog [lindex $cc_prog 0]
229     }
230     if {![is_remote host] && [which $cc_prog] == 0} then {
231         perror "$cc_prog does not exist"
232         return 0
233     }
234
235     remote_file build delete "$object"
236     remote_file host delete "$object"
237
238     set flags "-I$srcdir/$subdir"
239
240     # If we are compiling with gcc, we want to add gcc_gas_flag to
241     # flags.  Rather than determine this in some complex way, we guess
242     # based on the name of the compiler.
243     set ccexe $cc
244     set ccparm [string first " " $cc]
245     set ccflags ""
246     if { $ccparm > 0 } then {
247         set ccflags [string range $cc $ccparm end]
248         set ccexe [string range $cc 0 $ccparm]
249         set cc $ccexe
250     }
251     set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""]
252     if {[string match "*gcc*" $ccexe] || [string match "*++*" $ccexe]} then {
253         set flags "$gcc_gas_flag $flags"
254     }
255
256     if {[string match "*++*" $ccexe]} {
257         set flags "$flags $CXXFLAGS"
258     } else {
259         set flags "$flags $CFLAGS"
260     }
261
262     if [board_info [target_info name] exists multilib_flags] {
263         append flags " [board_info [target_info name] multilib_flags]"
264     }
265
266     verbose -log "$cc $flags $ccflags -c $source -o $object"
267
268     set status [remote_exec host [concat sh -c [list "$cc $flags $ccflags -c $source -o $object 2>&1"]] "" "/dev/null" "ld.tmp"]
269     remote_upload host "ld.tmp"
270     set exec_output [file_contents "ld.tmp"]
271     remote_file build delete "ld.tmp"
272     remote_file host delete "ld.tmp"
273     set exec_output [prune_warnings $exec_output]
274     if [string match "" $exec_output] then {
275         if {![file exists $object]} then {
276             regexp ".*/(\[^/\]*)$" $source all dobj
277             regsub "\\.c" $dobj ".o" realobj
278             verbose "looking for $realobj"
279             if {[remote_file host exists $realobj]} then {
280                 verbose -log "mv $realobj $object"
281                 remote_upload "$realobj" "$object"
282             } else {
283                 perror "$object not found after compilation"
284                 return 0
285             }
286         }
287         return 1
288     } else {
289         verbose -log "$exec_output"
290         perror "$source: compilation failed"
291         return 0
292     }
293 }
294
295 # Assemble a file.
296 #
297 proc default_ld_assemble { as source object } {
298     global ASFLAGS
299     global host_triplet
300
301     if ![info exists ASFLAGS] { set ASFLAGS "" }
302
303     set flags [big_or_little_endian]
304     set exec_output [run_host_cmd "$as" "$flags $ASFLAGS -o $object $source"]
305     set exec_output [prune_warnings $exec_output]
306     if [string match "" $exec_output] then {
307         return 1
308     } else {
309         perror "$source: assembly failed"
310         return 0
311     }
312 }
313
314 # Run nm on a file, putting the result in the array nm_output.
315 #
316 proc default_ld_nm { nm nmflags object } {
317     global NMFLAGS
318     global nm_output
319     global host_triplet
320
321     if {[info exists nm_output]} {
322       unset nm_output
323     }
324
325     if ![info exists NMFLAGS] { set NMFLAGS "" }
326
327     # Ensure consistent sorting of symbols
328     if {[info exists env(LC_ALL)]} {
329         set old_lc_all $env(LC_ALL)
330     }
331     set env(LC_ALL) "C"
332
333     verbose -log "$nm $NMFLAGS $nmflags $object >tmpdir/nm.out"
334
335     set status [remote_exec host [concat sh -c [list "$nm $NMFLAGS $nmflags $object 2>ld.stderr"]] "" "/dev/null" "tmpdir/nm.out"]
336     if {[info exists old_lc_all]} {
337         set env(LC_ALL) $old_lc_all
338     } else {
339         unset env(LC_ALL)
340     }
341     remote_upload host "ld.stderr"
342     remote_upload host "tmpdir/nm.out" "tmpdir/nm.out"
343     set exec_output [prune_warnings [file_contents "ld.stderr"]]
344     remote_file host delete "ld.stderr"
345     remote_file build delete "ld.stderr"
346     if [string match "" $exec_output] then {
347         set file [open tmpdir/nm.out r]
348         while { [gets $file line] != -1 } {
349             verbose "$line" 2
350             if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] \\.*(.+)$" $line whole value name] {
351                 set name [string trimleft $name "_"]
352                 verbose "Setting nm_output($name) to 0x$value" 2
353                 set nm_output($name) 0x$value
354             }
355         }
356         close $file
357         return 1
358     } else {
359         verbose -log "$exec_output"
360         perror "$object: nm failed"
361         return 0
362     }
363 }
364
365 # Define various symbols needed when not linking against all
366 # target libs.
367 proc ld_simple_link_defsyms {} {
368
369     set flags "--defsym __stack_chk_fail=0"
370
371     # ARM targets call __gccmain
372     if {[istarget arm*-*-*]       || \
373         [istarget strongarm*-*-*] || \
374         [istarget xscale*-*-*]    || \
375         [istarget thumb-*-*] } {
376         append flags " --defsym __gccmain=0"
377     }
378
379     # Windows targets need __main, prefixed with underscore.
380     if {[istarget *-*-cygwin* ] || [istarget *-*-mingw*]} {
381         append flags " --defsym ___main=0"
382     }
383
384     # PowerPC EABI code calls __eabi.
385     if {[istarget powerpc*-*-eabi*] || [istarget powerpc*-*-rtems*]} {
386         append flags " --defsym __eabi=0"
387     }
388
389     # mn10200 code calls __truncsipsi2_d0_d2.
390     if {[istarget mn10200*-*-*]} then {
391         append flags " --defsym __truncsipsi2_d0_d2=0"
392     }
393
394     # m6811/m6812 code has references to soft registers.
395     if {[istarget m6811-*-*] || [istarget m6812-*-*]} {
396         append flags " --defsym _.frame=0 --defsym _.d1=0 --defsym _.d2=0"
397         append flags " --defsym _.d3=0 --defsym _.d4=0"
398         append flags " --defsym _.tmp=0 --defsym _.xy=0 --defsym _.z=0"
399     }
400
401     # Some OpenBSD targets have ProPolice and reference __guard and
402     # __stack_smash_handler.
403     if [istarget *-*-openbsd*] {
404         append flags " --defsym __guard=0"
405         append flags " --defsym __stack_smash_handler=0"
406     }
407
408     return $flags
409 }
410
411 # run_dump_test FILE
412 # Copied from gas testsuite, tweaked and further extended.
413 #
414 # Assemble a .s file, then run some utility on it and check the output.
415 #
416 # There should be an assembly language file named FILE.s in the test
417 # suite directory, and a pattern file called FILE.d.  `run_dump_test'
418 # will assemble FILE.s, run some tool like `objdump', `objcopy', or
419 # `nm' on the .o file to produce textual output, and then analyze that
420 # with regexps.  The FILE.d file specifies what program to run, and
421 # what to expect in its output.
422 #
423 # The FILE.d file begins with zero or more option lines, which specify
424 # flags to pass to the assembler, the program to run to dump the
425 # assembler's output, and the options it wants.  The option lines have
426 # the syntax:
427 #
428 #         # OPTION: VALUE
429 #
430 # OPTION is the name of some option, like "name" or "objdump", and
431 # VALUE is OPTION's value.  The valid options are described below.
432 # Whitespace is ignored everywhere, except within VALUE.  The option
433 # list ends with the first line that doesn't match the above syntax
434 # (hmm, not great for error detection).
435 #
436 # The interesting options are:
437 #
438 #   name: TEST-NAME
439 #       The name of this test, passed to DejaGNU's `pass' and `fail'
440 #       commands.  If omitted, this defaults to FILE, the root of the
441 #       .s and .d files' names.
442 #
443 #   as: FLAGS
444 #       When assembling, pass FLAGS to the assembler.
445 #       If assembling several files, you can pass different assembler
446 #       options in the "source" directives.  See below.
447 #
448 #   ld: FLAGS
449 #       Link assembled files using FLAGS, in the order of the "source"
450 #       directives, when using multiple files.
451 #
452 #   ld_after_inputfiles: FLAGS
453 #       Similar to "ld", but put after all input files.
454 #
455 #   objcopy_linked_file: FLAGS
456 #       Run objcopy on the linked file with the specified flags.
457 #       This lets you transform the linked file using objcopy, before the
458 #       result is analyzed by an analyzer program specified below (which
459 #       may in turn *also* be objcopy).
460 #
461 #   PROG: PROGRAM-NAME
462 #       The name of the program to run to analyze the .o file produced
463 #       by the assembler or the linker output.  This can be omitted;
464 #       run_dump_test will guess which program to run by seeing which of
465 #       the flags options below is present.
466 #
467 #   objdump: FLAGS
468 #   nm: FLAGS
469 #   objcopy: FLAGS
470 #       Use the specified program to analyze the assembler or linker
471 #       output file, and pass it FLAGS, in addition to the output name.
472 #       Note that they are run with LC_ALL=C in the environment to give
473 #       consistent sorting of symbols.
474 #
475 #   source: SOURCE [FLAGS]
476 #       Assemble the file SOURCE.s using the flags in the "as" directive
477 #       and the (optional) FLAGS.  If omitted, the source defaults to
478 #       FILE.s.
479 #       This is useful if several .d files want to share a .s file.
480 #       More than one "source" directive can be given, which is useful
481 #       when testing linking.
482 #
483 #   xfail: TARGET
484 #       The test is expected to fail on TARGET.  This may occur more than
485 #       once.
486 #
487 #   target: TARGET
488 #       Only run the test for TARGET.  This may occur more than once; the
489 #       target being tested must match at least one.  You may provide target
490 #       name "cfi" for any target supporting the CFI statements.
491 #
492 #   notarget: TARGET
493 #       Do not run the test for TARGET.  This may occur more than once;
494 #       the target being tested must not match any of them.
495 #
496 #   error: REGEX
497 #       An error with message matching REGEX must be emitted for the test
498 #       to pass.  The PROG, objdump, nm and objcopy options have no
499 #       meaning and need not supplied if this is present.  Multiple "error"
500 #       directives append to the expected linker error message.
501 #
502 #   warning: REGEX
503 #       Expect a linker warning matching REGEX.  It is an error to issue
504 #       both "error" and "warning".  Multiple "warning" directives
505 #       append to the expected linker warning message.
506 #
507 # Each option may occur at most once unless otherwise mentioned.
508 #
509 # After the option lines come regexp lines.  `run_dump_test' calls
510 # `regexp_diff' to compare the output of the dumping tool against the
511 # regexps in FILE.d.  `regexp_diff' is defined in binutils-common.exp;
512 # see further comments there.
513 #
514 proc run_dump_test { name } {
515     global subdir srcdir
516     global OBJDUMP NM AS OBJCOPY READELF LD
517     global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
518     global host_triplet runtests
519     global env verbose
520
521     if [string match "*/*" $name] {
522         set file $name
523         set name [file tail $name]
524     } else {
525         set file "$srcdir/$subdir/$name"
526     }
527
528     if ![runtest_file_p $runtests $name] then {
529         return
530     }
531
532     set opt_array [slurp_options "${file}.d"]
533     if { $opt_array == -1 } {
534         perror "error reading options from $file.d"
535         unresolved $subdir/$name
536         return
537     }
538     set dumpfile tmpdir/dump.out
539     set run_ld 0
540     set run_objcopy 0
541     set opts(as) {}
542     set opts(ld) {}
543     set opts(ld_after_inputfiles) {}
544     set opts(xfail) {}
545     set opts(target) {}
546     set opts(notarget) {}
547     set opts(objdump) {}
548     set opts(nm) {}
549     set opts(objcopy) {}
550     set opts(readelf) {}
551     set opts(name) {}
552     set opts(PROG) {}
553     set opts(source) {}
554     set opts(error) {}
555     set opts(warning) {}
556     set opts(objcopy_linked_file) {}
557     set asflags(${file}.s) {}
558
559     foreach i $opt_array {
560         set opt_name [lindex $i 0]
561         set opt_val [lindex $i 1]
562         if ![info exists opts($opt_name)] {
563             perror "unknown option $opt_name in file $file.d"
564             unresolved $subdir/$name
565             return
566         }
567
568         switch -- $opt_name {
569             xfail {}
570             target {}
571             notarget {}
572             warning {}
573             error {}
574             source {
575                 # Move any source-specific as-flags to a separate array to
576                 # simplify processing.
577                 if { [llength $opt_val] > 1 } {
578                     set asflags([lindex $opt_val 0]) [lrange $opt_val 1 end]
579                     set opt_val [lindex $opt_val 0]
580                 } else {
581                     set asflags($opt_val) {}
582                 }
583             }
584             default {
585                 if [string length $opts($opt_name)] {
586                     perror "option $opt_name multiply set in $file.d"
587                     unresolved $subdir/$name
588                     return
589                 }
590
591                 # A single "# ld:" with no options should do the right thing.
592                 if { $opt_name == "ld" } {
593                     set run_ld 1
594                 }
595                 # Likewise objcopy_linked_file.
596                 if { $opt_name == "objcopy_linked_file" } {
597                     set run_objcopy 1
598                 }
599             }
600         }
601         if { $opt_name == "as" || $opt_name == "ld" } {
602             set opt_val [subst $opt_val]
603         }
604         set opts($opt_name) [concat $opts($opt_name) $opt_val]
605     }
606     foreach opt { as ld } {
607         regsub {\[big_or_little_endian\]} $opts($opt) \
608             [big_or_little_endian] opts($opt)
609     }
610
611     # Decide early whether we should run the test for this target.
612     if { [llength $opts(target)] > 0 } {
613         set targmatch 0
614         foreach targ $opts(target) {
615             if [istarget $targ] {
616                 set targmatch 1
617                 break
618             }
619         }
620         if { $targmatch == 0 } {
621             return
622         }
623     }
624     foreach targ $opts(notarget) {
625         if [istarget $targ] {
626             return
627         }
628     }
629
630     set program ""
631     # It's meaningless to require an output-testing method when we
632     # expect an error.
633     if { $opts(error) == "" } {
634         if {$opts(PROG) != ""} {
635             switch -- $opts(PROG) {
636                 objdump { set program objdump }
637                 nm      { set program nm }
638                 objcopy { set program objcopy }
639                 readelf { set program readelf }
640                 default
641                 { perror "unrecognized program option $opts(PROG) in $file.d"
642                   unresolved $subdir/$name
643                   return }
644             }
645         } else {
646         # Guess which program to run, by seeing which option was specified.
647             foreach p {objdump objcopy nm readelf} {
648                 if {$opts($p) != ""} {
649                     if {$program != ""} {
650                         perror "ambiguous dump program in $file.d"
651                         unresolved $subdir/$name
652                         return
653                     } else {
654                         set program $p
655                     }
656                 }
657             }
658         }
659         if { $program == "" && $opts(warning) == "" } {
660             perror "dump program unspecified in $file.d"
661             unresolved $subdir/$name
662             return
663         }
664     }
665
666     if { $opts(name) == "" } {
667         set testname "$subdir/$name"
668     } else {
669         set testname $opts(name)
670     }
671
672     if { $opts(source) == "" } {
673         set sourcefiles [list ${file}.s]
674     } else {
675         set sourcefiles {}
676         foreach sf $opts(source) {
677             if { [string match "/*" $sf] } {
678                 lappend sourcefiles "$sf"
679             } else {
680                 lappend sourcefiles "$srcdir/$subdir/$sf"
681             }
682             # Must have asflags indexed on source name.
683             set asflags($srcdir/$subdir/$sf) $asflags($sf)
684         }
685     }
686
687     # Time to setup xfailures.
688     foreach targ $opts(xfail) {
689         setup_xfail $targ
690     }
691
692     # Assemble each file.
693     set objfiles {}
694     for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
695         set sourcefile [lindex $sourcefiles $i]
696
697         set objfile "tmpdir/dump$i.o"
698         catch "exec rm -f $objfile" exec_output
699         lappend objfiles $objfile
700         set cmd "$AS $ASFLAGS $opts(as) $asflags($sourcefile) -o $objfile $sourcefile"
701
702         send_log "$cmd\n"
703         set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
704         remote_upload host "ld.tmp"
705         set comp_output [prune_warnings [file_contents "ld.tmp"]]
706         remote_file host delete "ld.tmp"
707         remote_file build delete "ld.tmp"
708
709         if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
710             send_log "$comp_output\n"
711             verbose "$comp_output" 3
712
713             set exitstat "succeeded"
714             if { $cmdret != 0 } { set exitstat "failed" }
715             verbose -log "$exitstat with: <$comp_output>"
716             fail $testname
717             return
718         }
719     }
720
721     set expmsg $opts(error)
722     if { $opts(warning) != "" } {
723         if { $expmsg != "" } {
724             perror "$testname: mixing error and warning test-directives"
725             return
726         }
727         set expmsg $opts(warning)
728     }
729
730     # Perhaps link the file(s).
731     if { $run_ld } {
732         set objfile "tmpdir/dump"
733         catch "exec rm -f $objfile" exec_output
734
735         # Add -L$srcdir/$subdir so that the linker command can use
736         # linker scripts in the source directory.
737         set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
738                    $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
739
740         send_log "$cmd\n"
741         set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
742         remote_upload host "ld.tmp"
743         set comp_output [file_contents "ld.tmp"]
744         remote_file host delete "ld.tmp"
745         remote_file build delete "ld.tmp"
746         set cmdret [lindex $cmdret 0]
747
748         if { $cmdret == 0 && $run_objcopy } {
749             set infile $objfile
750             set objfile "tmpdir/dump1"
751             remote_file host delete $objfile
752
753             # Note that we don't use OBJCOPYFLAGS here; any flags must be
754             # explicitly specified.
755             set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
756
757             send_log "$cmd\n"
758             set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
759             remote_upload host "ld.tmp"
760             append comp_output [file_contents "ld.tmp"]
761             remote_file host delete "ld.tmp"
762             remote_file build delete "ld.tmp"
763             set cmdret [lindex $cmdret 0]
764         }
765
766         regsub "\n$" $comp_output "" comp_output
767         if { $cmdret != 0 || $comp_output != "" || $expmsg != "" } then {
768             set exitstat "succeeded"
769             if { $cmdret != 0 } { set exitstat "failed" }
770             verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
771             send_log "$comp_output\n"
772             verbose "$comp_output" 3
773
774             if { ($expmsg == "") == ($comp_output == "") \
775                     && [regexp $expmsg $comp_output] \
776                     && (($cmdret == 0) == ($opts(error) == "")) } {
777                 # We have the expected output from ld.
778                 if { $opts(error) != "" || $program == "" } {
779                     pass $testname
780                     return
781                 }
782             } else {
783                 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
784                 fail $testname
785                 return
786             }
787         }
788     } else {
789         set objfile "tmpdir/dump0.o"
790     }
791
792     # We must not have expected failure if we get here.
793     if { $opts(error) != "" } {
794         fail $testname
795         return
796     }
797
798     set progopts1 $opts($program)
799     eval set progopts \$[string toupper $program]FLAGS
800     eval set binary \$[string toupper $program]
801
802     if { ![is_remote host] && [which $binary] == 0 } {
803         untested $testname
804         return
805     }
806
807     if { $progopts1 == "" } { set $progopts1 "-r" }
808     verbose "running $binary $progopts $progopts1" 3
809
810     # Objcopy, unlike the other two, won't send its output to stdout,
811     # so we have to run it specially.
812     set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
813     if { $program == "objcopy" } {
814         set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
815     }
816
817     # Ensure consistent sorting of symbols
818     if {[info exists env(LC_ALL)]} {
819         set old_lc_all $env(LC_ALL)
820     }
821     set env(LC_ALL) "C"
822     send_log "$cmd\n"
823     set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
824     set cmdret [lindex $cmdret 0]
825     remote_upload host "ld.tmp"
826     set comp_output [prune_warnings [file_contents "ld.tmp"]]
827     remote_file host delete "ld.tmp"
828     remote_file build delete "ld.tmp"
829     if {[info exists old_lc_all]} {
830         set env(LC_ALL) $old_lc_all
831     } else {
832         unset env(LC_ALL)
833     }
834     if { $cmdret != 0 || $comp_output != "" } {
835         send_log "exited abnormally with $cmdret, output:$comp_output\n"
836         fail $testname
837         return
838     }
839
840     if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
841     if { [regexp_diff $dumpfile "${file}.d"] } then {
842         fail $testname
843         if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
844         return
845     }
846
847     pass $testname
848 }
849
850 proc slurp_options { file } {
851     if [catch { set f [open $file r] } x] {
852         #perror "couldn't open `$file': $x"
853         perror "$x"
854         return -1
855     }
856     set opt_array {}
857     # whitespace expression
858     set ws  {[  ]*}
859     set nws {[^         ]*}
860     # whitespace is ignored anywhere except within the options list;
861     # option names are alphabetic plus underscore only.
862     set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
863     while { [gets $f line] != -1 } {
864         set line [string trim $line]
865         # Whitespace here is space-tab.
866         if [regexp $pat $line xxx opt_name opt_val] {
867             # match!
868             lappend opt_array [list $opt_name $opt_val]
869         } else {
870             break
871         }
872     }
873     close $f
874     return $opt_array
875 }
876
877 proc file_contents { filename } {
878     set file [open $filename r]
879     set contents [read $file]
880     close $file
881     return $contents
882 }
883
884 proc set_file_contents { filename contents } {
885     set file [open $filename w]
886     puts $file "$contents"
887     close $file
888 }
889
890 # Create an archive using ar
891 #
892 proc ar_simple_create { ar aropts target objects } {
893     remote_file host delete $target
894
895     set exec_output [run_host_cmd "$ar" "$aropts rc $target $objects"]
896     set exec_output [prune_warnings $exec_output]
897
898     if [string match "" $exec_output] then {
899         send_log "$exec_output\n"
900         return 1
901     } else {
902         return 0
903     }
904 }
905
906 # List contains test-items with 3 items followed by 2 lists, one item and
907 # one optional item:
908 # 0:name 1:ld/ar options 2:assembler options
909 # 3:filenames of assembler files 4: action and options. 5: name of output file
910 # 6:compiler flags (optional)
911 #
912 # Actions:
913 # objdump: Apply objdump options on result.  Compare with regex (last arg).
914 # nm: Apply nm options on result.  Compare with regex (last arg).
915 # readelf: Apply readelf options on result.  Compare with regex (last arg).
916 # ld: Don't apply anything on result.  Compare output during linking with 
917 #     regex (second arg).  Note that this *must* be the first action if it
918 #     is to be used at all; in all other cases, any output from the linker
919 #     during linking is treated as a sign of an error and FAILs the test.
920 #
921 proc run_ld_link_tests { ldtests } {
922     global ld
923     global as
924     global nm
925     global ar
926     global objdump
927     global READELF
928     global srcdir
929     global subdir
930     global env
931     global CC
932     global CFLAGS
933     global runtests
934     global exec_output
935
936     foreach testitem $ldtests {
937         set testname [lindex $testitem 0]
938
939         if ![runtest_file_p $runtests $testname] then {
940             continue
941         }
942
943         set ld_options [lindex $testitem 1]
944         set as_options [lindex $testitem 2]
945         set src_files  [lindex $testitem 3]
946         set actions [lindex $testitem 4]
947         set binfile tmpdir/[lindex $testitem 5]
948         set cflags [lindex $testitem 6]
949         set objfiles {}
950         set is_unresolved 0
951         set failed 0
952         set maybe_failed 0
953         set ld_output ""
954
955 #       verbose -log "Testname is $testname"
956 #       verbose -log "ld_options is $ld_options"
957 #       verbose -log "as_options is $as_options"
958 #       verbose -log "src_files is $src_files"
959 #       verbose -log "actions is $actions"
960 #       verbose -log "binfile is $binfile"
961
962         # Assemble each file in the test.
963         foreach src_file $src_files {
964             set objfile "tmpdir/[file rootname $src_file].o"
965             lappend objfiles $objfile
966
967             if { [file extension $src_file] == ".c" } {
968                 set as_file "tmpdir/[file rootname $src_file].s"
969                 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
970                     set is_unresolved 1
971                     break
972                 }
973             } else {
974                 set as_file "$srcdir/$subdir/$src_file"
975             }
976             if ![ld_assemble $as "$as_options $as_file" $objfile] {
977                 set is_unresolved 1
978                 break
979             }
980         }
981
982         # Catch assembler errors.
983         if { $is_unresolved != 0 } {
984             unresolved $testname
985             continue
986         }
987
988         if { [regexp ".*\\.a$" $binfile] } {
989             if { ![ar_simple_create $ar $ld_options $binfile "$objfiles"] } {
990                 fail $testname
991                 set failed 1
992             } else {
993                 set failed 0
994             }
995         } elseif { ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] } {
996             set maybe_failed 1
997             set ld_output "$exec_output"
998         } else {
999             set failed 0
1000         }
1001
1002         if { $failed == 0 } {
1003             foreach actionlist $actions {
1004                 set action [lindex $actionlist 0]
1005                 set progopts [lindex $actionlist 1]
1006
1007                 # There are actions where we run regexp_diff on the
1008                 # output, and there are other actions (presumably).
1009                 # Handling of the former look the same.
1010                 set dump_prog ""
1011                 switch -- $action {
1012                     objdump
1013                         { set dump_prog $objdump }
1014                     nm
1015                         { set dump_prog $nm }
1016                     readelf
1017                         { set dump_prog $READELF }
1018                     ld
1019                         { set dump_prog "ld" }
1020                     default
1021                         {
1022                             perror "Unrecognized action $action"
1023                             set is_unresolved 1
1024                             break
1025                         }
1026                     }
1027
1028                 if { $action == "ld" } {
1029                     set dumpfile [lindex $actionlist 1]
1030                     verbose "dumpfile is $dumpfile"
1031                     set_file_contents "tmpdir/ld.messages" "$ld_output"
1032                     verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
1033                     if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$dumpfile"] } then {
1034                         verbose "output is $ld_output" 2
1035                         set failed 1
1036                         break
1037                     }
1038                     set maybe_failed 0
1039                 } elseif { $maybe_failed != 0 } {
1040                     set failed 1
1041                     break
1042                 } elseif { $dump_prog != "" } {
1043                     set dumpfile [lindex $actionlist 2]
1044                     set binary $dump_prog
1045
1046                     # Ensure consistent sorting of symbols
1047                     if {[info exists env(LC_ALL)]} {
1048                         set old_lc_all $env(LC_ALL)
1049                     }
1050                     set env(LC_ALL) "C"
1051                     set cmd "$binary $progopts $binfile"
1052                     set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
1053                     send_log "$cmd\n"
1054                     remote_upload host "ld.stderr"
1055                     set comp_output [prune_warnings [file_contents "ld.stderr"]]
1056                     remote_file host delete "ld.stderr"
1057                     remote_file build delete "ld.stderr"
1058                     
1059                     if {[info exists old_lc_all]} {
1060                         set env(LC_ALL) $old_lc_all
1061                     } else {
1062                         unset env(LC_ALL)
1063                     }
1064
1065                     if ![string match "" $comp_output] then {
1066                         send_log "$comp_output\n"
1067                         set failed 1
1068                         break
1069                     }
1070
1071                     remote_upload host "dump.out"
1072
1073                     if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1074                         verbose "output is [file_contents "dump.out"]" 2
1075                         set failed 1
1076                         remote_file build delete "dump.out"
1077                         remote_file host delete "dump.out"
1078                         break
1079                     }
1080                     remote_file build delete "dump.out"
1081                     remote_file host delete "dump.out"
1082                 }
1083             }
1084
1085             if { $failed != 0 } {
1086                 fail $testname
1087             } else { if { $is_unresolved == 0 } {
1088                 pass $testname
1089             } }
1090         }
1091
1092         # Catch action errors.
1093         if { $is_unresolved != 0 } {
1094             unresolved $testname
1095             continue
1096         }
1097     }
1098 }
1099
1100 # This definition is taken from an unreleased version of DejaGnu.  Once
1101 # that version gets released, and has been out in the world for a few
1102 # months at least, it may be safe to delete this copy.
1103 if ![string length [info proc prune_warnings]] {
1104     #
1105     # prune_warnings -- delete various system verbosities from TEXT
1106     #
1107     # An example is:
1108     # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1109     #
1110     # Sites with particular verbose os's may wish to override this in site.exp.
1111     #
1112     proc prune_warnings { text } {
1113         # This is from sun4's.  Do it for all machines for now.
1114         # The "\\1" is to try to preserve a "\n" but only if necessary.
1115         regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1116
1117         # It might be tempting to get carried away and delete blank lines, etc.
1118         # Just delete *exactly* what we're ask to, and that's it.
1119         return $text
1120     }
1121 }
1122
1123 # targets_to_xfail is a list of target triplets to be xfailed.
1124 # ldtests contains test-items with 3 items followed by 1 lists, 2 items
1125 # and 3 optional items:
1126 #   0:name
1127 #   1:ld options
1128 #   2:assembler options
1129 #   3:filenames of source files
1130 #   4:name of output file
1131 #   5:expected output
1132 #   6:compiler flags (optional)
1133 #   7:language (optional)
1134 #   8:linker warning (optional)
1135
1136 proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
1137     global ld
1138     global as
1139     global srcdir
1140     global subdir
1141     global env
1142     global CC
1143     global CXX
1144     global CFLAGS
1145     global CXXFLAGS
1146     global errcnt
1147     global exec_output
1148
1149     foreach testitem $ldtests {
1150         foreach target $targets_to_xfail {
1151             setup_xfail $target
1152         }
1153         set testname [lindex $testitem 0]
1154         set ld_options [lindex $testitem 1]
1155         set as_options [lindex $testitem 2]
1156         set src_files  [lindex $testitem 3]
1157         set binfile tmpdir/[lindex $testitem 4]
1158         set expfile [lindex $testitem 5]
1159         set cflags [lindex $testitem 6]
1160         set lang [lindex $testitem 7]
1161         set warning [lindex $testitem 8]
1162         set objfiles {}
1163         set failed 0
1164
1165 #       verbose -log "Testname is $testname"
1166 #       verbose -log "ld_options is $ld_options"
1167 #       verbose -log "as_options is $as_options"
1168 #       verbose -log "src_files is $src_files"
1169 #       verbose -log "actions is $actions"
1170 #       verbose -log "binfile is $binfile"
1171
1172         # Assemble each file in the test.
1173         foreach src_file $src_files {
1174             set objfile "tmpdir/[file rootname $src_file].o"
1175             lappend objfiles $objfile
1176
1177             # We ignore warnings since some compilers may generate
1178             # incorrect section attributes and the assembler will warn
1179             # them.
1180             if { [ string match "c++" $lang ] } {
1181                 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1182             } else {
1183                 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1184             }
1185
1186             # We have to use $CC to build PIE and shared library.
1187             if { [ string match "c" $lang ] } {
1188                 set link_proc ld_simple_link
1189                 set link_cmd $CC
1190             } elseif { [ string match "c++" $lang ] } {
1191                 set link_proc ld_simple_link
1192                 set link_cmd $CXX
1193             } elseif { [ string match "-shared" $ld_options ] \
1194                  || [ string match "-pie" $ld_options ] } {
1195                 set link_proc ld_simple_link
1196                 set link_cmd $CC
1197             } else {
1198                 set link_proc ld_link
1199                 set link_cmd $ld
1200             }
1201
1202             if ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1203                 set failed 1
1204             } else {
1205                 set failed 0
1206             }
1207
1208             # Check if exec_output is expected.
1209             if { $warning != "" } then {
1210                 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1211                 if { [regexp $warning $exec_output] } then {
1212                     set failed 0
1213                 } else {
1214                     set failed 1
1215                 }
1216             }
1217
1218             if { $failed == 0 } {
1219                 send_log "Running: $binfile > $binfile.out\n"
1220                 verbose "Running: $binfile > $binfile.out"
1221                 catch "exec $binfile > $binfile.out" exec_output
1222             
1223                 if ![string match "" $exec_output] then {
1224                     send_log "$exec_output\n"
1225                     verbose "$exec_output" 1
1226                     set failed 1
1227                 } else {
1228                     send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1229                     verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1230                     catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1231                     set exec_output [prune_warnings $exec_output]
1232
1233                     if ![string match "" $exec_output] then {
1234                         send_log "$exec_output\n"
1235                         verbose "$exec_output" 1
1236                         set failed 1
1237                     }
1238                 }
1239             }
1240
1241             if { $failed != 0 } {
1242                 fail $testname
1243             } else {
1244                 set errcnt 0
1245                 pass $testname
1246             }
1247         }
1248     }
1249 }
1250
1251 # List contains test-items with 3 items followed by 2 lists, one item and
1252 # one optional item:
1253 #  0:name
1254 #  1:ld or ar options
1255 #  2:compile options
1256 #  3:filenames of source files
1257 #  4:action and options.
1258 #  5:name of output file
1259 #  6:language (optional)
1260 #
1261 # Actions:
1262 # objdump: Apply objdump options on result.  Compare with regex (last arg).
1263 # nm: Apply nm options on result.  Compare with regex (last arg).
1264 # readelf: Apply readelf options on result.  Compare with regex (last arg).
1265 #
1266 proc run_cc_link_tests { ldtests } {
1267     global nm
1268     global objdump
1269     global READELF
1270     global srcdir
1271     global subdir
1272     global env
1273     global CC
1274     global CXX
1275     global CFLAGS
1276     global CXXFLAGS
1277     global ar
1278
1279     foreach testitem $ldtests {
1280         set testname [lindex $testitem 0]
1281         set ldflags [lindex $testitem 1]
1282         set cflags [lindex $testitem 2]
1283         set src_files  [lindex $testitem 3]
1284         set actions [lindex $testitem 4]
1285         set binfile tmpdir/[lindex $testitem 5]
1286         set lang [lindex $testitem 6]
1287         set objfiles {}
1288         set is_unresolved 0
1289         set failed 0
1290
1291         # Compile each file in the test.
1292         foreach src_file $src_files {
1293             set objfile "tmpdir/[file rootname $src_file].o"
1294             lappend objfiles $objfile
1295
1296             # We ignore warnings since some compilers may generate
1297             # incorrect section attributes and the assembler will warn
1298             # them.
1299             if { [ string match "c++" $lang ] } {
1300                 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1301             } else {
1302                 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1303             }
1304         }
1305
1306         # Clear error and warning counts.
1307         reset_vars
1308
1309         if { [ string match "c++" $lang ] } {
1310             set cc_cmd $CXX
1311         } else {
1312             set cc_cmd $CC
1313         }
1314
1315         if { [regexp ".*\\.a$" $binfile] } {
1316             if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
1317                 fail $testname
1318                 set failed 1
1319             } else {
1320                 set failed 0
1321             }
1322         } elseif { ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] } {
1323             fail $testname
1324             set failed 1
1325         } else {
1326             set failed 0
1327         }
1328
1329         if { $failed == 0 } {
1330             foreach actionlist $actions {
1331                 set action [lindex $actionlist 0]
1332                 set progopts [lindex $actionlist 1]
1333
1334                 # There are actions where we run regexp_diff on the
1335                 # output, and there are other actions (presumably).
1336                 # Handling of the former look the same.
1337                 set dump_prog ""
1338                 switch -- $action {
1339                     objdump
1340                         { set dump_prog $objdump }
1341                     nm
1342                         { set dump_prog $nm }
1343                     readelf
1344                         { set dump_prog $READELF }
1345                     default
1346                         {
1347                             perror "Unrecognized action $action"
1348                             set is_unresolved 1
1349                             break
1350                         }
1351                     }
1352
1353                 if { $dump_prog != "" } {
1354                     set dumpfile [lindex $actionlist 2]
1355                     set binary $dump_prog
1356
1357                     # Ensure consistent sorting of symbols
1358                     if {[info exists env(LC_ALL)]} {
1359                         set old_lc_all $env(LC_ALL)
1360                     }
1361                     set env(LC_ALL) "C"
1362                     set cmd "$binary $progopts $binfile > dump.out"
1363                     send_log "$cmd\n"
1364                     catch "exec $cmd" comp_output
1365                     if {[info exists old_lc_all]} {
1366                         set env(LC_ALL) $old_lc_all
1367                     } else {
1368                         unset env(LC_ALL)
1369                     }
1370                     set comp_output [prune_warnings $comp_output]
1371
1372                     if ![string match "" $comp_output] then {
1373                         send_log "$comp_output\n"
1374                         set failed 1
1375                         break
1376                     }
1377
1378                     if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1379                         verbose "output is [file_contents "dump.out"]" 2
1380                         set failed 1
1381                         break
1382                     }
1383                 }
1384             }
1385
1386             if { $failed != 0 } {
1387                 fail $testname
1388             } else { if { $is_unresolved == 0 } {
1389                 pass $testname
1390             } }
1391         }
1392
1393         # Catch action errors.
1394         if { $is_unresolved != 0 } {
1395             unresolved $testname
1396             continue
1397         }
1398     }
1399 }
1400
1401 # Returns true if --gc-sections is supported on the target.
1402
1403 proc check_gc_sections_available { } {
1404     global gc_sections_available_saved
1405     global ld
1406     
1407     if {![info exists gc_sections_available_saved]} {
1408         # Some targets don't support gc-sections despite whatever's
1409         # advertised by ld's options.
1410         if {[istarget arc-*-*]
1411              || [istarget d30v-*-*]
1412              || [istarget dlx-*-*]
1413              || [istarget i960-*-*]
1414              || [istarget or32-*-*]
1415              || [istarget pj*-*-*]
1416              || [istarget alpha-*-*]
1417              || [istarget hppa64-*-*]
1418              || [istarget i370-*-*]
1419              || [istarget i860-*-*]
1420              || [istarget ia64-*-*]
1421              || [istarget mep-*-*]
1422              || [istarget mn10200-*-*]
1423              || [istarget *-*-cygwin]
1424              || [istarget *-*-mingw*] } {
1425             set gc_sections_available_saved 0
1426             return 0
1427         }
1428
1429         # elf2flt uses -q (--emit-relocs), which is incompatible with
1430         # --gc-sections.
1431         if { [board_info target exists ldflags]
1432              && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1433             set gc_sections_available_saved 0
1434             return 0
1435         }
1436
1437         # Check if the ld used by gcc supports --gc-sections.
1438         set ld_output [remote_exec host $ld "--help"]
1439         if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1440             set gc_sections_available_saved 1
1441         } else {
1442             set gc_sections_available_saved 0
1443         }
1444     }
1445     return $gc_sections_available_saved
1446 }
1447
1448 # Returns true if the target ld supports the plugin API.
1449 proc check_plugin_api_available { } {
1450     global plugin_api_available_saved
1451     global ld
1452     if {![info exists plugin_api_available_saved]} {
1453         # Check if the ld used by gcc supports --plugin.
1454         set ld_output [remote_exec host $ld "--help"]
1455         if { [ string first "-plugin" $ld_output ] >= 0 } {
1456             set plugin_api_available_saved 1
1457         } else {
1458             set plugin_api_available_saved 0
1459         }
1460     }
1461     return $plugin_api_available_saved
1462 }
1463
1464 # Check if the assembler supports CFI statements.
1465
1466 proc check_as_cfi { } {
1467     global check_as_cfi_result
1468     global as
1469     if [info exists check_as_cfi_result] {
1470         return $check_as_cfi_result
1471     }
1472     set as_file "tmpdir/check_as_cfi.s"
1473     set as_fh [open $as_file w 0666]
1474     puts $as_fh "# Generated file. DO NOT EDIT"
1475     puts $as_fh "\t.cfi_startproc"
1476     puts $as_fh "\t.cfi_endproc"
1477     close $as_fh
1478     remote_download host $as_file
1479     verbose -log "Checking CFI support:"
1480     rename "perror" "check_as_cfi_perror"
1481     proc perror { args } { }
1482     set success [ld_assemble $as $as_file "/dev/null"]
1483     rename "perror" ""
1484     rename "check_as_cfi_perror" "perror"
1485     #remote_file host delete $as_file
1486     set check_as_cfi_result $success
1487     return $success
1488 }
1489
1490 # Provide virtual target "cfi" for targets supporting CFI.
1491
1492 rename "istarget" "istarget_ld"
1493 proc istarget { target } {
1494     if {$target == "cfi"} {
1495         return [check_as_cfi]
1496     }
1497     return [istarget_ld $target]
1498 }