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