* lib/ld-lib.exp (default_ld_simple_link): Add $gcc_ld_flag before
[platform/upstream/binutils.git] / ld / testsuite / lib / ld-lib.exp
1 # Support routines for LD testsuite.
2 #   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 #    2004, 2005, 2006, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
4 #
5 # This file is part of the GNU Binutils.
6 #
7 # This file is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 # MA 02110-1301, USA.
21
22 # Extract and print the version number of ld.
23 #
24 proc default_ld_version { ld } {
25     global host_triplet
26
27     if { ![is_remote host] && [which $ld] == 0 } then {
28         perror "$ld does not exist"
29         exit 1
30     }
31
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"
37
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"
41     }
42 }
43
44 proc run_host_cmd { prog command } {
45     global link_output
46
47     if { ![is_remote host] && [which "$prog"] == 0 } then {
48         perror "$prog does not exist"
49         return 0
50     }
51
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"
59     }
60     remote_file build delete ld.tmp
61     remote_file host delete ld.tmp
62
63     if [string match "" $link_output] then {
64         return ""
65     }
66
67     verbose -log "$link_output"
68     return "$link_output"
69 }
70
71 proc run_host_cmd_yesno { prog command } {
72     global exec_output
73
74     set exec_output [prune_warnings [run_host_cmd "$prog" "$command"]]
75     if [string match "" $exec_output] then {
76         return 1;
77     }
78     return 0;
79 }
80
81 # Link an object using relocation.
82 #
83 proc default_ld_relocate { ld target objects } {
84     global HOSTING_EMU
85
86     remote_file host delete $target
87     return [run_host_cmd_yesno "$ld" "$HOSTING_EMU -o $target -r $objects"]
88 }
89
90 # Check to see if ld is being invoked with a non-endian output format
91 #
92 proc is_endian_output_format { object_flags } {
93
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
104     }
105 }
106
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.
115 #
116 proc big_or_little_endian {} {
117
118     if [board_info [target_info name] exists multilib_flags] {
119         set tmp_flags " [board_info [target_info name] multilib_flags]"
120
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
126                 }
127                 {*little*endian el EL -el -EL -ml -mel} {
128                     set flags " -EL"
129                     return $flags
130                 }
131             }
132         }
133     }
134
135     set flags ""
136     return $flags
137 }
138
139 # Link a program using ld.
140 #
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
149
150     set objs "$HOSTING_CRT0 $objects"
151     set libs "$LIBS $HOSTING_LIBS"
152
153     if [is_endian_output_format $objects] then {
154         set flags [big_or_little_endian]
155     } else {
156         set flags ""
157     }
158
159     remote_file host delete $target
160
161     return [run_host_cmd_yesno "$ld" "$HOSTING_EMU $flags -o $target $objs $libs"]
162 }
163
164 # Link a program using ld, without including any libraries.
165 #
166 proc default_ld_simple_link { ld target objects } {
167     global host_triplet
168     global gcc_ld_flag
169     global exec_output
170
171     if [is_endian_output_format $objects] then {
172         set flags [big_or_little_endian]
173     } else {
174         set flags ""
175     }
176
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     set ldflags ""
183     if { $ldparm > 0 } then {
184         set ldflags [string range $ld $ldparm end]
185         set ldexe [string range $ld 0 $ldparm]
186         set ld $ldexe
187     }
188     set ldexe [string replace $ldexe 0 [string last "/" $ldexe] ""]
189     if {[string match "*gcc*" $ldexe] || [string match "*++*" $ldexe]} then {
190         set ldflags "$gcc_ld_flag $ldflags"
191     }
192
193     remote_file host delete $target
194
195     set exec_output [run_host_cmd "$ld" "$ldflags $flags -o $target $objects"]
196     set exec_output [prune_warnings $exec_output]
197
198     # We don't care if we get a warning about a non-existent start
199     # symbol, since the default linker script might use ENTRY.
200     regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
201
202     if [string match "" $exec_output] then {
203         return 1
204     } else {
205         return 0
206     }
207 }
208
209 # Compile an object using cc.
210 #
211 proc default_ld_compile { cc source object } {
212     global CFLAGS
213     global CXXFLAGS
214     global srcdir
215     global subdir
216     global host_triplet
217     global gcc_gas_flag
218
219     set cc_prog $cc
220     if {[llength $cc_prog] > 1} then {
221         set cc_prog [lindex $cc_prog 0]
222     }
223     if {![is_remote host] && [which $cc_prog] == 0} then {
224         perror "$cc_prog does not exist"
225         return 0
226     }
227
228     remote_file build delete "$object"
229     remote_file host delete "$object"
230
231     set flags "-I$srcdir/$subdir"
232
233     # If we are compiling with gcc, we want to add gcc_gas_flag to
234     # flags.  Rather than determine this in some complex way, we guess
235     # based on the name of the compiler.
236     set ccexe $cc
237     set ccparm [string first " " $cc]
238     set ccflags ""
239     if { $ccparm > 0 } then {
240         set ccflags [string range $cc $ccparm end]
241         set ccexe [string range $cc 0 $ccparm]
242         set cc $ccexe
243     }
244     set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""]
245     if {[string match "*gcc*" $ccexe] || [string match "*++*" $ccexe]} then {
246         set flags "$gcc_gas_flag $flags"
247     }
248
249     if {[string match "*++*" $ccexe]} {
250         set flags "$flags $CXXFLAGS"
251     } else {
252         set flags "$flags $CFLAGS"
253     }
254
255     if [board_info [target_info name] exists multilib_flags] {
256         append flags " [board_info [target_info name] multilib_flags]"
257     }
258
259     verbose -log "$cc $flags $ccflags -c $source -o $object"
260
261     set status [remote_exec host [concat sh -c [list "$cc $flags $ccflags -c $source -o $object 2>&1"]] "" "/dev/null" "ld.tmp"]
262     remote_upload host "ld.tmp"
263     set exec_output [file_contents "ld.tmp"]
264     remote_file build delete "ld.tmp"
265     remote_file host delete "ld.tmp"
266     set exec_output [prune_warnings $exec_output]
267     if [string match "" $exec_output] then {
268         if {![file exists $object]} then {
269             regexp ".*/(\[^/\]*)$" $source all dobj
270             regsub "\\.c" $dobj ".o" realobj
271             verbose "looking for $realobj"
272             if {[remote_file host exists $realobj]} then {
273                 verbose -log "mv $realobj $object"
274                 remote_upload "$realobj" "$object"
275             } else {
276                 perror "$object not found after compilation"
277                 return 0
278             }
279         }
280         return 1
281     } else {
282         verbose -log "$exec_output"
283         perror "$source: compilation failed"
284         return 0
285     }
286 }
287
288 # Assemble a file.
289 #
290 proc default_ld_assemble { as source object } {
291     global ASFLAGS
292     global host_triplet
293
294     if ![info exists ASFLAGS] { set ASFLAGS "" }
295
296     set flags [big_or_little_endian]
297     set exec_output [run_host_cmd "$as" "$flags $ASFLAGS -o $object $source"]
298     set exec_output [prune_warnings $exec_output]
299     if [string match "" $exec_output] then {
300         return 1
301     } else {
302         perror "$source: assembly failed"
303         return 0
304     }
305 }
306
307 # Run nm on a file, putting the result in the array nm_output.
308 #
309 proc default_ld_nm { nm nmflags object } {
310     global NMFLAGS
311     global nm_output
312     global host_triplet
313
314     if {[info exists nm_output]} {
315       unset nm_output
316     }
317
318     if ![info exists NMFLAGS] { set NMFLAGS "" }
319
320     # Ensure consistent sorting of symbols
321     if {[info exists env(LC_ALL)]} {
322         set old_lc_all $env(LC_ALL)
323     }
324     set env(LC_ALL) "C"
325
326     verbose -log "$nm $NMFLAGS $nmflags $object >tmpdir/nm.out"
327
328     set status [remote_exec host [concat sh -c [list "$nm $NMFLAGS $nmflags $object 2>ld.stderr"]] "" "/dev/null" "tmpdir/nm.out"]
329     if {[info exists old_lc_all]} {
330         set env(LC_ALL) $old_lc_all
331     } else {
332         unset env(LC_ALL)
333     }
334     remote_upload host "ld.stderr"
335     remote_upload host "tmpdir/nm.out" "tmpdir/nm.out"
336     set exec_output [prune_warnings [file_contents "ld.stderr"]]
337     remote_file host delete "ld.stderr"
338     remote_file build delete "ld.stderr"
339     if [string match "" $exec_output] then {
340         set file [open tmpdir/nm.out r]
341         while { [gets $file line] != -1 } {
342             verbose "$line" 2
343             if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] \\.*(.+)$" $line whole value name] {
344                 set name [string trimleft $name "_"]
345                 verbose "Setting nm_output($name) to 0x$value" 2
346                 set nm_output($name) 0x$value
347             }
348         }
349         close $file
350         return 1
351     } else {
352         verbose -log "$exec_output"
353         perror "$object: nm failed"
354         return 0
355     }
356 }
357
358 # Define various symbols needed when not linking against all
359 # target libs.
360 proc ld_simple_link_defsyms {} {
361
362     set flags "--defsym __stack_chk_fail=0"
363
364     # ARM targets call __gccmain
365     if {[istarget arm*-*-*]       || \
366         [istarget strongarm*-*-*] || \
367         [istarget xscale*-*-*]    || \
368         [istarget thumb-*-*] } {
369         append flags " --defsym __gccmain=0"
370     }
371
372     # PowerPC EABI code calls __eabi.
373     if {[istarget powerpc*-*-eabi*] || [istarget powerpc*-*-rtems*]} {
374         append flags " --defsym __eabi=0"
375     }
376
377     # mn10200 code calls __truncsipsi2_d0_d2.
378     if {[istarget mn10200*-*-*]} then {
379         append flags " --defsym __truncsipsi2_d0_d2=0"
380     }
381
382     # m6811/m6812 code has references to soft registers.
383     if {[istarget m6811-*-*] || [istarget m6812-*-*]} {
384         append flags " --defsym _.frame=0 --defsym _.d1=0 --defsym _.d2=0"
385         append flags " --defsym _.d3=0 --defsym _.d4=0"
386         append flags " --defsym _.tmp=0 --defsym _.xy=0 --defsym _.z=0"
387     }
388
389     # Some OpenBSD targets have ProPolice and reference __guard and
390     # __stack_smash_handler.
391     if [istarget *-*-openbsd*] {
392         append flags " --defsym __guard=0"
393         append flags " --defsym __stack_smash_handler=0"
394     }
395
396     return $flags
397 }
398
399 # True if the object format is known to be ELF.
400 #
401 proc is_elf_format {} {
402     if { ![istarget *-*-sysv4*] \
403          && ![istarget *-*-unixware*] \
404          && ![istarget *-*-elf*] \
405          && ![istarget *-*-eabi*] \
406          && ![istarget hppa*64*-*-hpux*] \
407          && ![istarget *-*-linux*] \
408          && ![istarget frv-*-uclinux*] \
409          && ![istarget bfin-*-uclinux] \
410          && ![istarget sh*-*-uclinux*] \
411          && ![istarget *-*-irix5*] \
412          && ![istarget *-*-irix6*] \
413          && ![istarget *-*-netbsd*] \
414          && ![istarget *-*-solaris2*] } {
415         return 0
416     }
417
418     if { [istarget *-*-linux*aout*] \
419          || [istarget *-*-linux*oldld*] } {
420         return 0
421     }
422
423     if { ![istarget *-*-netbsdelf*] \
424          && ([istarget *-*-netbsd*aout*] \
425              || [istarget *-*-netbsdpe*] \
426              || [istarget arm*-*-netbsd*] \
427              || [istarget sparc-*-netbsd*] \
428              || [istarget i*86-*-netbsd*] \
429              || [istarget m68*-*-netbsd*] \
430              || [istarget vax-*-netbsd*] \
431              || [istarget ns32k-*-netbsd*]) } {
432         return 0
433     }
434     return 1
435 }
436
437 # True if the object format is known to be 64-bit ELF.
438 #
439 proc is_elf64 { binary_file } {
440     global READELF
441     global READELFFLAGS
442
443     set readelf_size ""
444     catch "exec $READELF $READELFFLAGS -h $binary_file > readelf.out" got
445
446     if ![string match "" $got] then {
447         return 0
448     }
449
450     if { ![regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \
451            [file_contents readelf.out] nil readelf_size] } {
452         return 0
453     }
454
455     if { $readelf_size == "64" } {
456         return 1
457     }
458
459     return 0
460 }
461
462 # True if the object format is known to be a.out.
463 #
464 proc is_aout_format {} {
465     if { [istarget *-*-*\[ab\]out*] \
466              || [istarget *-*-linux*oldld*] \
467              || [istarget *-*-msdos*] \
468              || [istarget arm-*-netbsd] \
469              || [istarget i?86-*-netbsd] \
470              || [istarget i?86-*-mach*] \
471              || [istarget i?86-*-vsta] \
472              || [istarget pdp11-*-*] \
473              || [istarget m68*-ericsson-ose] \
474              || [istarget m68k-hp-bsd*] \
475              || [istarget m68*-*-hpux*] \
476              || [istarget m68*-*-netbsd] \
477              || [istarget m68*-*-netbsd*4k*] \
478              || [istarget m68k-sony-*] \
479              || [istarget m68*-sun-sunos\[34\]*] \
480              || [istarget m68*-wrs-vxworks*] \
481              || [istarget ns32k-*-*] \
482              || [istarget sparc*-*-netbsd] \
483              || [istarget sparc-sun-sunos4*] \
484              || [istarget vax-dec-ultrix*] \
485              || [istarget vax-*-netbsd] } {
486         return 1
487     }
488     return 0
489 }
490
491 # True if the object format is known to be PE COFF.
492 #
493 proc is_pecoff_format {} {
494     if { ![istarget *-*-mingw*] \
495          && ![istarget *-*-cygwin*] \
496          && ![istarget *-*-cegcc*] \
497          && ![istarget *-*-pe*] } {
498         return 0
499     }
500
501     return 1
502 }
503
504 # Compares two files line-by-line.
505 #   Returns differences if exist.
506 #   Returns null if file(s) cannot be opened.
507 #
508 proc simple_diff { file_1 file_2 } {
509     global target
510
511     set eof -1
512     set differences 0
513
514     if [file exists $file_1] then {
515         set file_a [open $file_1 r]
516     } else {
517         warning "$file_1 doesn't exist"
518         return
519     }
520
521     if [file exists $file_2] then {
522         set file_b [open $file_2 r]
523     } else {
524         fail "$file_2 doesn't exist"
525         return
526     }
527
528     verbose "# Diff'ing: $file_1 $file_2\n" 2
529
530     while { [gets $file_a line] != $eof } {
531         if [regexp "^#.*$" $line] then {
532             continue
533         } else {
534             lappend list_a $line
535         }
536     }
537     close $file_a
538
539     while { [gets $file_b line] != $eof } {
540         if [regexp "^#.*$" $line] then {
541             continue
542         } else {
543             lappend list_b $line
544         }
545     }
546     close $file_b
547
548     for { set i 0 } { $i < [llength $list_a] } { incr i } {
549         set line_a [lindex $list_a $i]
550         set line_b [lindex $list_b $i]
551
552         verbose "\t$file_1: $i: $line_a\n" 3
553         verbose "\t$file_2: $i: $line_b\n" 3
554         if [string compare $line_a $line_b] then {
555             verbose -log "\t$file_1: $i: $line_a\n"
556             verbose -log "\t$file_2: $i: $line_b\n"
557
558             fail "Test: $target"
559             return
560         }
561     }
562
563     if { [llength $list_a] != [llength $list_b] } {
564         fail "Test: $target"
565         return
566     }
567
568     if $differences<1 then {
569         pass "Test: $target"
570     }
571 }
572
573 # run_dump_test FILE
574 # Copied from gas testsuite, tweaked and further extended.
575 #
576 # Assemble a .s file, then run some utility on it and check the output.
577 #
578 # There should be an assembly language file named FILE.s in the test
579 # suite directory, and a pattern file called FILE.d.  `run_dump_test'
580 # will assemble FILE.s, run some tool like `objdump', `objcopy', or
581 # `nm' on the .o file to produce textual output, and then analyze that
582 # with regexps.  The FILE.d file specifies what program to run, and
583 # what to expect in its output.
584 #
585 # The FILE.d file begins with zero or more option lines, which specify
586 # flags to pass to the assembler, the program to run to dump the
587 # assembler's output, and the options it wants.  The option lines have
588 # the syntax:
589 #
590 #         # OPTION: VALUE
591 #
592 # OPTION is the name of some option, like "name" or "objdump", and
593 # VALUE is OPTION's value.  The valid options are described below.
594 # Whitespace is ignored everywhere, except within VALUE.  The option
595 # list ends with the first line that doesn't match the above syntax
596 # (hmm, not great for error detection).
597 #
598 # The interesting options are:
599 #
600 #   name: TEST-NAME
601 #       The name of this test, passed to DejaGNU's `pass' and `fail'
602 #       commands.  If omitted, this defaults to FILE, the root of the
603 #       .s and .d files' names.
604 #
605 #   as: FLAGS
606 #       When assembling, pass FLAGS to the assembler.
607 #       If assembling several files, you can pass different assembler
608 #       options in the "source" directives.  See below.
609 #
610 #   ld: FLAGS
611 #       Link assembled files using FLAGS, in the order of the "source"
612 #       directives, when using multiple files.
613 #
614 #   ld_after_inputfiles: FLAGS
615 #       Similar to "ld", but put after all input files.
616 #
617 #   objcopy_linked_file: FLAGS
618 #       Run objcopy on the linked file with the specified flags.
619 #       This lets you transform the linked file using objcopy, before the
620 #       result is analyzed by an analyzer program specified below (which
621 #       may in turn *also* be objcopy).
622 #
623 #   PROG: PROGRAM-NAME
624 #       The name of the program to run to analyze the .o file produced
625 #       by the assembler or the linker output.  This can be omitted;
626 #       run_dump_test will guess which program to run by seeing which of
627 #       the flags options below is present.
628 #
629 #   objdump: FLAGS
630 #   nm: FLAGS
631 #   objcopy: FLAGS
632 #       Use the specified program to analyze the assembler or linker
633 #       output file, and pass it FLAGS, in addition to the output name.
634 #       Note that they are run with LC_ALL=C in the environment to give
635 #       consistent sorting of symbols.
636 #
637 #   source: SOURCE [FLAGS]
638 #       Assemble the file SOURCE.s using the flags in the "as" directive
639 #       and the (optional) FLAGS.  If omitted, the source defaults to
640 #       FILE.s.
641 #       This is useful if several .d files want to share a .s file.
642 #       More than one "source" directive can be given, which is useful
643 #       when testing linking.
644 #
645 #   xfail: TARGET
646 #       The test is expected to fail on TARGET.  This may occur more than
647 #       once.
648 #
649 #   target: TARGET
650 #       Only run the test for TARGET.  This may occur more than once; the
651 #       target being tested must match at least one.  You may provide target
652 #       name "cfi" for any target supporting the CFI statements.
653 #
654 #   notarget: TARGET
655 #       Do not run the test for TARGET.  This may occur more than once;
656 #       the target being tested must not match any of them.
657 #
658 #   error: REGEX
659 #       An error with message matching REGEX must be emitted for the test
660 #       to pass.  The PROG, objdump, nm and objcopy options have no
661 #       meaning and need not supplied if this is present.  Multiple "error"
662 #       directives append to the expected linker error message.
663 #
664 #   warning: REGEX
665 #       Expect a linker warning matching REGEX.  It is an error to issue
666 #       both "error" and "warning".  Multiple "warning" directives
667 #       append to the expected linker warning message.
668 #
669 # Each option may occur at most once unless otherwise mentioned.
670 #
671 # After the option lines come regexp lines.  `run_dump_test' calls
672 # `regexp_diff' to compare the output of the dumping tool against the
673 # regexps in FILE.d.  `regexp_diff' is defined later in this file; see
674 # further comments there.
675 #
676 proc run_dump_test { name } {
677     global subdir srcdir
678     global OBJDUMP NM AS OBJCOPY READELF LD
679     global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
680     global host_triplet runtests
681     global env verbose
682
683     if [string match "*/*" $name] {
684         set file $name
685         set name [file tail $name]
686     } else {
687         set file "$srcdir/$subdir/$name"
688     }
689
690     if ![runtest_file_p $runtests $name] then {
691         return
692     }
693
694     set opt_array [slurp_options "${file}.d"]
695     if { $opt_array == -1 } {
696         perror "error reading options from $file.d"
697         unresolved $subdir/$name
698         return
699     }
700     set dumpfile tmpdir/dump.out
701     set run_ld 0
702     set run_objcopy 0
703     set opts(as) {}
704     set opts(ld) {}
705     set opts(ld_after_inputfiles) {}
706     set opts(xfail) {}
707     set opts(target) {}
708     set opts(notarget) {}
709     set opts(objdump) {}
710     set opts(nm) {}
711     set opts(objcopy) {}
712     set opts(readelf) {}
713     set opts(name) {}
714     set opts(PROG) {}
715     set opts(source) {}
716     set opts(error) {}
717     set opts(warning) {}
718     set opts(objcopy_linked_file) {}
719     set asflags(${file}.s) {}
720
721     foreach i $opt_array {
722         set opt_name [lindex $i 0]
723         set opt_val [lindex $i 1]
724         if ![info exists opts($opt_name)] {
725             perror "unknown option $opt_name in file $file.d"
726             unresolved $subdir/$name
727             return
728         }
729
730         switch -- $opt_name {
731             xfail {}
732             target {}
733             notarget {}
734             warning {}
735             error {}
736             source {
737                 # Move any source-specific as-flags to a separate array to
738                 # simplify processing.
739                 if { [llength $opt_val] > 1 } {
740                     set asflags([lindex $opt_val 0]) [lrange $opt_val 1 end]
741                     set opt_val [lindex $opt_val 0]
742                 } else {
743                     set asflags($opt_val) {}
744                 }
745             }
746             default {
747                 if [string length $opts($opt_name)] {
748                     perror "option $opt_name multiply set in $file.d"
749                     unresolved $subdir/$name
750                     return
751                 }
752
753                 # A single "# ld:" with no options should do the right thing.
754                 if { $opt_name == "ld" } {
755                     set run_ld 1
756                 }
757                 # Likewise objcopy_linked_file.
758                 if { $opt_name == "objcopy_linked_file" } {
759                     set run_objcopy 1
760                 }
761             }
762         }
763         if { $opt_name == "as" || $opt_name == "ld" } {
764             set opt_val [subst $opt_val]
765         }
766         set opts($opt_name) [concat $opts($opt_name) $opt_val]
767     }
768     foreach opt { as ld } {
769         regsub {\[big_or_little_endian\]} $opts($opt) \
770             [big_or_little_endian] opts($opt)
771     }
772
773     # Decide early whether we should run the test for this target.
774     if { [llength $opts(target)] > 0 } {
775         set targmatch 0
776         foreach targ $opts(target) {
777             if [istarget $targ] {
778                 set targmatch 1
779                 break
780             }
781         }
782         if { $targmatch == 0 } {
783             return
784         }
785     }
786     foreach targ $opts(notarget) {
787         if [istarget $targ] {
788             return
789         }
790     }
791
792     set program ""
793     # It's meaningless to require an output-testing method when we
794     # expect an error.
795     if { $opts(error) == "" } {
796         if {$opts(PROG) != ""} {
797             switch -- $opts(PROG) {
798                 objdump { set program objdump }
799                 nm      { set program nm }
800                 objcopy { set program objcopy }
801                 readelf { set program readelf }
802                 default
803                 { perror "unrecognized program option $opts(PROG) in $file.d"
804                   unresolved $subdir/$name
805                   return }
806             }
807         } else {
808         # Guess which program to run, by seeing which option was specified.
809             foreach p {objdump objcopy nm readelf} {
810                 if {$opts($p) != ""} {
811                     if {$program != ""} {
812                         perror "ambiguous dump program in $file.d"
813                         unresolved $subdir/$name
814                         return
815                     } else {
816                         set program $p
817                     }
818                 }
819             }
820         }
821         if { $program == "" && $opts(warning) == "" } {
822             perror "dump program unspecified in $file.d"
823             unresolved $subdir/$name
824             return
825         }
826     }
827
828     if { $opts(name) == "" } {
829         set testname "$subdir/$name"
830     } else {
831         set testname $opts(name)
832     }
833
834     if { $opts(source) == "" } {
835         set sourcefiles [list ${file}.s]
836     } else {
837         set sourcefiles {}
838         foreach sf $opts(source) {
839             if { [string match "/*" $sf] } {
840                 lappend sourcefiles "$sf"
841             } else {
842                 lappend sourcefiles "$srcdir/$subdir/$sf"
843             }
844             # Must have asflags indexed on source name.
845             set asflags($srcdir/$subdir/$sf) $asflags($sf)
846         }
847     }
848
849     # Time to setup xfailures.
850     foreach targ $opts(xfail) {
851         setup_xfail $targ
852     }
853
854     # Assemble each file.
855     set objfiles {}
856     for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
857         set sourcefile [lindex $sourcefiles $i]
858
859         set objfile "tmpdir/dump$i.o"
860         catch "exec rm -f $objfile" exec_output
861         lappend objfiles $objfile
862         set cmd "$AS $ASFLAGS $opts(as) $asflags($sourcefile) -o $objfile $sourcefile"
863
864         send_log "$cmd\n"
865         set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
866         remote_upload host "ld.tmp"
867         set comp_output [prune_warnings [file_contents "ld.tmp"]]
868         remote_file host delete "ld.tmp"
869         remote_file build delete "ld.tmp"
870
871         if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
872             send_log "$comp_output\n"
873             verbose "$comp_output" 3
874
875             set exitstat "succeeded"
876             if { $cmdret != 0 } { set exitstat "failed" }
877             verbose -log "$exitstat with: <$comp_output>"
878             fail $testname
879             return
880         }
881     }
882
883     set expmsg $opts(error)
884     if { $opts(warning) != "" } {
885         if { $expmsg != "" } {
886             perror "$testname: mixing error and warning test-directives"
887             return
888         }
889         set expmsg $opts(warning)
890     }
891
892     # Perhaps link the file(s).
893     if { $run_ld } {
894         set objfile "tmpdir/dump"
895         catch "exec rm -f $objfile" exec_output
896
897         # Add -L$srcdir/$subdir so that the linker command can use
898         # linker scripts in the source directory.
899         set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
900                    $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
901
902         send_log "$cmd\n"
903         set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
904         remote_upload host "ld.tmp"
905         set comp_output [file_contents "ld.tmp"]
906         remote_file host delete "ld.tmp"
907         remote_file build delete "ld.tmp"
908         set cmdret [lindex $cmdret 0]
909
910         if { $cmdret == 0 && $run_objcopy } {
911             set infile $objfile
912             set objfile "tmpdir/dump1"
913             remote_file host delete $objfile
914
915             # Note that we don't use OBJCOPYFLAGS here; any flags must be
916             # explicitly specified.
917             set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
918
919             send_log "$cmd\n"
920             set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
921             remote_upload host "ld.tmp"
922             append comp_output [file_contents "ld.tmp"]
923             remote_file host delete "ld.tmp"
924             remote_file build delete "ld.tmp"
925             set cmdret [lindex $cmdret 0]
926         }
927
928         regsub "\n$" $comp_output "" comp_output
929         if { $cmdret != 0 || $comp_output != "" || $expmsg != "" } then {
930             set exitstat "succeeded"
931             if { $cmdret != 0 } { set exitstat "failed" }
932             verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
933             send_log "$comp_output\n"
934             verbose "$comp_output" 3
935
936             if { ($expmsg == "") == ($comp_output == "") \
937                     && [regexp $expmsg $comp_output] \
938                     && (($cmdret == 0) == ($opts(error) == "")) } {
939                 # We have the expected output from ld.
940                 if { $opts(error) != "" || $program == "" } {
941                     pass $testname
942                     return
943                 }
944             } else {
945                 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
946                 fail $testname
947                 return
948             }
949         }
950     } else {
951         set objfile "tmpdir/dump0.o"
952     }
953
954     # We must not have expected failure if we get here.
955     if { $opts(error) != "" } {
956         fail $testname
957         return
958     }
959
960     set progopts1 $opts($program)
961     eval set progopts \$[string toupper $program]FLAGS
962     eval set binary \$[string toupper $program]
963
964     if { ![is_remote host] && [which $binary] == 0 } {
965         untested $testname
966         return
967     }
968
969     if { $progopts1 == "" } { set $progopts1 "-r" }
970     verbose "running $binary $progopts $progopts1" 3
971
972     # Objcopy, unlike the other two, won't send its output to stdout,
973     # so we have to run it specially.
974     set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
975     if { $program == "objcopy" } {
976         set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
977     }
978
979     # Ensure consistent sorting of symbols
980     if {[info exists env(LC_ALL)]} {
981         set old_lc_all $env(LC_ALL)
982     }
983     set env(LC_ALL) "C"
984     send_log "$cmd\n"
985     set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
986     set cmdret [lindex $cmdret 0]
987     remote_upload host "ld.tmp"
988     set comp_output [prune_warnings [file_contents "ld.tmp"]]
989     remote_file host delete "ld.tmp"
990     remote_file build delete "ld.tmp"
991     if {[info exists old_lc_all]} {
992         set env(LC_ALL) $old_lc_all
993     } else {
994         unset env(LC_ALL)
995     }
996     if { $cmdret != 0 || $comp_output != "" } {
997         send_log "exited abnormally with $cmdret, output:$comp_output\n"
998         fail $testname
999         return
1000     }
1001
1002     if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
1003     if { [regexp_diff $dumpfile "${file}.d"] } then {
1004         fail $testname
1005         if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
1006         return
1007     }
1008
1009     pass $testname
1010 }
1011
1012 proc slurp_options { file } {
1013     if [catch { set f [open $file r] } x] {
1014         #perror "couldn't open `$file': $x"
1015         perror "$x"
1016         return -1
1017     }
1018     set opt_array {}
1019     # whitespace expression
1020     set ws  {[  ]*}
1021     set nws {[^         ]*}
1022     # whitespace is ignored anywhere except within the options list;
1023     # option names are alphabetic plus underscore only.
1024     set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
1025     while { [gets $f line] != -1 } {
1026         set line [string trim $line]
1027         # Whitespace here is space-tab.
1028         if [regexp $pat $line xxx opt_name opt_val] {
1029             # match!
1030             lappend opt_array [list $opt_name $opt_val]
1031         } else {
1032             break
1033         }
1034     }
1035     close $f
1036     return $opt_array
1037 }
1038
1039 # regexp_diff, copied from gas, based on simple_diff above.
1040 #       compares two files line-by-line
1041 #       file1 contains strings, file2 contains regexps and #-comments
1042 #       blank lines are ignored in either file
1043 #       returns non-zero if differences exist
1044 #
1045 proc regexp_diff { file_1 file_2 } {
1046
1047     set eof -1
1048     set end_1 0
1049     set end_2 0
1050     set differences 0
1051     set diff_pass 0
1052     set fail_if_match 0
1053
1054     if [file exists $file_1] then {
1055         set file_a [open $file_1 r]
1056     } else {
1057         warning "$file_1 doesn't exist"
1058         return 1
1059     }
1060
1061     if [file exists $file_2] then {
1062         set file_b [open $file_2 r]
1063     } else {
1064         fail "$file_2 doesn't exist"
1065         close $file_a
1066         return 1
1067     }
1068
1069     verbose " Regexp-diff'ing: $file_1 $file_2" 2
1070
1071     while { 1 } {
1072         set line_a ""
1073         set line_b ""
1074         while { [string length $line_a] == 0 } {
1075             if { [gets $file_a line_a] == $eof } {
1076                 set end_1 1
1077                 break
1078             }
1079         }
1080         while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
1081             if [ string match "#pass" $line_b ] {
1082                 set end_2 1
1083                 set diff_pass 1
1084                 break
1085             } elseif [ string match "#failif" $line_b ] {
1086                 send_log "fail if no difference\n"
1087                 verbose "fail if no difference" 3
1088                 set fail_if_match 1
1089             } elseif [ string match "#..." $line_b ] {
1090                 if { [gets $file_b line_b] == $eof } {
1091                     set end_2 1
1092                     set diff_pass 1
1093                     break
1094                 }
1095                 verbose "looking for \"^$line_b$\"" 3
1096                 while { ![regexp "^$line_b$" "$line_a"] } {
1097                     verbose "skipping    \"$line_a\"" 3
1098                     if { [gets $file_a line_a] == $eof } {
1099                         set end_1 1
1100                         break
1101                     }
1102                 }
1103                 break
1104             }
1105             if { [gets $file_b line_b] == $eof } {
1106                 set end_2 1
1107                 break
1108             }
1109         }
1110
1111         if { $diff_pass } {
1112             break
1113         } elseif { $end_1 && $end_2 } {
1114             break
1115         } elseif { $end_1 } {
1116             send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
1117             verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
1118             set differences 1
1119             break
1120         } elseif { $end_2 } {
1121             send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
1122             verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
1123             set differences 1
1124             break
1125         } else {
1126             verbose "regexp \"^$line_b$\"\nline   \"$line_a\"" 3
1127             if ![regexp "^$line_b$" "$line_a"] {
1128                 send_log "regexp_diff match failure\n"
1129                 send_log "regexp \"^$line_b$\"\nline   \"$line_a\"\n"
1130                 set differences 1
1131             }
1132         }
1133     }
1134
1135     if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
1136         send_log "$file_1 and $file_2 are different lengths\n"
1137         verbose "$file_1 and $file_2 are different lengths" 3
1138         set differences 1
1139     }
1140
1141     if { $fail_if_match } {
1142         if { $differences == 0 } {
1143             set differences 1
1144         } else {
1145             set differences 0
1146         }
1147     }
1148
1149     close $file_a
1150     close $file_b
1151
1152     return $differences
1153 }
1154
1155 proc file_contents { filename } {
1156     set file [open $filename r]
1157     set contents [read $file]
1158     close $file
1159     return $contents
1160 }
1161
1162 # Create an archive using ar
1163 #
1164 proc ar_simple_create { ar aropts target objects } {
1165     remote_file host delete $target
1166
1167     set exec_output [run_host_cmd "$ar" "$aropts rc $target $objects"]
1168     set exec_output [prune_warnings $exec_output]
1169
1170     if [string match "" $exec_output] then {
1171         send_log "$exec_output\n"
1172         return 1
1173     } else {
1174         return 0
1175     }
1176 }
1177
1178 # List contains test-items with 3 items followed by 2 lists, one item and
1179 # one optional item:
1180 # 0:name 1:ld/ar options 2:assembler options
1181 # 3:filenames of assembler files 4: action and options. 5: name of output file
1182 # 6:compiler flags (optional)
1183 #
1184 # Actions:
1185 # objdump: Apply objdump options on result.  Compare with regex (last arg).
1186 # nm: Apply nm options on result.  Compare with regex (last arg).
1187 # readelf: Apply readelf options on result.  Compare with regex (last arg).
1188 #
1189 proc run_ld_link_tests { ldtests } {
1190     global ld
1191     global as
1192     global nm
1193     global ar
1194     global objdump
1195     global READELF
1196     global srcdir
1197     global subdir
1198     global env
1199     global CC
1200     global CFLAGS
1201     global runtests
1202
1203     foreach testitem $ldtests {
1204         set testname [lindex $testitem 0]
1205
1206         if ![runtest_file_p $runtests $testname] then {
1207             continue
1208         }
1209
1210         set ld_options [lindex $testitem 1]
1211         set as_options [lindex $testitem 2]
1212         set src_files  [lindex $testitem 3]
1213         set actions [lindex $testitem 4]
1214         set binfile tmpdir/[lindex $testitem 5]
1215         set cflags [lindex $testitem 6]
1216         set objfiles {}
1217         set is_unresolved 0
1218         set failed 0
1219
1220 #       verbose -log "Testname is $testname"
1221 #       verbose -log "ld_options is $ld_options"
1222 #       verbose -log "as_options is $as_options"
1223 #       verbose -log "src_files is $src_files"
1224 #       verbose -log "actions is $actions"
1225 #       verbose -log "binfile is $binfile"
1226
1227         # Assemble each file in the test.
1228         foreach src_file $src_files {
1229             set objfile "tmpdir/[file rootname $src_file].o"
1230             lappend objfiles $objfile
1231
1232             if { [file extension $src_file] == ".c" } {
1233                 set as_file "tmpdir/[file rootname $src_file].s"
1234                 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1235                     set is_unresolved 1
1236                     break
1237                 }
1238             } else {
1239                 set as_file "$srcdir/$subdir/$src_file"
1240             }
1241             if ![ld_assemble $as "$as_options $as_file" $objfile] {
1242                 set is_unresolved 1
1243                 break
1244             }
1245         }
1246
1247         # Catch assembler errors.
1248         if { $is_unresolved != 0 } {
1249             unresolved $testname
1250             continue
1251         }
1252
1253         if { [regexp ".*\\.a$" $binfile] } {
1254             if { ![ar_simple_create $ar $ld_options $binfile "$objfiles"] } {
1255                 fail $testname
1256                 set failed 1
1257             } else {
1258                 set failed 0
1259             }
1260         } elseif { ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] } {
1261             fail $testname
1262             set failed 1
1263         } else {
1264             set failed 0
1265         }
1266
1267         if { $failed == 0 } {
1268             foreach actionlist $actions {
1269                 set action [lindex $actionlist 0]
1270                 set progopts [lindex $actionlist 1]
1271
1272                 # There are actions where we run regexp_diff on the
1273                 # output, and there are other actions (presumably).
1274                 # Handling of the former look the same.
1275                 set dump_prog ""
1276                 switch -- $action {
1277                     objdump
1278                         { set dump_prog $objdump }
1279                     nm
1280                         { set dump_prog $nm }
1281                     readelf
1282                         { set dump_prog $READELF }
1283                     default
1284                         {
1285                             perror "Unrecognized action $action"
1286                             set is_unresolved 1
1287                             break
1288                         }
1289                     }
1290
1291                 if { $dump_prog != "" } {
1292                     set dumpfile [lindex $actionlist 2]
1293                     set binary $dump_prog
1294
1295                     # Ensure consistent sorting of symbols
1296                     if {[info exists env(LC_ALL)]} {
1297                         set old_lc_all $env(LC_ALL)
1298                     }
1299                     set env(LC_ALL) "C"
1300                     set cmd "$binary $progopts $binfile"
1301                     set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
1302                     send_log "$cmd\n"
1303                     remote_upload host "ld.stderr"
1304                     set comp_output [prune_warnings [file_contents "ld.stderr"]]
1305                     remote_file host delete "ld.stderr"
1306                     remote_file build delete "ld.stderr"
1307                     
1308                     if {[info exists old_lc_all]} {
1309                         set env(LC_ALL) $old_lc_all
1310                     } else {
1311                         unset env(LC_ALL)
1312                     }
1313
1314                     if ![string match "" $comp_output] then {
1315                         send_log "$comp_output\n"
1316                         set failed 1
1317                         break
1318                     }
1319
1320                     remote_upload host "dump.out"
1321
1322                     if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1323                         verbose "output is [file_contents "dump.out"]" 2
1324                         set failed 1
1325                         remote_file build delete "dump.out"
1326                         remote_file host delete "dump.out"
1327                         break
1328                     }
1329                     remote_file build delete "dump.out"
1330                     remote_file host delete "dump.out"
1331                 }
1332             }
1333
1334             if { $failed != 0 } {
1335                 fail $testname
1336             } else { if { $is_unresolved == 0 } {
1337                 pass $testname
1338             } }
1339         }
1340
1341         # Catch action errors.
1342         if { $is_unresolved != 0 } {
1343             unresolved $testname
1344             continue
1345         }
1346     }
1347 }
1348
1349 # This definition is taken from an unreleased version of DejaGnu.  Once
1350 # that version gets released, and has been out in the world for a few
1351 # months at least, it may be safe to delete this copy.
1352 if ![string length [info proc prune_warnings]] {
1353     #
1354     # prune_warnings -- delete various system verbosities from TEXT
1355     #
1356     # An example is:
1357     # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1358     #
1359     # Sites with particular verbose os's may wish to override this in site.exp.
1360     #
1361     proc prune_warnings { text } {
1362         # This is from sun4's.  Do it for all machines for now.
1363         # The "\\1" is to try to preserve a "\n" but only if necessary.
1364         regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1365
1366         # It might be tempting to get carried away and delete blank lines, etc.
1367         # Just delete *exactly* what we're ask to, and that's it.
1368         return $text
1369     }
1370 }
1371
1372 # targets_to_xfail is a list of target triplets to be xfailed.
1373 # ldtests contains test-items with 3 items followed by 1 lists, 2 items
1374 # and 3 optional items:
1375 #   0:name
1376 #   1:ld options
1377 #   2:assembler options
1378 #   3:filenames of source files
1379 #   4:name of output file
1380 #   5:expected output
1381 #   6:compiler flags (optional)
1382 #   7:language (optional)
1383 #   8:linker warning (optional)
1384
1385 proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
1386     global ld
1387     global as
1388     global srcdir
1389     global subdir
1390     global env
1391     global CC
1392     global CXX
1393     global CFLAGS
1394     global CXXFLAGS
1395     global errcnt
1396     global exec_output
1397
1398     foreach testitem $ldtests {
1399         foreach target $targets_to_xfail {
1400             setup_xfail $target
1401         }
1402         set testname [lindex $testitem 0]
1403         set ld_options [lindex $testitem 1]
1404         set as_options [lindex $testitem 2]
1405         set src_files  [lindex $testitem 3]
1406         set binfile tmpdir/[lindex $testitem 4]
1407         set expfile [lindex $testitem 5]
1408         set cflags [lindex $testitem 6]
1409         set lang [lindex $testitem 7]
1410         set warning [lindex $testitem 8]
1411         set objfiles {}
1412         set failed 0
1413
1414 #       verbose -log "Testname is $testname"
1415 #       verbose -log "ld_options is $ld_options"
1416 #       verbose -log "as_options is $as_options"
1417 #       verbose -log "src_files is $src_files"
1418 #       verbose -log "actions is $actions"
1419 #       verbose -log "binfile is $binfile"
1420
1421         # Assemble each file in the test.
1422         foreach src_file $src_files {
1423             set objfile "tmpdir/[file rootname $src_file].o"
1424             lappend objfiles $objfile
1425
1426             # We ignore warnings since some compilers may generate
1427             # incorrect section attributes and the assembler will warn
1428             # them.
1429             if { [ string match "c++" $lang ] } {
1430                 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1431             } else {
1432                 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1433             }
1434
1435             # We have to use $CC to build PIE and shared library.
1436             if { [ string match "c" $lang ] } {
1437                 set link_proc ld_simple_link
1438                 set link_cmd $CC
1439             } elseif { [ string match "c++" $lang ] } {
1440                 set link_proc ld_simple_link
1441                 set link_cmd $CXX
1442             } elseif { [ string match "-shared" $ld_options ] \
1443                  || [ string match "-pie" $ld_options ] } {
1444                 set link_proc ld_simple_link
1445                 set link_cmd $CC
1446             } else {
1447                 set link_proc ld_link
1448                 set link_cmd $ld
1449             }
1450
1451             if ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1452                 set failed 1
1453             } else {
1454                 set failed 0
1455             }
1456
1457             # Check if exec_output is expected.
1458             if { $warning != "" } then {
1459                 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1460                 if { [regexp $warning $exec_output] } then {
1461                     set failed 0
1462                 } else {
1463                     set failed 1
1464                 }
1465             }
1466
1467             if { $failed == 0 } {
1468                 send_log "Running: $binfile > $binfile.out\n"
1469                 verbose "Running: $binfile > $binfile.out"
1470                 catch "exec $binfile > $binfile.out" exec_output
1471             
1472                 if ![string match "" $exec_output] then {
1473                     send_log "$exec_output\n"
1474                     verbose "$exec_output" 1
1475                     set failed 1
1476                 } else {
1477                     send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1478                     verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1479                     catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1480                     set exec_output [prune_warnings $exec_output]
1481
1482                     if ![string match "" $exec_output] then {
1483                         send_log "$exec_output\n"
1484                         verbose "$exec_output" 1
1485                         set failed 1
1486                     }
1487                 }
1488             }
1489
1490             if { $failed != 0 } {
1491                 fail $testname
1492             } else {
1493                 set errcnt 0
1494                 pass $testname
1495             }
1496         }
1497     }
1498 }
1499
1500 # List contains test-items with 3 items followed by 2 lists, one item and
1501 # one optional item:
1502 #  0:name
1503 #  1:ld or ar options
1504 #  2:compile options
1505 #  3:filenames of source files
1506 #  4:action and options.
1507 #  5:name of output file
1508 #  6:language (optional)
1509 #
1510 # Actions:
1511 # objdump: Apply objdump options on result.  Compare with regex (last arg).
1512 # nm: Apply nm options on result.  Compare with regex (last arg).
1513 # readelf: Apply readelf options on result.  Compare with regex (last arg).
1514 #
1515 proc run_cc_link_tests { ldtests } {
1516     global nm
1517     global objdump
1518     global READELF
1519     global srcdir
1520     global subdir
1521     global env
1522     global CC
1523     global CXX
1524     global CFLAGS
1525     global CXXFLAGS
1526     global ar
1527
1528     foreach testitem $ldtests {
1529         set testname [lindex $testitem 0]
1530         set ldflags [lindex $testitem 1]
1531         set cflags [lindex $testitem 2]
1532         set src_files  [lindex $testitem 3]
1533         set actions [lindex $testitem 4]
1534         set binfile tmpdir/[lindex $testitem 5]
1535         set lang [lindex $testitem 6]
1536         set objfiles {}
1537         set is_unresolved 0
1538         set failed 0
1539
1540         # Compile each file in the test.
1541         foreach src_file $src_files {
1542             set objfile "tmpdir/[file rootname $src_file].o"
1543             lappend objfiles $objfile
1544
1545             # We ignore warnings since some compilers may generate
1546             # incorrect section attributes and the assembler will warn
1547             # them.
1548             if { [ string match "c++" $lang ] } {
1549                 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1550             } else {
1551                 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1552             }
1553         }
1554
1555         # Clear error and warning counts.
1556         reset_vars
1557
1558         if { [ string match "c++" $lang ] } {
1559             set cc_cmd $CXX
1560         } else {
1561             set cc_cmd $CC
1562         }
1563
1564         if { [regexp ".*\\.a$" $binfile] } {
1565             if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
1566                 fail $testname
1567                 set failed 1
1568             } else {
1569                 set failed 0
1570             }
1571         } elseif { ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] } {
1572             fail $testname
1573             set failed 1
1574         } else {
1575             set failed 0
1576         }
1577
1578         if { $failed == 0 } {
1579             foreach actionlist $actions {
1580                 set action [lindex $actionlist 0]
1581                 set progopts [lindex $actionlist 1]
1582
1583                 # There are actions where we run regexp_diff on the
1584                 # output, and there are other actions (presumably).
1585                 # Handling of the former look the same.
1586                 set dump_prog ""
1587                 switch -- $action {
1588                     objdump
1589                         { set dump_prog $objdump }
1590                     nm
1591                         { set dump_prog $nm }
1592                     readelf
1593                         { set dump_prog $READELF }
1594                     default
1595                         {
1596                             perror "Unrecognized action $action"
1597                             set is_unresolved 1
1598                             break
1599                         }
1600                     }
1601
1602                 if { $dump_prog != "" } {
1603                     set dumpfile [lindex $actionlist 2]
1604                     set binary $dump_prog
1605
1606                     # Ensure consistent sorting of symbols
1607                     if {[info exists env(LC_ALL)]} {
1608                         set old_lc_all $env(LC_ALL)
1609                     }
1610                     set env(LC_ALL) "C"
1611                     set cmd "$binary $progopts $binfile > dump.out"
1612                     send_log "$cmd\n"
1613                     catch "exec $cmd" comp_output
1614                     if {[info exists old_lc_all]} {
1615                         set env(LC_ALL) $old_lc_all
1616                     } else {
1617                         unset env(LC_ALL)
1618                     }
1619                     set comp_output [prune_warnings $comp_output]
1620
1621                     if ![string match "" $comp_output] then {
1622                         send_log "$comp_output\n"
1623                         set failed 1
1624                         break
1625                     }
1626
1627                     if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1628                         verbose "output is [file_contents "dump.out"]" 2
1629                         set failed 1
1630                         break
1631                     }
1632                 }
1633             }
1634
1635             if { $failed != 0 } {
1636                 fail $testname
1637             } else { if { $is_unresolved == 0 } {
1638                 pass $testname
1639             } }
1640         }
1641
1642         # Catch action errors.
1643         if { $is_unresolved != 0 } {
1644             unresolved $testname
1645             continue
1646         }
1647     }
1648 }
1649
1650 # Returns true if --gc-sections is supported on the target.
1651
1652 proc check_gc_sections_available { } {
1653     global gc_sections_available_saved
1654     global ld
1655     
1656     if {![info exists gc_sections_available_saved]} {
1657         # Some targets don't support gc-sections despite whatever's
1658         # advertised by ld's options.
1659         if { [istarget alpha*-*-*]
1660              || [istarget mep-*-*]
1661              || [istarget ia64-*-*]
1662              || [istarget *-*-cygwin]
1663              || [istarget *-*-mingw*] } {
1664             set gc_sections_available_saved 0
1665             return 0
1666         }
1667
1668         # elf2flt uses -q (--emit-relocs), which is incompatible with
1669         # --gc-sections.
1670         if { [board_info target exists ldflags]
1671              && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1672             set gc_sections_available_saved 0
1673             return 0
1674         }
1675
1676         # Check if the ld used by gcc supports --gc-sections.
1677         set ld_output [remote_exec host $ld "--help"]
1678         if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1679             set gc_sections_available_saved 1
1680         } else {
1681             set gc_sections_available_saved 0
1682         }
1683     }
1684     return $gc_sections_available_saved
1685 }
1686
1687 # Check if the assembler supports CFI statements.
1688
1689 proc check_as_cfi { } {
1690     global check_as_cfi_result
1691     global as
1692     if [info exists check_as_cfi_result] {
1693         return $check_as_cfi_result
1694     }
1695     set as_file "tmpdir/check_as_cfi.s"
1696     set as_fh [open $as_file w 0666]
1697     puts $as_fh "# Generated file. DO NOT EDIT"
1698     puts $as_fh "\t.cfi_startproc"
1699     puts $as_fh "\t.cfi_endproc"
1700     close $as_fh
1701     remote_download host $as_file
1702     verbose -log "Checking CFI support:"
1703     rename "perror" "check_as_cfi_perror"
1704     proc perror { args } { }
1705     set success [ld_assemble $as $as_file "/dev/null"]
1706     rename "perror" ""
1707     rename "check_as_cfi_perror" "perror"
1708     #remote_file host delete $as_file
1709     set check_as_cfi_result $success
1710     return $success
1711 }
1712
1713 # Provide virtual target "cfi" for targets supporting CFI.
1714
1715 rename "istarget" "istarget_ld"
1716 proc istarget { target } {
1717     if {$target == "cfi"} {
1718         return [check_as_cfi]
1719     }
1720     return [istarget_ld $target]
1721 }