2010-05-21 Daniel Jacobowitz <dan@codesourcery.com>
[binutils.git] / ld / testsuite / lib / ld-lib.exp
blob9e8b809f83359d03d48a047cd2895643b93b9186
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 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 { ![is_remote host] && [which $ld] == 0 } then {
28 perror "$ld does not exist"
29 exit 1
32 remote_exec host "$ld --version" "" "/dev/null" "ld.version"
33 remote_upload host "ld.version"
34 set tmp [prune_warnings [file_contents "ld.version"]]
35 remote_file build delete "ld.version"
36 remote_file host delete "ld.version"
38 regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number
39 if [info exists number] then {
40 clone_output "$ld $number\n"
44 proc run_host_cmd { prog command } {
45 global link_output
47 if { ![is_remote host] && [which "$prog"] == 0 } then {
48 perror "$prog does not exist"
49 return 0
52 verbose -log "$prog $command"
53 set status [remote_exec host [concat sh -c [list "$prog $command 2>&1"]] "" "/dev/null" "ld.tmp"]
54 remote_upload host "ld.tmp"
55 set link_output [file_contents "ld.tmp"]
56 regsub "\n$" $link_output "" link_output
57 if { [lindex $status 0] != 0 && [string match "" $link_output] } then {
58 append link_output "child process exited abnormally"
60 remote_file build delete ld.tmp
61 remote_file host delete ld.tmp
63 if [string match "" $link_output] then {
64 return ""
67 verbose -log "$link_output"
68 return "$link_output"
71 proc run_host_cmd_yesno { prog command } {
72 global exec_output
74 set exec_output [prune_warnings [run_host_cmd "$prog" "$command"]]
75 if [string match "" $exec_output] then {
76 return 1;
78 return 0;
81 # Link an object using relocation.
83 proc default_ld_relocate { ld target objects } {
84 global HOSTING_EMU
86 remote_file host delete $target
87 return [run_host_cmd_yesno "$ld" "$HOSTING_EMU -o $target -r $objects"]
90 # Check to see if ld is being invoked with a non-endian output format
92 proc is_endian_output_format { object_flags } {
94 if {[string match "*-oformat binary*" $object_flags] || \
95 [string match "*-oformat ieee*" $object_flags] || \
96 [string match "*-oformat ihex*" $object_flags] || \
97 [string match "*-oformat netbsd-core*" $object_flags] || \
98 [string match "*-oformat srec*" $object_flags] || \
99 [string match "*-oformat tekhex*" $object_flags] || \
100 [string match "*-oformat trad-core*" $object_flags] } then {
101 return 0
102 } else {
103 return 1
107 # Look for big-endian or little-endian switches in the multlib
108 # options and translate these into a -EB or -EL switch. Note
109 # we cannot rely upon proc process_multilib_options to do this
110 # for us because for some targets the compiler does not support
111 # -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
112 # the site.exp file will include the switch "-mbig-endian"
113 # (rather than "big-endian") which is not detected by proc
114 # process_multilib_options.
116 proc big_or_little_endian {} {
118 if [board_info [target_info name] exists multilib_flags] {
119 set tmp_flags " [board_info [target_info name] multilib_flags]"
121 foreach x $tmp_flags {
122 case $x in {
123 {*big*endian eb EB -eb -EB -mb -meb} {
124 set flags " -EB"
125 return $flags
127 {*little*endian el EL -el -EL -ml -mel} {
128 set flags " -EL"
129 return $flags
135 set flags ""
136 return $flags
139 # Link a program using ld.
141 proc default_ld_link { ld target objects } {
142 global HOSTING_EMU
143 global HOSTING_CRT0
144 global HOSTING_LIBS
145 global LIBS
146 global host_triplet
147 global link_output
148 global exec_output
150 set objs "$HOSTING_CRT0 $objects"
151 set libs "$LIBS $HOSTING_LIBS"
153 if [is_endian_output_format $objects] then {
154 set flags [big_or_little_endian]
155 } else {
156 set flags ""
159 remote_file host delete $target
161 return [run_host_cmd_yesno "$ld" "$HOSTING_EMU $flags -o $target $objs $libs"]
164 # Link a program using ld, without including any libraries.
166 proc default_ld_simple_link { ld target objects } {
167 global host_triplet
168 global gcc_ld_flag
169 global exec_output
171 if [is_endian_output_format $objects] then {
172 set flags [big_or_little_endian]
173 } else {
174 set flags ""
177 # If we are compiling with gcc, we want to add gcc_ld_flag to
178 # flags. Rather than determine this in some complex way, we guess
179 # based on the name of the compiler.
180 set ldexe $ld
181 set ldparm [string first " " $ld]
182 if { $ldparm > 0 } then {
183 set ldexe [string range $ld 0 $ldparm]
185 set ldexe [string replace $ldexe 0 [string last "/" $ldexe] ""]
186 if {[string match "*gcc*" $ldexe] || [string match "*++*" $ldexe]} then {
187 set flags "$gcc_ld_flag $flags"
190 remote_file host delete $target
192 set exec_output [run_host_cmd "$ld" "$flags -o $target $objects"]
193 set exec_output [prune_warnings $exec_output]
195 # We don't care if we get a warning about a non-existent start
196 # symbol, since the default linker script might use ENTRY.
197 regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
199 if [string match "" $exec_output] then {
200 return 1
201 } else {
202 return 0
206 # Compile an object using cc.
208 proc default_ld_compile { cc source object } {
209 global CFLAGS
210 global CXXFLAGS
211 global srcdir
212 global subdir
213 global host_triplet
214 global gcc_gas_flag
216 set cc_prog $cc
217 if {[llength $cc_prog] > 1} then {
218 set cc_prog [lindex $cc_prog 0]
220 if {![is_remote host] && [which $cc_prog] == 0} then {
221 perror "$cc_prog does not exist"
222 return 0
225 remote_file build delete "$object"
226 remote_file host delete "$object"
228 set flags "-I$srcdir/$subdir"
230 # If we are compiling with gcc, we want to add gcc_gas_flag to
231 # flags. Rather than determine this in some complex way, we guess
232 # based on the name of the compiler.
233 set ccexe $cc
234 set ccparm [string first " " $cc]
235 set ccflags ""
236 if { $ccparm > 0 } then {
237 set ccflags [string range $cc $ccparm end]
238 set ccexe [string range $cc 0 $ccparm]
239 set cc $ccexe
241 set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""]
242 if {[string match "*gcc*" $ccexe] || [string match "*++*" $ccexe]} then {
243 set flags "$gcc_gas_flag $flags"
246 if {[string match "*++*" $ccexe]} {
247 set flags "$flags $CXXFLAGS"
248 } else {
249 set flags "$flags $CFLAGS"
252 if [board_info [target_info name] exists multilib_flags] {
253 append flags " [board_info [target_info name] multilib_flags]"
256 verbose -log "$cc $flags $ccflags -c $source -o $object"
258 set status [remote_exec host [concat sh -c [list "$cc $flags $ccflags -c $source -o $object 2>&1"]] "" "/dev/null" "ld.tmp"]
259 remote_upload host "ld.tmp"
260 set exec_output [file_contents "ld.tmp"]
261 remote_file build delete "ld.tmp"
262 remote_file host delete "ld.tmp"
263 set exec_output [prune_warnings $exec_output]
264 if [string match "" $exec_output] then {
265 if {![file exists $object]} then {
266 regexp ".*/(\[^/\]*)$" $source all dobj
267 regsub "\\.c" $dobj ".o" realobj
268 verbose "looking for $realobj"
269 if {[remote_file host exists $realobj]} then {
270 verbose -log "mv $realobj $object"
271 remote_upload "$realobj" "$object"
272 } else {
273 perror "$object not found after compilation"
274 return 0
277 return 1
278 } else {
279 verbose -log "$exec_output"
280 perror "$source: compilation failed"
281 return 0
285 # Assemble a file.
287 proc default_ld_assemble { as source object } {
288 global ASFLAGS
289 global host_triplet
291 if ![info exists ASFLAGS] { set ASFLAGS "" }
293 set flags [big_or_little_endian]
294 set exec_output [run_host_cmd "$as" "$flags $ASFLAGS -o $object $source"]
295 set exec_output [prune_warnings $exec_output]
296 if [string match "" $exec_output] then {
297 return 1
298 } else {
299 perror "$source: assembly failed"
300 return 0
304 # Run nm on a file, putting the result in the array nm_output.
306 proc default_ld_nm { nm nmflags object } {
307 global NMFLAGS
308 global nm_output
309 global host_triplet
311 if {[info exists nm_output]} {
312 unset nm_output
315 if ![info exists NMFLAGS] { set NMFLAGS "" }
317 # Ensure consistent sorting of symbols
318 if {[info exists env(LC_ALL)]} {
319 set old_lc_all $env(LC_ALL)
321 set env(LC_ALL) "C"
323 verbose -log "$nm $NMFLAGS $nmflags $object >tmpdir/nm.out"
325 set status [remote_exec host [concat sh -c [list "$nm $NMFLAGS $nmflags $object 2>ld.stderr"]] "" "/dev/null" "tmpdir/nm.out"]
326 if {[info exists old_lc_all]} {
327 set env(LC_ALL) $old_lc_all
328 } else {
329 unset env(LC_ALL)
331 remote_upload host "ld.stderr"
332 remote_upload host "tmpdir/nm.out" "tmpdir/nm.out"
333 set exec_output [prune_warnings [file_contents "ld.stderr"]]
334 remote_file host delete "ld.stderr"
335 remote_file build delete "ld.stderr"
336 if [string match "" $exec_output] then {
337 set file [open tmpdir/nm.out r]
338 while { [gets $file line] != -1 } {
339 verbose "$line" 2
340 if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] \\.*(.+)$" $line whole value name] {
341 set name [string trimleft $name "_"]
342 verbose "Setting nm_output($name) to 0x$value" 2
343 set nm_output($name) 0x$value
346 close $file
347 return 1
348 } else {
349 verbose -log "$exec_output"
350 perror "$object: nm failed"
351 return 0
355 # Define various symbols needed when not linking against all
356 # target libs.
357 proc ld_simple_link_defsyms {} {
359 set flags "--defsym __stack_chk_fail=0"
361 # ARM targets call __gccmain
362 if {[istarget arm*-*-*] || \
363 [istarget strongarm*-*-*] || \
364 [istarget xscale*-*-*] || \
365 [istarget thumb-*-*] } {
366 append flags " --defsym __gccmain=0"
369 # PowerPC EABI code calls __eabi.
370 if {[istarget powerpc*-*-eabi*] || [istarget powerpc*-*-rtems*]} {
371 append flags " --defsym __eabi=0"
374 # mn10200 code calls __truncsipsi2_d0_d2.
375 if {[istarget mn10200*-*-*]} then {
376 append flags " --defsym __truncsipsi2_d0_d2=0"
379 # m6811/m6812 code has references to soft registers.
380 if {[istarget m6811-*-*] || [istarget m6812-*-*]} {
381 append flags " --defsym _.frame=0 --defsym _.d1=0 --defsym _.d2=0"
382 append flags " --defsym _.d3=0 --defsym _.d4=0"
383 append flags " --defsym _.tmp=0 --defsym _.xy=0 --defsym _.z=0"
386 # Some OpenBSD targets have ProPolice and reference __guard and
387 # __stack_smash_handler.
388 if [istarget *-*-openbsd*] {
389 append flags " --defsym __guard=0"
390 append flags " --defsym __stack_smash_handler=0"
393 return $flags
396 # True if the object format is known to be ELF.
398 proc is_elf_format {} {
399 if { ![istarget *-*-sysv4*] \
400 && ![istarget *-*-unixware*] \
401 && ![istarget *-*-elf*] \
402 && ![istarget *-*-eabi*] \
403 && ![istarget hppa*64*-*-hpux*] \
404 && ![istarget *-*-linux*] \
405 && ![istarget frv-*-uclinux*] \
406 && ![istarget bfin-*-uclinux] \
407 && ![istarget sh*-*-uclinux*] \
408 && ![istarget *-*-irix5*] \
409 && ![istarget *-*-irix6*] \
410 && ![istarget *-*-netbsd*] \
411 && ![istarget *-*-solaris2*] } {
412 return 0
415 if { [istarget *-*-linux*aout*] \
416 || [istarget *-*-linux*oldld*] } {
417 return 0
420 if { ![istarget *-*-netbsdelf*] \
421 && ([istarget *-*-netbsd*aout*] \
422 || [istarget *-*-netbsdpe*] \
423 || [istarget arm*-*-netbsd*] \
424 || [istarget sparc-*-netbsd*] \
425 || [istarget i*86-*-netbsd*] \
426 || [istarget m68*-*-netbsd*] \
427 || [istarget vax-*-netbsd*] \
428 || [istarget ns32k-*-netbsd*]) } {
429 return 0
431 return 1
434 # True if the object format is known to be 64-bit ELF.
436 proc is_elf64 { binary_file } {
437 global READELF
438 global READELFFLAGS
440 set readelf_size ""
441 catch "exec $READELF $READELFFLAGS -h $binary_file > readelf.out" got
443 if ![string match "" $got] then {
444 return 0
447 if { ![regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \
448 [file_contents readelf.out] nil readelf_size] } {
449 return 0
452 if { $readelf_size == "64" } {
453 return 1
456 return 0
459 # True if the object format is known to be a.out.
461 proc is_aout_format {} {
462 if { [istarget *-*-*\[ab\]out*] \
463 || [istarget *-*-linux*oldld*] \
464 || [istarget *-*-msdos*] \
465 || [istarget arm-*-netbsd] \
466 || [istarget i?86-*-netbsd] \
467 || [istarget i?86-*-mach*] \
468 || [istarget i?86-*-vsta] \
469 || [istarget pdp11-*-*] \
470 || [istarget m68*-ericsson-ose] \
471 || [istarget m68k-hp-bsd*] \
472 || [istarget m68*-*-hpux*] \
473 || [istarget m68*-*-netbsd] \
474 || [istarget m68*-*-netbsd*4k*] \
475 || [istarget m68k-sony-*] \
476 || [istarget m68*-sun-sunos\[34\]*] \
477 || [istarget m68*-wrs-vxworks*] \
478 || [istarget ns32k-*-*] \
479 || [istarget sparc*-*-netbsd] \
480 || [istarget sparc-sun-sunos4*] \
481 || [istarget vax-dec-ultrix*] \
482 || [istarget vax-*-netbsd] } {
483 return 1
485 return 0
488 # True if the object format is known to be PE COFF.
490 proc is_pecoff_format {} {
491 if { ![istarget *-*-mingw*] \
492 && ![istarget *-*-cygwin*] \
493 && ![istarget *-*-cegcc*] \
494 && ![istarget *-*-pe*] } {
495 return 0
498 return 1
501 # Compares two files line-by-line.
502 # Returns differences if exist.
503 # Returns null if file(s) cannot be opened.
505 proc simple_diff { file_1 file_2 } {
506 global target
508 set eof -1
509 set differences 0
511 if [file exists $file_1] then {
512 set file_a [open $file_1 r]
513 } else {
514 warning "$file_1 doesn't exist"
515 return
518 if [file exists $file_2] then {
519 set file_b [open $file_2 r]
520 } else {
521 fail "$file_2 doesn't exist"
522 return
525 verbose "# Diff'ing: $file_1 $file_2\n" 2
527 while { [gets $file_a line] != $eof } {
528 if [regexp "^#.*$" $line] then {
529 continue
530 } else {
531 lappend list_a $line
534 close $file_a
536 while { [gets $file_b line] != $eof } {
537 if [regexp "^#.*$" $line] then {
538 continue
539 } else {
540 lappend list_b $line
543 close $file_b
545 for { set i 0 } { $i < [llength $list_a] } { incr i } {
546 set line_a [lindex $list_a $i]
547 set line_b [lindex $list_b $i]
549 verbose "\t$file_1: $i: $line_a\n" 3
550 verbose "\t$file_2: $i: $line_b\n" 3
551 if [string compare $line_a $line_b] then {
552 verbose -log "\t$file_1: $i: $line_a\n"
553 verbose -log "\t$file_2: $i: $line_b\n"
555 fail "Test: $target"
556 return
560 if { [llength $list_a] != [llength $list_b] } {
561 fail "Test: $target"
562 return
565 if $differences<1 then {
566 pass "Test: $target"
570 # run_dump_test FILE
571 # Copied from gas testsuite, tweaked and further extended.
573 # Assemble a .s file, then run some utility on it and check the output.
575 # There should be an assembly language file named FILE.s in the test
576 # suite directory, and a pattern file called FILE.d. `run_dump_test'
577 # will assemble FILE.s, run some tool like `objdump', `objcopy', or
578 # `nm' on the .o file to produce textual output, and then analyze that
579 # with regexps. The FILE.d file specifies what program to run, and
580 # what to expect in its output.
582 # The FILE.d file begins with zero or more option lines, which specify
583 # flags to pass to the assembler, the program to run to dump the
584 # assembler's output, and the options it wants. The option lines have
585 # the syntax:
587 # # OPTION: VALUE
589 # OPTION is the name of some option, like "name" or "objdump", and
590 # VALUE is OPTION's value. The valid options are described below.
591 # Whitespace is ignored everywhere, except within VALUE. The option
592 # list ends with the first line that doesn't match the above syntax
593 # (hmm, not great for error detection).
595 # The interesting options are:
597 # name: TEST-NAME
598 # The name of this test, passed to DejaGNU's `pass' and `fail'
599 # commands. If omitted, this defaults to FILE, the root of the
600 # .s and .d files' names.
602 # as: FLAGS
603 # When assembling, pass FLAGS to the assembler.
604 # If assembling several files, you can pass different assembler
605 # options in the "source" directives. See below.
607 # ld: FLAGS
608 # Link assembled files using FLAGS, in the order of the "source"
609 # directives, when using multiple files.
611 # ld_after_inputfiles: FLAGS
612 # Similar to "ld", but put after all input files.
614 # objcopy_linked_file: FLAGS
615 # Run objcopy on the linked file with the specified flags.
616 # This lets you transform the linked file using objcopy, before the
617 # result is analyzed by an analyzer program specified below (which
618 # may in turn *also* be objcopy).
620 # PROG: PROGRAM-NAME
621 # The name of the program to run to analyze the .o file produced
622 # by the assembler or the linker output. This can be omitted;
623 # run_dump_test will guess which program to run by seeing which of
624 # the flags options below is present.
626 # objdump: FLAGS
627 # nm: FLAGS
628 # objcopy: FLAGS
629 # Use the specified program to analyze the assembler or linker
630 # output file, and pass it FLAGS, in addition to the output name.
631 # Note that they are run with LC_ALL=C in the environment to give
632 # consistent sorting of symbols.
634 # source: SOURCE [FLAGS]
635 # Assemble the file SOURCE.s using the flags in the "as" directive
636 # and the (optional) FLAGS. If omitted, the source defaults to
637 # FILE.s.
638 # This is useful if several .d files want to share a .s file.
639 # More than one "source" directive can be given, which is useful
640 # when testing linking.
642 # xfail: TARGET
643 # The test is expected to fail on TARGET. This may occur more than
644 # once.
646 # target: TARGET
647 # Only run the test for TARGET. This may occur more than once; the
648 # target being tested must match at least one. You may provide target
649 # name "cfi" for any target supporting the CFI statements.
651 # notarget: TARGET
652 # Do not run the test for TARGET. This may occur more than once;
653 # the target being tested must not match any of them.
655 # error: REGEX
656 # An error with message matching REGEX must be emitted for the test
657 # to pass. The PROG, objdump, nm and objcopy options have no
658 # meaning and need not supplied if this is present. Multiple "error"
659 # directives append to the expected linker error message.
661 # warning: REGEX
662 # Expect a linker warning matching REGEX. It is an error to issue
663 # both "error" and "warning". Multiple "warning" directives
664 # append to the expected linker warning message.
666 # Each option may occur at most once unless otherwise mentioned.
668 # After the option lines come regexp lines. `run_dump_test' calls
669 # `regexp_diff' to compare the output of the dumping tool against the
670 # regexps in FILE.d. `regexp_diff' is defined later in this file; see
671 # further comments there.
673 proc run_dump_test { name } {
674 global subdir srcdir
675 global OBJDUMP NM AS OBJCOPY READELF LD
676 global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
677 global host_triplet runtests
678 global env verbose
680 if [string match "*/*" $name] {
681 set file $name
682 set name [file tail $name]
683 } else {
684 set file "$srcdir/$subdir/$name"
687 if ![runtest_file_p $runtests $name] then {
688 return
691 set opt_array [slurp_options "${file}.d"]
692 if { $opt_array == -1 } {
693 perror "error reading options from $file.d"
694 unresolved $subdir/$name
695 return
697 set dumpfile tmpdir/dump.out
698 set run_ld 0
699 set run_objcopy 0
700 set opts(as) {}
701 set opts(ld) {}
702 set opts(ld_after_inputfiles) {}
703 set opts(xfail) {}
704 set opts(target) {}
705 set opts(notarget) {}
706 set opts(objdump) {}
707 set opts(nm) {}
708 set opts(objcopy) {}
709 set opts(readelf) {}
710 set opts(name) {}
711 set opts(PROG) {}
712 set opts(source) {}
713 set opts(error) {}
714 set opts(warning) {}
715 set opts(objcopy_linked_file) {}
716 set asflags(${file}.s) {}
718 foreach i $opt_array {
719 set opt_name [lindex $i 0]
720 set opt_val [lindex $i 1]
721 if ![info exists opts($opt_name)] {
722 perror "unknown option $opt_name in file $file.d"
723 unresolved $subdir/$name
724 return
727 switch -- $opt_name {
728 xfail {}
729 target {}
730 notarget {}
731 warning {}
732 error {}
733 source {
734 # Move any source-specific as-flags to a separate array to
735 # simplify processing.
736 if { [llength $opt_val] > 1 } {
737 set asflags([lindex $opt_val 0]) [lrange $opt_val 1 end]
738 set opt_val [lindex $opt_val 0]
739 } else {
740 set asflags($opt_val) {}
743 default {
744 if [string length $opts($opt_name)] {
745 perror "option $opt_name multiply set in $file.d"
746 unresolved $subdir/$name
747 return
750 # A single "# ld:" with no options should do the right thing.
751 if { $opt_name == "ld" } {
752 set run_ld 1
754 # Likewise objcopy_linked_file.
755 if { $opt_name == "objcopy_linked_file" } {
756 set run_objcopy 1
760 if { $opt_name == "as" || $opt_name == "ld" } {
761 set opt_val [subst $opt_val]
763 set opts($opt_name) [concat $opts($opt_name) $opt_val]
765 foreach opt { as ld } {
766 regsub {\[big_or_little_endian\]} $opts($opt) \
767 [big_or_little_endian] opts($opt)
770 # Decide early whether we should run the test for this target.
771 if { [llength $opts(target)] > 0 } {
772 set targmatch 0
773 foreach targ $opts(target) {
774 if [istarget $targ] {
775 set targmatch 1
776 break
779 if { $targmatch == 0 } {
780 return
783 foreach targ $opts(notarget) {
784 if [istarget $targ] {
785 return
789 set program ""
790 # It's meaningless to require an output-testing method when we
791 # expect an error.
792 if { $opts(error) == "" } {
793 if {$opts(PROG) != ""} {
794 switch -- $opts(PROG) {
795 objdump { set program objdump }
796 nm { set program nm }
797 objcopy { set program objcopy }
798 readelf { set program readelf }
799 default
800 { perror "unrecognized program option $opts(PROG) in $file.d"
801 unresolved $subdir/$name
802 return }
804 } else {
805 # Guess which program to run, by seeing which option was specified.
806 foreach p {objdump objcopy nm readelf} {
807 if {$opts($p) != ""} {
808 if {$program != ""} {
809 perror "ambiguous dump program in $file.d"
810 unresolved $subdir/$name
811 return
812 } else {
813 set program $p
818 if { $program == "" && $opts(warning) == "" } {
819 perror "dump program unspecified in $file.d"
820 unresolved $subdir/$name
821 return
825 if { $opts(name) == "" } {
826 set testname "$subdir/$name"
827 } else {
828 set testname $opts(name)
831 if { $opts(source) == "" } {
832 set sourcefiles [list ${file}.s]
833 } else {
834 set sourcefiles {}
835 foreach sf $opts(source) {
836 if { [string match "/*" $sf] } {
837 lappend sourcefiles "$sf"
838 } else {
839 lappend sourcefiles "$srcdir/$subdir/$sf"
841 # Must have asflags indexed on source name.
842 set asflags($srcdir/$subdir/$sf) $asflags($sf)
846 # Time to setup xfailures.
847 foreach targ $opts(xfail) {
848 setup_xfail $targ
851 # Assemble each file.
852 set objfiles {}
853 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
854 set sourcefile [lindex $sourcefiles $i]
856 set objfile "tmpdir/dump$i.o"
857 catch "exec rm -f $objfile" exec_output
858 lappend objfiles $objfile
859 set cmd "$AS $ASFLAGS $opts(as) $asflags($sourcefile) -o $objfile $sourcefile"
861 send_log "$cmd\n"
862 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
863 remote_upload host "ld.tmp"
864 set comp_output [prune_warnings [file_contents "ld.tmp"]]
865 remote_file host delete "ld.tmp"
866 remote_file build delete "ld.tmp"
868 if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
869 send_log "$comp_output\n"
870 verbose "$comp_output" 3
872 set exitstat "succeeded"
873 if { $cmdret != 0 } { set exitstat "failed" }
874 verbose -log "$exitstat with: <$comp_output>"
875 fail $testname
876 return
880 set expmsg $opts(error)
881 if { $opts(warning) != "" } {
882 if { $expmsg != "" } {
883 perror "$testname: mixing error and warning test-directives"
884 return
886 set expmsg $opts(warning)
889 # Perhaps link the file(s).
890 if { $run_ld } {
891 set objfile "tmpdir/dump"
892 catch "exec rm -f $objfile" exec_output
894 # Add -L$srcdir/$subdir so that the linker command can use
895 # linker scripts in the source directory.
896 set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
897 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
899 send_log "$cmd\n"
900 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
901 remote_upload host "ld.tmp"
902 set comp_output [file_contents "ld.tmp"]
903 remote_file host delete "ld.tmp"
904 remote_file build delete "ld.tmp"
905 set cmdret [lindex $cmdret 0]
907 if { $cmdret == 0 && $run_objcopy } {
908 set infile $objfile
909 set objfile "tmpdir/dump1"
910 remote_file host delete $objfile
912 # Note that we don't use OBJCOPYFLAGS here; any flags must be
913 # explicitly specified.
914 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
916 send_log "$cmd\n"
917 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
918 remote_upload host "ld.tmp"
919 append comp_output [file_contents "ld.tmp"]
920 remote_file host delete "ld.tmp"
921 remote_file build delete "ld.tmp"
922 set cmdret [lindex $cmdret 0]
925 regsub "\n$" $comp_output "" comp_output
926 if { $cmdret != 0 || $comp_output != "" || $expmsg != "" } then {
927 set exitstat "succeeded"
928 if { $cmdret != 0 } { set exitstat "failed" }
929 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
930 send_log "$comp_output\n"
931 verbose "$comp_output" 3
933 if { ($expmsg == "") == ($comp_output == "") \
934 && [regexp $expmsg $comp_output] \
935 && (($cmdret == 0) == ($opts(error) == "")) } {
936 # We have the expected output from ld.
937 if { $opts(error) != "" || $program == "" } {
938 pass $testname
939 return
941 } else {
942 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
943 fail $testname
944 return
947 } else {
948 set objfile "tmpdir/dump0.o"
951 # We must not have expected failure if we get here.
952 if { $opts(error) != "" } {
953 fail $testname
954 return
957 set progopts1 $opts($program)
958 eval set progopts \$[string toupper $program]FLAGS
959 eval set binary \$[string toupper $program]
961 if { ![is_remote host] && [which $binary] == 0 } {
962 untested $testname
963 return
966 if { $progopts1 == "" } { set $progopts1 "-r" }
967 verbose "running $binary $progopts $progopts1" 3
969 # Objcopy, unlike the other two, won't send its output to stdout,
970 # so we have to run it specially.
971 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
972 if { $program == "objcopy" } {
973 set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
976 # Ensure consistent sorting of symbols
977 if {[info exists env(LC_ALL)]} {
978 set old_lc_all $env(LC_ALL)
980 set env(LC_ALL) "C"
981 send_log "$cmd\n"
982 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
983 set cmdret [lindex $cmdret 0]
984 remote_upload host "ld.tmp"
985 set comp_output [prune_warnings [file_contents "ld.tmp"]]
986 remote_file host delete "ld.tmp"
987 remote_file build delete "ld.tmp"
988 if {[info exists old_lc_all]} {
989 set env(LC_ALL) $old_lc_all
990 } else {
991 unset env(LC_ALL)
993 if { $cmdret != 0 || $comp_output != "" } {
994 send_log "exited abnormally with $cmdret, output:$comp_output\n"
995 fail $testname
996 return
999 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
1000 if { [regexp_diff $dumpfile "${file}.d"] } then {
1001 fail $testname
1002 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
1003 return
1006 pass $testname
1009 proc slurp_options { file } {
1010 if [catch { set f [open $file r] } x] {
1011 #perror "couldn't open `$file': $x"
1012 perror "$x"
1013 return -1
1015 set opt_array {}
1016 # whitespace expression
1017 set ws {[ ]*}
1018 set nws {[^ ]*}
1019 # whitespace is ignored anywhere except within the options list;
1020 # option names are alphabetic plus underscore only.
1021 set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
1022 while { [gets $f line] != -1 } {
1023 set line [string trim $line]
1024 # Whitespace here is space-tab.
1025 if [regexp $pat $line xxx opt_name opt_val] {
1026 # match!
1027 lappend opt_array [list $opt_name $opt_val]
1028 } else {
1029 break
1032 close $f
1033 return $opt_array
1036 # regexp_diff, copied from gas, based on simple_diff above.
1037 # compares two files line-by-line
1038 # file1 contains strings, file2 contains regexps and #-comments
1039 # blank lines are ignored in either file
1040 # returns non-zero if differences exist
1042 proc regexp_diff { file_1 file_2 } {
1044 set eof -1
1045 set end_1 0
1046 set end_2 0
1047 set differences 0
1048 set diff_pass 0
1049 set fail_if_match 0
1051 if [file exists $file_1] then {
1052 set file_a [open $file_1 r]
1053 } else {
1054 warning "$file_1 doesn't exist"
1055 return 1
1058 if [file exists $file_2] then {
1059 set file_b [open $file_2 r]
1060 } else {
1061 fail "$file_2 doesn't exist"
1062 close $file_a
1063 return 1
1066 verbose " Regexp-diff'ing: $file_1 $file_2" 2
1068 while { 1 } {
1069 set line_a ""
1070 set line_b ""
1071 while { [string length $line_a] == 0 } {
1072 if { [gets $file_a line_a] == $eof } {
1073 set end_1 1
1074 break
1077 while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
1078 if [ string match "#pass" $line_b ] {
1079 set end_2 1
1080 set diff_pass 1
1081 break
1082 } elseif [ string match "#failif" $line_b ] {
1083 send_log "fail if no difference\n"
1084 verbose "fail if no difference" 3
1085 set fail_if_match 1
1086 } elseif [ string match "#..." $line_b ] {
1087 if { [gets $file_b line_b] == $eof } {
1088 set end_2 1
1089 set diff_pass 1
1090 break
1092 verbose "looking for \"^$line_b$\"" 3
1093 while { ![regexp "^$line_b$" "$line_a"] } {
1094 verbose "skipping \"$line_a\"" 3
1095 if { [gets $file_a line_a] == $eof } {
1096 set end_1 1
1097 break
1100 break
1102 if { [gets $file_b line_b] == $eof } {
1103 set end_2 1
1104 break
1108 if { $diff_pass } {
1109 break
1110 } elseif { $end_1 && $end_2 } {
1111 break
1112 } elseif { $end_1 } {
1113 send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
1114 verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
1115 set differences 1
1116 break
1117 } elseif { $end_2 } {
1118 send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
1119 verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
1120 set differences 1
1121 break
1122 } else {
1123 verbose "regexp \"^$line_b$\"\nline \"$line_a\"" 3
1124 if ![regexp "^$line_b$" "$line_a"] {
1125 send_log "regexp_diff match failure\n"
1126 send_log "regexp \"^$line_b$\"\nline \"$line_a\"\n"
1127 set differences 1
1132 if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
1133 send_log "$file_1 and $file_2 are different lengths\n"
1134 verbose "$file_1 and $file_2 are different lengths" 3
1135 set differences 1
1138 if { $fail_if_match } {
1139 if { $differences == 0 } {
1140 set differences 1
1141 } else {
1142 set differences 0
1146 close $file_a
1147 close $file_b
1149 return $differences
1152 proc file_contents { filename } {
1153 set file [open $filename r]
1154 set contents [read $file]
1155 close $file
1156 return $contents
1159 # Create an archive using ar
1161 proc ar_simple_create { ar aropts target objects } {
1162 remote_file host delete $target
1164 set exec_output [run_host_cmd "$ar" "$aropts rc $target $objects"]
1165 set exec_output [prune_warnings $exec_output]
1167 if [string match "" $exec_output] then {
1168 send_log "$exec_output\n"
1169 return 1
1170 } else {
1171 return 0
1175 # List contains test-items with 3 items followed by 2 lists, one item and
1176 # one optional item:
1177 # 0:name 1:ld/ar options 2:assembler options
1178 # 3:filenames of assembler files 4: action and options. 5: name of output file
1179 # 6:compiler flags (optional)
1181 # Actions:
1182 # objdump: Apply objdump options on result. Compare with regex (last arg).
1183 # nm: Apply nm options on result. Compare with regex (last arg).
1184 # readelf: Apply readelf options on result. Compare with regex (last arg).
1186 proc run_ld_link_tests { ldtests } {
1187 global ld
1188 global as
1189 global nm
1190 global ar
1191 global objdump
1192 global READELF
1193 global srcdir
1194 global subdir
1195 global env
1196 global CC
1197 global CFLAGS
1198 global runtests
1200 foreach testitem $ldtests {
1201 set testname [lindex $testitem 0]
1203 if ![runtest_file_p $runtests $testname] then {
1204 continue
1207 set ld_options [lindex $testitem 1]
1208 set as_options [lindex $testitem 2]
1209 set src_files [lindex $testitem 3]
1210 set actions [lindex $testitem 4]
1211 set binfile tmpdir/[lindex $testitem 5]
1212 set cflags [lindex $testitem 6]
1213 set objfiles {}
1214 set is_unresolved 0
1215 set failed 0
1217 # verbose -log "Testname is $testname"
1218 # verbose -log "ld_options is $ld_options"
1219 # verbose -log "as_options is $as_options"
1220 # verbose -log "src_files is $src_files"
1221 # verbose -log "actions is $actions"
1222 # verbose -log "binfile is $binfile"
1224 # Assemble each file in the test.
1225 foreach src_file $src_files {
1226 set objfile "tmpdir/[file rootname $src_file].o"
1227 lappend objfiles $objfile
1229 if { [file extension $src_file] == ".c" } {
1230 set as_file "tmpdir/[file rootname $src_file].s"
1231 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1232 set is_unresolved 1
1233 break
1235 } else {
1236 set as_file "$srcdir/$subdir/$src_file"
1238 if ![ld_assemble $as "$as_options $as_file" $objfile] {
1239 set is_unresolved 1
1240 break
1244 # Catch assembler errors.
1245 if { $is_unresolved != 0 } {
1246 unresolved $testname
1247 continue
1250 if { [regexp ".*\\.a$" $binfile] } {
1251 if { ![ar_simple_create $ar $ld_options $binfile "$objfiles"] } {
1252 fail $testname
1253 set failed 1
1254 } else {
1255 set failed 0
1257 } elseif { ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] } {
1258 fail $testname
1259 set failed 1
1260 } else {
1261 set failed 0
1264 if { $failed == 0 } {
1265 foreach actionlist $actions {
1266 set action [lindex $actionlist 0]
1267 set progopts [lindex $actionlist 1]
1269 # There are actions where we run regexp_diff on the
1270 # output, and there are other actions (presumably).
1271 # Handling of the former look the same.
1272 set dump_prog ""
1273 switch -- $action {
1274 objdump
1275 { set dump_prog $objdump }
1277 { set dump_prog $nm }
1278 readelf
1279 { set dump_prog $READELF }
1280 default
1282 perror "Unrecognized action $action"
1283 set is_unresolved 1
1284 break
1288 if { $dump_prog != "" } {
1289 set dumpfile [lindex $actionlist 2]
1290 set binary $dump_prog
1292 # Ensure consistent sorting of symbols
1293 if {[info exists env(LC_ALL)]} {
1294 set old_lc_all $env(LC_ALL)
1296 set env(LC_ALL) "C"
1297 set cmd "$binary $progopts $binfile"
1298 set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
1299 send_log "$cmd\n"
1300 remote_upload host "ld.stderr"
1301 set comp_output [prune_warnings [file_contents "ld.stderr"]]
1302 remote_file host delete "ld.stderr"
1303 remote_file build delete "ld.stderr"
1305 if {[info exists old_lc_all]} {
1306 set env(LC_ALL) $old_lc_all
1307 } else {
1308 unset env(LC_ALL)
1311 if ![string match "" $comp_output] then {
1312 send_log "$comp_output\n"
1313 set failed 1
1314 break
1317 remote_upload host "dump.out"
1319 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1320 verbose "output is [file_contents "dump.out"]" 2
1321 set failed 1
1322 remote_file build delete "dump.out"
1323 remote_file host delete "dump.out"
1324 break
1326 remote_file build delete "dump.out"
1327 remote_file host delete "dump.out"
1331 if { $failed != 0 } {
1332 fail $testname
1333 } else { if { $is_unresolved == 0 } {
1334 pass $testname
1338 # Catch action errors.
1339 if { $is_unresolved != 0 } {
1340 unresolved $testname
1341 continue
1346 # This definition is taken from an unreleased version of DejaGnu. Once
1347 # that version gets released, and has been out in the world for a few
1348 # months at least, it may be safe to delete this copy.
1349 if ![string length [info proc prune_warnings]] {
1351 # prune_warnings -- delete various system verbosities from TEXT
1353 # An example is:
1354 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1356 # Sites with particular verbose os's may wish to override this in site.exp.
1358 proc prune_warnings { text } {
1359 # This is from sun4's. Do it for all machines for now.
1360 # The "\\1" is to try to preserve a "\n" but only if necessary.
1361 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1363 # It might be tempting to get carried away and delete blank lines, etc.
1364 # Just delete *exactly* what we're ask to, and that's it.
1365 return $text
1369 # targets_to_xfail is a list of target triplets to be xfailed.
1370 # ldtests contains test-items with 3 items followed by 1 lists, 2 items
1371 # and 3 optional items:
1372 # 0:name
1373 # 1:ld options
1374 # 2:assembler options
1375 # 3:filenames of source files
1376 # 4:name of output file
1377 # 5:expected output
1378 # 6:compiler flags (optional)
1379 # 7:language (optional)
1380 # 8:linker warning (optional)
1382 proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
1383 global ld
1384 global as
1385 global srcdir
1386 global subdir
1387 global env
1388 global CC
1389 global CXX
1390 global CFLAGS
1391 global CXXFLAGS
1392 global errcnt
1393 global exec_output
1395 foreach testitem $ldtests {
1396 foreach target $targets_to_xfail {
1397 setup_xfail $target
1399 set testname [lindex $testitem 0]
1400 set ld_options [lindex $testitem 1]
1401 set as_options [lindex $testitem 2]
1402 set src_files [lindex $testitem 3]
1403 set binfile tmpdir/[lindex $testitem 4]
1404 set expfile [lindex $testitem 5]
1405 set cflags [lindex $testitem 6]
1406 set lang [lindex $testitem 7]
1407 set warning [lindex $testitem 8]
1408 set objfiles {}
1409 set failed 0
1411 # verbose -log "Testname is $testname"
1412 # verbose -log "ld_options is $ld_options"
1413 # verbose -log "as_options is $as_options"
1414 # verbose -log "src_files is $src_files"
1415 # verbose -log "actions is $actions"
1416 # verbose -log "binfile is $binfile"
1418 # Assemble each file in the test.
1419 foreach src_file $src_files {
1420 set objfile "tmpdir/[file rootname $src_file].o"
1421 lappend objfiles $objfile
1423 # We ignore warnings since some compilers may generate
1424 # incorrect section attributes and the assembler will warn
1425 # them.
1426 if { [ string match "c++" $lang ] } {
1427 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1428 } else {
1429 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1432 # We have to use $CC to build PIE and shared library.
1433 if { [ string match "c" $lang ] } {
1434 set link_proc ld_simple_link
1435 set link_cmd $CC
1436 } elseif { [ string match "c++" $lang ] } {
1437 set link_proc ld_simple_link
1438 set link_cmd $CXX
1439 } elseif { [ string match "-shared" $ld_options ] \
1440 || [ string match "-pie" $ld_options ] } {
1441 set link_proc ld_simple_link
1442 set link_cmd $CC
1443 } else {
1444 set link_proc ld_link
1445 set link_cmd $ld
1448 if ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1449 set failed 1
1450 } else {
1451 set failed 0
1454 # Check if exec_output is expected.
1455 if { $warning != "" } then {
1456 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1457 if { [regexp $warning $exec_output] } then {
1458 set failed 0
1459 } else {
1460 set failed 1
1464 if { $failed == 0 } {
1465 send_log "Running: $binfile > $binfile.out\n"
1466 verbose "Running: $binfile > $binfile.out"
1467 catch "exec $binfile > $binfile.out" exec_output
1469 if ![string match "" $exec_output] then {
1470 send_log "$exec_output\n"
1471 verbose "$exec_output" 1
1472 set failed 1
1473 } else {
1474 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1475 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1476 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1477 set exec_output [prune_warnings $exec_output]
1479 if ![string match "" $exec_output] then {
1480 send_log "$exec_output\n"
1481 verbose "$exec_output" 1
1482 set failed 1
1487 if { $failed != 0 } {
1488 fail $testname
1489 } else {
1490 set errcnt 0
1491 pass $testname
1497 # List contains test-items with 3 items followed by 2 lists, one item and
1498 # one optional item:
1499 # 0:name
1500 # 1:ld or ar options
1501 # 2:compile options
1502 # 3:filenames of source files
1503 # 4:action and options.
1504 # 5:name of output file
1505 # 6:language (optional)
1507 # Actions:
1508 # objdump: Apply objdump options on result. Compare with regex (last arg).
1509 # nm: Apply nm options on result. Compare with regex (last arg).
1510 # readelf: Apply readelf options on result. Compare with regex (last arg).
1512 proc run_cc_link_tests { ldtests } {
1513 global nm
1514 global objdump
1515 global READELF
1516 global srcdir
1517 global subdir
1518 global env
1519 global CC
1520 global CXX
1521 global CFLAGS
1522 global CXXFLAGS
1523 global ar
1525 foreach testitem $ldtests {
1526 set testname [lindex $testitem 0]
1527 set ldflags [lindex $testitem 1]
1528 set cflags [lindex $testitem 2]
1529 set src_files [lindex $testitem 3]
1530 set actions [lindex $testitem 4]
1531 set binfile tmpdir/[lindex $testitem 5]
1532 set lang [lindex $testitem 6]
1533 set objfiles {}
1534 set is_unresolved 0
1535 set failed 0
1537 # Compile each file in the test.
1538 foreach src_file $src_files {
1539 set objfile "tmpdir/[file rootname $src_file].o"
1540 lappend objfiles $objfile
1542 # We ignore warnings since some compilers may generate
1543 # incorrect section attributes and the assembler will warn
1544 # them.
1545 if { [ string match "c++" $lang ] } {
1546 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1547 } else {
1548 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1552 # Clear error and warning counts.
1553 reset_vars
1555 if { [ string match "c++" $lang ] } {
1556 set cc_cmd $CXX
1557 } else {
1558 set cc_cmd $CC
1561 if { [regexp ".*\\.a$" $binfile] } {
1562 if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
1563 fail $testname
1564 set failed 1
1565 } else {
1566 set failed 0
1568 } elseif { ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] } {
1569 fail $testname
1570 set failed 1
1571 } else {
1572 set failed 0
1575 if { $failed == 0 } {
1576 foreach actionlist $actions {
1577 set action [lindex $actionlist 0]
1578 set progopts [lindex $actionlist 1]
1580 # There are actions where we run regexp_diff on the
1581 # output, and there are other actions (presumably).
1582 # Handling of the former look the same.
1583 set dump_prog ""
1584 switch -- $action {
1585 objdump
1586 { set dump_prog $objdump }
1588 { set dump_prog $nm }
1589 readelf
1590 { set dump_prog $READELF }
1591 default
1593 perror "Unrecognized action $action"
1594 set is_unresolved 1
1595 break
1599 if { $dump_prog != "" } {
1600 set dumpfile [lindex $actionlist 2]
1601 set binary $dump_prog
1603 # Ensure consistent sorting of symbols
1604 if {[info exists env(LC_ALL)]} {
1605 set old_lc_all $env(LC_ALL)
1607 set env(LC_ALL) "C"
1608 set cmd "$binary $progopts $binfile > dump.out"
1609 send_log "$cmd\n"
1610 catch "exec $cmd" comp_output
1611 if {[info exists old_lc_all]} {
1612 set env(LC_ALL) $old_lc_all
1613 } else {
1614 unset env(LC_ALL)
1616 set comp_output [prune_warnings $comp_output]
1618 if ![string match "" $comp_output] then {
1619 send_log "$comp_output\n"
1620 set failed 1
1621 break
1624 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1625 verbose "output is [file_contents "dump.out"]" 2
1626 set failed 1
1627 break
1632 if { $failed != 0 } {
1633 fail $testname
1634 } else { if { $is_unresolved == 0 } {
1635 pass $testname
1639 # Catch action errors.
1640 if { $is_unresolved != 0 } {
1641 unresolved $testname
1642 continue
1647 # Returns true if --gc-sections is supported on the target.
1649 proc check_gc_sections_available { } {
1650 global gc_sections_available_saved
1651 global ld
1653 if {![info exists gc_sections_available_saved]} {
1654 # Some targets don't support gc-sections despite whatever's
1655 # advertised by ld's options.
1656 if { [istarget alpha*-*-*]
1657 || [istarget mep-*-*]
1658 || [istarget ia64-*-*]
1659 || [istarget *-*-cygwin]
1660 || [istarget *-*-mingw*] } {
1661 set gc_sections_available_saved 0
1662 return 0
1665 # elf2flt uses -q (--emit-relocs), which is incompatible with
1666 # --gc-sections.
1667 if { [board_info target exists ldflags]
1668 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1669 set gc_sections_available_saved 0
1670 return 0
1673 # Check if the ld used by gcc supports --gc-sections.
1674 set ld_output [remote_exec host $ld "--help"]
1675 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1676 set gc_sections_available_saved 1
1677 } else {
1678 set gc_sections_available_saved 0
1681 return $gc_sections_available_saved
1684 # Check if the assembler supports CFI statements.
1686 proc check_as_cfi { } {
1687 global check_as_cfi_result
1688 global as
1689 if [info exists check_as_cfi_result] {
1690 return $check_as_cfi_result
1692 set as_file "tmpdir/check_as_cfi.s"
1693 set as_fh [open $as_file w 0666]
1694 puts $as_fh "# Generated file. DO NOT EDIT"
1695 puts $as_fh "\t.cfi_startproc"
1696 puts $as_fh "\t.cfi_endproc"
1697 close $as_fh
1698 remote_download host $as_file
1699 verbose -log "Checking CFI support:"
1700 rename "perror" "check_as_cfi_perror"
1701 proc perror { args } { }
1702 set success [ld_assemble $as $as_file "/dev/null"]
1703 rename "perror" ""
1704 rename "check_as_cfi_perror" "perror"
1705 #remote_file host delete $as_file
1706 set check_as_cfi_result $success
1707 return $success
1710 # Provide virtual target "cfi" for targets supporting CFI.
1712 rename "istarget" "istarget_ld"
1713 proc istarget { target } {
1714 if {$target == "cfi"} {
1715 return [check_as_cfi]
1717 return [istarget_ld $target]