1 # Support routines for LD testsuite.
2 # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 # 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
5 # This file is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
19 # Extract and print the version number of ld.
21 proc default_ld_version { ld } {
24 if { [which $ld] == 0 } then {
25 perror "$ld does not exist"
29 catch "exec $ld --version" tmp
30 set tmp [prune_warnings $tmp]
31 regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number
32 if [info exists number] then {
33 clone_output "$ld $number\n"
37 # Link an object using relocation.
39 proc default_ld_relocate { ld target objects } {
44 if { [which $ld] == 0 } then {
45 perror "$ld does not exist"
49 catch "exec rm -f $target" exec_output
51 verbose -log "$ld $HOSTING_EMU -o $target -r $objects"
53 catch "exec $ld $HOSTING_EMU -o $target -r $objects" exec_output
54 set exec_output [prune_warnings $exec_output]
55 if [string match "" $exec_output] then {
58 verbose -log "$exec_output"
63 # Check to see if ld is being invoked with a non-endian output format
65 proc is_endian_output_format { object_flags } {
67 if {[string match "*-oformat binary*" $object_flags] || \
68 [string match "*-oformat ieee*" $object_flags] || \
69 [string match "*-oformat ihex*" $object_flags] || \
70 [string match "*-oformat netbsd-core*" $object_flags] || \
71 [string match "*-oformat srec*" $object_flags] || \
72 [string match "*-oformat tekhex*" $object_flags] || \
73 [string match "*-oformat trad-core*" $object_flags] } then {
80 # Look for big-endian or little-endian switches in the multlib
81 # options and translate these into a -EB or -EL switch. Note
82 # we cannot rely upon proc process_multilib_options to do this
83 # for us because for some targets the compiler does not support
84 # -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
85 # the site.exp file will include the switch "-mbig-endian"
86 # (rather than "big-endian") which is not detected by proc
87 # process_multilib_options.
89 proc big_or_little_endian {} {
91 if [board_info [target_info name] exists multilib_flags] {
92 set tmp_flags " [board_info [target_info name] multilib_flags]"
94 foreach x $tmp_flags {
96 {*big*endian eb EB -eb -EB -mb -meb} {
100 {*little*endian el EL -el -EL -ml -mel} {
112 # Link a program using ld.
114 proc default_ld_link { ld target objects } {
123 set objs "$HOSTING_CRT0 $objects"
124 set libs "$LIBS $HOSTING_LIBS"
126 if { [which $ld] == 0 } then {
127 perror "$ld does not exist"
131 if [is_endian_output_format $objects] then {
132 set flags [big_or_little_endian]
137 catch "exec rm -f $target" exec_output
139 verbose -log "$ld $HOSTING_EMU $flags -o $target $objs $libs"
141 catch "exec $ld $HOSTING_EMU $flags -o $target $objs $libs" link_output
142 set exec_output [prune_warnings $link_output]
143 if [string match "" $exec_output] then {
146 verbose -log "$exec_output"
151 # Link a program using ld, without including any libraries.
153 proc default_ld_simple_link { ld target objects } {
159 if { [which $ld] == 0 } then {
160 perror "$ld does not exist"
164 if [is_endian_output_format $objects] then {
165 set flags [big_or_little_endian]
170 # If we are compiling with gcc, we want to add gcc_ld_flag to
171 # flags. Rather than determine this in some complex way, we guess
172 # based on the name of the compiler.
174 set ldparm [string first " " $ld]
175 if { $ldparm > 0 } then {
176 set ldexe [string range $ld 0 $ldparm]
178 set ldexe [string replace $ldexe 0 [string last "/" $ldexe] ""]
179 if {[string match "*gcc*" $ldexe] || [string match "*++*" $ldexe]} then {
180 set flags "$gcc_ld_flag $flags"
183 catch "exec rm -f $target" exec_output
185 verbose -log "$ld $flags -o $target $objects"
187 catch "exec $ld $flags -o $target $objects" link_output
188 set exec_output [prune_warnings $link_output]
190 # We don't care if we get a warning about a non-existent start
191 # symbol, since the default linker script might use ENTRY.
192 regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
194 if [string match "" $exec_output] then {
197 verbose -log "$exec_output"
202 # Compile an object using cc.
204 proc default_ld_compile { cc source object } {
212 if {[llength $cc_prog] > 1} then {
213 set cc_prog [lindex $cc_prog 0]
215 if {[which $cc_prog] == 0} then {
216 perror "$cc_prog does not exist"
220 catch "exec rm -f $object" exec_output
222 set flags "-I$srcdir/$subdir $CFLAGS"
224 # If we are compiling with gcc, we want to add gcc_gas_flag to
225 # flags. Rather than determine this in some complex way, we guess
226 # based on the name of the compiler.
228 set ccparm [string first " " $cc]
230 if { $ccparm > 0 } then {
231 set ccflags [string range $cc $ccparm end]
232 set ccexe [string range $cc 0 $ccparm]
235 set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""]
236 if {[string match "*gcc*" $ccexe] || [string match "*++*" $ccexe]} then {
237 set flags "$gcc_gas_flag $flags"
240 if [board_info [target_info name] exists multilib_flags] {
241 append flags " [board_info [target_info name] multilib_flags]"
244 verbose -log "$cc $flags $ccflags -c $source -o $object"
246 catch "exec $cc $flags $ccflags -c $source -o $object" exec_output
247 set exec_output [prune_warnings $exec_output]
248 if [string match "" $exec_output] then {
249 if {![file exists $object]} then {
250 regexp ".*/(\[^/\]*)$" $source all dobj
251 regsub "\\.c" $dobj ".o" realobj
252 verbose "looking for $realobj"
253 if {[file exists $realobj]} then {
254 verbose -log "mv $realobj $object"
255 catch "exec mv $realobj $object" exec_output
256 set exec_output [prune_warnings $exec_output]
257 if {![string match "" $exec_output]} then {
258 verbose -log "$exec_output"
259 perror "could not move $realobj to $object"
263 perror "$object not found after compilation"
269 verbose -log "$exec_output"
270 perror "$source: compilation failed"
277 proc default_ld_assemble { as source object } {
281 if {[which $as] == 0} then {
282 perror "$as does not exist"
286 if ![info exists ASFLAGS] { set ASFLAGS "" }
288 set flags [big_or_little_endian]
290 verbose -log "$as $flags $ASFLAGS -o $object $source"
292 catch "exec $as $flags $ASFLAGS -o $object $source" exec_output
293 set exec_output [prune_warnings $exec_output]
294 if [string match "" $exec_output] then {
297 verbose -log "$exec_output"
298 perror "$source: assembly failed"
303 # Run nm on a file, putting the result in the array nm_output.
305 proc default_ld_nm { nm nmflags object } {
310 if {[which $nm] == 0} then {
311 perror "$nm does not exist"
315 if {[info exists nm_output]} {
319 if ![info exists NMFLAGS] { set NMFLAGS "" }
321 # Ensure consistent sorting of symbols
322 if {[info exists env(LC_ALL)]} {
323 set old_lc_all $env(LC_ALL)
326 verbose -log "$nm $NMFLAGS $nmflags $object >tmpdir/nm.out"
328 catch "exec $nm $NMFLAGS $nmflags $object >tmpdir/nm.out" exec_output
329 if {[info exists old_lc_all]} {
330 set env(LC_ALL) $old_lc_all
334 set exec_output [prune_warnings $exec_output]
335 if [string match "" $exec_output] then {
336 set file [open tmpdir/nm.out r]
337 while { [gets $file line] != -1 } {
339 if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] \\.*(.+)$" $line whole value name] {
340 set name [string trimleft $name "_"]
341 verbose "Setting nm_output($name) to 0x$value" 2
342 set nm_output($name) 0x$value
348 verbose -log "$exec_output"
349 perror "$object: nm failed"
354 # True if the object format is known to be ELF.
356 proc is_elf_format {} {
357 if { ![istarget *-*-sysv4*] \
358 && ![istarget *-*-unixware*] \
359 && ![istarget *-*-elf*] \
360 && ![istarget *-*-eabi*] \
361 && ![istarget hppa*64*-*-hpux*] \
362 && ![istarget *-*-linux*] \
363 && ![istarget frv-*-uclinux*] \
364 && ![istarget *-*-irix5*] \
365 && ![istarget *-*-irix6*] \
366 && ![istarget *-*-netbsd*] \
367 && ![istarget *-*-solaris2*] } {
371 if { [istarget *-*-linux*aout*] \
372 || [istarget *-*-linux*oldld*] } {
376 if { ![istarget *-*-netbsdelf*] \
377 && ([istarget *-*-netbsd*aout*] \
378 || [istarget *-*-netbsdpe*] \
379 || [istarget arm*-*-netbsd*] \
380 || [istarget sparc-*-netbsd*] \
381 || [istarget i*86-*-netbsd*] \
382 || [istarget m68*-*-netbsd*] \
383 || [istarget vax-*-netbsd*] \
384 || [istarget ns32k-*-netbsd*]) } {
390 # True if the object format is known to be 64-bit ELF.
392 proc is_elf64 { binary_file } {
397 catch "exec $READELF $READELFFLAGS -h $binary_file > readelf.out" got
399 if ![string match "" $got] then {
403 if { ![regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \
404 [file_contents readelf.out] nil readelf_size] } {
408 if { $readelf_size == "64" } {
415 # True if the object format is known to be a.out.
417 proc is_aout_format {} {
418 if { [istarget *-*-*\[ab\]out*] \
419 || [istarget *-*-linux*oldld*] \
420 || [istarget *-*-msdos*] \
421 || [istarget arm-*-netbsd] \
422 || [istarget i?86-*-netbsd] \
423 || [istarget i?86-*-mach*] \
424 || [istarget i?86-*-vsta] \
425 || [istarget pdp11-*-*] \
426 || [istarget m68*-ericsson-ose] \
427 || [istarget m68k-hp-bsd*] \
428 || [istarget m68*-*-hpux*] \
429 || [istarget m68*-*-netbsd] \
430 || [istarget m68*-*-netbsd*4k*] \
431 || [istarget m68k-sony-*] \
432 || [istarget m68*-sun-sunos\[34\]*] \
433 || [istarget m68*-wrs-vxworks*] \
434 || [istarget ns32k-*-*] \
435 || [istarget sparc*-*-netbsd] \
436 || [istarget sparc-sun-sunos4*] \
437 || [istarget vax-dec-ultrix*] \
438 || [istarget vax-*-netbsd] } {
444 # True if the object format is known to be PE COFF.
446 proc is_pecoff_format {} {
447 if { ![istarget *-*-mingw*] \
448 && ![istarget *-*-cygwin*] \
449 && ![istarget *-*-pe*] } {
456 # Compares two files line-by-line.
457 # Returns differences if exist.
458 # Returns null if file(s) cannot be opened.
460 proc simple_diff { file_1 file_2 } {
466 if [file exists $file_1] then {
467 set file_a [open $file_1 r]
469 warning "$file_1 doesn't exist"
473 if [file exists $file_2] then {
474 set file_b [open $file_2 r]
476 fail "$file_2 doesn't exist"
480 verbose "# Diff'ing: $file_1 $file_2\n" 2
482 while { [gets $file_a line] != $eof } {
483 if [regexp "^#.*$" $line] then {
491 while { [gets $file_b line] != $eof } {
492 if [regexp "^#.*$" $line] then {
500 for { set i 0 } { $i < [llength $list_a] } { incr i } {
501 set line_a [lindex $list_a $i]
502 set line_b [lindex $list_b $i]
504 verbose "\t$file_1: $i: $line_a\n" 3
505 verbose "\t$file_2: $i: $line_b\n" 3
506 if [string compare $line_a $line_b] then {
507 verbose -log "\t$file_1: $i: $line_a\n"
508 verbose -log "\t$file_2: $i: $line_b\n"
515 if { [llength $list_a] != [llength $list_b] } {
520 if $differences<1 then {
526 # Copied from gas testsuite, tweaked and further extended.
528 # Assemble a .s file, then run some utility on it and check the output.
530 # There should be an assembly language file named FILE.s in the test
531 # suite directory, and a pattern file called FILE.d. `run_dump_test'
532 # will assemble FILE.s, run some tool like `objdump', `objcopy', or
533 # `nm' on the .o file to produce textual output, and then analyze that
534 # with regexps. The FILE.d file specifies what program to run, and
535 # what to expect in its output.
537 # The FILE.d file begins with zero or more option lines, which specify
538 # flags to pass to the assembler, the program to run to dump the
539 # assembler's output, and the options it wants. The option lines have
544 # OPTION is the name of some option, like "name" or "objdump", and
545 # VALUE is OPTION's value. The valid options are described below.
546 # Whitespace is ignored everywhere, except within VALUE. The option
547 # list ends with the first line that doesn't match the above syntax
548 # (hmm, not great for error detection).
550 # The interesting options are:
553 # The name of this test, passed to DejaGNU's `pass' and `fail'
554 # commands. If omitted, this defaults to FILE, the root of the
555 # .s and .d files' names.
558 # When assembling, pass FLAGS to the assembler.
559 # If assembling several files, you can pass different assembler
560 # options in the "source" directives. See below.
563 # Link assembled files using FLAGS, in the order of the "source"
564 # directives, when using multiple files.
566 # objcopy_linked_file: FLAGS
567 # Run objcopy on the linked file with the specified flags.
568 # This lets you transform the linked file using objcopy, before the
569 # result is analyzed by an analyzer program specified below (which
570 # may in turn *also* be objcopy).
573 # The name of the program to run to analyze the .o file produced
574 # by the assembler or the linker output. This can be omitted;
575 # run_dump_test will guess which program to run by seeing which of
576 # the flags options below is present.
581 # Use the specified program to analyze the assembler or linker
582 # output file, and pass it FLAGS, in addition to the output name.
583 # Note that they are run with LC_ALL=C in the environment to give
584 # consistent sorting of symbols.
586 # source: SOURCE [FLAGS]
587 # Assemble the file SOURCE.s using the flags in the "as" directive
588 # and the (optional) FLAGS. If omitted, the source defaults to
590 # This is useful if several .d files want to share a .s file.
591 # More than one "source" directive can be given, which is useful
592 # when testing linking.
595 # The test is expected to fail on TARGET. This may occur more than
599 # Only run the test for TARGET. This may occur more than once; the
600 # target being tested must match at least one.
603 # Do not run the test for TARGET. This may occur more than once;
604 # the target being tested must not match any of them.
607 # An error with message matching REGEX must be emitted for the test
608 # to pass. The PROG, objdump, nm and objcopy options have no
609 # meaning and need not supplied if this is present.
612 # Expect a linker warning matching REGEX. It is an error to issue
613 # both "error" and "warning".
615 # Each option may occur at most once unless otherwise mentioned.
617 # After the option lines come regexp lines. `run_dump_test' calls
618 # `regexp_diff' to compare the output of the dumping tool against the
619 # regexps in FILE.d. `regexp_diff' is defined later in this file; see
620 # further comments there.
622 proc run_dump_test { name } {
624 global OBJDUMP NM AS OBJCOPY READELF LD
625 global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
626 global host_triplet runtests
629 if [string match "*/*" $name] {
631 set name [file tail $name]
633 set file "$srcdir/$subdir/$name"
636 if ![runtest_file_p $runtests $name] then {
640 set opt_array [slurp_options "${file}.d"]
641 if { $opt_array == -1 } {
642 perror "error reading options from $file.d"
643 unresolved $subdir/$name
646 set dumpfile tmpdir/dump.out
653 set opts(notarget) {}
663 set opts(objcopy_linked_file) {}
664 set asflags(${file}.s) {}
666 foreach i $opt_array {
667 set opt_name [lindex $i 0]
668 set opt_val [lindex $i 1]
669 if ![info exists opts($opt_name)] {
670 perror "unknown option $opt_name in file $file.d"
671 unresolved $subdir/$name
675 switch -- $opt_name {
680 # Move any source-specific as-flags to a separate array to
681 # simplify processing.
682 if { [llength $opt_val] > 1 } {
683 set asflags([lindex $opt_val 0]) [lrange $opt_val 1 end]
684 set opt_val [lindex $opt_val 0]
686 set asflags($opt_val) {}
690 if [string length $opts($opt_name)] {
691 perror "option $opt_name multiply set in $file.d"
692 unresolved $subdir/$name
696 # A single "# ld:" with no options should do the right thing.
697 if { $opt_name == "ld" } {
700 # Likewise objcopy_linked_file.
701 if { $opt_name == "objcopy_linked_file" } {
706 set opts($opt_name) [concat $opts($opt_name) $opt_val]
709 # Decide early whether we should run the test for this target.
710 if { [llength $opts(target)] > 0 } {
712 foreach targ $opts(target) {
713 if [istarget $targ] {
718 if { $targmatch == 0 } {
722 foreach targ $opts(notarget) {
723 if [istarget $targ] {
729 # It's meaningless to require an output-testing method when we
731 if { $opts(error) == "" } {
732 if {$opts(PROG) != ""} {
733 switch -- $opts(PROG) {
734 objdump { set program objdump }
735 nm { set program nm }
736 objcopy { set program objcopy }
737 readelf { set program readelf }
739 { perror "unrecognized program option $opts(PROG) in $file.d"
740 unresolved $subdir/$name
744 # Guess which program to run, by seeing which option was specified.
745 foreach p {objdump objcopy nm readelf} {
746 if {$opts($p) != ""} {
747 if {$program != ""} {
748 perror "ambiguous dump program in $file.d"
749 unresolved $subdir/$name
757 if { $program == "" && $opts(warning) == "" } {
758 perror "dump program unspecified in $file.d"
759 unresolved $subdir/$name
764 if { $opts(name) == "" } {
765 set testname "$subdir/$name"
767 set testname $opts(name)
770 if { $opts(source) == "" } {
771 set sourcefiles [list ${file}.s]
774 foreach sf $opts(source) {
775 if { [string match "/*" $sf] } {
776 lappend sourcefiles "$sf"
778 lappend sourcefiles "$srcdir/$subdir/$sf"
780 # Must have asflags indexed on source name.
781 set asflags($srcdir/$subdir/$sf) $asflags($sf)
785 # Time to setup xfailures.
786 foreach targ $opts(xfail) {
790 # Assemble each file.
792 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
793 set sourcefile [lindex $sourcefiles $i]
795 set objfile "tmpdir/dump$i.o"
796 catch "exec rm -f $objfile" exec_output
797 lappend objfiles $objfile
798 set cmd "$AS $ASFLAGS $opts(as) $asflags($sourcefile) -o $objfile $sourcefile"
801 set cmdret [catch "exec $cmd" comp_output]
802 set comp_output [prune_warnings $comp_output]
804 if { $cmdret != 0 || ![string match "" $comp_output] } then {
805 send_log "$comp_output\n"
806 verbose "$comp_output" 3
808 set exitstat "succeeded"
809 if { $cmdret != 0 } { set exitstat "failed" }
810 verbose -log "$exitstat with: <$comp_output>"
816 set expmsg $opts(error)
817 if { $opts(warning) != "" } {
818 if { $expmsg != "" } {
819 perror "$testname: mixing error and warning test-directives"
822 set expmsg $opts(warning)
825 # Perhaps link the file(s).
827 set objfile "tmpdir/dump"
828 catch "exec rm -f $objfile" exec_output
830 # Add -L$srcdir/$subdir so that the linker command can use
831 # linker scripts in the source directory.
832 set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
833 $opts(ld) -o $objfile $objfiles"
836 set cmdret [catch "exec $cmd" comp_output]
837 set comp_output [prune_warnings $comp_output]
839 if { $cmdret != 0 } then {
840 # If the executed program writes to stderr and stderr is not
841 # redirected, exec *always* returns failure, regardless of the
842 # program exit code. Thankfully, we can retrieve the true
843 # return status from a special variable. Redirection would
844 # cause a Tcl-specific message to be appended, and we'd rather
845 # not deal with that if we can help it.
847 if { [lindex $errorCode 0] == "NONE" } {
852 if { $cmdret == 0 && $run_objcopy } {
854 set objfile "tmpdir/dump1"
855 catch "exec rm -f $objfile" exec_output
857 # Note that we don't use OBJCOPYFLAGS here; any flags must be
858 # explicitly specified.
859 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
862 set cmdret [catch "exec $cmd" comp_output]
863 append comp_output [prune_warnings $comp_output]
865 if { $cmdret != 0 } then {
867 if { [lindex $errorCode 0] == "NONE" } {
873 if { $cmdret != 0 || $comp_output != "" || $expmsg != "" } then {
874 set exitstat "succeeded"
875 if { $cmdret != 0 } { set exitstat "failed" }
876 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
877 send_log "$comp_output\n"
878 verbose "$comp_output" 3
880 if { [regexp $expmsg $comp_output] \
881 && (($cmdret == 0) == ($opts(warning) != "")) } {
882 # We have the expected output from ld.
883 if { $opts(error) != "" || $program == "" } {
888 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
894 set objfile "tmpdir/dump0.o"
897 # We must not have expected failure if we get here.
898 if { $opts(error) != "" } {
903 set progopts1 $opts($program)
904 eval set progopts \$[string toupper $program]FLAGS
905 eval set binary \$[string toupper $program]
907 if { [which $binary] == 0 } {
912 if { $progopts1 == "" } { set $progopts1 "-r" }
913 verbose "running $binary $progopts $progopts1" 3
915 # Objcopy, unlike the other two, won't send its output to stdout,
916 # so we have to run it specially.
917 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
918 if { $program == "objcopy" } {
919 set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
922 # Ensure consistent sorting of symbols
923 if {[info exists env(LC_ALL)]} {
924 set old_lc_all $env(LC_ALL)
928 catch "exec $cmd" comp_output
929 if {[info exists old_lc_all]} {
930 set env(LC_ALL) $old_lc_all
934 set comp_output [prune_warnings $comp_output]
935 if ![string match "" $comp_output] then {
936 send_log "$comp_output\n"
941 verbose_eval {[file_contents $dumpfile]} 3
942 if { [regexp_diff $dumpfile "${file}.d"] } then {
944 verbose "output is [file_contents $dumpfile]" 2
951 proc slurp_options { file } {
952 if [catch { set f [open $file r] } x] {
953 #perror "couldn't open `$file': $x"
958 # whitespace expression
961 # whitespace is ignored anywhere except within the options list;
962 # option names are alphabetic plus underscore only.
963 set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
964 while { [gets $f line] != -1 } {
965 set line [string trim $line]
966 # Whitespace here is space-tab.
967 if [regexp $pat $line xxx opt_name opt_val] {
969 lappend opt_array [list $opt_name $opt_val]
978 # regexp_diff, copied from gas, based on simple_diff above.
979 # compares two files line-by-line
980 # file1 contains strings, file2 contains regexps and #-comments
981 # blank lines are ignored in either file
982 # returns non-zero if differences exist
984 proc regexp_diff { file_1 file_2 } {
992 if [file exists $file_1] then {
993 set file_a [open $file_1 r]
995 warning "$file_1 doesn't exist"
999 if [file exists $file_2] then {
1000 set file_b [open $file_2 r]
1002 fail "$file_2 doesn't exist"
1007 verbose " Regexp-diff'ing: $file_1 $file_2" 2
1012 while { [string length $line_a] == 0 } {
1013 if { [gets $file_a line_a] == $eof } {
1018 while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
1019 if [ string match "#pass" $line_b ] {
1023 } elseif [ string match "#..." $line_b ] {
1024 if { [gets $file_b line_b] == $eof } {
1029 verbose "looking for \"^$line_b$\"" 3
1030 while { ![regexp "^$line_b$" "$line_a"] } {
1031 verbose "skipping \"$line_a\"" 3
1032 if { [gets $file_a line_a] == $eof } {
1039 if { [gets $file_b line_b] == $eof } {
1047 } elseif { $end_1 && $end_2 } {
1049 } elseif { $end_1 } {
1050 send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
1051 verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
1054 } elseif { $end_2 } {
1055 send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
1056 verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
1060 verbose "regexp \"^$line_b$\"\nline \"$line_a\"" 3
1061 if ![regexp "^$line_b$" "$line_a"] {
1062 send_log "regexp_diff match failure\n"
1063 send_log "regexp \"^$line_b$\"\nline \"$line_a\"\n"
1069 if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
1070 send_log "$file_1 and $file_2 are different lengths\n"
1071 verbose "$file_1 and $file_2 are different lengths" 3
1081 proc file_contents { filename } {
1082 set file [open $filename r]
1083 set contents [read $file]
1088 # List contains test-items with 3 items followed by 2 lists, one item and
1089 # one optional item:
1090 # 0:name 1:ld options 2:assembler options
1091 # 3:filenames of assembler files 4: action and options. 5: name of output file
1092 # 6:compiler flags (optional)
1095 # objdump: Apply objdump options on result. Compare with regex (last arg).
1096 # nm: Apply nm options on result. Compare with regex (last arg).
1097 # readelf: Apply readelf options on result. Compare with regex (last arg).
1099 proc run_ld_link_tests { ldtests } {
1111 foreach testitem $ldtests {
1112 set testname [lindex $testitem 0]
1113 set ld_options [lindex $testitem 1]
1114 set as_options [lindex $testitem 2]
1115 set src_files [lindex $testitem 3]
1116 set actions [lindex $testitem 4]
1117 set binfile tmpdir/[lindex $testitem 5]
1118 set cflags [lindex $testitem 6]
1123 # verbose -log "Testname is $testname"
1124 # verbose -log "ld_options is $ld_options"
1125 # verbose -log "as_options is $as_options"
1126 # verbose -log "src_files is $src_files"
1127 # verbose -log "actions is $actions"
1128 # verbose -log "binfile is $binfile"
1130 # Assemble each file in the test.
1131 foreach src_file $src_files {
1132 set objfile "tmpdir/[file rootname $src_file].o"
1133 lappend objfiles $objfile
1135 if { [file extension $src_file] == ".c" } {
1136 set as_file "tmpdir/[file rootname $src_file].s"
1137 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1142 set as_file "$srcdir/$subdir/$src_file"
1144 if ![ld_assemble $as "$as_options $as_file" $objfile] {
1150 # Catch assembler errors.
1151 if { $is_unresolved != 0 } {
1152 unresolved $testname
1156 if ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1160 foreach actionlist $actions {
1161 set action [lindex $actionlist 0]
1162 set progopts [lindex $actionlist 1]
1164 # There are actions where we run regexp_diff on the
1165 # output, and there are other actions (presumably).
1166 # Handling of the former look the same.
1170 { set dump_prog $objdump }
1172 { set dump_prog $nm }
1174 { set dump_prog $READELF }
1177 perror "Unrecognized action $action"
1183 if { $dump_prog != "" } {
1184 set dumpfile [lindex $actionlist 2]
1185 set binary $dump_prog
1187 # Ensure consistent sorting of symbols
1188 if {[info exists env(LC_ALL)]} {
1189 set old_lc_all $env(LC_ALL)
1192 set cmd "$binary $progopts $binfile > dump.out"
1194 catch "exec $cmd" comp_output
1195 if {[info exists old_lc_all]} {
1196 set env(LC_ALL) $old_lc_all
1200 set comp_output [prune_warnings $comp_output]
1202 if ![string match "" $comp_output] then {
1203 send_log "$comp_output\n"
1208 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1209 verbose "output is [file_contents "dump.out"]" 2
1216 if { $failed != 0 } {
1218 } else { if { $is_unresolved == 0 } {
1223 # Catch action errors.
1224 if { $is_unresolved != 0 } {
1225 unresolved $testname
1232 proc verbose_eval { expr { level 1 } } {
1234 if $verbose>$level then { eval verbose "$expr" $level }
1237 # This definition is taken from an unreleased version of DejaGnu. Once
1238 # that version gets released, and has been out in the world for a few
1239 # months at least, it may be safe to delete this copy.
1240 if ![string length [info proc prune_warnings]] {
1242 # prune_warnings -- delete various system verbosities from TEXT
1245 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1247 # Sites with particular verbose os's may wish to override this in site.exp.
1249 proc prune_warnings { text } {
1250 # This is from sun4's. Do it for all machines for now.
1251 # The "\\1" is to try to preserve a "\n" but only if necessary.
1252 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1254 # It might be tempting to get carried away and delete blank lines, etc.
1255 # Just delete *exactly* what we're ask to, and that's it.
1260 # targets_to_xfail is a list of target triplets to be xfailed.
1261 # ldtests contains test-items with 3 items followed by 1 lists, 2 items
1262 # and 3 optional items:
1265 # 2:assembler options
1266 # 3:filenames of source files
1267 # 4:name of output file
1269 # 6:compiler flags (optional)
1270 # 7:language (optional)
1271 # 8:linker warning (optional)
1273 proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
1285 foreach testitem $ldtests {
1286 foreach target $targets_to_xfail {
1289 set testname [lindex $testitem 0]
1290 set ld_options [lindex $testitem 1]
1291 set as_options [lindex $testitem 2]
1292 set src_files [lindex $testitem 3]
1293 set binfile tmpdir/[lindex $testitem 4]
1294 set expfile [lindex $testitem 5]
1295 set cflags [lindex $testitem 6]
1296 set lang [lindex $testitem 7]
1297 set warning [lindex $testitem 8]
1301 # verbose -log "Testname is $testname"
1302 # verbose -log "ld_options is $ld_options"
1303 # verbose -log "as_options is $as_options"
1304 # verbose -log "src_files is $src_files"
1305 # verbose -log "actions is $actions"
1306 # verbose -log "binfile is $binfile"
1308 # Assemble each file in the test.
1309 foreach src_file $src_files {
1310 set objfile "tmpdir/[file rootname $src_file].o"
1311 lappend objfiles $objfile
1313 # We ignore warnings since some compilers may generate
1314 # incorrect section attributes and the assembler will warn
1316 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1318 # We have to use $CC to build PIE and shared library.
1319 if { [ string match "c" $lang ] } {
1320 set link_proc ld_simple_link
1322 } elseif { [ string match "c++" $lang ] } {
1323 set link_proc ld_simple_link
1325 } elseif { [ string match "-shared" $ld_options ] \
1326 || [ string match "-pie" $ld_options ] } {
1327 set link_proc ld_simple_link
1330 set link_proc ld_link
1334 if ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1340 # Check if exec_output is expected.
1341 if { $warning != "" } then {
1342 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1343 if { [regexp $warning $exec_output] } then {
1350 if { $failed == 0 } {
1351 send_log "Running: $binfile > $binfile.out\n"
1352 verbose "Running: $binfile > $binfile.out"
1353 catch "exec $binfile > $binfile.out" exec_output
1355 if ![string match "" $exec_output] then {
1356 send_log "$exec_output\n"
1357 verbose "$exec_output" 1
1360 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1361 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1362 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1363 set exec_output [prune_warnings $exec_output]
1365 if ![string match "" $exec_output] then {
1366 send_log "$exec_output\n"
1367 verbose "$exec_output" 1
1373 if { $failed != 0 } {
1383 # List contains test-items with 3 items followed by 2 lists, one item and
1384 # one optional item:
1388 # 3:filenames of source files
1389 # 4:action and options.
1390 # 5:name of output file
1391 # 6:language (optional)
1394 # objdump: Apply objdump options on result. Compare with regex (last arg).
1395 # nm: Apply nm options on result. Compare with regex (last arg).
1396 # readelf: Apply readelf options on result. Compare with regex (last arg).
1398 proc run_cc_link_tests { ldtests } {
1409 foreach testitem $ldtests {
1410 set testname [lindex $testitem 0]
1411 set ldflags [lindex $testitem 1]
1412 set cflags [lindex $testitem 2]
1413 set src_files [lindex $testitem 3]
1414 set actions [lindex $testitem 4]
1415 set binfile tmpdir/[lindex $testitem 5]
1416 set lang [lindex $testitem 6]
1421 # Compile each file in the test.
1422 foreach src_file $src_files {
1423 set objfile "tmpdir/[file rootname $src_file].o"
1424 lappend objfiles $objfile
1426 # We ignore warnings since some compilers may generate
1427 # incorrect section attributes and the assembler will warn
1429 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1432 # Clear error and warning counts.
1435 if { [ string match "c++" $lang ] } {
1441 if ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] {
1445 foreach actionlist $actions {
1446 set action [lindex $actionlist 0]
1447 set progopts [lindex $actionlist 1]
1449 # There are actions where we run regexp_diff on the
1450 # output, and there are other actions (presumably).
1451 # Handling of the former look the same.
1455 { set dump_prog $objdump }
1457 { set dump_prog $nm }
1459 { set dump_prog $READELF }
1462 perror "Unrecognized action $action"
1468 if { $dump_prog != "" } {
1469 set dumpfile [lindex $actionlist 2]
1470 set binary $dump_prog
1472 # Ensure consistent sorting of symbols
1473 if {[info exists env(LC_ALL)]} {
1474 set old_lc_all $env(LC_ALL)
1477 set cmd "$binary $progopts $binfile > dump.out"
1479 catch "exec $cmd" comp_output
1480 if {[info exists old_lc_all]} {
1481 set env(LC_ALL) $old_lc_all
1485 set comp_output [prune_warnings $comp_output]
1487 if ![string match "" $comp_output] then {
1488 send_log "$comp_output\n"
1493 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1494 verbose "output is [file_contents "dump.out"]" 2
1501 if { $failed != 0 } {
1503 } else { if { $is_unresolved == 0 } {
1508 # Catch action errors.
1509 if { $is_unresolved != 0 } {
1510 unresolved $testname