]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - ld/testsuite/lib/ld-lib.exp
binutils/testsuite/
[thirdparty/binutils-gdb.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 }