1 # Support routines for LD testsuite.
2 # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 # 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 # Free Software Foundation, Inc.
6 # This file is part of the GNU Binutils.
8 # This file is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 proc load_common_lib { name } {
25 load_file $srcdir/../../binutils/testsuite/lib/$name
28 load_common_lib binutils-common.exp
30 # Returns 1 if the gcc for the target is at least version MAJOR.MINOR
31 # Returns 0 otherwise.
33 proc at_least_gcc_version { major minor } {
35 if {![info exists CC]} {
41 set state [remote_exec host $CC --version]
42 set tmp "[lindex $state 1]\n"
43 # Look for (eg) 4.6.1 in the version output.
44 set ver_re "\[^\\.0-9\]+(\[1-9\]\[0-9\]*)\\.(\[0-9\]+)(?:\\.\[0-9\]+)?"
45 regexp $ver_re $tmp fred maj min
46 verbose "gcc version: $tmp"
47 if { ![info exists maj] || ![info exists min] } then {
48 perror "can't decipher gcc version number, fix the framework!"
51 verbose "major gcc version is $maj, want at least $major"
52 if { $maj == $major } then {
53 verbose "minor gcc version is $min, want at least $minor"
54 return [expr $min >= $minor]
56 return [expr $maj > $major]
60 # Extract and print the version number of ld.
62 proc default_ld_version { ld } {
65 if { ![is_remote host] && [which $ld] == 0 } then {
66 perror "$ld does not exist"
70 remote_exec host "$ld --version" "" "/dev/null" "ld.version"
71 remote_upload host "ld.version"
72 set tmp [prune_warnings [file_contents "ld.version"]]
73 remote_file build delete "ld.version"
74 remote_file host delete "ld.version"
76 regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number
77 if [info exists number] then {
78 clone_output "$ld $number\n"
82 proc run_host_cmd { prog command } {
85 if { ![is_remote host] && [which "$prog"] == 0 } then {
86 perror "$prog does not exist"
90 verbose -log "$prog $command"
91 set status [remote_exec host [concat sh -c [list "$prog $command 2>&1"]] "" "/dev/null" "ld.tmp"]
92 remote_upload host "ld.tmp"
93 set link_output [file_contents "ld.tmp"]
94 regsub "\n$" $link_output "" link_output
95 if { [lindex $status 0] != 0 && [string match "" $link_output] } then {
96 append link_output "child process exited abnormally"
98 remote_file build delete ld.tmp
99 remote_file host delete ld.tmp
101 if [string match "" $link_output] then {
105 verbose -log "$link_output"
106 return "$link_output"
109 proc run_host_cmd_yesno { prog command } {
112 set exec_output [prune_warnings [run_host_cmd "$prog" "$command"]]
113 if [string match "" $exec_output] then {
119 # Link an object using relocation.
121 proc default_ld_relocate { ld target objects } {
124 remote_file host delete $target
125 return [run_host_cmd_yesno "$ld" "$HOSTING_EMU -o $target -r $objects"]
128 # Check to see if ld is being invoked with a non-endian output format
130 proc is_endian_output_format { object_flags } {
132 if {[string match "*-oformat binary*" $object_flags] || \
133 [string match "*-oformat ieee*" $object_flags] || \
134 [string match "*-oformat ihex*" $object_flags] || \
135 [string match "*-oformat netbsd-core*" $object_flags] || \
136 [string match "*-oformat srec*" $object_flags] || \
137 [string match "*-oformat tekhex*" $object_flags] || \
138 [string match "*-oformat trad-core*" $object_flags] } then {
145 # Look for big-endian or little-endian switches in the multlib
146 # options and translate these into a -EB or -EL switch. Note
147 # we cannot rely upon proc process_multilib_options to do this
148 # for us because for some targets the compiler does not support
149 # -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
150 # the site.exp file will include the switch "-mbig-endian"
151 # (rather than "big-endian") which is not detected by proc
152 # process_multilib_options.
154 proc big_or_little_endian {} {
156 if [board_info [target_info name] exists multilib_flags] {
157 set tmp_flags " [board_info [target_info name] multilib_flags]"
159 foreach x $tmp_flags {
161 {*big*endian eb EB -eb -EB -mb -meb} {
165 {*little*endian el EL -el -EL -ml -mel} {
177 # Link a program using ld.
179 proc default_ld_link { ld target objects } {
188 set objs "$HOSTING_CRT0 $objects"
189 set libs "$LIBS $HOSTING_LIBS"
191 if [is_endian_output_format $objects] then {
192 set flags [big_or_little_endian]
197 remote_file host delete $target
199 return [run_host_cmd_yesno "$ld" "$HOSTING_EMU $flags -o $target $objs $libs"]
202 # Link a program using ld, without including any libraries.
204 proc default_ld_simple_link { ld target objects } {
209 if [is_endian_output_format $objects] then {
210 set flags [big_or_little_endian]
215 # If we are compiling with gcc, we want to add gcc_ld_flag to
216 # flags. Rather than determine this in some complex way, we guess
217 # based on the name of the compiler.
219 set ldparm [string first " " $ld]
221 if { $ldparm > 0 } then {
222 set ldflags [string range $ld $ldparm end]
223 set ldexe [string range $ld 0 $ldparm]
226 set ldexe [string replace $ldexe 0 [string last "/" $ldexe] ""]
227 if {[string match "*gcc*" $ldexe] || [string match "*++*" $ldexe]} then {
228 set ldflags "$gcc_ld_flag $ldflags"
231 remote_file host delete $target
233 set exec_output [run_host_cmd "$ld" "$ldflags $flags -o $target $objects"]
234 set exec_output [prune_warnings $exec_output]
236 # We don't care if we get a warning about a non-existent start
237 # symbol, since the default linker script might use ENTRY.
238 regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
240 if [string match "" $exec_output] then {
247 # Compile an object using cc.
249 proc default_ld_compile { cc source object } {
258 if {[llength $cc_prog] > 1} then {
259 set cc_prog [lindex $cc_prog 0]
261 if {![is_remote host] && [which $cc_prog] == 0} then {
262 perror "$cc_prog does not exist"
266 remote_file build delete "$object"
267 remote_file host delete "$object"
269 set flags "-I$srcdir/$subdir"
271 # If we are compiling with gcc, we want to add gcc_gas_flag to
272 # flags. Rather than determine this in some complex way, we guess
273 # based on the name of the compiler.
275 set ccparm [string first " " $cc]
277 if { $ccparm > 0 } then {
278 set ccflags [string range $cc $ccparm end]
279 set ccexe [string range $cc 0 $ccparm]
282 set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""]
283 if {[string match "*gcc*" $ccexe] || [string match "*++*" $ccexe]} then {
284 set flags "$gcc_gas_flag $flags"
287 if {[string match "*++*" $ccexe]} {
288 set flags "$flags $CXXFLAGS"
290 set flags "$flags $CFLAGS"
293 if [board_info [target_info name] exists multilib_flags] {
294 append flags " [board_info [target_info name] multilib_flags]"
297 verbose -log "$cc $flags $ccflags -c $source -o $object"
299 set status [remote_exec host [concat sh -c [list "$cc $flags $ccflags -c $source -o $object 2>&1"]] "" "/dev/null" "ld.tmp"]
300 remote_upload host "ld.tmp"
301 set exec_output [file_contents "ld.tmp"]
302 remote_file build delete "ld.tmp"
303 remote_file host delete "ld.tmp"
304 set exec_output [prune_warnings $exec_output]
305 if [string match "" $exec_output] then {
306 if {![file exists $object]} then {
307 regexp ".*/(\[^/\]*)$" $source all dobj
308 regsub "\\.c" $dobj ".o" realobj
309 verbose "looking for $realobj"
310 if {[remote_file host exists $realobj]} then {
311 verbose -log "mv $realobj $object"
312 remote_upload "$realobj" "$object"
314 perror "$object not found after compilation"
320 verbose -log "$exec_output"
321 perror "$source: compilation failed"
328 proc default_ld_assemble { as in_flags source object } {
332 if ![info exists ASFLAGS] { set ASFLAGS "" }
334 set flags [big_or_little_endian]
335 set exec_output [run_host_cmd "$as" "$flags $in_flags $ASFLAGS -o $object $source"]
336 set exec_output [prune_warnings $exec_output]
337 if [string match "" $exec_output] then {
340 perror "$source: assembly failed"
345 # Run nm on a file, putting the result in the array nm_output.
347 proc default_ld_nm { nm nmflags object } {
352 if {[info exists nm_output]} {
356 if ![info exists NMFLAGS] { set NMFLAGS "" }
358 # Ensure consistent sorting of symbols
359 if {[info exists env(LC_ALL)]} {
360 set old_lc_all $env(LC_ALL)
364 verbose -log "$nm $NMFLAGS $nmflags $object >tmpdir/nm.out"
366 set status [remote_exec host [concat sh -c [list "$nm $NMFLAGS $nmflags $object 2>ld.stderr"]] "" "/dev/null" "tmpdir/nm.out"]
367 if {[info exists old_lc_all]} {
368 set env(LC_ALL) $old_lc_all
372 remote_upload host "ld.stderr"
373 remote_upload host "tmpdir/nm.out" "tmpdir/nm.out"
374 set exec_output [prune_warnings [file_contents "ld.stderr"]]
375 remote_file host delete "ld.stderr"
376 remote_file build delete "ld.stderr"
377 if [string match "" $exec_output] then {
378 set file [open tmpdir/nm.out r]
379 while { [gets $file line] != -1 } {
381 if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] \\.*(.+)$" $line whole value name] {
382 set name [string trimleft $name "_"]
383 verbose "Setting nm_output($name) to 0x$value" 2
384 set nm_output($name) 0x$value
390 verbose -log "$exec_output"
391 perror "$object: nm failed"
396 # Define various symbols needed when not linking against all
398 proc ld_simple_link_defsyms {} {
400 set flags "--defsym __stack_chk_fail=0"
402 # ARM targets call __gccmain
403 if {[istarget arm*-*-*]} {
404 append flags " --defsym __gccmain=0"
407 # Windows targets need __main, prefixed with underscore.
408 if {[istarget *-*-cygwin* ] || [istarget *-*-mingw*]} {
409 append flags " --defsym ___main=0"
412 # PowerPC EABI code calls __eabi.
413 if {[istarget powerpc*-*-eabi*] || [istarget powerpc*-*-rtems*]} {
414 append flags " --defsym __eabi=0"
417 # mn10200 code calls __truncsipsi2_d0_d2.
418 if {[istarget mn10200*-*-*]} then {
419 append flags " --defsym __truncsipsi2_d0_d2=0"
422 # m6811/m6812 code has references to soft registers.
423 if {[istarget m6811-*-*] || [istarget m6812-*-*] || [istarget m68hc1*-*-*]} {
424 append flags " --defsym _.frame=0 --defsym _.d1=0 --defsym _.d2=0"
425 append flags " --defsym _.d3=0 --defsym _.d4=0"
426 append flags " --defsym _.tmp=0 --defsym _.xy=0 --defsym _.z=0"
429 # Some OpenBSD targets have ProPolice and reference __guard and
430 # __stack_smash_handler.
431 if [istarget *-*-openbsd*] {
432 append flags " --defsym __guard=0"
433 append flags " --defsym __stack_smash_handler=0"
439 # run_dump_test FILE (optional:) EXTRA_OPTIONS
440 # Copied from gas testsuite, tweaked and further extended.
442 # Assemble a .s file, then run some utility on it and check the output.
444 # There should be an assembly language file named FILE.s in the test
445 # suite directory, and a pattern file called FILE.d. `run_dump_test'
446 # will assemble FILE.s, run some tool like `objdump', `objcopy', or
447 # `nm' on the .o file to produce textual output, and then analyze that
448 # with regexps. The FILE.d file specifies what program to run, and
449 # what to expect in its output.
451 # The FILE.d file begins with zero or more option lines, which specify
452 # flags to pass to the assembler, the program to run to dump the
453 # assembler's output, and the options it wants. The option lines have
458 # OPTION is the name of some option, like "name" or "objdump", and
459 # VALUE is OPTION's value. The valid options are described below.
460 # Whitespace is ignored everywhere, except within VALUE. The option
461 # list ends with the first line that doesn't match the above syntax
462 # (hmm, not great for error detection).
464 # The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of
465 # two-element lists. The first element of each is an option name, and
466 # the second additional arguments to be added on to the end of the
467 # option list as given in FILE.d. (If omitted, no additional options
470 # The interesting options are:
473 # The name of this test, passed to DejaGNU's `pass' and `fail'
474 # commands. If omitted, this defaults to FILE, the root of the
475 # .s and .d files' names.
478 # When assembling, pass FLAGS to the assembler.
479 # If assembling several files, you can pass different assembler
480 # options in the "source" directives. See below.
483 # Link assembled files using FLAGS, in the order of the "source"
484 # directives, when using multiple files.
486 # ld_after_inputfiles: FLAGS
487 # Similar to "ld", but put after all input files.
489 # objcopy_linked_file: FLAGS
490 # Run objcopy on the linked file with the specified flags.
491 # This lets you transform the linked file using objcopy, before the
492 # result is analyzed by an analyzer program specified below (which
493 # may in turn *also* be objcopy).
496 # The name of the program to run to analyze the .o file produced
497 # by the assembler or the linker output. This can be omitted;
498 # run_dump_test will guess which program to run by seeing which of
499 # the flags options below is present.
504 # Use the specified program to analyze the assembler or linker
505 # output file, and pass it FLAGS, in addition to the output name.
506 # Note that they are run with LC_ALL=C in the environment to give
507 # consistent sorting of symbols.
509 # source: SOURCE [FLAGS]
510 # Assemble the file SOURCE.s using the flags in the "as" directive
511 # and the (optional) FLAGS. If omitted, the source defaults to
513 # This is useful if several .d files want to share a .s file.
514 # More than one "source" directive can be given, which is useful
515 # when testing linking.
518 # Match against DUMP.d. If omitted, this defaults to FILE.d. This
519 # is useful if several .d files differ by options only. Options are
520 # always read from FILE.d.
523 # The test is expected to fail on TARGET. This may occur more than
527 # Only run the test for TARGET. This may occur more than once; the
528 # target being tested must match at least one. You may provide target
529 # name "cfi" for any target supporting the CFI statements.
532 # Do not run the test for TARGET. This may occur more than once;
533 # the target being tested must not match any of them.
536 # An error with message matching REGEX must be emitted for the test
537 # to pass. The PROG, objdump, nm and objcopy options have no
538 # meaning and need not supplied if this is present. Multiple "error"
539 # directives append to the expected linker error message.
542 # Expect a linker warning matching REGEX. It is an error to issue
543 # both "error" and "warning". Multiple "warning" directives
544 # append to the expected linker warning message.
546 # Each option may occur at most once unless otherwise mentioned.
548 # After the option lines come regexp lines. `run_dump_test' calls
549 # `regexp_diff' to compare the output of the dumping tool against the
550 # regexps in FILE.d. `regexp_diff' is defined in binutils-common.exp;
551 # see further comments there.
553 proc run_dump_test { name {extra_options {}} } {
555 global OBJDUMP NM AS OBJCOPY READELF LD
556 global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
557 global host_triplet runtests
560 if [string match "*/*" $name] {
562 set name [file tail $name]
564 set file "$srcdir/$subdir/$name"
567 if ![runtest_file_p $runtests $name] then {
571 set opt_array [slurp_options "${file}.d"]
572 if { $opt_array == -1 } {
573 perror "error reading options from $file.d"
574 unresolved $subdir/$name
577 set dumpfile tmpdir/dump.out
582 set opts(ld_after_inputfiles) {}
585 set opts(notarget) {}
596 set opts(objcopy_linked_file) {}
598 foreach i $opt_array {
599 set opt_name [lindex $i 0]
600 set opt_val [lindex $i 1]
601 if ![info exists opts($opt_name)] {
602 perror "unknown option $opt_name in file $file.d"
603 unresolved $subdir/$name
607 switch -- $opt_name {
614 # Move any source-specific as-flags to a separate list to
615 # simplify processing.
616 if { [llength $opt_val] > 1 } {
617 lappend asflags [lrange $opt_val 1 end]
618 set opt_val [lindex $opt_val 0]
624 if [string length $opts($opt_name)] {
625 perror "option $opt_name multiply set in $file.d"
626 unresolved $subdir/$name
630 # A single "# ld:" with no options should do the right thing.
631 if { $opt_name == "ld" } {
634 # Likewise objcopy_linked_file.
635 if { $opt_name == "objcopy_linked_file" } {
640 if { $opt_name == "as" || $opt_name == "ld" } {
641 set opt_val [subst $opt_val]
644 # Append differently whether it's a message (without space) or
645 # an option or list (with space).
646 switch -- $opt_name {
649 append opts($opt_name) $opt_val
652 set opts($opt_name) [concat $opts($opt_name) $opt_val]
657 foreach i $extra_options {
658 set opt_name [lindex $i 0]
659 set opt_val [lindex $i 1]
660 if ![info exists opts($opt_name)] {
661 perror "unknown option $opt_name given in extra_opts"
662 unresolved $subdir/$name
665 # Add extra option to end of existing option, adding space
667 if { ![regexp "warning|error" $opt_name]
668 && [string length $opts($opt_name)] } {
669 append opts($opt_name) " "
671 append opts($opt_name) $opt_val
674 foreach opt { as ld } {
675 regsub {\[big_or_little_endian\]} $opts($opt) \
676 [big_or_little_endian] opts($opt)
679 # Decide early whether we should run the test for this target.
680 if { [llength $opts(target)] > 0 } {
682 foreach targ $opts(target) {
683 if [istarget $targ] {
688 if { $targmatch == 0 } {
692 foreach targ $opts(notarget) {
693 if [istarget $targ] {
699 # It's meaningless to require an output-testing method when we
701 if { $opts(error) == "" } {
702 if {$opts(PROG) != ""} {
703 switch -- $opts(PROG) {
704 objdump { set program objdump }
705 nm { set program nm }
706 objcopy { set program objcopy }
707 readelf { set program readelf }
709 { perror "unrecognized program option $opts(PROG) in $file.d"
710 unresolved $subdir/$name
714 # Guess which program to run, by seeing which option was specified.
715 foreach p {objdump objcopy nm readelf} {
716 if {$opts($p) != ""} {
717 if {$program != ""} {
718 perror "ambiguous dump program in $file.d"
719 unresolved $subdir/$name
727 if { $program == "" && $opts(warning) == "" } {
728 perror "dump program unspecified in $file.d"
729 unresolved $subdir/$name
734 if { $opts(name) == "" } {
735 set testname "$subdir/$name"
737 set testname $opts(name)
740 if { $opts(source) == "" } {
741 set sourcefiles [list ${file}.s]
742 set asflags [list ""]
745 foreach sf $opts(source) {
746 if { [string match "/*" $sf] } {
747 lappend sourcefiles "$sf"
749 lappend sourcefiles "$srcdir/$subdir/$sf"
754 if { $opts(dump) == "" } {
757 set dfile $srcdir/$subdir/$opts(dump)
760 # Time to setup xfailures.
761 foreach targ $opts(xfail) {
765 # Assemble each file.
767 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
768 set sourcefile [lindex $sourcefiles $i]
769 set sourceasflags [lindex $asflags $i]
771 set objfile "tmpdir/dump$i.o"
772 catch "exec rm -f $objfile" exec_output
773 lappend objfiles $objfile
774 set cmd "$AS $ASFLAGS $opts(as) $sourceasflags -o $objfile $sourcefile"
777 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
778 remote_upload host "ld.tmp"
779 set comp_output [prune_warnings [file_contents "ld.tmp"]]
780 remote_file host delete "ld.tmp"
781 remote_file build delete "ld.tmp"
783 if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
784 send_log "$comp_output\n"
785 verbose "$comp_output" 3
787 set exitstat "succeeded"
788 if { $cmdret != 0 } { set exitstat "failed" }
789 verbose -log "$exitstat with: <$comp_output>"
795 set expmsg $opts(error)
796 if { $opts(warning) != "" } {
797 if { $expmsg != "" } {
798 perror "$testname: mixing error and warning test-directives"
801 set expmsg $opts(warning)
804 # Perhaps link the file(s).
806 set objfile "tmpdir/dump"
807 catch "exec rm -f $objfile" exec_output
809 # Add -L$srcdir/$subdir so that the linker command can use
810 # linker scripts in the source directory.
811 set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
812 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
815 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
816 remote_upload host "ld.tmp"
817 set comp_output [file_contents "ld.tmp"]
818 remote_file host delete "ld.tmp"
819 remote_file build delete "ld.tmp"
820 set cmdret [lindex $cmdret 0]
822 if { $cmdret == 0 && $run_objcopy } {
824 set objfile "tmpdir/dump1"
825 remote_file host delete $objfile
827 # Note that we don't use OBJCOPYFLAGS here; any flags must be
828 # explicitly specified.
829 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
832 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
833 remote_upload host "ld.tmp"
834 append comp_output [file_contents "ld.tmp"]
835 remote_file host delete "ld.tmp"
836 remote_file build delete "ld.tmp"
837 set cmdret [lindex $cmdret 0]
840 regsub "\n$" $comp_output "" comp_output
841 if { $cmdret != 0 || $comp_output != "" || $expmsg != "" } then {
842 set exitstat "succeeded"
843 if { $cmdret != 0 } { set exitstat "failed" }
844 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
845 send_log "$comp_output\n"
846 verbose "$comp_output" 3
848 if { ($expmsg == "") == ($comp_output == "") \
849 && [regexp $expmsg $comp_output] \
850 && (($cmdret == 0) == ($opts(error) == "")) } {
851 # We have the expected output from ld.
852 if { $opts(error) != "" || $program == "" } {
857 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
863 set objfile "tmpdir/dump0.o"
866 # We must not have expected failure if we get here.
867 if { $opts(error) != "" } {
872 set progopts1 $opts($program)
873 eval set progopts \$[string toupper $program]FLAGS
874 eval set binary \$[string toupper $program]
876 if { ![is_remote host] && [which $binary] == 0 } {
881 if { $progopts1 == "" } { set $progopts1 "-r" }
882 verbose "running $binary $progopts $progopts1" 3
884 # Objcopy, unlike the other two, won't send its output to stdout,
885 # so we have to run it specially.
886 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
887 if { $program == "objcopy" } {
888 set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
891 # Ensure consistent sorting of symbols
892 if {[info exists env(LC_ALL)]} {
893 set old_lc_all $env(LC_ALL)
897 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
898 set cmdret [lindex $cmdret 0]
899 remote_upload host "ld.tmp"
900 set comp_output [prune_warnings [file_contents "ld.tmp"]]
901 remote_file host delete "ld.tmp"
902 remote_file build delete "ld.tmp"
903 if {[info exists old_lc_all]} {
904 set env(LC_ALL) $old_lc_all
908 if { $cmdret != 0 || $comp_output != "" } {
909 send_log "exited abnormally with $cmdret, output:$comp_output\n"
914 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
915 if { [regexp_diff $dumpfile "${dfile}"] } then {
917 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
924 proc slurp_options { file } {
925 # If options_regsub(foo) is set to {a b}, then the contents of a
926 # "#foo:" line will have regsub -all applied to replace a with b.
927 global options_regsub
929 if [catch { set f [open $file r] } x] {
930 #perror "couldn't open `$file': $x"
935 # whitespace expression
938 # whitespace is ignored anywhere except within the options list;
939 # option names are alphabetic plus underscore only.
940 set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
941 while { [gets $f line] != -1 } {
942 set line [string trim $line]
943 # Whitespace here is space-tab.
944 if [regexp $pat $line xxx opt_name opt_val] {
946 if [info exists options_regsub($opt_name)] {
947 set subst $options_regsub($opt_name)
948 regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \
951 lappend opt_array [list $opt_name $opt_val]
960 proc file_contents { filename } {
961 set file [open $filename r]
962 set contents [read $file]
967 proc set_file_contents { filename contents } {
968 set file [open $filename w]
969 puts $file "$contents"
973 # Create an archive using ar
975 proc ar_simple_create { ar aropts target objects } {
976 remote_file host delete $target
978 set exec_output [run_host_cmd "$ar" "$aropts rc $target $objects"]
979 set exec_output [prune_warnings $exec_output]
981 if [string match "" $exec_output] then {
982 send_log "$exec_output\n"
989 # List contains test-items with 3 items followed by 2 lists, one item and
993 # 2:assembler options
994 # 3:filenames of assembler files
995 # 4:list of actions, options and expected outputs.
996 # 5:name of output file
997 # 6:compiler flags (optional)
999 # Actions: { command command-line-options file-containg-expected-output-regexps }
1001 # objdump: Apply objdump options on result.
1002 # nm: Apply nm options on result.
1003 # readelf: Apply readelf options on result.
1004 # ld: Don't apply anything on result. Compare output during linking with
1005 # the file containing regexps (which is the second arg, not the third).
1006 # Note that this *must* be the first action if it is to be used at all;
1007 # in all other cases, any output from the linker during linking is
1008 # treated as a sign of an error and FAILs the test.
1010 proc run_ld_link_tests { ldtests } {
1025 foreach testitem $ldtests {
1026 set testname [lindex $testitem 0]
1028 if ![runtest_file_p $runtests $testname] then {
1032 set ld_options [lindex $testitem 1]
1033 set as_options [lindex $testitem 2]
1034 set src_files [lindex $testitem 3]
1035 set actions [lindex $testitem 4]
1036 set binfile tmpdir/[lindex $testitem 5]
1037 set cflags [lindex $testitem 6]
1044 # verbose -log "Testname is $testname"
1045 # verbose -log "ld_options is $ld_options"
1046 # verbose -log "as_options is $as_options"
1047 # verbose -log "src_files is $src_files"
1048 # verbose -log "actions is $actions"
1049 # verbose -log "binfile is $binfile"
1051 # Assemble each file in the test.
1052 foreach src_file $src_files {
1053 set fileroot "[file rootname [file tail $src_file]]"
1054 set objfile "tmpdir/$fileroot.o"
1055 lappend objfiles $objfile
1057 if { [file extension $src_file] == ".c" } {
1058 set as_file "tmpdir/$fileroot.s"
1059 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1064 set as_file "$srcdir/$subdir/$src_file"
1066 if ![ld_assemble $as "$as_options $as_file" $objfile] {
1072 # Catch assembler errors.
1073 if { $is_unresolved } {
1074 unresolved $testname
1078 if { [regexp ".*\\.a$" $binfile] } {
1079 if { ![ar_simple_create $ar $ld_options $binfile "$objfiles"] } {
1082 } elseif { ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] } {
1084 set ld_output "$exec_output"
1088 foreach actionlist $actions {
1089 set action [lindex $actionlist 0]
1090 set progopts [lindex $actionlist 1]
1092 # There are actions where we run regexp_diff on the
1093 # output, and there are other actions (presumably).
1094 # Handling of the former look the same.
1098 { set dump_prog $objdump }
1100 { set dump_prog $nm }
1102 { set dump_prog $READELF }
1104 { set dump_prog "ld" }
1107 perror "Unrecognized action $action"
1113 if { $action == "ld" } {
1114 set regexpfile $progopts
1115 verbose "regexpfile is $srcdir/$subdir/$regexpfile"
1116 set_file_contents "tmpdir/ld.messages" "$ld_output"
1117 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
1118 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$regexpfile"] } then {
1119 verbose "output is $ld_output" 2
1124 } elseif { !$maybe_failed && $dump_prog != "" } {
1125 set dumpfile [lindex $actionlist 2]
1126 set binary $dump_prog
1128 # Ensure consistent sorting of symbols
1129 if {[info exists env(LC_ALL)]} {
1130 set old_lc_all $env(LC_ALL)
1133 set cmd "$binary $progopts $binfile"
1134 set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
1136 remote_upload host "ld.stderr"
1137 set comp_output [prune_warnings [file_contents "ld.stderr"]]
1138 remote_file host delete "ld.stderr"
1139 remote_file build delete "ld.stderr"
1141 if {[info exists old_lc_all]} {
1142 set env(LC_ALL) $old_lc_all
1147 if ![string match "" $comp_output] then {
1148 send_log "$comp_output\n"
1153 remote_upload host "dump.out"
1155 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1156 verbose "output is [file_contents "dump.out"]" 2
1158 remote_file build delete "dump.out"
1159 remote_file host delete "dump.out"
1162 remote_file build delete "dump.out"
1163 remote_file host delete "dump.out"
1168 if { $is_unresolved } {
1169 unresolved $testname
1170 } elseif { $maybe_failed || $failed } {
1178 # This definition is taken from an unreleased version of DejaGnu. Once
1179 # that version gets released, and has been out in the world for a few
1180 # months at least, it may be safe to delete this copy.
1181 if ![string length [info proc prune_warnings]] {
1183 # prune_warnings -- delete various system verbosities from TEXT
1186 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1188 # Sites with particular verbose os's may wish to override this in site.exp.
1190 proc prune_warnings { text } {
1191 # This is from sun4's. Do it for all machines for now.
1192 # The "\\1" is to try to preserve a "\n" but only if necessary.
1193 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1195 # It might be tempting to get carried away and delete blank lines, etc.
1196 # Just delete *exactly* what we're ask to, and that's it.
1201 # targets_to_xfail is a list of target triplets to be xfailed.
1202 # ldtests contains test-items with 3 items followed by 1 lists, 2 items
1203 # and 3 optional items:
1206 # 2:assembler options
1207 # 3:filenames of source files
1208 # 4:name of output file
1210 # 6:compiler flags (optional)
1211 # 7:language (optional)
1212 # 8:linker warning (optional)
1214 proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
1227 foreach testitem $ldtests {
1228 foreach target $targets_to_xfail {
1231 set testname [lindex $testitem 0]
1232 set ld_options [lindex $testitem 1]
1233 set as_options [lindex $testitem 2]
1234 set src_files [lindex $testitem 3]
1235 set binfile tmpdir/[lindex $testitem 4]
1236 set expfile [lindex $testitem 5]
1237 set cflags [lindex $testitem 6]
1238 set lang [lindex $testitem 7]
1239 set warning [lindex $testitem 8]
1243 # verbose -log "Testname is $testname"
1244 # verbose -log "ld_options is $ld_options"
1245 # verbose -log "as_options is $as_options"
1246 # verbose -log "src_files is $src_files"
1247 # verbose -log "actions is $actions"
1248 # verbose -log "binfile is $binfile"
1250 # Assemble each file in the test.
1251 foreach src_file $src_files {
1252 set fileroot "[file rootname [file tail $src_file]]"
1253 set objfile "tmpdir/$fileroot.o"
1254 lappend objfiles $objfile
1256 # We ignore warnings since some compilers may generate
1257 # incorrect section attributes and the assembler will warn
1259 if { [ string match "c++" $lang ] } {
1260 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1262 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1265 # We have to use $CC to build PIE and shared library.
1266 if { [ string match "c" $lang ] } {
1267 set link_proc ld_simple_link
1269 } elseif { [ string match "c++" $lang ] } {
1270 set link_proc ld_simple_link
1272 } elseif { [ string match "-shared" $ld_options ] \
1273 || [ string match "-pie" $ld_options ] } {
1274 set link_proc ld_simple_link
1277 set link_proc ld_link
1281 if ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1287 # Check if exec_output is expected.
1288 if { $warning != "" } then {
1289 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1290 if { [regexp $warning $exec_output] } then {
1297 if { $failed == 0 } {
1298 send_log "Running: $binfile > $binfile.out\n"
1299 verbose "Running: $binfile > $binfile.out"
1300 catch "exec $binfile > $binfile.out" exec_output
1302 if ![string match "" $exec_output] then {
1303 send_log "$exec_output\n"
1304 verbose "$exec_output" 1
1307 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1308 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1309 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1310 set exec_output [prune_warnings $exec_output]
1312 if ![string match "" $exec_output] then {
1313 send_log "$exec_output\n"
1314 verbose "$exec_output" 1
1320 if { $failed != 0 } {
1330 # List contains test-items with 3 items followed by 2 lists, one item and
1331 # one optional item:
1333 # 1:ld or ar options
1335 # 3:filenames of source files
1336 # 4:action and options.
1337 # 5:name of output file
1338 # 6:language (optional)
1339 # 7:linker warnings (optional)
1342 # objdump: Apply objdump options on result. Compare with regex (last arg).
1343 # nm: Apply nm options on result. Compare with regex (last arg).
1344 # readelf: Apply readelf options on result. Compare with regex (last arg).
1346 proc run_cc_link_tests { ldtests } {
1360 foreach testitem $ldtests {
1361 set testname [lindex $testitem 0]
1362 set ldflags [lindex $testitem 1]
1363 set cflags [lindex $testitem 2]
1364 set src_files [lindex $testitem 3]
1365 set actions [lindex $testitem 4]
1366 set binfile tmpdir/[lindex $testitem 5]
1367 set lang [lindex $testitem 6]
1368 set warnings [lindex $testitem 7]
1373 # Compile each file in the test.
1374 foreach src_file $src_files {
1375 set fileroot "[file rootname [file tail $src_file]]"
1376 set objfile "tmpdir/$fileroot.o"
1377 lappend objfiles $objfile
1379 # We ignore warnings since some compilers may generate
1380 # incorrect section attributes and the assembler will warn
1382 if { [ string match "c++" $lang ] } {
1383 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1385 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1389 # Clear error and warning counts.
1392 if { [ string match "c++" $lang ] } {
1398 if { [regexp ".*\\.a$" $binfile] } {
1399 if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
1405 } elseif { ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] } {
1406 # Check if exec_output is expected.
1407 if { $warnings != "" } then {
1408 verbose -log "returned with: <$exec_output>, expected: <$warnings>"
1409 if { [regexp $warnings $exec_output] } then {
1422 if { $failed == 0 } {
1423 foreach actionlist $actions {
1424 set action [lindex $actionlist 0]
1425 set progopts [lindex $actionlist 1]
1427 # There are actions where we run regexp_diff on the
1428 # output, and there are other actions (presumably).
1429 # Handling of the former look the same.
1433 { set dump_prog $objdump }
1435 { set dump_prog $nm }
1437 { set dump_prog $READELF }
1440 perror "Unrecognized action $action"
1446 if { $dump_prog != "" } {
1447 set dumpfile [lindex $actionlist 2]
1448 set binary $dump_prog
1450 # Ensure consistent sorting of symbols
1451 if {[info exists env(LC_ALL)]} {
1452 set old_lc_all $env(LC_ALL)
1455 set cmd "$binary $progopts $binfile > dump.out"
1457 catch "exec $cmd" comp_output
1458 if {[info exists old_lc_all]} {
1459 set env(LC_ALL) $old_lc_all
1463 set comp_output [prune_warnings $comp_output]
1465 if ![string match "" $comp_output] then {
1466 send_log "$comp_output\n"
1471 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1472 verbose "output is [file_contents "dump.out"]" 2
1479 if { $failed != 0 } {
1481 } else { if { $is_unresolved == 0 } {
1486 # Catch action errors.
1487 if { $is_unresolved != 0 } {
1488 unresolved $testname
1494 # Returns true if --gc-sections is supported on the target.
1496 proc check_gc_sections_available { } {
1497 global gc_sections_available_saved
1500 if {![info exists gc_sections_available_saved]} {
1501 # Some targets don't support gc-sections despite whatever's
1502 # advertised by ld's options.
1503 if {[istarget arc-*-*]
1504 || [istarget d30v-*-*]
1505 || [istarget dlx-*-*]
1506 || [istarget i960-*-*]
1507 || [istarget or32-*-*]
1508 || [istarget pj*-*-*]
1509 || [istarget alpha-*-*]
1510 || [istarget hppa*64-*-*]
1511 || [istarget i370-*-*]
1512 || [istarget i860-*-*]
1513 || [istarget ia64-*-*]
1514 || [istarget mep-*-*]
1515 || [istarget mn10200-*-*]
1516 || [istarget *-*-cygwin]
1517 || [istarget *-*-mingw*] } {
1518 set gc_sections_available_saved 0
1522 # elf2flt uses -q (--emit-relocs), which is incompatible with
1524 if { [board_info target exists ldflags]
1525 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1526 set gc_sections_available_saved 0
1530 # Check if the ld used by gcc supports --gc-sections.
1531 # FIXME: this test is useless since ld --help always says
1532 # --gc-sections is available
1533 set ld_output [remote_exec host $ld "--help"]
1534 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1535 set gc_sections_available_saved 1
1537 set gc_sections_available_saved 0
1540 return $gc_sections_available_saved
1543 # Returns true if -shared is supported on the target
1544 # Only used and accurate for ELF targets at the moment
1546 proc check_shared_lib_support { } {
1547 if {![istarget arc-*-*]
1548 && ![istarget avr-*-*]
1549 && ![istarget cr16-*-*]
1550 && ![istarget cris*-*-*]
1551 && ![istarget crx-*-*]
1552 && ![istarget d10v-*-*]
1553 && ![istarget d30v-*-*]
1554 && ![istarget dlx-*-*]
1555 && ![istarget epiphany-*-*]
1556 && ![istarget fr30-*-*]
1557 && ![istarget frv-*-*]
1558 && ![istarget h8300-*-*]
1559 && ![istarget i860-*-*]
1560 && ![istarget i960-*-*]
1561 && ![istarget ip2k-*-*]
1562 && ![istarget iq2000-*-*]
1563 && ![istarget lm32-*-*]
1564 && ![istarget m32c-*-*]
1565 && ![istarget m32r-*-*]
1566 && ![istarget m6811-*-*]
1567 && ![istarget m6812-*-*]
1568 && ![istarget m68hc1*-*-*]
1569 && ![istarget mcore*-*-*]
1570 && ![istarget mep-*-*]
1571 && ![istarget microblaze-*-*]
1572 && ![istarget mn10200-*-*]
1573 && ![istarget moxie-*-*]
1574 && ![istarget msp430-*-*]
1575 && ![istarget mt-*-*]
1576 && ![istarget openrisc-*-*]
1577 && ![istarget or32-*-*]
1578 && ![istarget pj-*-*]
1579 && ![istarget rx-*-*]
1580 && ![istarget spu-*-*]
1581 && ![istarget v850*-*-*]
1582 && ![istarget xstormy16-*-*]
1583 && ![istarget *-*-irix*]
1584 && ![istarget *-*-rtems] } {
1590 # Returns true if the target ld supports the plugin API.
1591 proc check_plugin_api_available { } {
1592 global plugin_api_available_saved
1594 if {![info exists plugin_api_available_saved]} {
1595 # Check if the ld used by gcc supports --plugin.
1596 set ld_output [remote_exec host $ld "--help"]
1597 if { [ string first "-plugin" $ld_output ] >= 0 } {
1598 set plugin_api_available_saved 1
1600 set plugin_api_available_saved 0
1603 return $plugin_api_available_saved
1606 # Check if the assembler supports CFI statements.
1608 proc check_as_cfi { } {
1609 global check_as_cfi_result
1611 if [info exists check_as_cfi_result] {
1612 return $check_as_cfi_result
1614 set as_file "tmpdir/check_as_cfi.s"
1615 set as_fh [open $as_file w 0666]
1616 puts $as_fh "# Generated file. DO NOT EDIT"
1617 puts $as_fh "\t.cfi_startproc"
1618 puts $as_fh "\t.cfi_endproc"
1620 remote_download host $as_file
1621 verbose -log "Checking CFI support:"
1622 rename "perror" "check_as_cfi_perror"
1623 proc perror { args } { }
1624 set success [ld_assemble $as $as_file "/dev/null"]
1626 rename "check_as_cfi_perror" "perror"
1627 #remote_file host delete $as_file
1628 set check_as_cfi_result $success
1632 # Provide virtual target "cfi" for targets supporting CFI.
1634 rename "istarget" "istarget_ld"
1635 proc istarget { target } {
1636 if {$target == "cfi"} {
1637 return [check_as_cfi]
1639 return [istarget_ld $target]