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