]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - ld/testsuite/lib/ld-lib.exp
ld/xc16x: This target does not support -shared
[thirdparty/binutils-gdb.git] / ld / testsuite / lib / ld-lib.exp
1 # Support routines for LD testsuite.
2 # Copyright (C) 1994-2016 Free Software Foundation, Inc.
3 #
4 # This file is part of the GNU Binutils.
5 #
6 # This file is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 # MA 02110-1301, USA.
20
21 proc load_common_lib { name } {
22 global srcdir
23 load_file $srcdir/../../binutils/testsuite/lib/$name
24 }
25
26 load_common_lib binutils-common.exp
27
28 # Returns 1 if the gcc for the target is at least version MAJOR.MINOR
29 # Returns 0 otherwise.
30 #
31 proc at_least_gcc_version { major minor } {
32 global CC
33
34 if {![info exists CC]} {
35 set CC [find_gcc]
36 }
37 if { $CC == "" } {
38 return 0
39 }
40 set state [remote_exec host $CC --version]
41 if { [lindex $state 0] != 0 } {
42 return 0;
43 }
44 set tmp "[lindex $state 1]\n"
45 # Look for (eg) 4.6.1 in the version output.
46 set ver_re "\[^\\.0-9\]+(\[1-9\]\[0-9\]*)\\.(\[0-9\]+)(?:\\.\[0-9\]+)?"
47 regexp $ver_re $tmp fred maj min
48 verbose "gcc version: $tmp"
49 if { ![info exists maj] || ![info exists min] } then {
50 perror "can't decipher gcc version number, fix the framework!"
51 return 0
52 }
53 verbose "major gcc version is $maj, want at least $major"
54 if { $maj == $major } then {
55 verbose "minor gcc version is $min, want at least $minor"
56 return [expr $min >= $minor]
57 } else {
58 return [expr $maj > $major]
59 }
60 }
61
62 # Extract and print the version number of ld.
63 #
64 proc default_ld_version { ld } {
65 global host_triplet
66
67 if { ![is_remote host] && [which $ld] == 0 } then {
68 perror "$ld does not exist"
69 exit 1
70 }
71
72 remote_exec host "$ld --version" "" "/dev/null" "ld.version"
73 remote_upload host "ld.version"
74 set tmp [prune_warnings [file_contents "ld.version"]]
75 remote_file build delete "ld.version"
76 remote_file host delete "ld.version"
77
78 regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number
79 if [info exists number] then {
80 clone_output "$ld $number\n"
81 }
82 }
83
84 proc run_host_cmd { prog command } {
85 global link_output
86 global gcc_B_opt
87 global ld_L_opt
88
89 if { ![is_remote host] && [which "$prog"] == 0 } then {
90 perror "$prog does not exist"
91 return 0
92 }
93
94 # If we are compiling with gcc, we want to add gcc_B_opt and
95 # ld_L_opt to flags. However, if $prog already has -B options,
96 # which might be the case when running gcc out of a build
97 # directory, we want our -B options to come first.
98 set gccexe $prog
99 set gccparm [string first " " $gccexe]
100 set gccflags ""
101 if { $gccparm > 0 } then {
102 set gccflags [string range $gccexe $gccparm end]
103 set gccexe [string range $gccexe 0 $gccparm]
104 set prog $gccexe
105 }
106 set gccexe [string replace $gccexe 0 [string last "/" $gccexe] ""]
107 if {[string match "*cc*" $gccexe] || [string match "*++*" $gccexe]} then {
108 set gccflags "$gcc_B_opt $gccflags $ld_L_opt"
109 }
110
111 verbose -log "$prog $gccflags $command"
112 set status [remote_exec host [concat sh -c [list "$prog $gccflags $command 2>&1"]] "" "/dev/null" "ld.tmp"]
113 remote_upload host "ld.tmp"
114 set link_output [file_contents "ld.tmp"]
115 regsub "\n$" $link_output "" link_output
116 if { [lindex $status 0] != 0 && [string match "" $link_output] } then {
117 append link_output "child process exited abnormally"
118 }
119 remote_file build delete ld.tmp
120 remote_file host delete ld.tmp
121
122 if [string match "" $link_output] then {
123 return ""
124 }
125
126 verbose -log "$link_output"
127 return "$link_output"
128 }
129
130 proc run_host_cmd_yesno { prog command } {
131 global exec_output
132 global errcnt warncnt
133
134 set exec_output [prune_warnings [run_host_cmd "$prog" "$command"]]
135 # Ignore error and warning.
136 set errcnt 0
137 set warncnt 0
138 if [string match "" $exec_output] then {
139 return 1;
140 }
141 return 0;
142 }
143
144 # Link an object using relocation.
145 #
146 proc default_ld_relocate { ld target objects } {
147 global HOSTING_EMU
148
149 remote_file host delete $target
150 return [run_host_cmd_yesno "$ld" "$HOSTING_EMU -o $target -r $objects"]
151 }
152
153 # Check to see if ld is being invoked with a non-endian output format
154 #
155 proc is_endian_output_format { object_flags } {
156
157 if {[string match "*-oformat binary*" $object_flags] || \
158 [string match "*-oformat ieee*" $object_flags] || \
159 [string match "*-oformat ihex*" $object_flags] || \
160 [string match "*-oformat netbsd-core*" $object_flags] || \
161 [string match "*-oformat srec*" $object_flags] || \
162 [string match "*-oformat tekhex*" $object_flags] || \
163 [string match "*-oformat trad-core*" $object_flags] } then {
164 return 0
165 } else {
166 return 1
167 }
168 }
169
170 # Look for big-endian or little-endian switches in the multlib
171 # options and translate these into a -EB or -EL switch. Note
172 # we cannot rely upon proc process_multilib_options to do this
173 # for us because for some targets the compiler does not support
174 # -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
175 # the site.exp file will include the switch "-mbig-endian"
176 # (rather than "big-endian") which is not detected by proc
177 # process_multilib_options.
178 #
179 proc big_or_little_endian {} {
180
181 if [board_info [target_info name] exists multilib_flags] {
182 set tmp_flags " [board_info [target_info name] multilib_flags]"
183
184 foreach x $tmp_flags {
185 case $x in {
186 {*big*endian eb EB -eb -EB -mb -meb} {
187 set flags " -EB"
188 return $flags
189 }
190 {*little*endian el EL -el -EL -ml -mel} {
191 set flags " -EL"
192 return $flags
193 }
194 }
195 }
196 }
197
198 set flags ""
199 return $flags
200 }
201
202 # Link a program using ld.
203 #
204 proc default_ld_link { ld target objects } {
205 global HOSTING_EMU
206 global HOSTING_CRT0
207 global HOSTING_SCRT0
208 global HOSTING_LIBS
209 global HOSTING_SLIBS
210 global LIBS
211 global host_triplet
212 global link_output
213 global exec_output
214
215 if { [ string match "* -pie *" $objects ] } {
216 set objs "$HOSTING_SCRT0 $objects"
217 set libs "$LIBS $HOSTING_SLIBS"
218 } else {
219 set objs "$HOSTING_CRT0 $objects"
220 set libs "$LIBS $HOSTING_LIBS"
221 }
222
223 if [is_endian_output_format $objects] then {
224 set flags [big_or_little_endian]
225 } else {
226 set flags ""
227 }
228
229 remote_file host delete $target
230
231 return [run_host_cmd_yesno "$ld" "$HOSTING_EMU $flags -o $target $objs $libs"]
232 }
233
234 # Link a program using ld, without including any libraries.
235 #
236 proc default_ld_simple_link { ld target objects } {
237 global host_triplet
238 global exec_output
239
240 set flags ""
241 if [is_endian_output_format $objects] then {
242 set flags [big_or_little_endian]
243 }
244
245 remote_file host delete $target
246 set exec_output [run_host_cmd "$ld" "$flags -o $target $objects"]
247 set exec_output [prune_warnings $exec_output]
248
249 # We don't care if we get a warning about a non-existent start
250 # symbol, since the default linker script might use ENTRY.
251 regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
252
253 return [string match "" $exec_output]
254 }
255
256 # Compile an object using cc.
257 #
258 proc default_ld_compile { cc source object } {
259 global CFLAGS
260 global CXXFLAGS
261 global srcdir
262 global subdir
263 global host_triplet
264 global gcc_B_opt
265
266 set cc_prog $cc
267 if {[llength $cc_prog] > 1} then {
268 set cc_prog [lindex $cc_prog 0]
269 }
270 if {![is_remote host] && [which $cc_prog] == 0} then {
271 perror "$cc_prog does not exist"
272 return 0
273 }
274
275 remote_file build delete "$object"
276 remote_file host delete "$object"
277
278 set flags "$gcc_B_opt -I$srcdir/$subdir"
279
280 # If we are compiling with gcc, we want to add gcc_B_opt to flags.
281 # However, if $prog already has -B options, which might be the
282 # case when running gcc out of a build directory, we want our -B
283 # options to come first.
284 set ccexe $cc
285 set ccparm [string first " " $cc]
286 set ccflags ""
287 if { $ccparm > 0 } then {
288 set ccflags [string range $cc $ccparm end]
289 set ccexe [string range $cc 0 $ccparm]
290 set cc $ccexe
291 }
292
293 set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""]
294 if {[string match "*++*" $ccexe]} {
295 append flags " $CXXFLAGS"
296 } else {
297 append flags " $CFLAGS"
298 }
299
300 if [board_info [target_info name] exists cflags] {
301 append flags " [board_info [target_info name] cflags]"
302 }
303
304 if [board_info [target_info name] exists multilib_flags] {
305 append flags " [board_info [target_info name] multilib_flags]"
306 }
307
308 set cmd "$cc $flags $ccflags -c $source -o $object"
309 verbose -log "$cmd"
310
311 set status [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
312 remote_upload host "ld.tmp"
313 set exec_output [file_contents "ld.tmp"]
314 remote_file build delete "ld.tmp"
315 remote_file host delete "ld.tmp"
316 set exec_output [prune_warnings $exec_output]
317 if [string match "" $exec_output] then {
318 if {![file exists $object]} then {
319 regexp ".*/(\[^/\]*)$" $source all dobj
320 regsub "\\.c" $dobj ".o" realobj
321 verbose "looking for $realobj"
322 if {[remote_file host exists $realobj]} then {
323 verbose -log "mv $realobj $object"
324 remote_upload "$realobj" "$object"
325 } else {
326 perror "$object not found after compilation"
327 return 0
328 }
329 }
330 return 1
331 } else {
332 verbose -log "$exec_output"
333 perror "$source: compilation failed"
334 return 0
335 }
336 }
337
338 # Assemble a file.
339 #
340 proc default_ld_assemble { as in_flags source object } {
341 global ASFLAGS
342 global host_triplet
343 global srcdir
344 global subdir
345
346 if ![info exists ASFLAGS] { set ASFLAGS "" }
347
348 set flags "[big_or_little_endian] -I$srcdir/$subdir"
349 set exec_output [run_host_cmd "$as" "$flags $in_flags $ASFLAGS -o $object $source"]
350 set exec_output [prune_warnings $exec_output]
351 if [string match "" $exec_output] then {
352 return 1
353 } else {
354 perror "$source: assembly failed"
355 return 0
356 }
357 }
358
359 # Run nm on a file, putting the result in the array nm_output.
360 #
361 proc default_ld_nm { nm nmflags object } {
362 global NMFLAGS
363 global nm_output
364 global host_triplet
365
366 if {[info exists nm_output]} {
367 unset nm_output
368 }
369
370 if ![info exists NMFLAGS] { set NMFLAGS "" }
371
372 # Ensure consistent sorting of symbols
373 if {[info exists env(LC_ALL)]} {
374 set old_lc_all $env(LC_ALL)
375 }
376 set env(LC_ALL) "C"
377
378 verbose -log "$nm $NMFLAGS $nmflags $object >tmpdir/nm.out"
379
380 set status [remote_exec host [concat sh -c [list "$nm $NMFLAGS $nmflags $object 2>ld.stderr"]] "" "/dev/null" "tmpdir/nm.out"]
381 if {[info exists old_lc_all]} {
382 set env(LC_ALL) $old_lc_all
383 } else {
384 unset env(LC_ALL)
385 }
386 remote_upload host "ld.stderr"
387 remote_upload host "tmpdir/nm.out" "tmpdir/nm.out"
388 set exec_output [prune_warnings [file_contents "ld.stderr"]]
389 remote_file host delete "ld.stderr"
390 remote_file build delete "ld.stderr"
391 if [string match "" $exec_output] then {
392 set file [open tmpdir/nm.out r]
393 while { [gets $file line] != -1 } {
394 verbose "$line" 2
395 if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] \\.*(.+)$" $line whole value name] {
396 set name [string trimleft $name "_"]
397 verbose "Setting nm_output($name) to 0x$value" 2
398 set nm_output($name) 0x$value
399 }
400 }
401 close $file
402 return 1
403 } else {
404 verbose -log "$exec_output"
405 perror "$object: nm failed"
406 return 0
407 }
408 }
409
410 # Define various symbols needed when not linking against all
411 # target libs.
412 proc ld_simple_link_defsyms {} {
413
414 set flags "--defsym __stack_chk_fail=0"
415
416 # ARM targets call __gccmain
417 if {[istarget arm*-*-*]} {
418 append flags " --defsym __gccmain=0"
419 }
420
421 # Windows targets need __main, some prefixed with underscore.
422 if {[istarget *-*-cygwin* ] || [istarget *-*-mingw*]} {
423 append flags " --defsym __main=0 --defsym ___main=0"
424 }
425
426 # PowerPC EABI code calls __eabi.
427 if {[istarget powerpc*-*-eabi*] || [istarget powerpc*-*-rtems*]} {
428 append flags " --defsym __eabi=0"
429 }
430
431 # mn10200 code calls __truncsipsi2_d0_d2.
432 if {[istarget mn10200*-*-*]} then {
433 append flags " --defsym __truncsipsi2_d0_d2=0"
434 }
435
436 # m6811/m6812 code has references to soft registers.
437 if {[istarget m6811-*-*] || [istarget m6812-*-*] || [istarget m68hc1*-*-*]} {
438 append flags " --defsym _.frame=0 --defsym _.d1=0 --defsym _.d2=0"
439 append flags " --defsym _.d3=0 --defsym _.d4=0"
440 append flags " --defsym _.tmp=0 --defsym _.xy=0 --defsym _.z=0"
441 }
442
443 # Some OpenBSD targets have ProPolice and reference __guard and
444 # __stack_smash_handler.
445 if [istarget *-*-openbsd*] {
446 append flags " --defsym __guard=0"
447 append flags " --defsym __stack_smash_handler=0"
448 }
449
450 return $flags
451 }
452
453 # run_dump_test FILE (optional:) EXTRA_OPTIONS
454 # Copied from gas testsuite, tweaked and further extended.
455 #
456 # Assemble a .s file, then run some utility on it and check the output.
457 #
458 # There should be an assembly language file named FILE.s in the test
459 # suite directory, and a pattern file called FILE.d. `run_dump_test'
460 # will assemble FILE.s, run some tool like `objdump', `objcopy', or
461 # `nm' on the .o file to produce textual output, and then analyze that
462 # with regexps. The FILE.d file specifies what program to run, and
463 # what to expect in its output.
464 #
465 # The FILE.d file begins with zero or more option lines, which specify
466 # flags to pass to the assembler, the program to run to dump the
467 # assembler's output, and the options it wants. The option lines have
468 # the syntax:
469 #
470 # # OPTION: VALUE
471 #
472 # OPTION is the name of some option, like "name" or "objdump", and
473 # VALUE is OPTION's value. The valid options are described below.
474 # Whitespace is ignored everywhere, except within VALUE. The option
475 # list ends with the first line that doesn't match the above syntax
476 # (hmm, not great for error detection).
477 #
478 # The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of
479 # two-element lists. The first element of each is an option name, and
480 # the second additional arguments to be added on to the end of the
481 # option list as given in FILE.d. (If omitted, no additional options
482 # are added.)
483 #
484 # The interesting options are:
485 #
486 # name: TEST-NAME
487 # The name of this test, passed to DejaGNU's `pass' and `fail'
488 # commands. If omitted, this defaults to FILE, the root of the
489 # .s and .d files' names.
490 #
491 # as: FLAGS
492 # When assembling, pass FLAGS to the assembler.
493 # If assembling several files, you can pass different assembler
494 # options in the "source" directives. See below.
495 #
496 # ld: FLAGS
497 # Link assembled files using FLAGS, in the order of the "source"
498 # directives, when using multiple files.
499 #
500 # ld_after_inputfiles: FLAGS
501 # Similar to "ld", but put after all input files.
502 #
503 # objcopy_objects: FLAGS
504 # Run objcopy with the specified flags after assembling any source
505 # that has the special marker RUN_OBJCOPY in the source specific
506 # flags.
507 #
508 # objcopy_linked_file: FLAGS
509 # Run objcopy on the linked file with the specified flags.
510 # This lets you transform the linked file using objcopy, before the
511 # result is analyzed by an analyzer program specified below (which
512 # may in turn *also* be objcopy).
513 #
514 # PROG: PROGRAM-NAME
515 # The name of the program to run to analyze the .o file produced
516 # by the assembler or the linker output. This can be omitted;
517 # run_dump_test will guess which program to run by seeing which of
518 # the flags options below is present.
519 #
520 # readelf: FLAGS
521 # objdump: FLAGS
522 # nm: FLAGS
523 # objcopy: FLAGS
524 # Use the specified program to analyze the assembler or linker
525 # output file, and pass it FLAGS, in addition to the output name.
526 # Note that they are run with LC_ALL=C in the environment to give
527 # consistent sorting of symbols.
528 #
529 # source: SOURCE [FLAGS]
530 # Assemble the file SOURCE.s using the flags in the "as" directive
531 # and the (optional) FLAGS. If omitted, the source defaults to
532 # FILE.s.
533 # This is useful if several .d files want to share a .s file.
534 # More than one "source" directive can be given, which is useful
535 # when testing linking.
536 #
537 # dump: DUMP
538 # Match against DUMP.d. If omitted, this defaults to FILE.d. This
539 # is useful if several .d files differ by options only. Options are
540 # always read from FILE.d.
541 #
542 # xfail: TARGET
543 # The test is expected to fail on TARGET. This may occur more than
544 # once.
545 #
546 # target: TARGET
547 # Only run the test for TARGET. This may occur more than once; the
548 # target being tested must match at least one. You may provide target
549 # name "cfi" for any target supporting the CFI statements.
550 #
551 # notarget: TARGET
552 # Do not run the test for TARGET. This may occur more than once;
553 # the target being tested must not match any of them.
554 #
555 # error: REGEX
556 # An error with message matching REGEX must be emitted for the test
557 # to pass. The PROG, readelf, objdump, nm and objcopy options have
558 # no meaning and need not be supplied if this is present. Multiple
559 # "error" directives append to the expected linker error message.
560 #
561 # error_output: FILE
562 # Means the same as 'error', except the regular expression lines
563 # are contains in FILE.
564 #
565 # warning: REGEX
566 # Expect a linker warning matching REGEX. It is an error to issue
567 # both "error" and "warning". Multiple "warning" directives
568 # append to the expected linker warning message.
569 #
570 # warning_output: FILE
571 # Means the same as 'warning', except the regular expression
572 # lines are contains in FILE.
573 #
574 # map: FILE
575 # Adding this option will cause the linker to generate a linker
576 # map file, using the -Map=MAPFILE command line option. If
577 # there is no -Map=MAPFILE in the 'ld: FLAGS' then one will be
578 # added to the linker command line. The contents of the
579 # generated MAPFILE are then compared against the regexp lines
580 # in FILE using `regexp_diff' (see below for details).
581 #
582 # Each option may occur at most once unless otherwise mentioned.
583 #
584 # After the option lines come regexp lines. `run_dump_test' calls
585 # `regexp_diff' to compare the output of the dumping tool against the
586 # regexps in FILE.d. `regexp_diff' is defined in binutils-common.exp;
587 # see further comments there.
588 #
589 proc run_dump_test { name {extra_options {}} } {
590 global subdir srcdir
591 global OBJDUMP NM AS OBJCOPY READELF LD
592 global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
593 global host_triplet runtests
594 global env verbose
595 global ld_elf_shared_opt
596
597 if { [is_elf_format] && [check_shared_lib_support] } {
598 set ld_extra_opt "$ld_elf_shared_opt"
599 } else {
600 set ld_extra_opt ""
601 }
602
603 if [string match "*/*" $name] {
604 set file $name
605 set name [file tail $name]
606 } else {
607 set file "$srcdir/$subdir/$name"
608 }
609
610 if ![runtest_file_p $runtests $name] then {
611 return
612 }
613
614 set opt_array [slurp_options "${file}.d"]
615 if { $opt_array == -1 } {
616 perror "error reading options from $file.d"
617 unresolved $subdir/$name
618 return
619 }
620 set dumpfile tmpdir/dump.out
621 set run_ld 0
622 set run_objcopy 0
623 set opts(as) {}
624 set opts(ld) {}
625 set opts(ld_after_inputfiles) {}
626 set opts(xfail) {}
627 set opts(target) {}
628 set opts(notarget) {}
629 set opts(objdump) {}
630 set opts(nm) {}
631 set opts(objcopy) {}
632 set opts(readelf) {}
633 set opts(name) {}
634 set opts(PROG) {}
635 set opts(source) {}
636 set opts(dump) {}
637 set opts(error) {}
638 set opts(warning) {}
639 set opts(error_output) {}
640 set opts(warning_output) {}
641 set opts(objcopy_linked_file) {}
642 set opts(objcopy_objects) {}
643 set opts(map) {}
644
645 foreach i $opt_array {
646 set opt_name [lindex $i 0]
647 set opt_val [lindex $i 1]
648 if ![info exists opts($opt_name)] {
649 perror "unknown option $opt_name in file $file.d"
650 unresolved $subdir/$name
651 return
652 }
653
654 switch -- $opt_name {
655 xfail {}
656 target {}
657 notarget {}
658 warning {}
659 error {}
660 source {
661 # Move any source-specific as-flags to a separate list to
662 # simplify processing.
663 if { [llength $opt_val] > 1 } {
664 lappend asflags [lrange $opt_val 1 end]
665 set opt_val [lindex $opt_val 0]
666 } else {
667 lappend asflags {}
668 }
669 }
670 default {
671 if [string length $opts($opt_name)] {
672 perror "option $opt_name multiply set in $file.d"
673 unresolved $subdir/$name
674 return
675 }
676
677 # A single "# ld:" with no options should do the right thing.
678 if { $opt_name == "ld" } {
679 set run_ld 1
680 }
681 # Likewise objcopy_linked_file.
682 if { $opt_name == "objcopy_linked_file" } {
683 set run_objcopy 1
684 }
685 }
686 }
687 if { $opt_name == "as" || $opt_name == "ld" } {
688 set opt_val [subst $opt_val]
689 }
690
691 # Append differently whether it's a message (without space) or
692 # an option or list (with space).
693 switch -- $opt_name {
694 warning -
695 error {
696 append opts($opt_name) $opt_val
697 }
698 default {
699 set opts($opt_name) [concat $opts($opt_name) $opt_val]
700 }
701 }
702 }
703
704 foreach i $extra_options {
705 set opt_name [lindex $i 0]
706 set opt_val [lindex $i 1]
707 if ![info exists opts($opt_name)] {
708 perror "unknown option $opt_name given in extra_opts"
709 unresolved $subdir/$name
710 return
711 }
712 # Add extra option to end of existing option, adding space
713 # if necessary.
714 if { ![regexp "warning|error" $opt_name]
715 && [string length $opts($opt_name)] } {
716 append opts($opt_name) " "
717 }
718 append opts($opt_name) $opt_val
719 }
720
721 foreach opt { as ld } {
722 regsub {\[big_or_little_endian\]} $opts($opt) \
723 [big_or_little_endian] opts($opt)
724 }
725
726 # Decide early whether we should run the test for this target.
727 if { [llength $opts(target)] > 0 } {
728 set targmatch 0
729 foreach targ $opts(target) {
730 if [istarget $targ] {
731 set targmatch 1
732 break
733 }
734 }
735 if { $targmatch == 0 } {
736 return
737 }
738 }
739 foreach targ $opts(notarget) {
740 if [istarget $targ] {
741 return
742 }
743 }
744
745 set program ""
746 # It's meaningless to require an output-testing method when we
747 # expect an error.
748 if { $opts(error) == "" && $opts(error_output) == "" } {
749 if {$opts(PROG) != ""} {
750 switch -- $opts(PROG) {
751 objdump { set program objdump }
752 nm { set program nm }
753 objcopy { set program objcopy }
754 readelf { set program readelf }
755 default
756 { perror "unrecognized program option $opts(PROG) in $file.d"
757 unresolved $subdir/$name
758 return }
759 }
760 } else {
761 # Guess which program to run, by seeing which option was specified.
762 foreach p {objdump objcopy nm readelf} {
763 if {$opts($p) != ""} {
764 if {$program != ""} {
765 perror "ambiguous dump program in $file.d"
766 unresolved $subdir/$name
767 return
768 } else {
769 set program $p
770 }
771 }
772 }
773 }
774 if { $program == "" \
775 && $opts(map) == "" \
776 && $opts(warning) == "" \
777 && $opts(warning_output) == "" \
778 && $opts(error) == "" \
779 && $opts(error_output) == "" } {
780 perror "dump program unspecified in $file.d"
781 unresolved $subdir/$name
782 return
783 }
784 }
785
786 if { $opts(name) == "" } {
787 set testname "$subdir/$name"
788 } else {
789 set testname $opts(name)
790 }
791
792 if { $opts(source) == "" } {
793 set sourcefiles [list ${file}.s]
794 set asflags [list ""]
795 } else {
796 set sourcefiles {}
797 foreach sf $opts(source) {
798 if { [string match "/*" $sf] } {
799 lappend sourcefiles "$sf"
800 } else {
801 lappend sourcefiles "$srcdir/$subdir/$sf"
802 }
803 }
804 }
805
806 if { $opts(dump) == "" } {
807 set dfile ${file}.d
808 } else {
809 set dfile $srcdir/$subdir/$opts(dump)
810 }
811
812 # Time to setup xfailures.
813 foreach targ $opts(xfail) {
814 setup_xfail $targ
815 }
816
817 # Assemble each file.
818 set objfiles {}
819 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
820 set sourcefile [lindex $sourcefiles $i]
821 set sourceasflags [lindex $asflags $i]
822 set run_objcopy_objects 0
823
824 if { [string match "*RUN_OBJCOPY*" $sourceasflags] } {
825 set run_objcopy_objects 1
826 }
827 regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
828
829 set objfile "tmpdir/dump$i.o"
830 catch "exec rm -f $objfile" exec_output
831 lappend objfiles $objfile
832 set cmd "$AS $ASFLAGS $opts(as) $sourceasflags -o $objfile $sourcefile"
833
834 send_log "$cmd\n"
835 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
836 remote_upload host "ld.tmp"
837 set comp_output [prune_warnings [file_contents "ld.tmp"]]
838 remote_file host delete "ld.tmp"
839 remote_file build delete "ld.tmp"
840
841 if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
842 send_log "$comp_output\n"
843 verbose "$comp_output" 3
844
845 set exitstat "succeeded"
846 if { $cmdret != 0 } { set exitstat "failed" }
847 verbose -log "$exitstat with: <$comp_output>"
848 fail $testname
849 return
850 }
851
852 if { $run_objcopy_objects } {
853 set cmd "$OBJCOPY $opts(objcopy_objects) $objfile"
854
855 send_log "$cmd\n"
856 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \
857 "" "/dev/null" "objcopy.tmp"]
858 remote_upload host "objcopy.tmp"
859 set comp_output [prune_warnings [file_contents "objcopy.tmp"]]
860 remote_file host delete "objcopy.tmp"
861 remote_file build delete "objcopy.tmp"
862
863 if { [lindex $cmdret 0] != 0 \
864 || ![string match "" $comp_output] } {
865 send_log "$comp_output\n"
866 verbose "$comp_output" 3
867
868 set exitstat "succeeded"
869 if { $cmdret != 0 } { set exitstat "failed" }
870 verbose -log "$exitstat with: <$comp_output>"
871 fail $testname
872 return
873 }
874 }
875 }
876
877 if { (($opts(warning) != "") && ($opts(error) != "")) \
878 || (($opts(warning) != "") && ($opts(error_output) != "")) \
879 || (($opts(warning) != "") && ($opts(warning_output) != "")) \
880 || (($opts(error) != "") && ($opts(warning_output) != "")) \
881 || (($opts(error) != "") && ($opts(error_output) != "")) \
882 || (($opts(warning_output) != "") && ($opts(error_output) != "")) } {
883 perror "$testname: bad mix of warning, error, warning_output, and error_output test-directives"
884 unresolved $testname
885 return
886 }
887
888 set check_ld(source) ""
889 set check_ld(terminal) 0
890 if { $opts(error) != "" \
891 || $opts(warning) != "" \
892 || $opts(error_output) != "" \
893 || $opts(warning_output) != "" } {
894
895 if { $opts(error) != "" || $opts(error_output) != "" } {
896 set check_ld(terminal) 1
897 } else {
898 set check_ld(terminal) 0
899 }
900
901 if { $opts(error) != "" || $opts(warning) != "" } {
902 set check_ld(source) "regex"
903 if { $opts(error) != "" } {
904 set check_ld(regex) $opts(error)
905 } else {
906 set check_ld(regex) $opts(warning)
907 }
908 } else {
909 set check_ld(source) "file"
910 if { $opts(error_output) != "" } {
911 set check_ld(file) $opts(error_output)
912 } else {
913 set check_ld(file) $opts(warning_output)
914 }
915 }
916 }
917
918 # Perhaps link the file(s).
919 if { $run_ld } {
920 set objfile "tmpdir/dump"
921 catch "exec rm -f $objfile" exec_output
922
923 # Add -L$srcdir/$subdir so that the linker command can use
924 # linker scripts in the source directory.
925 set cmd "$LD $ld_extra_opt $LDFLAGS -L$srcdir/$subdir \
926 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
927
928 # If needed then check for, or add a -Map option.
929 set mapfile ""
930 if { $opts(map) != "" } then {
931 if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then {
932 # Found existing mapfile option
933 verbose -log "Existing mapfile '$mapfile' found"
934 } else {
935 # No mapfile option.
936 set mapfile "tmpdir/dump.map"
937 verbose -log "Adding mapfile '$mapfile'"
938 set cmd "$cmd -Map=$mapfile"
939 }
940 }
941
942 send_log "$cmd\n"
943 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
944 remote_upload host "ld.tmp"
945 set comp_output [file_contents "ld.tmp"]
946 remote_file host delete "ld.tmp"
947 remote_file build delete "ld.tmp"
948 set cmdret [lindex $cmdret 0]
949
950 if { $cmdret == 0 && $run_objcopy } {
951 set infile $objfile
952 set objfile "tmpdir/dump1"
953 remote_file host delete $objfile
954
955 # Note that we don't use OBJCOPYFLAGS here; any flags must be
956 # explicitly specified.
957 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
958
959 send_log "$cmd\n"
960 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
961 remote_upload host "ld.tmp"
962 append comp_output [file_contents "ld.tmp"]
963 remote_file host delete "ld.tmp"
964 remote_file build delete "ld.tmp"
965 set cmdret [lindex $cmdret 0]
966 }
967
968 regsub "\n$" $comp_output "" comp_output
969 if { $cmdret != 0 || $comp_output != "" || $check_ld(source) != "" } then {
970 set exitstat "succeeded"
971 if { $cmdret != 0 } { set exitstat "failed" }
972
973 if { $check_ld(source) == "regexp" } {
974 verbose -log "$exitstat with: <$comp_output>, expected: <$check_ld(regex)>"
975 } elseif { $check_ld(source) == "file" } {
976 verbose -log "$exitstat with: <$comp_output>, expected in file $check_ld(file)"
977 set_file_contents "tmpdir/ld.messages" "$comp_output"
978 } else {
979 verbose -log "$exitstat with: <$comp_output>, no expected output"
980 }
981 send_log "$comp_output\n"
982 verbose "$comp_output" 3
983
984 if { (($check_ld(source) == "") == ($comp_output == "")) \
985 && (($cmdret == 0) == ($check_ld(terminal) == 0)) \
986 && ((($check_ld(source) == "regex") \
987 && ($check_ld(regex) == "") == ($comp_output == "") \
988 && [regexp $check_ld(regex) $comp_output]) \
989 || (($check_ld(source) == "file") \
990 && (![regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$check_ld(file)"]))) } {
991 # We have the expected output from ld.
992 if { $check_ld(terminal) || $program == "" } {
993 pass $testname
994 return
995 }
996 } else {
997 fail $testname
998 return
999 }
1000 }
1001
1002 if { $opts(map) != "" } then {
1003 # Check the map file matches.
1004 set map_pattern_file $srcdir/$subdir/$opts(map)
1005 verbose -log "Compare '$mapfile' against '$map_pattern_file'"
1006 if { [regexp_diff $mapfile $map_pattern_file] } then {
1007 fail "$testname (map file check)"
1008 } else {
1009 pass "$testname (map file check)"
1010 }
1011
1012 if { $program == "" } then {
1013 return
1014 }
1015 }
1016 } else {
1017 set objfile "tmpdir/dump0.o"
1018 }
1019
1020 # We must not have expected failure if we get here.
1021 if { $opts(error) != "" } {
1022 fail $testname
1023 return
1024 }
1025
1026 set progopts1 $opts($program)
1027 eval set progopts \$[string toupper $program]FLAGS
1028 eval set binary \$[string toupper $program]
1029
1030 if { ![is_remote host] && [which $binary] == 0 } {
1031 untested $testname
1032 return
1033 }
1034
1035 if { $progopts1 == "" } { set $progopts1 "-r" }
1036 verbose "running $binary $progopts $progopts1" 3
1037
1038 # Objcopy, unlike the other two, won't send its output to stdout,
1039 # so we have to run it specially.
1040 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
1041 if { $program == "objcopy" } {
1042 set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
1043 }
1044
1045 # Ensure consistent sorting of symbols
1046 if {[info exists env(LC_ALL)]} {
1047 set old_lc_all $env(LC_ALL)
1048 }
1049 set env(LC_ALL) "C"
1050 send_log "$cmd\n"
1051 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
1052 set cmdret [lindex $cmdret 0]
1053 remote_upload host "ld.tmp"
1054 set comp_output [prune_warnings [file_contents "ld.tmp"]]
1055 remote_file host delete "ld.tmp"
1056 remote_file build delete "ld.tmp"
1057 if {[info exists old_lc_all]} {
1058 set env(LC_ALL) $old_lc_all
1059 } else {
1060 unset env(LC_ALL)
1061 }
1062 if { $cmdret != 0 || $comp_output != "" } {
1063 send_log "exited abnormally with $cmdret, output:$comp_output\n"
1064 fail $testname
1065 return
1066 }
1067
1068 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
1069 if { [regexp_diff $dumpfile "${dfile}"] } then {
1070 fail $testname
1071 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
1072 return
1073 }
1074
1075 pass $testname
1076 }
1077
1078 proc slurp_options { file } {
1079 # If options_regsub(foo) is set to {a b}, then the contents of a
1080 # "#foo:" line will have regsub -all applied to replace a with b.
1081 global options_regsub
1082
1083 if [catch { set f [open $file r] } x] {
1084 #perror "couldn't open `$file': $x"
1085 perror "$x"
1086 return -1
1087 }
1088 set opt_array {}
1089 # whitespace expression
1090 set ws {[ ]*}
1091 set nws {[^ ]*}
1092 # whitespace is ignored anywhere except within the options list;
1093 # option names are alphabetic plus underscore only.
1094 set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
1095 while { [gets $f line] != -1 } {
1096 set line [string trim $line]
1097 # Whitespace here is space-tab.
1098 if [regexp $pat $line xxx opt_name opt_val] {
1099 # match!
1100 if [info exists options_regsub($opt_name)] {
1101 set subst $options_regsub($opt_name)
1102 regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \
1103 opt_val
1104 }
1105 lappend opt_array [list $opt_name $opt_val]
1106 } else {
1107 break
1108 }
1109 }
1110 close $f
1111 return $opt_array
1112 }
1113
1114 proc file_contents { filename } {
1115 set file [open $filename r]
1116 set contents [read $file]
1117 close $file
1118 return $contents
1119 }
1120
1121 proc set_file_contents { filename contents } {
1122 set file [open $filename w]
1123 puts $file "$contents"
1124 close $file
1125 }
1126
1127 # Create an archive using ar
1128 #
1129 proc ar_simple_create { ar aropts target objects } {
1130 remote_file host delete $target
1131
1132 set exec_output [run_host_cmd "$ar" "-rc $aropts $target $objects"]
1133 set exec_output [prune_warnings $exec_output]
1134
1135 if [string match "" $exec_output] then {
1136 send_log "$exec_output\n"
1137 return 1
1138 } else {
1139 return 0
1140 }
1141 }
1142
1143 # List contains test-items with 3 items followed by 2 lists, one item and
1144 # one optional item:
1145 # 0:name
1146 # 1:ld/ar leading options, placed before object files
1147 # 2:ld/ar trailing options, placed after object files
1148 # 3:assembler options
1149 # 4:filenames of assembler files
1150 # 5:list of actions, options and expected outputs.
1151 # 6:name of output file
1152 # 7:compiler flags (optional)
1153 #
1154 # Actions: { command command-line-options file-containg-expected-output-regexps }
1155 # Commands:
1156 # objdump: Apply objdump options on result.
1157 # nm: Apply nm options on result.
1158 # readelf: Apply readelf options on result.
1159 # ld: Don't apply anything on result. Compare output during linking with
1160 # the file containing regexps (which is the second arg, not the third).
1161 # Note that this *must* be the first action if it is to be used at all;
1162 # in all other cases, any output from the linker during linking is
1163 # treated as a sign of an error and FAILs the test.
1164 #
1165 # args is an optional list of target triplets to be xfailed.
1166 #
1167 proc run_ld_link_tests { ldtests args } {
1168 global ld
1169 global as
1170 global nm
1171 global ar
1172 global objdump
1173 global READELF
1174 global srcdir
1175 global subdir
1176 global env
1177 global CC
1178 global CFLAGS
1179 global runtests
1180 global exec_output
1181 global ld_elf_shared_opt
1182
1183 if { [is_elf_format] && [check_shared_lib_support] } {
1184 set ld_extra_opt "$ld_elf_shared_opt"
1185 } else {
1186 set ld_extra_opt ""
1187 }
1188
1189 foreach testitem $ldtests {
1190 set testname [lindex $testitem 0]
1191
1192 if ![runtest_file_p $runtests $testname] then {
1193 continue
1194 }
1195
1196 foreach target $args {
1197 setup_xfail $target
1198 }
1199
1200 set ld_options [lindex $testitem 1]
1201 set ld_after [lindex $testitem 2]
1202 set as_options [lindex $testitem 3]
1203 set src_files [lindex $testitem 4]
1204 set actions [lindex $testitem 5]
1205 set binfile tmpdir/[lindex $testitem 6]
1206 set cflags [lindex $testitem 7]
1207 set objfiles {}
1208 set is_unresolved 0
1209 set failed 0
1210 set maybe_failed 0
1211 set ld_output ""
1212
1213 # verbose -log "Testname is $testname"
1214 # verbose -log "ld_options is $ld_options"
1215 # verbose -log "ld_after is $ld_after"
1216 # verbose -log "as_options is $as_options"
1217 # verbose -log "src_files is $src_files"
1218 # verbose -log "actions is $actions"
1219 # verbose -log "binfile is $binfile"
1220
1221 # Assemble each file in the test.
1222 foreach src_file $src_files {
1223 set fileroot "[file rootname [file tail $src_file]]"
1224 set objfile "tmpdir/$fileroot.o"
1225 lappend objfiles $objfile
1226
1227 if { [file extension $src_file] == ".c" } {
1228 set as_file "tmpdir/$fileroot.s"
1229 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1230 set is_unresolved 1
1231 break
1232 }
1233 } else {
1234 set as_file "$srcdir/$subdir/$src_file"
1235 }
1236 if ![ld_assemble $as "$as_options $as_file" $objfile] {
1237 set is_unresolved 1
1238 break
1239 }
1240 }
1241
1242 # Catch assembler errors.
1243 if { $is_unresolved } {
1244 unresolved $testname
1245 continue
1246 }
1247
1248 if { $binfile eq "tmpdir/" } {
1249 # compile only
1250 } elseif { [regexp ".*\\.a$" $binfile] } {
1251 if { ![ar_simple_create $ar $ld_options $binfile "$objfiles $ld_after"] } {
1252 set failed 1
1253 }
1254 } elseif { ![ld_simple_link $ld $binfile "$ld_extra_opt -L$srcdir/$subdir $ld_options $objfiles $ld_after"] } {
1255 set maybe_failed 1
1256 set ld_output "$exec_output"
1257 }
1258
1259 if { !$failed } {
1260 foreach actionlist $actions {
1261 set action [lindex $actionlist 0]
1262 set progopts [lindex $actionlist 1]
1263
1264 # There are actions where we run regexp_diff on the
1265 # output, and there are other actions (presumably).
1266 # Handling of the former look the same.
1267 set dump_prog ""
1268 switch -- $action {
1269 objdump
1270 { set dump_prog $objdump }
1271 nm
1272 { set dump_prog $nm }
1273 readelf
1274 { set dump_prog $READELF }
1275 ld
1276 { set dump_prog "ld" }
1277 default
1278 {
1279 perror "Unrecognized action $action"
1280 set is_unresolved 1
1281 break
1282 }
1283 }
1284
1285 if { $action == "ld" } {
1286 set regexpfile $progopts
1287 verbose "regexpfile is $srcdir/$subdir/$regexpfile"
1288 set_file_contents "tmpdir/ld.messages" "$ld_output"
1289 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
1290 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$regexpfile"] } then {
1291 verbose "output is $ld_output" 2
1292 set failed 1
1293 break
1294 }
1295 set maybe_failed 0
1296 } elseif { !$maybe_failed && $dump_prog != "" } {
1297 set dumpfile [lindex $actionlist 2]
1298 set binary $dump_prog
1299
1300 # Ensure consistent sorting of symbols
1301 if {[info exists env(LC_ALL)]} {
1302 set old_lc_all $env(LC_ALL)
1303 }
1304 set env(LC_ALL) "C"
1305 set cmd "$binary $progopts $binfile"
1306 set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
1307 send_log "$cmd\n"
1308 remote_upload host "ld.stderr"
1309 set comp_output [prune_warnings [file_contents "ld.stderr"]]
1310 remote_file host delete "ld.stderr"
1311 remote_file build delete "ld.stderr"
1312
1313 if {[info exists old_lc_all]} {
1314 set env(LC_ALL) $old_lc_all
1315 } else {
1316 unset env(LC_ALL)
1317 }
1318
1319 if ![string match "" $comp_output] then {
1320 send_log "$comp_output\n"
1321 set failed 1
1322 break
1323 }
1324
1325 remote_upload host "dump.out"
1326
1327 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1328 verbose "output is [file_contents "dump.out"]" 2
1329 set failed 1
1330 remote_file build delete "dump.out"
1331 remote_file host delete "dump.out"
1332 break
1333 }
1334 remote_file build delete "dump.out"
1335 remote_file host delete "dump.out"
1336 }
1337 }
1338 }
1339
1340 if { $is_unresolved } {
1341 unresolved $testname
1342 } elseif { $maybe_failed || $failed } {
1343 fail $testname
1344 } else {
1345 pass $testname
1346 }
1347 }
1348 }
1349
1350 # This definition is taken from an unreleased version of DejaGnu. Once
1351 # that version gets released, and has been out in the world for a few
1352 # months at least, it may be safe to delete this copy.
1353 if ![string length [info proc prune_warnings]] {
1354 #
1355 # prune_warnings -- delete various system verbosities from TEXT
1356 #
1357 # An example is:
1358 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1359 #
1360 # Sites with particular verbose os's may wish to override this in site.exp.
1361 #
1362 proc prune_warnings { text } {
1363 # This is from sun4's. Do it for all machines for now.
1364 # The "\\1" is to try to preserve a "\n" but only if necessary.
1365 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1366
1367 # It might be tempting to get carried away and delete blank lines, etc.
1368 # Just delete *exactly* what we're ask to, and that's it.
1369 return $text
1370 }
1371 }
1372
1373 # ldtests contains test-items with 3 items followed by 1 lists, 2 items
1374 # and 3 optional items:
1375 # 0:name
1376 # 1:ld options
1377 # 2:assembler options
1378 # 3:filenames of source files
1379 # 4:name of output file
1380 # 5:expected output
1381 # 6:compiler flags (optional)
1382 # 7:language (optional)
1383 # 8:linker warning (optional)
1384 # args is an optional list of target triplets to be xfailed.
1385
1386 proc run_ld_link_exec_tests { ldtests args } {
1387 global ld
1388 global as
1389 global srcdir
1390 global subdir
1391 global env
1392 global CC
1393 global CXX
1394 global CFLAGS
1395 global CXXFLAGS
1396 global errcnt
1397 global exec_output
1398
1399 foreach testitem $ldtests {
1400 foreach target $args {
1401 setup_xfail $target
1402 }
1403 set testname [lindex $testitem 0]
1404 set ld_options [lindex $testitem 1]
1405 set as_options [lindex $testitem 2]
1406 set src_files [lindex $testitem 3]
1407 set binfile tmpdir/[lindex $testitem 4]
1408 set expfile [lindex $testitem 5]
1409 set cflags [lindex $testitem 6]
1410 set lang [lindex $testitem 7]
1411 set warning [lindex $testitem 8]
1412 set objfiles {}
1413 set failed 0
1414
1415 # verbose -log "Testname is $testname"
1416 # verbose -log "ld_options is $ld_options"
1417 # verbose -log "as_options is $as_options"
1418 # verbose -log "src_files is $src_files"
1419 # verbose -log "binfile is $binfile"
1420
1421 # Assemble each file in the test.
1422 foreach src_file $src_files {
1423 set fileroot "[file rootname [file tail $src_file]]"
1424 set objfile "tmpdir/$fileroot.o"
1425 lappend objfiles $objfile
1426
1427 # We ignore warnings since some compilers may generate
1428 # incorrect section attributes and the assembler will warn
1429 # them.
1430 if { [ string match "c++" $lang ] } {
1431 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1432 } else {
1433 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1434 }
1435 }
1436
1437 # We have to use $CC to build PIE and shared library.
1438 if { [ string match "c" $lang ] } {
1439 set link_proc ld_simple_link
1440 set link_cmd $CC
1441 } elseif { [ string match "c++" $lang ] } {
1442 set link_proc ld_simple_link
1443 set link_cmd $CXX
1444 } elseif { [ string match "-shared" $ld_options ] \
1445 || [ string match "-pie" $ld_options ] } {
1446 set link_proc ld_simple_link
1447 set link_cmd $CC
1448 } else {
1449 set link_proc ld_link
1450 set link_cmd $ld
1451 }
1452
1453 if { $binfile eq "tmpdir/" } {
1454 # compile only
1455 pass $testname
1456 continue;
1457 } elseif ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1458 set failed 1
1459 }
1460
1461 # Check if exec_output is expected.
1462 if { $warning != "" } then {
1463 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1464 if { [regexp $warning $exec_output] } then {
1465 set failed 0
1466 } else {
1467 set failed 1
1468 }
1469 }
1470
1471 if { $failed == 0 } {
1472 send_log "Running: $binfile > $binfile.out\n"
1473 verbose "Running: $binfile > $binfile.out"
1474 catch "exec $binfile > $binfile.out" exec_output
1475
1476 if ![string match "" $exec_output] then {
1477 send_log "$exec_output\n"
1478 verbose "$exec_output" 1
1479 set failed 1
1480 } else {
1481 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1482 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1483 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1484 set exec_output [prune_warnings $exec_output]
1485
1486 if ![string match "" $exec_output] then {
1487 send_log "$exec_output\n"
1488 verbose "$exec_output" 1
1489 set failed 1
1490 }
1491 }
1492 }
1493
1494 if { $failed != 0 } {
1495 fail $testname
1496 } else {
1497 set errcnt 0
1498 pass $testname
1499 }
1500 }
1501 }
1502
1503 # List contains test-items with 3 items followed by 2 lists, one item and
1504 # one optional item:
1505 # 0:name
1506 # 1:ld or ar options
1507 # 2:compile options
1508 # 3:filenames of source files
1509 # 4:action and options.
1510 # 5:name of output file
1511 # 6:language (optional)
1512 # 7:linker warnings (optional)
1513 #
1514 # Actions:
1515 # objdump: Apply objdump options on result. Compare with regex (last arg).
1516 # nm: Apply nm options on result. Compare with regex (last arg).
1517 # readelf: Apply readelf options on result. Compare with regex (last arg).
1518 #
1519 proc run_cc_link_tests { ldtests } {
1520 global nm
1521 global objdump
1522 global READELF
1523 global srcdir
1524 global subdir
1525 global env
1526 global CC
1527 global CXX
1528 global CFLAGS
1529 global CXXFLAGS
1530 global ar
1531 global exec_output
1532 global board_cflags
1533
1534 if [board_info [target_info name] exists cflags] {
1535 set board_cflags " [board_info [target_info name] cflags]"
1536 } else {
1537 set board_cflags ""
1538 }
1539
1540 foreach testitem $ldtests {
1541 set testname [lindex $testitem 0]
1542 set ldflags [lindex $testitem 1]
1543 set cflags [lindex $testitem 2]
1544 set src_files [lindex $testitem 3]
1545 set actions [lindex $testitem 4]
1546 set binfile tmpdir/[lindex $testitem 5]
1547 set lang [lindex $testitem 6]
1548 set warnings [lindex $testitem 7]
1549 set objfiles {}
1550 set is_unresolved 0
1551 set failed 0
1552
1553 #verbose -log "testname is $testname"
1554 #verbose -log "ldflags is $ldflags"
1555 #verbose -log "cflags is $cflags"
1556 #verbose -log "src_files is $src_files"
1557 #verbose -log "actions is $actions"
1558 #verbose -log "binfile is $binfile"
1559 #verbose -log "lang is $lang"
1560 #verbose -log "warnings is $warnings"
1561
1562 # Compile each file in the test.
1563 foreach src_file $src_files {
1564 set fileroot "[file rootname [file tail $src_file]]"
1565 set objfile "tmpdir/$fileroot.o"
1566 lappend objfiles $objfile
1567
1568 # We ignore warnings since some compilers may generate
1569 # incorrect section attributes and the assembler will warn
1570 # them.
1571 if { [ string match "c++" $lang ] } {
1572 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1573 } else {
1574 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1575 }
1576 }
1577
1578 # Clear error and warning counts.
1579 reset_vars
1580
1581 if { [ string match "c++" $lang ] } {
1582 set cc_cmd $CXX
1583 } else {
1584 set cc_cmd $CC
1585 }
1586
1587 if { $binfile eq "tmpdir/" } {
1588 # compile only
1589 } elseif { [regexp ".*\\.a$" $binfile] } {
1590 if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
1591 set failed 1
1592 }
1593 } else {
1594 if { ![ld_simple_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"] } {
1595 set failed 1
1596 }
1597
1598 # Check if exec_output is expected.
1599 if { $warnings != "" } then {
1600 verbose -log "returned with: <$exec_output>, expected: <$warnings>"
1601 if { [regexp $warnings $exec_output] } then {
1602 set failed 0
1603 } else {
1604 set failed 1
1605 }
1606 }
1607 }
1608
1609 if { $failed == 0 } {
1610 foreach actionlist $actions {
1611 set action [lindex $actionlist 0]
1612 set progopts [lindex $actionlist 1]
1613
1614 # There are actions where we run regexp_diff on the
1615 # output, and there are other actions (presumably).
1616 # Handling of the former look the same.
1617 set dump_prog ""
1618 switch -- $action {
1619 objdump
1620 { set dump_prog $objdump }
1621 nm
1622 { set dump_prog $nm }
1623 readelf
1624 { set dump_prog $READELF }
1625 default
1626 {
1627 perror "Unrecognized action $action"
1628 set is_unresolved 1
1629 break
1630 }
1631 }
1632
1633 if { $dump_prog != "" } {
1634 set dumpfile [lindex $actionlist 2]
1635 set binary $dump_prog
1636
1637 # Ensure consistent sorting of symbols
1638 if {[info exists env(LC_ALL)]} {
1639 set old_lc_all $env(LC_ALL)
1640 }
1641 set env(LC_ALL) "C"
1642 set cmd "$binary $progopts $binfile > dump.out"
1643 send_log "$cmd\n"
1644 catch "exec $cmd" comp_output
1645 if {[info exists old_lc_all]} {
1646 set env(LC_ALL) $old_lc_all
1647 } else {
1648 unset env(LC_ALL)
1649 }
1650 set comp_output [prune_warnings $comp_output]
1651
1652 if ![string match "" $comp_output] then {
1653 send_log "$comp_output\n"
1654 set failed 1
1655 break
1656 }
1657
1658 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1659 verbose "output is [file_contents "dump.out"]" 2
1660 set failed 1
1661 break
1662 }
1663 }
1664 }
1665 }
1666
1667 if { $failed } {
1668 fail $testname
1669 } elseif { $is_unresolved } {
1670 unresolved $testname
1671 } else {
1672 pass $testname
1673 }
1674 }
1675 }
1676
1677 # Returns true if --gc-sections is supported on the target.
1678
1679 proc check_gc_sections_available { } {
1680 global gc_sections_available_saved
1681 global ld
1682
1683 if {![info exists gc_sections_available_saved]} {
1684 # Some targets don't support gc-sections despite whatever's
1685 # advertised by ld's options.
1686 if { [istarget d30v-*-*]
1687 || [istarget dlx-*-*]
1688 || [istarget i960-*-*]
1689 || [istarget pj*-*-*]
1690 || [istarget alpha-*-*]
1691 || [istarget hppa*64-*-*]
1692 || [istarget i370-*-*]
1693 || [istarget i860-*-*]
1694 || [istarget ia64-*-*]
1695 || [istarget mep-*-*]
1696 || [istarget mn10200-*-*] } {
1697 set gc_sections_available_saved 0
1698 return 0
1699 }
1700
1701 # elf2flt uses -q (--emit-relocs), which is incompatible with
1702 # --gc-sections.
1703 if { [board_info target exists ldflags]
1704 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1705 set gc_sections_available_saved 0
1706 return 0
1707 }
1708
1709 # Check if the ld used by gcc supports --gc-sections.
1710 # FIXME: this test is useless since ld --help always says
1711 # --gc-sections is available
1712 set ld_output [remote_exec host $ld "--help"]
1713 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1714 set gc_sections_available_saved 1
1715 } else {
1716 set gc_sections_available_saved 0
1717 }
1718 }
1719 return $gc_sections_available_saved
1720 }
1721
1722 # Returns true if -shared is supported on the target
1723 # Only used and accurate for ELF targets at the moment
1724
1725 proc check_shared_lib_support { } {
1726 if {![istarget aarch64*-*-elf]
1727 && ![istarget arc*-*-elf*]
1728 && ![istarget arm*-*-elf]
1729 && ![istarget avr-*-*]
1730 && ![istarget cr16-*-*]
1731 && ![istarget cris*-*-elf]
1732 && ![istarget crx-*-*]
1733 && ![istarget d10v-*-*]
1734 && ![istarget d30v-*-*]
1735 && ![istarget dlx-*-*]
1736 && ![istarget epiphany-*-*]
1737 && ![istarget fr30-*-*]
1738 && ![istarget frv-*-*]
1739 && ![istarget ft32-*-*]
1740 && ![istarget h8300-*-*]
1741 && ![istarget i860-*-*]
1742 && ![istarget i960-*-*]
1743 && ![istarget ip2k-*-*]
1744 && ![istarget iq2000-*-*]
1745 && ![istarget lm32-*-*]
1746 && ![istarget m32c-*-*]
1747 && ![istarget m32r-*-*]
1748 && ![istarget m6811-*-*]
1749 && ![istarget m6812-*-*]
1750 && ![istarget m68hc1*-*-*]
1751 && ![istarget mcore*-*-*]
1752 && ![istarget mep-*-*]
1753 && ![istarget microblaze-*-*]
1754 && ![istarget mips*-*-elf]
1755 && ![istarget mn10200-*-*]
1756 && ![istarget moxie-*-*]
1757 && ![istarget msp430-*-*]
1758 && ![istarget mt-*-*]
1759 && ![istarget nds32*-*-*]
1760 && ![istarget or1k*-*-*]
1761 && ![istarget pj-*-*]
1762 && ![istarget rl78-*-*]
1763 && ![istarget rx-*-*]
1764 && ![istarget spu-*-*]
1765 && ![istarget v850*-*-*]
1766 && ![istarget visium-*-*]
1767 && ![istarget xc16x-*-elf]
1768 && ![istarget xgate-*-*]
1769 && ![istarget xstormy16-*-*]
1770 && ![istarget *-*-irix*]
1771 && ![istarget *-*-rtems] } {
1772 return 1
1773 }
1774 return 0
1775 }
1776
1777 # Return true if target uses genelf.em (assuming it is ELF).
1778 proc is_generic_elf { } {
1779 if { [istarget "d30v-*-*"]
1780 || [istarget "dlx-*-*"]
1781 || [istarget "fr30-*-*"]
1782 || ([istarget "frv-*-*"] && ![istarget "frv-*-linux*"])
1783 || [istarget "ft32-*-*"]
1784 || [istarget "i860-*-*"]
1785 || [istarget "i960-*-*"]
1786 || [istarget "iq2000-*-*"]
1787 || [istarget "mn10200-*-*"]
1788 || [istarget "moxie-*-*"]
1789 || [istarget "msp430-*-*"]
1790 || [istarget "mt-*-*"]
1791 || [istarget "pj*-*-*"] } {
1792 return 1;
1793 }
1794 return 0;
1795 }
1796
1797 # Returns true if the target ld supports the plugin API.
1798 proc check_plugin_api_available { } {
1799 global plugin_api_available_saved
1800 global ld
1801 if {![info exists plugin_api_available_saved]} {
1802 # Check if the ld used by gcc supports --plugin.
1803 set ld_output [remote_exec host $ld "--help"]
1804 if { [ string first "-plugin PLUGIN" $ld_output ] >= 0 } {
1805 set plugin_api_available_saved 1
1806 } else {
1807 set plugin_api_available_saved 0
1808 }
1809 }
1810 return $plugin_api_available_saved
1811 }
1812
1813 # Sets ld_sysroot to the current sysroot (empty if not supported) and
1814 # returns true if the target ld supports sysroot.
1815 proc check_sysroot_available { } {
1816 global ld_sysroot_available_saved ld ld_sysroot
1817 if {![info exists ld_sysroot_available_saved]} {
1818 # Check if ld supports --sysroot *other* than empty.
1819 set ld_sysroot [string trimright [lindex [remote_exec host $ld "--print-sysroot"] 1]]
1820 if { $ld_sysroot == "" } {
1821 set ld_sysroot_available_saved 0
1822 } else {
1823 set ld_sysroot_available_saved 1
1824 }
1825 }
1826 return $ld_sysroot_available_saved
1827 }
1828
1829 # Returns 1 if plugin is enabled in gcc. Returns 0 otherwise.
1830 proc check_gcc_plugin_enabled { } {
1831 global CC
1832
1833 if {![info exists CC]} {
1834 set CC [find_gcc]
1835 }
1836 if { $CC == ""} {
1837 return 0
1838 }
1839 set state [remote_exec host $CC -v]
1840 if { [lindex $state 0] != 0 } {
1841 return 0;
1842 }
1843 for { set i 1 } { $i < [llength $state] } { incr i } {
1844 set v [lindex $state $i]
1845 if { [ string match "*--disable-plugin*" $v ] } {
1846 verbose "plugin is disabled by $v"
1847 return 0;
1848 }
1849 }
1850
1851 return 1;
1852 }
1853
1854 # Returns true if the target compiler supports LTO
1855 proc check_lto_available { } {
1856 global lto_available_saved
1857 global CC
1858
1859 if {![info exists lto_available_saved]} {
1860 if { ![check_gcc_plugin_enabled] } {
1861 set lto_available_saved 0
1862 return 0
1863 }
1864 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1865 # -ffat-lto-objects, we always run LTO tests on Linux with
1866 # GCC 4.9 or newer.
1867 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1868 set lto_available_saved 1
1869 return 1
1870 }
1871 # Check if gcc supports -flto -fuse-linker-plugin
1872 set flags ""
1873 if [board_info [target_info name] exists cflags] {
1874 append flags " [board_info [target_info name] cflags]"
1875 }
1876 if [board_info [target_info name] exists ldflags] {
1877 append flags " [board_info [target_info name] ldflags]"
1878 }
1879
1880 set basename "tmpdir/lto[pid]"
1881 set src ${basename}.c
1882 set output ${basename}.out
1883 set f [open $src "w"]
1884 puts $f "int main() { return 0; }"
1885 close $f
1886 if [is_remote host] {
1887 set src [remote_download host $src]
1888 }
1889 set lto_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -fuse-linker-plugin $src -o $output"]
1890 remote_file host delete $src
1891 remote_file host delete $output
1892 file delete $src
1893 }
1894 return $lto_available_saved
1895 }
1896
1897 # Returns true if the target compiler supports LTO -ffat-lto-objects
1898 proc check_lto_fat_available { } {
1899 global lto_fat_available_saved
1900 global CC
1901
1902 if {![info exists lto_fat_available_saved]} {
1903 if { ![check_gcc_plugin_enabled] } {
1904 set lto_fat_available_saved 0
1905 return 0
1906 }
1907 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1908 # -ffat-lto-objects, we always run LTO tests on Linux with
1909 # GCC 4.9 or newer.
1910 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1911 set lto_fat_available_saved 1
1912 return 1
1913 }
1914 # Check if gcc supports -flto -fuse-linker-plugin
1915 set flags ""
1916 if [board_info [target_info name] exists cflags] {
1917 append flags " [board_info [target_info name] cflags]"
1918 }
1919 if [board_info [target_info name] exists ldflags] {
1920 append flags " [board_info [target_info name] ldflags]"
1921 }
1922
1923 set basename "tmpdir/lto[pid]"
1924 set src ${basename}.c
1925 set output ${basename}.out
1926 set f [open $src "w"]
1927 puts $f "int main() { return 0; }"
1928 close $f
1929 if [is_remote host] {
1930 set src [remote_download host $src]
1931 }
1932 set lto_fat_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -ffat-lto-objects -fuse-linker-plugin $src -o $output"]
1933 remote_file host delete $src
1934 remote_file host delete $output
1935 file delete $src
1936 }
1937 return $lto_fat_available_saved
1938 }
1939
1940 # Returns true if the target compiler supports LTO and -shared
1941 proc check_lto_shared_available { } {
1942 global lto_shared_available_saved
1943 global CC
1944
1945 if {![info exists lto_shared_available_saved]} {
1946 if { ![check_gcc_plugin_enabled] } {
1947 set lto_shared_available_saved 0
1948 return 0
1949 }
1950 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1951 # -ffat-lto-objects, we always run LTO tests on Linux with
1952 # GCC 4.9 or newer.
1953 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1954 set lto_shared_available_saved 1
1955 return 1
1956 }
1957 # Check if gcc supports -flto -fuse-linker-plugin -shared
1958 set flags ""
1959 if [board_info [target_info name] exists cflags] {
1960 append flags " [board_info [target_info name] cflags]"
1961 }
1962 if [board_info [target_info name] exists ldflags] {
1963 append flags " [board_info [target_info name] ldflags]"
1964 }
1965
1966 set basename "tmpdir/lto_shared[pid]"
1967 set src ${basename}.c
1968 set output ${basename}.so
1969 set f [open $src "w"]
1970 puts $f ""
1971 close $f
1972 if [is_remote host] {
1973 set src [remote_download host $src]
1974 }
1975 set lto_shared_available_saved [run_host_cmd_yesno "$CC" "$flags -shared -fPIC -flto -fuse-linker-plugin $src -o $output"]
1976 remote_file host delete $src
1977 remote_file host delete $output
1978 file delete $src
1979 }
1980 return $lto_shared_available_saved
1981 }
1982
1983 # Check if the assembler supports CFI statements.
1984
1985 proc check_as_cfi { } {
1986 global check_as_cfi_result
1987 global as
1988 if [info exists check_as_cfi_result] {
1989 return $check_as_cfi_result
1990 }
1991 set as_file "tmpdir/check_as_cfi.s"
1992 set as_fh [open $as_file w 0666]
1993 puts $as_fh "# Generated file. DO NOT EDIT"
1994 puts $as_fh "\t.cfi_startproc"
1995 puts $as_fh "\t.cfi_endproc"
1996 close $as_fh
1997 remote_download host $as_file
1998 verbose -log "Checking CFI support:"
1999 rename "perror" "check_as_cfi_perror"
2000 proc perror { args } { }
2001 set success [ld_assemble $as $as_file "/dev/null"]
2002 rename "perror" ""
2003 rename "check_as_cfi_perror" "perror"
2004 #remote_file host delete $as_file
2005 set check_as_cfi_result $success
2006 return $success
2007 }
2008
2009 # Returns true if IFUNC works.
2010
2011 proc check_ifunc_available { } {
2012 global ifunc_available_saved
2013 global CC
2014
2015 if {![info exists ifunc_available_saved]} {
2016 if { [which $CC] == 0 } {
2017 set ifunc_available_saved 0
2018 return 0
2019 }
2020 # Check if gcc supports -flto -fuse-linker-plugin
2021 set flags ""
2022 if [board_info [target_info name] exists cflags] {
2023 append flags " [board_info [target_info name] cflags]"
2024 }
2025 if [board_info [target_info name] exists ldflags] {
2026 append flags " [board_info [target_info name] ldflags]"
2027 }
2028
2029 set basename "tmpdir/ifunc[pid]"
2030 set src ${basename}.c
2031 set output ${basename}.out
2032 set f [open $src "w"]
2033 puts $f "extern int library_func2 (void);"
2034 puts $f "int main (void)"
2035 puts $f "{"
2036 puts $f " if (library_func2 () != 2) __builtin_abort ();"
2037 puts $f " return 0; "
2038 puts $f "}"
2039 puts $f "static int library_func1 (void) {return 2; }"
2040 puts $f "void *foo (void) __asm__ (\"library_func2\");"
2041 puts $f "void *foo (void) { return library_func1; }"
2042 puts $f "__asm__(\".type library_func2, %gnu_indirect_function\");"
2043 close $f
2044 if [is_remote host] {
2045 set src [remote_download host $src]
2046 }
2047 set ifunc_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
2048 if { $ifunc_available_saved == 1 } {
2049 set ifunc_available_saved [run_host_cmd_yesno "$output" ""]
2050 }
2051 remote_file host delete $src
2052 remote_file host delete $output
2053 file delete $src
2054 }
2055 return $ifunc_available_saved
2056 }
2057
2058 # Returns true if ifunc attribute works.
2059
2060 proc check_ifunc_attribute_available { } {
2061 global ifunc_attribute_available_saved
2062 global CC
2063
2064 if {![info exists ifunc_attribute_available_saved]} {
2065 if { [which $CC] == 0 } {
2066 set ifunc_attribute_available_saved 0
2067 return 0
2068 }
2069 # Check if gcc supports -flto -fuse-linker-plugin
2070 set flags ""
2071 if [board_info [target_info name] exists cflags] {
2072 append flags " [board_info [target_info name] cflags]"
2073 }
2074 if [board_info [target_info name] exists ldflags] {
2075 append flags " [board_info [target_info name] ldflags]"
2076 }
2077
2078 set basename "tmpdir/ifunc[pid]"
2079 set src ${basename}.c
2080 set output ${basename}.out
2081 set f [open $src "w"]
2082 puts $f "extern int library_func2 (void) __attribute__ ((ifunc (\"foo\")));"
2083 puts $f "int main (void)"
2084 puts $f "{"
2085 puts $f " if (library_func2 () != 2) __builtin_abort ();"
2086 puts $f " return 0; "
2087 puts $f "}"
2088 puts $f "static int library_func1 (void) {return 2; }"
2089 puts $f "void *foo (void) { return library_func1; }"
2090 close $f
2091 if [is_remote host] {
2092 set src [remote_download host $src]
2093 }
2094 set ifunc_attribute_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
2095 if { $ifunc_attribute_available_saved == 1 } {
2096 set ifunc_attribute_available_saved [run_host_cmd_yesno "$output" ""]
2097 }
2098 remote_file host delete $src
2099 remote_file host delete $output
2100 file delete $src
2101 }
2102 return $ifunc_attribute_available_saved
2103 }
2104
2105 # Provide virtual target "cfi" for targets supporting CFI.
2106
2107 rename "istarget" "istarget_ld"
2108 proc istarget { target } {
2109 if {$target == "cfi"} {
2110 return [check_as_cfi]
2111 }
2112 return [istarget_ld $target]
2113 }