Set OSABI field back to 0 (SysV), to avoid interoperability problems
[nacl-binutils.git] / ld / testsuite / lib / ld-lib.exp
blobc983f1b4bf7e1c33e4a0edba6a5084a7f7384ed0
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 part of the GNU Binutils.
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.
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.
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.
22 # Extract and print the version number of ld.
24 proc default_ld_version { ld } {
25 global host_triplet
27 if { [which $ld] == 0 } then {
28 perror "$ld does not exist"
29 exit 1
32 catch "exec $ld --version" tmp
33 set tmp [prune_warnings $tmp]
34 regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number
35 if [info exists number] then {
36 clone_output "$ld $number\n"
40 # Link an object using relocation.
42 proc default_ld_relocate { ld target objects } {
43 global HOSTING_EMU
44 global host_triplet
45 global exec_output
47 if { [which $ld] == 0 } then {
48 perror "$ld does not exist"
49 return 0
52 catch "exec rm -f $target" exec_output
54 verbose -log "$ld $HOSTING_EMU -o $target -r $objects"
56 catch "exec $ld $HOSTING_EMU -o $target -r $objects" exec_output
57 set exec_output [prune_warnings $exec_output]
58 if [string match "" $exec_output] then {
59 return 1
60 } else {
61 verbose -log "$exec_output"
62 return 0
66 # Check to see if ld is being invoked with a non-endian output format
68 proc is_endian_output_format { object_flags } {
70 if {[string match "*-oformat binary*" $object_flags] || \
71 [string match "*-oformat ieee*" $object_flags] || \
72 [string match "*-oformat ihex*" $object_flags] || \
73 [string match "*-oformat netbsd-core*" $object_flags] || \
74 [string match "*-oformat srec*" $object_flags] || \
75 [string match "*-oformat tekhex*" $object_flags] || \
76 [string match "*-oformat trad-core*" $object_flags] } then {
77 return 0
78 } else {
79 return 1
83 # Look for big-endian or little-endian switches in the multlib
84 # options and translate these into a -EB or -EL switch. Note
85 # we cannot rely upon proc process_multilib_options to do this
86 # for us because for some targets the compiler does not support
87 # -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
88 # the site.exp file will include the switch "-mbig-endian"
89 # (rather than "big-endian") which is not detected by proc
90 # process_multilib_options.
92 proc big_or_little_endian {} {
94 if [board_info [target_info name] exists multilib_flags] {
95 set tmp_flags " [board_info [target_info name] multilib_flags]"
97 foreach x $tmp_flags {
98 case $x in {
99 {*big*endian eb EB -eb -EB -mb -meb} {
100 set flags " -EB"
101 return $flags
103 {*little*endian el EL -el -EL -ml -mel} {
104 set flags " -EL"
105 return $flags
111 set flags ""
112 return $flags
115 # Link a program using ld.
117 proc default_ld_link { ld target objects } {
118 global HOSTING_EMU
119 global HOSTING_CRT0
120 global HOSTING_LIBS
121 global LIBS
122 global host_triplet
123 global link_output
124 global exec_output
126 set objs "$HOSTING_CRT0 $objects"
127 set libs "$LIBS $HOSTING_LIBS"
129 if { [which $ld] == 0 } then {
130 perror "$ld does not exist"
131 return 0
134 if [is_endian_output_format $objects] then {
135 set flags [big_or_little_endian]
136 } else {
137 set flags ""
140 catch "exec rm -f $target" exec_output
142 verbose -log "$ld $HOSTING_EMU $flags -o $target $objs $libs"
144 catch "exec $ld $HOSTING_EMU $flags -o $target $objs $libs" link_output
145 set exec_output [prune_warnings $link_output]
146 if [string match "" $exec_output] then {
147 return 1
148 } else {
149 verbose -log "$exec_output"
150 return 0
154 # Link a program using ld, without including any libraries.
156 proc default_ld_simple_link { ld target objects } {
157 global host_triplet
158 global link_output
159 global gcc_ld_flag
160 global exec_output
162 if { [which $ld] == 0 } then {
163 perror "$ld does not exist"
164 return 0
167 if [is_endian_output_format $objects] then {
168 set flags [big_or_little_endian]
169 } else {
170 set flags ""
173 # If we are compiling with gcc, we want to add gcc_ld_flag to
174 # flags. Rather than determine this in some complex way, we guess
175 # based on the name of the compiler.
176 set ldexe $ld
177 set ldparm [string first " " $ld]
178 if { $ldparm > 0 } then {
179 set ldexe [string range $ld 0 $ldparm]
181 set ldexe [string replace $ldexe 0 [string last "/" $ldexe] ""]
182 if {[string match "*gcc*" $ldexe] || [string match "*++*" $ldexe]} then {
183 set flags "$gcc_ld_flag $flags"
186 catch "exec rm -f $target" exec_output
188 verbose -log "$ld $flags -o $target $objects"
190 catch "exec $ld $flags -o $target $objects" link_output
191 set exec_output [prune_warnings $link_output]
193 # We don't care if we get a warning about a non-existent start
194 # symbol, since the default linker script might use ENTRY.
195 regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
197 if [string match "" $exec_output] then {
198 return 1
199 } else {
200 verbose -log "$exec_output"
201 return 0
205 # Compile an object using cc.
207 proc default_ld_compile { cc source object } {
208 global CFLAGS
209 global srcdir
210 global subdir
211 global host_triplet
212 global gcc_gas_flag
214 set cc_prog $cc
215 if {[llength $cc_prog] > 1} then {
216 set cc_prog [lindex $cc_prog 0]
218 if {[which $cc_prog] == 0} then {
219 perror "$cc_prog does not exist"
220 return 0
223 catch "exec rm -f $object" exec_output
225 set flags "-I$srcdir/$subdir $CFLAGS"
227 # If we are compiling with gcc, we want to add gcc_gas_flag to
228 # flags. Rather than determine this in some complex way, we guess
229 # based on the name of the compiler.
230 set ccexe $cc
231 set ccparm [string first " " $cc]
232 set ccflags ""
233 if { $ccparm > 0 } then {
234 set ccflags [string range $cc $ccparm end]
235 set ccexe [string range $cc 0 $ccparm]
236 set cc $ccexe
238 set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""]
239 if {[string match "*gcc*" $ccexe] || [string match "*++*" $ccexe]} then {
240 set flags "$gcc_gas_flag $flags"
243 if [board_info [target_info name] exists multilib_flags] {
244 append flags " [board_info [target_info name] multilib_flags]"
247 verbose -log "$cc $flags $ccflags -c $source -o $object"
249 catch "exec $cc $flags $ccflags -c $source -o $object" exec_output
250 set exec_output [prune_warnings $exec_output]
251 if [string match "" $exec_output] then {
252 if {![file exists $object]} then {
253 regexp ".*/(\[^/\]*)$" $source all dobj
254 regsub "\\.c" $dobj ".o" realobj
255 verbose "looking for $realobj"
256 if {[file exists $realobj]} then {
257 verbose -log "mv $realobj $object"
258 catch "exec mv $realobj $object" exec_output
259 set exec_output [prune_warnings $exec_output]
260 if {![string match "" $exec_output]} then {
261 verbose -log "$exec_output"
262 perror "could not move $realobj to $object"
263 return 0
265 } else {
266 perror "$object not found after compilation"
267 return 0
270 return 1
271 } else {
272 verbose -log "$exec_output"
273 perror "$source: compilation failed"
274 return 0
278 # Assemble a file.
280 proc default_ld_assemble { as source object } {
281 global ASFLAGS
282 global host_triplet
284 if {[which $as] == 0} then {
285 perror "$as does not exist"
286 return 0
289 if ![info exists ASFLAGS] { set ASFLAGS "" }
291 set flags [big_or_little_endian]
293 verbose -log "$as $flags $ASFLAGS -o $object $source"
295 catch "exec $as $flags $ASFLAGS -o $object $source" exec_output
296 set exec_output [prune_warnings $exec_output]
297 if [string match "" $exec_output] then {
298 return 1
299 } else {
300 verbose -log "$exec_output"
301 perror "$source: assembly failed"
302 return 0
306 # Run nm on a file, putting the result in the array nm_output.
308 proc default_ld_nm { nm nmflags object } {
309 global NMFLAGS
310 global nm_output
311 global host_triplet
313 if {[which $nm] == 0} then {
314 perror "$nm does not exist"
315 return 0
318 if {[info exists nm_output]} {
319 unset nm_output
322 if ![info exists NMFLAGS] { set NMFLAGS "" }
324 # Ensure consistent sorting of symbols
325 if {[info exists env(LC_ALL)]} {
326 set old_lc_all $env(LC_ALL)
328 set env(LC_ALL) "C"
329 verbose -log "$nm $NMFLAGS $nmflags $object >tmpdir/nm.out"
331 catch "exec $nm $NMFLAGS $nmflags $object >tmpdir/nm.out" exec_output
332 if {[info exists old_lc_all]} {
333 set env(LC_ALL) $old_lc_all
334 } else {
335 unset env(LC_ALL)
337 set exec_output [prune_warnings $exec_output]
338 if [string match "" $exec_output] then {
339 set file [open tmpdir/nm.out r]
340 while { [gets $file line] != -1 } {
341 verbose "$line" 2
342 if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] \\.*(.+)$" $line whole value name] {
343 set name [string trimleft $name "_"]
344 verbose "Setting nm_output($name) to 0x$value" 2
345 set nm_output($name) 0x$value
348 close $file
349 return 1
350 } else {
351 verbose -log "$exec_output"
352 perror "$object: nm failed"
353 return 0
357 # True if the object format is known to be ELF.
359 proc is_elf_format {} {
360 if { ![istarget *-*-sysv4*] \
361 && ![istarget *-*-unixware*] \
362 && ![istarget *-*-elf*] \
363 && ![istarget *-*-eabi*] \
364 && ![istarget hppa*64*-*-hpux*] \
365 && ![istarget *-*-linux*] \
366 && ![istarget frv-*-uclinux*] \
367 && ![istarget *-*-irix5*] \
368 && ![istarget *-*-irix6*] \
369 && ![istarget *-*-netbsd*] \
370 && ![istarget *-*-solaris2*] } {
371 return 0
374 if { [istarget *-*-linux*aout*] \
375 || [istarget *-*-linux*oldld*] } {
376 return 0
379 if { ![istarget *-*-netbsdelf*] \
380 && ([istarget *-*-netbsd*aout*] \
381 || [istarget *-*-netbsdpe*] \
382 || [istarget arm*-*-netbsd*] \
383 || [istarget sparc-*-netbsd*] \
384 || [istarget i*86-*-netbsd*] \
385 || [istarget m68*-*-netbsd*] \
386 || [istarget vax-*-netbsd*] \
387 || [istarget ns32k-*-netbsd*]) } {
388 return 0
390 return 1
393 # True if the object format is known to be 64-bit ELF.
395 proc is_elf64 { binary_file } {
396 global READELF
397 global READELFFLAGS
399 set readelf_size ""
400 catch "exec $READELF $READELFFLAGS -h $binary_file > readelf.out" got
402 if ![string match "" $got] then {
403 return 0
406 if { ![regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \
407 [file_contents readelf.out] nil readelf_size] } {
408 return 0
411 if { $readelf_size == "64" } {
412 return 1
415 return 0
418 # True if the object format is known to be a.out.
420 proc is_aout_format {} {
421 if { [istarget *-*-*\[ab\]out*] \
422 || [istarget *-*-linux*oldld*] \
423 || [istarget *-*-msdos*] \
424 || [istarget arm-*-netbsd] \
425 || [istarget i?86-*-netbsd] \
426 || [istarget i?86-*-mach*] \
427 || [istarget i?86-*-vsta] \
428 || [istarget pdp11-*-*] \
429 || [istarget m68*-ericsson-ose] \
430 || [istarget m68k-hp-bsd*] \
431 || [istarget m68*-*-hpux*] \
432 || [istarget m68*-*-netbsd] \
433 || [istarget m68*-*-netbsd*4k*] \
434 || [istarget m68k-sony-*] \
435 || [istarget m68*-sun-sunos\[34\]*] \
436 || [istarget m68*-wrs-vxworks*] \
437 || [istarget ns32k-*-*] \
438 || [istarget sparc*-*-netbsd] \
439 || [istarget sparc-sun-sunos4*] \
440 || [istarget vax-dec-ultrix*] \
441 || [istarget vax-*-netbsd] } {
442 return 1
444 return 0
447 # True if the object format is known to be PE COFF.
449 proc is_pecoff_format {} {
450 if { ![istarget *-*-mingw*] \
451 && ![istarget *-*-cygwin*] \
452 && ![istarget *-*-pe*] } {
453 return 0
456 return 1
459 # Compares two files line-by-line.
460 # Returns differences if exist.
461 # Returns null if file(s) cannot be opened.
463 proc simple_diff { file_1 file_2 } {
464 global target
466 set eof -1
467 set differences 0
469 if [file exists $file_1] then {
470 set file_a [open $file_1 r]
471 } else {
472 warning "$file_1 doesn't exist"
473 return
476 if [file exists $file_2] then {
477 set file_b [open $file_2 r]
478 } else {
479 fail "$file_2 doesn't exist"
480 return
483 verbose "# Diff'ing: $file_1 $file_2\n" 2
485 while { [gets $file_a line] != $eof } {
486 if [regexp "^#.*$" $line] then {
487 continue
488 } else {
489 lappend list_a $line
492 close $file_a
494 while { [gets $file_b line] != $eof } {
495 if [regexp "^#.*$" $line] then {
496 continue
497 } else {
498 lappend list_b $line
501 close $file_b
503 for { set i 0 } { $i < [llength $list_a] } { incr i } {
504 set line_a [lindex $list_a $i]
505 set line_b [lindex $list_b $i]
507 verbose "\t$file_1: $i: $line_a\n" 3
508 verbose "\t$file_2: $i: $line_b\n" 3
509 if [string compare $line_a $line_b] then {
510 verbose -log "\t$file_1: $i: $line_a\n"
511 verbose -log "\t$file_2: $i: $line_b\n"
513 fail "Test: $target"
514 return
518 if { [llength $list_a] != [llength $list_b] } {
519 fail "Test: $target"
520 return
523 if $differences<1 then {
524 pass "Test: $target"
528 # run_dump_test FILE
529 # Copied from gas testsuite, tweaked and further extended.
531 # Assemble a .s file, then run some utility on it and check the output.
533 # There should be an assembly language file named FILE.s in the test
534 # suite directory, and a pattern file called FILE.d. `run_dump_test'
535 # will assemble FILE.s, run some tool like `objdump', `objcopy', or
536 # `nm' on the .o file to produce textual output, and then analyze that
537 # with regexps. The FILE.d file specifies what program to run, and
538 # what to expect in its output.
540 # The FILE.d file begins with zero or more option lines, which specify
541 # flags to pass to the assembler, the program to run to dump the
542 # assembler's output, and the options it wants. The option lines have
543 # the syntax:
545 # # OPTION: VALUE
547 # OPTION is the name of some option, like "name" or "objdump", and
548 # VALUE is OPTION's value. The valid options are described below.
549 # Whitespace is ignored everywhere, except within VALUE. The option
550 # list ends with the first line that doesn't match the above syntax
551 # (hmm, not great for error detection).
553 # The interesting options are:
555 # name: TEST-NAME
556 # The name of this test, passed to DejaGNU's `pass' and `fail'
557 # commands. If omitted, this defaults to FILE, the root of the
558 # .s and .d files' names.
560 # as: FLAGS
561 # When assembling, pass FLAGS to the assembler.
562 # If assembling several files, you can pass different assembler
563 # options in the "source" directives. See below.
565 # ld: FLAGS
566 # Link assembled files using FLAGS, in the order of the "source"
567 # directives, when using multiple files.
569 # objcopy_linked_file: FLAGS
570 # Run objcopy on the linked file with the specified flags.
571 # This lets you transform the linked file using objcopy, before the
572 # result is analyzed by an analyzer program specified below (which
573 # may in turn *also* be objcopy).
575 # PROG: PROGRAM-NAME
576 # The name of the program to run to analyze the .o file produced
577 # by the assembler or the linker output. This can be omitted;
578 # run_dump_test will guess which program to run by seeing which of
579 # the flags options below is present.
581 # objdump: FLAGS
582 # nm: FLAGS
583 # objcopy: FLAGS
584 # Use the specified program to analyze the assembler or linker
585 # output file, and pass it FLAGS, in addition to the output name.
586 # Note that they are run with LC_ALL=C in the environment to give
587 # consistent sorting of symbols.
589 # source: SOURCE [FLAGS]
590 # Assemble the file SOURCE.s using the flags in the "as" directive
591 # and the (optional) FLAGS. If omitted, the source defaults to
592 # FILE.s.
593 # This is useful if several .d files want to share a .s file.
594 # More than one "source" directive can be given, which is useful
595 # when testing linking.
597 # xfail: TARGET
598 # The test is expected to fail on TARGET. This may occur more than
599 # once.
601 # target: TARGET
602 # Only run the test for TARGET. This may occur more than once; the
603 # target being tested must match at least one.
605 # notarget: TARGET
606 # Do not run the test for TARGET. This may occur more than once;
607 # the target being tested must not match any of them.
609 # error: REGEX
610 # An error with message matching REGEX must be emitted for the test
611 # to pass. The PROG, objdump, nm and objcopy options have no
612 # meaning and need not supplied if this is present.
614 # warning: REGEX
615 # Expect a linker warning matching REGEX. It is an error to issue
616 # both "error" and "warning".
618 # Each option may occur at most once unless otherwise mentioned.
620 # After the option lines come regexp lines. `run_dump_test' calls
621 # `regexp_diff' to compare the output of the dumping tool against the
622 # regexps in FILE.d. `regexp_diff' is defined later in this file; see
623 # further comments there.
625 proc run_dump_test { name } {
626 global subdir srcdir
627 global OBJDUMP NM AS OBJCOPY READELF LD
628 global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
629 global host_triplet runtests
630 global env
632 if [string match "*/*" $name] {
633 set file $name
634 set name [file tail $name]
635 } else {
636 set file "$srcdir/$subdir/$name"
639 if ![runtest_file_p $runtests $name] then {
640 return
643 set opt_array [slurp_options "${file}.d"]
644 if { $opt_array == -1 } {
645 perror "error reading options from $file.d"
646 unresolved $subdir/$name
647 return
649 set dumpfile tmpdir/dump.out
650 set run_ld 0
651 set run_objcopy 0
652 set opts(as) {}
653 set opts(ld) {}
654 set opts(xfail) {}
655 set opts(target) {}
656 set opts(notarget) {}
657 set opts(objdump) {}
658 set opts(nm) {}
659 set opts(objcopy) {}
660 set opts(readelf) {}
661 set opts(name) {}
662 set opts(PROG) {}
663 set opts(source) {}
664 set opts(error) {}
665 set opts(warning) {}
666 set opts(objcopy_linked_file) {}
667 set asflags(${file}.s) {}
669 foreach i $opt_array {
670 set opt_name [lindex $i 0]
671 set opt_val [lindex $i 1]
672 if ![info exists opts($opt_name)] {
673 perror "unknown option $opt_name in file $file.d"
674 unresolved $subdir/$name
675 return
678 switch -- $opt_name {
679 xfail {}
680 target {}
681 notarget {}
682 source {
683 # Move any source-specific as-flags to a separate array to
684 # simplify processing.
685 if { [llength $opt_val] > 1 } {
686 set asflags([lindex $opt_val 0]) [lrange $opt_val 1 end]
687 set opt_val [lindex $opt_val 0]
688 } else {
689 set asflags($opt_val) {}
692 default {
693 if [string length $opts($opt_name)] {
694 perror "option $opt_name multiply set in $file.d"
695 unresolved $subdir/$name
696 return
699 # A single "# ld:" with no options should do the right thing.
700 if { $opt_name == "ld" } {
701 set run_ld 1
703 # Likewise objcopy_linked_file.
704 if { $opt_name == "objcopy_linked_file" } {
705 set run_objcopy 1
709 set opts($opt_name) [concat $opts($opt_name) $opt_val]
712 # Decide early whether we should run the test for this target.
713 if { [llength $opts(target)] > 0 } {
714 set targmatch 0
715 foreach targ $opts(target) {
716 if [istarget $targ] {
717 set targmatch 1
718 break
721 if { $targmatch == 0 } {
722 return
725 foreach targ $opts(notarget) {
726 if [istarget $targ] {
727 return
731 set program ""
732 # It's meaningless to require an output-testing method when we
733 # expect an error.
734 if { $opts(error) == "" } {
735 if {$opts(PROG) != ""} {
736 switch -- $opts(PROG) {
737 objdump { set program objdump }
738 nm { set program nm }
739 objcopy { set program objcopy }
740 readelf { set program readelf }
741 default
742 { perror "unrecognized program option $opts(PROG) in $file.d"
743 unresolved $subdir/$name
744 return }
746 } else {
747 # Guess which program to run, by seeing which option was specified.
748 foreach p {objdump objcopy nm readelf} {
749 if {$opts($p) != ""} {
750 if {$program != ""} {
751 perror "ambiguous dump program in $file.d"
752 unresolved $subdir/$name
753 return
754 } else {
755 set program $p
760 if { $program == "" && $opts(warning) == "" } {
761 perror "dump program unspecified in $file.d"
762 unresolved $subdir/$name
763 return
767 if { $opts(name) == "" } {
768 set testname "$subdir/$name"
769 } else {
770 set testname $opts(name)
773 if { $opts(source) == "" } {
774 set sourcefiles [list ${file}.s]
775 } else {
776 set sourcefiles {}
777 foreach sf $opts(source) {
778 if { [string match "/*" $sf] } {
779 lappend sourcefiles "$sf"
780 } else {
781 lappend sourcefiles "$srcdir/$subdir/$sf"
783 # Must have asflags indexed on source name.
784 set asflags($srcdir/$subdir/$sf) $asflags($sf)
788 # Time to setup xfailures.
789 foreach targ $opts(xfail) {
790 setup_xfail $targ
793 # Assemble each file.
794 set objfiles {}
795 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
796 set sourcefile [lindex $sourcefiles $i]
798 set objfile "tmpdir/dump$i.o"
799 catch "exec rm -f $objfile" exec_output
800 lappend objfiles $objfile
801 set cmd "$AS $ASFLAGS $opts(as) $asflags($sourcefile) -o $objfile $sourcefile"
803 send_log "$cmd\n"
804 set cmdret [catch "exec $cmd" comp_output]
805 set comp_output [prune_warnings $comp_output]
807 if { $cmdret != 0 || ![string match "" $comp_output] } then {
808 send_log "$comp_output\n"
809 verbose "$comp_output" 3
811 set exitstat "succeeded"
812 if { $cmdret != 0 } { set exitstat "failed" }
813 verbose -log "$exitstat with: <$comp_output>"
814 fail $testname
815 return
819 set expmsg $opts(error)
820 if { $opts(warning) != "" } {
821 if { $expmsg != "" } {
822 perror "$testname: mixing error and warning test-directives"
823 return
825 set expmsg $opts(warning)
828 # Perhaps link the file(s).
829 if { $run_ld } {
830 set objfile "tmpdir/dump"
831 catch "exec rm -f $objfile" exec_output
833 # Add -L$srcdir/$subdir so that the linker command can use
834 # linker scripts in the source directory.
835 set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
836 $opts(ld) -o $objfile $objfiles"
838 send_log "$cmd\n"
839 set cmdret [catch "exec $cmd" comp_output]
840 set comp_output [prune_warnings $comp_output]
842 if { $cmdret != 0 } then {
843 # If the executed program writes to stderr and stderr is not
844 # redirected, exec *always* returns failure, regardless of the
845 # program exit code. Thankfully, we can retrieve the true
846 # return status from a special variable. Redirection would
847 # cause a Tcl-specific message to be appended, and we'd rather
848 # not deal with that if we can help it.
849 global errorCode
850 if { [lindex $errorCode 0] == "NONE" } {
851 set cmdret 0
855 if { $cmdret == 0 && $run_objcopy } {
856 set infile $objfile
857 set objfile "tmpdir/dump1"
858 catch "exec rm -f $objfile" exec_output
860 # Note that we don't use OBJCOPYFLAGS here; any flags must be
861 # explicitly specified.
862 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
864 send_log "$cmd\n"
865 set cmdret [catch "exec $cmd" comp_output]
866 append comp_output [prune_warnings $comp_output]
868 if { $cmdret != 0 } then {
869 global errorCode
870 if { [lindex $errorCode 0] == "NONE" } {
871 set cmdret 0
876 if { $cmdret != 0 || $comp_output != "" || $expmsg != "" } then {
877 set exitstat "succeeded"
878 if { $cmdret != 0 } { set exitstat "failed" }
879 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
880 send_log "$comp_output\n"
881 verbose "$comp_output" 3
883 if { [regexp $expmsg $comp_output] \
884 && (($cmdret == 0) == ($opts(warning) != "")) } {
885 # We have the expected output from ld.
886 if { $opts(error) != "" || $program == "" } {
887 pass $testname
888 return
890 } else {
891 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
892 fail $testname
893 return
896 } else {
897 set objfile "tmpdir/dump0.o"
900 # We must not have expected failure if we get here.
901 if { $opts(error) != "" } {
902 fail $testname
903 return
906 set progopts1 $opts($program)
907 eval set progopts \$[string toupper $program]FLAGS
908 eval set binary \$[string toupper $program]
910 if { [which $binary] == 0 } {
911 untested $testname
912 return
915 if { $progopts1 == "" } { set $progopts1 "-r" }
916 verbose "running $binary $progopts $progopts1" 3
918 # Objcopy, unlike the other two, won't send its output to stdout,
919 # so we have to run it specially.
920 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
921 if { $program == "objcopy" } {
922 set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
925 # Ensure consistent sorting of symbols
926 if {[info exists env(LC_ALL)]} {
927 set old_lc_all $env(LC_ALL)
929 set env(LC_ALL) "C"
930 send_log "$cmd\n"
931 catch "exec $cmd" comp_output
932 if {[info exists old_lc_all]} {
933 set env(LC_ALL) $old_lc_all
934 } else {
935 unset env(LC_ALL)
937 set comp_output [prune_warnings $comp_output]
938 if ![string match "" $comp_output] then {
939 send_log "$comp_output\n"
940 fail $testname
941 return
944 verbose_eval {[file_contents $dumpfile]} 3
945 if { [regexp_diff $dumpfile "${file}.d"] } then {
946 fail $testname
947 verbose "output is [file_contents $dumpfile]" 2
948 return
951 pass $testname
954 proc slurp_options { file } {
955 if [catch { set f [open $file r] } x] {
956 #perror "couldn't open `$file': $x"
957 perror "$x"
958 return -1
960 set opt_array {}
961 # whitespace expression
962 set ws {[ ]*}
963 set nws {[^ ]*}
964 # whitespace is ignored anywhere except within the options list;
965 # option names are alphabetic plus underscore only.
966 set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
967 while { [gets $f line] != -1 } {
968 set line [string trim $line]
969 # Whitespace here is space-tab.
970 if [regexp $pat $line xxx opt_name opt_val] {
971 # match!
972 lappend opt_array [list $opt_name $opt_val]
973 } else {
974 break
977 close $f
978 return $opt_array
981 # regexp_diff, copied from gas, based on simple_diff above.
982 # compares two files line-by-line
983 # file1 contains strings, file2 contains regexps and #-comments
984 # blank lines are ignored in either file
985 # returns non-zero if differences exist
987 proc regexp_diff { file_1 file_2 } {
989 set eof -1
990 set end_1 0
991 set end_2 0
992 set differences 0
993 set diff_pass 0
995 if [file exists $file_1] then {
996 set file_a [open $file_1 r]
997 } else {
998 warning "$file_1 doesn't exist"
999 return 1
1002 if [file exists $file_2] then {
1003 set file_b [open $file_2 r]
1004 } else {
1005 fail "$file_2 doesn't exist"
1006 close $file_a
1007 return 1
1010 verbose " Regexp-diff'ing: $file_1 $file_2" 2
1012 while { 1 } {
1013 set line_a ""
1014 set line_b ""
1015 while { [string length $line_a] == 0 } {
1016 if { [gets $file_a line_a] == $eof } {
1017 set end_1 1
1018 break
1021 while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
1022 if [ string match "#pass" $line_b ] {
1023 set end_2 1
1024 set diff_pass 1
1025 break
1026 } elseif [ string match "#..." $line_b ] {
1027 if { [gets $file_b line_b] == $eof } {
1028 set end_2 1
1029 set diff_pass 1
1030 break
1032 verbose "looking for \"^$line_b$\"" 3
1033 while { ![regexp "^$line_b$" "$line_a"] } {
1034 verbose "skipping \"$line_a\"" 3
1035 if { [gets $file_a line_a] == $eof } {
1036 set end_1 1
1037 break
1040 break
1042 if { [gets $file_b line_b] == $eof } {
1043 set end_2 1
1044 break
1048 if { $diff_pass } {
1049 break
1050 } elseif { $end_1 && $end_2 } {
1051 break
1052 } elseif { $end_1 } {
1053 send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
1054 verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
1055 set differences 1
1056 break
1057 } elseif { $end_2 } {
1058 send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
1059 verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
1060 set differences 1
1061 break
1062 } else {
1063 verbose "regexp \"^$line_b$\"\nline \"$line_a\"" 3
1064 if ![regexp "^$line_b$" "$line_a"] {
1065 send_log "regexp_diff match failure\n"
1066 send_log "regexp \"^$line_b$\"\nline \"$line_a\"\n"
1067 set differences 1
1072 if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
1073 send_log "$file_1 and $file_2 are different lengths\n"
1074 verbose "$file_1 and $file_2 are different lengths" 3
1075 set differences 1
1078 close $file_a
1079 close $file_b
1081 return $differences
1084 proc file_contents { filename } {
1085 set file [open $filename r]
1086 set contents [read $file]
1087 close $file
1088 return $contents
1091 # List contains test-items with 3 items followed by 2 lists, one item and
1092 # one optional item:
1093 # 0:name 1:ld options 2:assembler options
1094 # 3:filenames of assembler files 4: action and options. 5: name of output file
1095 # 6:compiler flags (optional)
1097 # Actions:
1098 # objdump: Apply objdump options on result. Compare with regex (last arg).
1099 # nm: Apply nm options on result. Compare with regex (last arg).
1100 # readelf: Apply readelf options on result. Compare with regex (last arg).
1102 proc run_ld_link_tests { ldtests } {
1103 global ld
1104 global as
1105 global nm
1106 global objdump
1107 global READELF
1108 global srcdir
1109 global subdir
1110 global env
1111 global CC
1112 global CFLAGS
1114 foreach testitem $ldtests {
1115 set testname [lindex $testitem 0]
1116 set ld_options [lindex $testitem 1]
1117 set as_options [lindex $testitem 2]
1118 set src_files [lindex $testitem 3]
1119 set actions [lindex $testitem 4]
1120 set binfile tmpdir/[lindex $testitem 5]
1121 set cflags [lindex $testitem 6]
1122 set objfiles {}
1123 set is_unresolved 0
1124 set failed 0
1126 # verbose -log "Testname is $testname"
1127 # verbose -log "ld_options is $ld_options"
1128 # verbose -log "as_options is $as_options"
1129 # verbose -log "src_files is $src_files"
1130 # verbose -log "actions is $actions"
1131 # verbose -log "binfile is $binfile"
1133 # Assemble each file in the test.
1134 foreach src_file $src_files {
1135 set objfile "tmpdir/[file rootname $src_file].o"
1136 lappend objfiles $objfile
1138 if { [file extension $src_file] == ".c" } {
1139 set as_file "tmpdir/[file rootname $src_file].s"
1140 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1141 set is_unresolved 1
1142 break
1144 } else {
1145 set as_file "$srcdir/$subdir/$src_file"
1147 if ![ld_assemble $as "$as_options $as_file" $objfile] {
1148 set is_unresolved 1
1149 break
1153 # Catch assembler errors.
1154 if { $is_unresolved != 0 } {
1155 unresolved $testname
1156 continue
1159 if ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1160 fail $testname
1161 } else {
1162 set failed 0
1163 foreach actionlist $actions {
1164 set action [lindex $actionlist 0]
1165 set progopts [lindex $actionlist 1]
1167 # There are actions where we run regexp_diff on the
1168 # output, and there are other actions (presumably).
1169 # Handling of the former look the same.
1170 set dump_prog ""
1171 switch -- $action {
1172 objdump
1173 { set dump_prog $objdump }
1175 { set dump_prog $nm }
1176 readelf
1177 { set dump_prog $READELF }
1178 default
1180 perror "Unrecognized action $action"
1181 set is_unresolved 1
1182 break
1186 if { $dump_prog != "" } {
1187 set dumpfile [lindex $actionlist 2]
1188 set binary $dump_prog
1190 # Ensure consistent sorting of symbols
1191 if {[info exists env(LC_ALL)]} {
1192 set old_lc_all $env(LC_ALL)
1194 set env(LC_ALL) "C"
1195 set cmd "$binary $progopts $binfile > dump.out"
1196 send_log "$cmd\n"
1197 catch "exec $cmd" comp_output
1198 if {[info exists old_lc_all]} {
1199 set env(LC_ALL) $old_lc_all
1200 } else {
1201 unset env(LC_ALL)
1203 set comp_output [prune_warnings $comp_output]
1205 if ![string match "" $comp_output] then {
1206 send_log "$comp_output\n"
1207 set failed 1
1208 break
1211 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1212 verbose "output is [file_contents "dump.out"]" 2
1213 set failed 1
1214 break
1219 if { $failed != 0 } {
1220 fail $testname
1221 } else { if { $is_unresolved == 0 } {
1222 pass $testname
1226 # Catch action errors.
1227 if { $is_unresolved != 0 } {
1228 unresolved $testname
1229 continue
1235 proc verbose_eval { expr { level 1 } } {
1236 global verbose
1237 if $verbose>$level then { eval verbose "$expr" $level }
1240 # This definition is taken from an unreleased version of DejaGnu. Once
1241 # that version gets released, and has been out in the world for a few
1242 # months at least, it may be safe to delete this copy.
1243 if ![string length [info proc prune_warnings]] {
1245 # prune_warnings -- delete various system verbosities from TEXT
1247 # An example is:
1248 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1250 # Sites with particular verbose os's may wish to override this in site.exp.
1252 proc prune_warnings { text } {
1253 # This is from sun4's. Do it for all machines for now.
1254 # The "\\1" is to try to preserve a "\n" but only if necessary.
1255 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1257 # It might be tempting to get carried away and delete blank lines, etc.
1258 # Just delete *exactly* what we're ask to, and that's it.
1259 return $text
1263 # targets_to_xfail is a list of target triplets to be xfailed.
1264 # ldtests contains test-items with 3 items followed by 1 lists, 2 items
1265 # and 3 optional items:
1266 # 0:name
1267 # 1:ld options
1268 # 2:assembler options
1269 # 3:filenames of source files
1270 # 4:name of output file
1271 # 5:expected output
1272 # 6:compiler flags (optional)
1273 # 7:language (optional)
1274 # 8:linker warning (optional)
1276 proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
1277 global ld
1278 global as
1279 global srcdir
1280 global subdir
1281 global env
1282 global CC
1283 global CXX
1284 global CFLAGS
1285 global errcnt
1286 global exec_output
1288 foreach testitem $ldtests {
1289 foreach target $targets_to_xfail {
1290 setup_xfail $target
1292 set testname [lindex $testitem 0]
1293 set ld_options [lindex $testitem 1]
1294 set as_options [lindex $testitem 2]
1295 set src_files [lindex $testitem 3]
1296 set binfile tmpdir/[lindex $testitem 4]
1297 set expfile [lindex $testitem 5]
1298 set cflags [lindex $testitem 6]
1299 set lang [lindex $testitem 7]
1300 set warning [lindex $testitem 8]
1301 set objfiles {}
1302 set failed 0
1304 # verbose -log "Testname is $testname"
1305 # verbose -log "ld_options is $ld_options"
1306 # verbose -log "as_options is $as_options"
1307 # verbose -log "src_files is $src_files"
1308 # verbose -log "actions is $actions"
1309 # verbose -log "binfile is $binfile"
1311 # Assemble each file in the test.
1312 foreach src_file $src_files {
1313 set objfile "tmpdir/[file rootname $src_file].o"
1314 lappend objfiles $objfile
1316 # We ignore warnings since some compilers may generate
1317 # incorrect section attributes and the assembler will warn
1318 # them.
1319 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1321 # We have to use $CC to build PIE and shared library.
1322 if { [ string match "c" $lang ] } {
1323 set link_proc ld_simple_link
1324 set link_cmd $CC
1325 } elseif { [ string match "c++" $lang ] } {
1326 set link_proc ld_simple_link
1327 set link_cmd $CXX
1328 } elseif { [ string match "-shared" $ld_options ] \
1329 || [ string match "-pie" $ld_options ] } {
1330 set link_proc ld_simple_link
1331 set link_cmd $CC
1332 } else {
1333 set link_proc ld_link
1334 set link_cmd $ld
1337 if ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1338 set failed 1
1339 } else {
1340 set failed 0
1343 # Check if exec_output is expected.
1344 if { $warning != "" } then {
1345 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1346 if { [regexp $warning $exec_output] } then {
1347 set failed 0
1348 } else {
1349 set failed 1
1353 if { $failed == 0 } {
1354 send_log "Running: $binfile > $binfile.out\n"
1355 verbose "Running: $binfile > $binfile.out"
1356 catch "exec $binfile > $binfile.out" exec_output
1358 if ![string match "" $exec_output] then {
1359 send_log "$exec_output\n"
1360 verbose "$exec_output" 1
1361 set failed 1
1362 } else {
1363 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1364 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1365 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1366 set exec_output [prune_warnings $exec_output]
1368 if ![string match "" $exec_output] then {
1369 send_log "$exec_output\n"
1370 verbose "$exec_output" 1
1371 set failed 1
1376 if { $failed != 0 } {
1377 fail $testname
1378 } else {
1379 set errcnt 0
1380 pass $testname
1386 # List contains test-items with 3 items followed by 2 lists, one item and
1387 # one optional item:
1388 # 0:name
1389 # 1:link options
1390 # 2:compile options
1391 # 3:filenames of source files
1392 # 4:action and options.
1393 # 5:name of output file
1394 # 6:language (optional)
1396 # Actions:
1397 # objdump: Apply objdump options on result. Compare with regex (last arg).
1398 # nm: Apply nm options on result. Compare with regex (last arg).
1399 # readelf: Apply readelf options on result. Compare with regex (last arg).
1401 proc run_cc_link_tests { ldtests } {
1402 global nm
1403 global objdump
1404 global READELF
1405 global srcdir
1406 global subdir
1407 global env
1408 global CC
1409 global CXX
1410 global CFLAGS
1412 foreach testitem $ldtests {
1413 set testname [lindex $testitem 0]
1414 set ldflags [lindex $testitem 1]
1415 set cflags [lindex $testitem 2]
1416 set src_files [lindex $testitem 3]
1417 set actions [lindex $testitem 4]
1418 set binfile tmpdir/[lindex $testitem 5]
1419 set lang [lindex $testitem 6]
1420 set objfiles {}
1421 set is_unresolved 0
1422 set failed 0
1424 # Compile each file in the test.
1425 foreach src_file $src_files {
1426 set objfile "tmpdir/[file rootname $src_file].o"
1427 lappend objfiles $objfile
1429 # We ignore warnings since some compilers may generate
1430 # incorrect section attributes and the assembler will warn
1431 # them.
1432 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1435 # Clear error and warning counts.
1436 reset_vars
1438 if { [ string match "c++" $lang ] } {
1439 set cc_cmd $CXX
1440 } else {
1441 set cc_cmd $CC
1444 if ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] {
1445 fail $testname
1446 } else {
1447 set failed 0
1448 foreach actionlist $actions {
1449 set action [lindex $actionlist 0]
1450 set progopts [lindex $actionlist 1]
1452 # There are actions where we run regexp_diff on the
1453 # output, and there are other actions (presumably).
1454 # Handling of the former look the same.
1455 set dump_prog ""
1456 switch -- $action {
1457 objdump
1458 { set dump_prog $objdump }
1460 { set dump_prog $nm }
1461 readelf
1462 { set dump_prog $READELF }
1463 default
1465 perror "Unrecognized action $action"
1466 set is_unresolved 1
1467 break
1471 if { $dump_prog != "" } {
1472 set dumpfile [lindex $actionlist 2]
1473 set binary $dump_prog
1475 # Ensure consistent sorting of symbols
1476 if {[info exists env(LC_ALL)]} {
1477 set old_lc_all $env(LC_ALL)
1479 set env(LC_ALL) "C"
1480 set cmd "$binary $progopts $binfile > dump.out"
1481 send_log "$cmd\n"
1482 catch "exec $cmd" comp_output
1483 if {[info exists old_lc_all]} {
1484 set env(LC_ALL) $old_lc_all
1485 } else {
1486 unset env(LC_ALL)
1488 set comp_output [prune_warnings $comp_output]
1490 if ![string match "" $comp_output] then {
1491 send_log "$comp_output\n"
1492 set failed 1
1493 break
1496 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1497 verbose "output is [file_contents "dump.out"]" 2
1498 set failed 1
1499 break
1504 if { $failed != 0 } {
1505 fail $testname
1506 } else { if { $is_unresolved == 0 } {
1507 pass $testname
1511 # Catch action errors.
1512 if { $is_unresolved != 0 } {
1513 unresolved $testname
1514 continue