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