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 22proc load_common_lib { name } { 23 global srcdir 24 load_file $srcdir/../../binutils/testsuite/lib/$name 25} 26 27load_common_lib binutils-common.exp 28 29# Extract and print the version number of ld. 30# 31proc 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 51proc 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 78proc 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# 90proc 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# 99proc 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# 123proc 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# 148proc 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# 173proc 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# 218proc 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# 297proc 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# 316proc 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. 367proc 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# 514proc 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 850proc 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 877proc file_contents { filename } { 878 set file [open $filename r] 879 set contents [read $file] 880 close $file 881 return $contents 882} 883 884proc 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# 892proc 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# 921proc 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 } { 984 unresolved $testname 985 continue 986 } 987 988 if { [regexp ".*\\.a$" $binfile] } { 989 if { ![ar_simple_create $ar $ld_options $binfile "$objfiles"] } { 990 set failed 1 991 } 992 } elseif { ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] } { 993 set maybe_failed 1 994 set ld_output "$exec_output" 995 } 996 997 if { !$failed } { 998 foreach actionlist $actions { 999 set action [lindex $actionlist 0] 1000 set progopts [lindex $actionlist 1] 1001 1002 # There are actions where we run regexp_diff on the 1003 # output, and there are other actions (presumably). 1004 # Handling of the former look the same. 1005 set dump_prog "" 1006 switch -- $action { 1007 objdump 1008 { set dump_prog $objdump } 1009 nm 1010 { set dump_prog $nm } 1011 readelf 1012 { set dump_prog $READELF } 1013 ld 1014 { set dump_prog "ld" } 1015 default 1016 { 1017 perror "Unrecognized action $action" 1018 set is_unresolved 1 1019 break 1020 } 1021 } 1022 1023 if { $action == "ld" } { 1024 set dumpfile [lindex $actionlist 1] 1025 verbose "dumpfile is $dumpfile" 1026 set_file_contents "tmpdir/ld.messages" "$ld_output" 1027 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'" 1028 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$dumpfile"] } then { 1029 verbose "output is $ld_output" 2 1030 set failed 1 1031 break 1032 } 1033 set maybe_failed 0 1034 } elseif { !$maybe_failed && $dump_prog != "" } { 1035 set dumpfile [lindex $actionlist 2] 1036 set binary $dump_prog 1037 1038 # Ensure consistent sorting of symbols 1039 if {[info exists env(LC_ALL)]} { 1040 set old_lc_all $env(LC_ALL) 1041 } 1042 set env(LC_ALL) "C" 1043 set cmd "$binary $progopts $binfile" 1044 set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"] 1045 send_log "$cmd\n" 1046 remote_upload host "ld.stderr" 1047 set comp_output [prune_warnings [file_contents "ld.stderr"]] 1048 remote_file host delete "ld.stderr" 1049 remote_file build delete "ld.stderr" 1050 1051 if {[info exists old_lc_all]} { 1052 set env(LC_ALL) $old_lc_all 1053 } else { 1054 unset env(LC_ALL) 1055 } 1056 1057 if ![string match "" $comp_output] then { 1058 send_log "$comp_output\n" 1059 set failed 1 1060 break 1061 } 1062 1063 remote_upload host "dump.out" 1064 1065 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then { 1066 verbose "output is [file_contents "dump.out"]" 2 1067 set failed 1 1068 remote_file build delete "dump.out" 1069 remote_file host delete "dump.out" 1070 break 1071 } 1072 remote_file build delete "dump.out" 1073 remote_file host delete "dump.out" 1074 } 1075 } 1076 } 1077 1078 if { $is_unresolved } { 1079 unresolved $testname 1080 } elseif { $maybe_failed || $failed } { 1081 fail $testname 1082 } else { 1083 pass $testname 1084 } 1085 } 1086} 1087 1088# This definition is taken from an unreleased version of DejaGnu. Once 1089# that version gets released, and has been out in the world for a few 1090# months at least, it may be safe to delete this copy. 1091if ![string length [info proc prune_warnings]] { 1092 # 1093 # prune_warnings -- delete various system verbosities from TEXT 1094 # 1095 # An example is: 1096 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9 1097 # 1098 # Sites with particular verbose os's may wish to override this in site.exp. 1099 # 1100 proc prune_warnings { text } { 1101 # This is from sun4's. Do it for all machines for now. 1102 # The "\\1" is to try to preserve a "\n" but only if necessary. 1103 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text 1104 1105 # It might be tempting to get carried away and delete blank lines, etc. 1106 # Just delete *exactly* what we're ask to, and that's it. 1107 return $text 1108 } 1109} 1110 1111# targets_to_xfail is a list of target triplets to be xfailed. 1112# ldtests contains test-items with 3 items followed by 1 lists, 2 items 1113# and 3 optional items: 1114# 0:name 1115# 1:ld options 1116# 2:assembler options 1117# 3:filenames of source files 1118# 4:name of output file 1119# 5:expected output 1120# 6:compiler flags (optional) 1121# 7:language (optional) 1122# 8:linker warning (optional) 1123 1124proc run_ld_link_exec_tests { targets_to_xfail ldtests } { 1125 global ld 1126 global as 1127 global srcdir 1128 global subdir 1129 global env 1130 global CC 1131 global CXX 1132 global CFLAGS 1133 global CXXFLAGS 1134 global errcnt 1135 global exec_output 1136 1137 foreach testitem $ldtests { 1138 foreach target $targets_to_xfail { 1139 setup_xfail $target 1140 } 1141 set testname [lindex $testitem 0] 1142 set ld_options [lindex $testitem 1] 1143 set as_options [lindex $testitem 2] 1144 set src_files [lindex $testitem 3] 1145 set binfile tmpdir/[lindex $testitem 4] 1146 set expfile [lindex $testitem 5] 1147 set cflags [lindex $testitem 6] 1148 set lang [lindex $testitem 7] 1149 set warning [lindex $testitem 8] 1150 set objfiles {} 1151 set failed 0 1152 1153# verbose -log "Testname is $testname" 1154# verbose -log "ld_options is $ld_options" 1155# verbose -log "as_options is $as_options" 1156# verbose -log "src_files is $src_files" 1157# verbose -log "actions is $actions" 1158# verbose -log "binfile is $binfile" 1159 1160 # Assemble each file in the test. 1161 foreach src_file $src_files { 1162 set objfile "tmpdir/[file rootname $src_file].o" 1163 lappend objfiles $objfile 1164 1165 # We ignore warnings since some compilers may generate 1166 # incorrect section attributes and the assembler will warn 1167 # them. 1168 if { [ string match "c++" $lang ] } { 1169 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile 1170 } else { 1171 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile 1172 } 1173 1174 # We have to use $CC to build PIE and shared library. 1175 if { [ string match "c" $lang ] } { 1176 set link_proc ld_simple_link 1177 set link_cmd $CC 1178 } elseif { [ string match "c++" $lang ] } { 1179 set link_proc ld_simple_link 1180 set link_cmd $CXX 1181 } elseif { [ string match "-shared" $ld_options ] \ 1182 || [ string match "-pie" $ld_options ] } { 1183 set link_proc ld_simple_link 1184 set link_cmd $CC 1185 } else { 1186 set link_proc ld_link 1187 set link_cmd $ld 1188 } 1189 1190 if ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] { 1191 set failed 1 1192 } else { 1193 set failed 0 1194 } 1195 1196 # Check if exec_output is expected. 1197 if { $warning != "" } then { 1198 verbose -log "returned with: <$exec_output>, expected: <$warning>" 1199 if { [regexp $warning $exec_output] } then { 1200 set failed 0 1201 } else { 1202 set failed 1 1203 } 1204 } 1205 1206 if { $failed == 0 } { 1207 send_log "Running: $binfile > $binfile.out\n" 1208 verbose "Running: $binfile > $binfile.out" 1209 catch "exec $binfile > $binfile.out" exec_output 1210 1211 if ![string match "" $exec_output] then { 1212 send_log "$exec_output\n" 1213 verbose "$exec_output" 1 1214 set failed 1 1215 } else { 1216 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n" 1217 verbose "diff $binfile.out $srcdir/$subdir/$expfile" 1218 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output 1219 set exec_output [prune_warnings $exec_output] 1220 1221 if ![string match "" $exec_output] then { 1222 send_log "$exec_output\n" 1223 verbose "$exec_output" 1 1224 set failed 1 1225 } 1226 } 1227 } 1228 1229 if { $failed != 0 } { 1230 fail $testname 1231 } else { 1232 set errcnt 0 1233 pass $testname 1234 } 1235 } 1236 } 1237} 1238 1239# List contains test-items with 3 items followed by 2 lists, one item and 1240# one optional item: 1241# 0:name 1242# 1:ld or ar options 1243# 2:compile options 1244# 3:filenames of source files 1245# 4:action and options. 1246# 5:name of output file 1247# 6:language (optional) 1248# 1249# Actions: 1250# objdump: Apply objdump options on result. Compare with regex (last arg). 1251# nm: Apply nm options on result. Compare with regex (last arg). 1252# readelf: Apply readelf options on result. Compare with regex (last arg). 1253# 1254proc run_cc_link_tests { ldtests } { 1255 global nm 1256 global objdump 1257 global READELF 1258 global srcdir 1259 global subdir 1260 global env 1261 global CC 1262 global CXX 1263 global CFLAGS 1264 global CXXFLAGS 1265 global ar 1266 1267 foreach testitem $ldtests { 1268 set testname [lindex $testitem 0] 1269 set ldflags [lindex $testitem 1] 1270 set cflags [lindex $testitem 2] 1271 set src_files [lindex $testitem 3] 1272 set actions [lindex $testitem 4] 1273 set binfile tmpdir/[lindex $testitem 5] 1274 set lang [lindex $testitem 6] 1275 set objfiles {} 1276 set is_unresolved 0 1277 set failed 0 1278 1279 # Compile each file in the test. 1280 foreach src_file $src_files { 1281 set objfile "tmpdir/[file rootname $src_file].o" 1282 lappend objfiles $objfile 1283 1284 # We ignore warnings since some compilers may generate 1285 # incorrect section attributes and the assembler will warn 1286 # them. 1287 if { [ string match "c++" $lang ] } { 1288 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile 1289 } else { 1290 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile 1291 } 1292 } 1293 1294 # Clear error and warning counts. 1295 reset_vars 1296 1297 if { [ string match "c++" $lang ] } { 1298 set cc_cmd $CXX 1299 } else { 1300 set cc_cmd $CC 1301 } 1302 1303 if { [regexp ".*\\.a$" $binfile] } { 1304 if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } { 1305 fail $testname 1306 set failed 1 1307 } else { 1308 set failed 0 1309 } 1310 } elseif { ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] } { 1311 fail $testname 1312 set failed 1 1313 } else { 1314 set failed 0 1315 } 1316 1317 if { $failed == 0 } { 1318 foreach actionlist $actions { 1319 set action [lindex $actionlist 0] 1320 set progopts [lindex $actionlist 1] 1321 1322 # There are actions where we run regexp_diff on the 1323 # output, and there are other actions (presumably). 1324 # Handling of the former look the same. 1325 set dump_prog "" 1326 switch -- $action { 1327 objdump 1328 { set dump_prog $objdump } 1329 nm 1330 { set dump_prog $nm } 1331 readelf 1332 { set dump_prog $READELF } 1333 default 1334 { 1335 perror "Unrecognized action $action" 1336 set is_unresolved 1 1337 break 1338 } 1339 } 1340 1341 if { $dump_prog != "" } { 1342 set dumpfile [lindex $actionlist 2] 1343 set binary $dump_prog 1344 1345 # Ensure consistent sorting of symbols 1346 if {[info exists env(LC_ALL)]} { 1347 set old_lc_all $env(LC_ALL) 1348 } 1349 set env(LC_ALL) "C" 1350 set cmd "$binary $progopts $binfile > dump.out" 1351 send_log "$cmd\n" 1352 catch "exec $cmd" comp_output 1353 if {[info exists old_lc_all]} { 1354 set env(LC_ALL) $old_lc_all 1355 } else { 1356 unset env(LC_ALL) 1357 } 1358 set comp_output [prune_warnings $comp_output] 1359 1360 if ![string match "" $comp_output] then { 1361 send_log "$comp_output\n" 1362 set failed 1 1363 break 1364 } 1365 1366 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then { 1367 verbose "output is [file_contents "dump.out"]" 2 1368 set failed 1 1369 break 1370 } 1371 } 1372 } 1373 1374 if { $failed != 0 } { 1375 fail $testname 1376 } else { if { $is_unresolved == 0 } { 1377 pass $testname 1378 } } 1379 } 1380 1381 # Catch action errors. 1382 if { $is_unresolved != 0 } { 1383 unresolved $testname 1384 continue 1385 } 1386 } 1387} 1388 1389# Returns true if --gc-sections is supported on the target. 1390 1391proc check_gc_sections_available { } { 1392 global gc_sections_available_saved 1393 global ld 1394 1395 if {![info exists gc_sections_available_saved]} { 1396 # Some targets don't support gc-sections despite whatever's 1397 # advertised by ld's options. 1398 if {[istarget arc-*-*] 1399 || [istarget d30v-*-*] 1400 || [istarget dlx-*-*] 1401 || [istarget i960-*-*] 1402 || [istarget or32-*-*] 1403 || [istarget pj*-*-*] 1404 || [istarget alpha-*-*] 1405 || [istarget hppa64-*-*] 1406 || [istarget i370-*-*] 1407 || [istarget i860-*-*] 1408 || [istarget ia64-*-*] 1409 || [istarget mep-*-*] 1410 || [istarget mn10200-*-*] 1411 || [istarget *-*-cygwin] 1412 || [istarget *-*-mingw*] } { 1413 set gc_sections_available_saved 0 1414 return 0 1415 } 1416 1417 # elf2flt uses -q (--emit-relocs), which is incompatible with 1418 # --gc-sections. 1419 if { [board_info target exists ldflags] 1420 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } { 1421 set gc_sections_available_saved 0 1422 return 0 1423 } 1424 1425 # Check if the ld used by gcc supports --gc-sections. 1426 set ld_output [remote_exec host $ld "--help"] 1427 if { [ string first "--gc-sections" $ld_output ] >= 0 } { 1428 set gc_sections_available_saved 1 1429 } else { 1430 set gc_sections_available_saved 0 1431 } 1432 } 1433 return $gc_sections_available_saved 1434} 1435 1436# Returns true if the target ld supports the plugin API. 1437proc check_plugin_api_available { } { 1438 global plugin_api_available_saved 1439 global ld 1440 if {![info exists plugin_api_available_saved]} { 1441 # Check if the ld used by gcc supports --plugin. 1442 set ld_output [remote_exec host $ld "--help"] 1443 if { [ string first "-plugin" $ld_output ] >= 0 } { 1444 set plugin_api_available_saved 1 1445 } else { 1446 set plugin_api_available_saved 0 1447 } 1448 } 1449 return $plugin_api_available_saved 1450} 1451 1452# Check if the assembler supports CFI statements. 1453 1454proc check_as_cfi { } { 1455 global check_as_cfi_result 1456 global as 1457 if [info exists check_as_cfi_result] { 1458 return $check_as_cfi_result 1459 } 1460 set as_file "tmpdir/check_as_cfi.s" 1461 set as_fh [open $as_file w 0666] 1462 puts $as_fh "# Generated file. DO NOT EDIT" 1463 puts $as_fh "\t.cfi_startproc" 1464 puts $as_fh "\t.cfi_endproc" 1465 close $as_fh 1466 remote_download host $as_file 1467 verbose -log "Checking CFI support:" 1468 rename "perror" "check_as_cfi_perror" 1469 proc perror { args } { } 1470 set success [ld_assemble $as $as_file "/dev/null"] 1471 rename "perror" "" 1472 rename "check_as_cfi_perror" "perror" 1473 #remote_file host delete $as_file 1474 set check_as_cfi_result $success 1475 return $success 1476} 1477 1478# Provide virtual target "cfi" for targets supporting CFI. 1479 1480rename "istarget" "istarget_ld" 1481proc istarget { target } { 1482 if {$target == "cfi"} { 1483 return [check_as_cfi] 1484 } 1485 return [istarget_ld $target] 1486} 1487