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