cd9e930cab9a637fa402730659ba7a86dc99a735
[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     global ld_elf_shared_opt
593
594     if { [is_elf_format] && [check_shared_lib_support] } {
595         set ld_extra_opt "$ld_elf_shared_opt"
596     } else {
597         set ld_extra_opt ""
598     }
599
600     if [string match "*/*" $name] {
601         set file $name
602         set name [file tail $name]
603     } else {
604         set file "$srcdir/$subdir/$name"
605     }
606
607     if ![runtest_file_p $runtests $name] then {
608         return
609     }
610
611     set opt_array [slurp_options "${file}.d"]
612     if { $opt_array == -1 } {
613         perror "error reading options from $file.d"
614         unresolved $subdir/$name
615         return
616     }
617     set dumpfile tmpdir/dump.out
618     set run_ld 0
619     set run_objcopy 0
620     set opts(as) {}
621     set opts(ld) {}
622     set opts(ld_after_inputfiles) {}
623     set opts(xfail) {}
624     set opts(target) {}
625     set opts(notarget) {}
626     set opts(objdump) {}
627     set opts(nm) {}
628     set opts(objcopy) {}
629     set opts(readelf) {}
630     set opts(name) {}
631     set opts(PROG) {}
632     set opts(source) {}
633     set opts(dump) {}
634     set opts(error) {}
635     set opts(warning) {}
636     set opts(error_output) {}
637     set opts(warning_output) {}
638     set opts(objcopy_linked_file) {}
639     set opts(objcopy_objects) {}
640     set opts(map) {}
641
642     foreach i $opt_array {
643         set opt_name [lindex $i 0]
644         set opt_val [lindex $i 1]
645         if ![info exists opts($opt_name)] {
646             perror "unknown option $opt_name in file $file.d"
647             unresolved $subdir/$name
648             return
649         }
650
651         switch -- $opt_name {
652             xfail {}
653             target {}
654             notarget {}
655             warning {}
656             error {}
657             source {
658                 # Move any source-specific as-flags to a separate list to
659                 # simplify processing.
660                 if { [llength $opt_val] > 1 } {
661                     lappend asflags [lrange $opt_val 1 end]
662                     set opt_val [lindex $opt_val 0]
663                 } else {
664                     lappend asflags {}
665                 }
666             }
667             default {
668                 if [string length $opts($opt_name)] {
669                     perror "option $opt_name multiply set in $file.d"
670                     unresolved $subdir/$name
671                     return
672                 }
673
674                 # A single "# ld:" with no options should do the right thing.
675                 if { $opt_name == "ld" } {
676                     set run_ld 1
677                 }
678                 # Likewise objcopy_linked_file.
679                 if { $opt_name == "objcopy_linked_file" } {
680                     set run_objcopy 1
681                 }
682             }
683         }
684         if { $opt_name == "as" || $opt_name == "ld" } {
685             set opt_val [subst $opt_val]
686         }
687
688         # Append differently whether it's a message (without space) or
689         # an option or list (with space).
690         switch -- $opt_name {
691             warning -
692             error {
693                 append opts($opt_name) $opt_val
694             }
695             default {
696                 set opts($opt_name) [concat $opts($opt_name) $opt_val]
697             }
698         }
699     }
700
701     foreach i $extra_options {
702         set opt_name [lindex $i 0]
703         set opt_val [lindex $i 1]
704         if ![info exists opts($opt_name)] {
705             perror "unknown option $opt_name given in extra_opts"
706             unresolved $subdir/$name
707             return
708         }
709         # Add extra option to end of existing option, adding space
710         # if necessary.
711         if { ![regexp "warning|error" $opt_name]
712              && [string length $opts($opt_name)] } {
713             append opts($opt_name) " "
714         }
715         append opts($opt_name) $opt_val
716     }
717
718     foreach opt { as ld } {
719         regsub {\[big_or_little_endian\]} $opts($opt) \
720             [big_or_little_endian] opts($opt)
721     }
722
723     # Decide early whether we should run the test for this target.
724     if { [llength $opts(target)] > 0 } {
725         set targmatch 0
726         foreach targ $opts(target) {
727             if [istarget $targ] {
728                 set targmatch 1
729                 break
730             }
731         }
732         if { $targmatch == 0 } {
733             return
734         }
735     }
736     foreach targ $opts(notarget) {
737         if [istarget $targ] {
738             return
739         }
740     }
741
742     set program ""
743     # It's meaningless to require an output-testing method when we
744     # expect an error.
745     if { $opts(error) == "" && $opts(error_output) == "" } {
746         if {$opts(PROG) != ""} {
747             switch -- $opts(PROG) {
748                 objdump { set program objdump }
749                 nm      { set program nm }
750                 objcopy { set program objcopy }
751                 readelf { set program readelf }
752                 default
753                 { perror "unrecognized program option $opts(PROG) in $file.d"
754                   unresolved $subdir/$name
755                   return }
756             }
757         } else {
758         # Guess which program to run, by seeing which option was specified.
759             foreach p {objdump objcopy nm readelf} {
760                 if {$opts($p) != ""} {
761                     if {$program != ""} {
762                         perror "ambiguous dump program in $file.d"
763                         unresolved $subdir/$name
764                         return
765                     } else {
766                         set program $p
767                     }
768                 }
769             }
770         }
771         if { $program == "" \
772                  && $opts(map) == "" \
773                  && $opts(warning) == "" \
774                  && $opts(warning_output) == "" \
775                  && $opts(error) == "" \
776                  && $opts(error_output) == "" } {
777             perror "dump program unspecified in $file.d"
778             unresolved $subdir/$name
779             return
780         }
781     }
782
783     if { $opts(name) == "" } {
784         set testname "$subdir/$name"
785     } else {
786         set testname $opts(name)
787     }
788
789     if { $opts(source) == "" } {
790         set sourcefiles [list ${file}.s]
791         set asflags [list ""]
792     } else {
793         set sourcefiles {}
794         foreach sf $opts(source) {
795             if { [string match "/*" $sf] } {
796                 lappend sourcefiles "$sf"
797             } else {
798                 lappend sourcefiles "$srcdir/$subdir/$sf"
799             }
800         }
801     }
802
803     if { $opts(dump) == "" } {
804         set dfile ${file}.d
805     } else {
806         set dfile $srcdir/$subdir/$opts(dump)
807     }
808
809     # Time to setup xfailures.
810     foreach targ $opts(xfail) {
811         setup_xfail $targ
812     }
813
814     # Assemble each file.
815     set objfiles {}
816     for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
817         set sourcefile [lindex $sourcefiles $i]
818         set sourceasflags [lindex $asflags $i]
819         set run_objcopy_objects 0
820
821         if { [string match "*RUN_OBJCOPY*" $sourceasflags] } {
822             set run_objcopy_objects 1
823         }
824         regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
825
826         set objfile "tmpdir/dump$i.o"
827         catch "exec rm -f $objfile" exec_output
828         lappend objfiles $objfile
829         set cmd "$AS $ASFLAGS $opts(as) $sourceasflags -o $objfile $sourcefile"
830
831         send_log "$cmd\n"
832         set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
833         remote_upload host "ld.tmp"
834         set comp_output [prune_warnings [file_contents "ld.tmp"]]
835         remote_file host delete "ld.tmp"
836         remote_file build delete "ld.tmp"
837
838         if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
839             send_log "$comp_output\n"
840             verbose "$comp_output" 3
841
842             set exitstat "succeeded"
843             if { $cmdret != 0 } { set exitstat "failed" }
844             verbose -log "$exitstat with: <$comp_output>"
845             fail $testname
846             return
847         }
848
849         if { $run_objcopy_objects } {
850             set cmd "$OBJCOPY $opts(objcopy_objects) $objfile"
851
852             send_log "$cmd\n"
853             set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \
854                         "" "/dev/null" "objcopy.tmp"]
855             remote_upload host "objcopy.tmp"
856             set comp_output [prune_warnings [file_contents "objcopy.tmp"]]
857             remote_file host delete "objcopy.tmp"
858             remote_file build delete "objcopy.tmp"
859
860             if { [lindex $cmdret 0] != 0 \
861                   || ![string match "" $comp_output] } {
862                 send_log "$comp_output\n"
863                 verbose "$comp_output" 3
864
865                 set exitstat "succeeded"
866                 if { $cmdret != 0 } { set exitstat "failed" }
867                 verbose -log "$exitstat with: <$comp_output>"
868                 fail $testname
869                 return
870             }
871         }
872     }
873
874     if { (($opts(warning) != "") && ($opts(error) != "")) \
875          || (($opts(warning) != "") && ($opts(error_output) != "")) \
876          || (($opts(warning) != "") && ($opts(warning_output) != "")) \
877          || (($opts(error) != "") && ($opts(warning_output) != "")) \
878          || (($opts(error) != "") && ($opts(error_output) != "")) \
879          || (($opts(warning_output) != "") && ($opts(error_output) != "")) } {
880         perror "$testname: bad mix of warning, error, warning_output, and error_output test-directives"
881         unresolved $testname
882         return
883     }
884
885     set check_ld(source) ""
886     set check_ld(terminal) 0
887     if { $opts(error) != "" \
888          || $opts(warning) != "" \
889          || $opts(error_output) != "" \
890          || $opts(warning_output) != "" } {
891
892         if { $opts(error) != "" || $opts(error_output) != "" } {
893             set check_ld(terminal) 1
894         } else {
895             set check_ld(terminal) 0
896         }
897
898         if { $opts(error) != "" || $opts(warning) != "" } {
899             set check_ld(source) "regex"
900             if { $opts(error) != "" } {
901                 set check_ld(regex) $opts(error)
902             } else {
903                 set check_ld(regex) $opts(warning)
904             }
905         } else {
906             set check_ld(source) "file"
907             if { $opts(error_output) != "" } {
908                 set check_ld(file) $opts(error_output)
909             } else {
910                 set check_ld(file) $opts(warning_output)
911             }
912         }
913     }
914
915     # Perhaps link the file(s).
916     if { $run_ld } {
917         set objfile "tmpdir/dump"
918         catch "exec rm -f $objfile" exec_output
919
920         # Add -L$srcdir/$subdir so that the linker command can use
921         # linker scripts in the source directory.
922         set cmd "$LD $ld_extra_opt $LDFLAGS -L$srcdir/$subdir \
923                    $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
924
925         # If needed then check for, or add a -Map option.
926         set mapfile ""
927         if { $opts(map) != "" } then {
928             if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then {
929                 # Found existing mapfile option
930                 verbose -log "Existing mapfile '$mapfile' found"
931             } else {
932                 # No mapfile option.
933                 set mapfile "tmpdir/dump.map"
934                 verbose -log "Adding mapfile '$mapfile'"
935                 set cmd "$cmd -Map=$mapfile"
936             }
937         }
938
939         send_log "$cmd\n"
940         set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
941         remote_upload host "ld.tmp"
942         set comp_output [file_contents "ld.tmp"]
943         remote_file host delete "ld.tmp"
944         remote_file build delete "ld.tmp"
945         set cmdret [lindex $cmdret 0]
946
947         if { $cmdret == 0 && $run_objcopy } {
948             set infile $objfile
949             set objfile "tmpdir/dump1"
950             remote_file host delete $objfile
951
952             # Note that we don't use OBJCOPYFLAGS here; any flags must be
953             # explicitly specified.
954             set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
955
956             send_log "$cmd\n"
957             set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
958             remote_upload host "ld.tmp"
959             append comp_output [file_contents "ld.tmp"]
960             remote_file host delete "ld.tmp"
961             remote_file build delete "ld.tmp"
962             set cmdret [lindex $cmdret 0]
963         }
964
965         regsub "\n$" $comp_output "" comp_output
966         if { $cmdret != 0 || $comp_output != "" || $check_ld(source) != "" } then {
967             set exitstat "succeeded"
968             if { $cmdret != 0 } { set exitstat "failed" }
969
970             if { $check_ld(source) == "regexp" } {
971                 verbose -log "$exitstat with: <$comp_output>, expected: <$check_ld(regex)>"
972             } elseif { $check_ld(source) == "file" } {
973                 verbose -log "$exitstat with: <$comp_output>, expected in file $check_ld(file)"
974                 set_file_contents "tmpdir/ld.messages" "$comp_output"
975             } else {
976                 verbose -log "$exitstat with: <$comp_output>, no expected output"
977             }
978             send_log "$comp_output\n"
979             verbose "$comp_output" 3
980
981             if { (($check_ld(source) == "") == ($comp_output == "")) \
982                  && (($cmdret == 0) == ($check_ld(terminal) == 0)) \
983                  && ((($check_ld(source) == "regex") \
984                       && ($check_ld(regex) == "") == ($comp_output == "") \
985                       && [regexp $check_ld(regex) $comp_output]) \
986                      || (($check_ld(source) == "file") \
987                          && (![regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$check_ld(file)"]))) } {
988                 # We have the expected output from ld.
989                 if { $check_ld(terminal) || $program == "" } {
990                     pass $testname
991                     return
992                 }
993             } else {
994                 fail $testname
995                 return
996             }
997         }
998
999         if { $opts(map) != "" } then {
1000             # Check the map file matches.
1001             set map_pattern_file $srcdir/$subdir/$opts(map)
1002             verbose -log "Compare '$mapfile' against '$map_pattern_file'"
1003             if { [regexp_diff $mapfile $map_pattern_file] } then {
1004                 fail "$testname (map file check)"
1005             } else {
1006                 pass "$testname (map file check)"
1007             }
1008
1009             if { $program == "" } then {
1010                 return
1011             }
1012         }
1013     } else {
1014         set objfile "tmpdir/dump0.o"
1015     }
1016
1017     # We must not have expected failure if we get here.
1018     if { $opts(error) != "" } {
1019         fail $testname
1020         return
1021     }
1022
1023     set progopts1 $opts($program)
1024     eval set progopts \$[string toupper $program]FLAGS
1025     eval set binary \$[string toupper $program]
1026
1027     if { ![is_remote host] && [which $binary] == 0 } {
1028         untested $testname
1029         return
1030     }
1031
1032     if { $progopts1 == "" } { set $progopts1 "-r" }
1033     verbose "running $binary $progopts $progopts1" 3
1034
1035     # Objcopy, unlike the other two, won't send its output to stdout,
1036     # so we have to run it specially.
1037     set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
1038     if { $program == "objcopy" } {
1039         set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
1040     }
1041
1042     # Ensure consistent sorting of symbols
1043     if {[info exists env(LC_ALL)]} {
1044         set old_lc_all $env(LC_ALL)
1045     }
1046     set env(LC_ALL) "C"
1047     send_log "$cmd\n"
1048     set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
1049     set cmdret [lindex $cmdret 0]
1050     remote_upload host "ld.tmp"
1051     set comp_output [prune_warnings [file_contents "ld.tmp"]]
1052     remote_file host delete "ld.tmp"
1053     remote_file build delete "ld.tmp"
1054     if {[info exists old_lc_all]} {
1055         set env(LC_ALL) $old_lc_all
1056     } else {
1057         unset env(LC_ALL)
1058     }
1059     if { $cmdret != 0 || $comp_output != "" } {
1060         send_log "exited abnormally with $cmdret, output:$comp_output\n"
1061         fail $testname
1062         return
1063     }
1064
1065     if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
1066     if { [regexp_diff $dumpfile "${dfile}"] } then {
1067         fail $testname
1068         if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
1069         return
1070     }
1071
1072     pass $testname
1073 }
1074
1075 proc slurp_options { file } {
1076     # If options_regsub(foo) is set to {a b}, then the contents of a
1077     # "#foo:" line will have regsub -all applied to replace a with b.
1078     global options_regsub
1079
1080     if [catch { set f [open $file r] } x] {
1081         #perror "couldn't open `$file': $x"
1082         perror "$x"
1083         return -1
1084     }
1085     set opt_array {}
1086     # whitespace expression
1087     set ws  {[  ]*}
1088     set nws {[^         ]*}
1089     # whitespace is ignored anywhere except within the options list;
1090     # option names are alphabetic plus underscore only.
1091     set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
1092     while { [gets $f line] != -1 } {
1093         set line [string trim $line]
1094         # Whitespace here is space-tab.
1095         if [regexp $pat $line xxx opt_name opt_val] {
1096             # match!
1097             if [info exists options_regsub($opt_name)] {
1098                 set subst $options_regsub($opt_name)
1099                 regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \
1100                     opt_val
1101             }
1102             lappend opt_array [list $opt_name $opt_val]
1103         } else {
1104             break
1105         }
1106     }
1107     close $f
1108     return $opt_array
1109 }
1110
1111 proc file_contents { filename } {
1112     set file [open $filename r]
1113     set contents [read $file]
1114     close $file
1115     return $contents
1116 }
1117
1118 proc set_file_contents { filename contents } {
1119     set file [open $filename w]
1120     puts $file "$contents"
1121     close $file
1122 }
1123
1124 # Create an archive using ar
1125 #
1126 proc ar_simple_create { ar aropts target objects } {
1127     remote_file host delete $target
1128
1129     set exec_output [run_host_cmd "$ar" "-rc $aropts $target $objects"]
1130     set exec_output [prune_warnings $exec_output]
1131
1132     if [string match "" $exec_output] then {
1133         send_log "$exec_output\n"
1134         return 1
1135     } else {
1136         return 0
1137     }
1138 }
1139
1140 # List contains test-items with 3 items followed by 2 lists, one item and
1141 # one optional item:
1142 #  0:name
1143 #  1:ld/ar leading options, placed before object files
1144 #  2:ld/ar trailing options, placed after object files
1145 #  3:assembler options
1146 #  4:filenames of assembler files
1147 #  5:list of actions, options and expected outputs.
1148 #  6:name of output file
1149 #  7:compiler flags (optional)
1150 #
1151 # Actions: { command command-line-options file-containg-expected-output-regexps }
1152 # Commands:
1153 #   objdump: Apply objdump options on result.
1154 #   nm: Apply nm options on result.
1155 #   readelf: Apply readelf options on result.
1156 #   ld: Don't apply anything on result.  Compare output during linking with
1157 #     the file containing regexps (which is the second arg, not the third).
1158 #     Note that this *must* be the first action if it is to be used at all;
1159 #     in all other cases, any output from the linker during linking is
1160 #     treated as a sign of an error and FAILs the test.
1161 #
1162 # args is an optional list of target triplets to be xfailed.
1163 #
1164 proc run_ld_link_tests { ldtests args } {
1165     global ld
1166     global as
1167     global nm
1168     global ar
1169     global objdump
1170     global READELF
1171     global srcdir
1172     global subdir
1173     global env
1174     global CC
1175     global CFLAGS
1176     global runtests
1177     global exec_output
1178     global ld_elf_shared_opt
1179
1180     if { [is_elf_format] && [check_shared_lib_support] } {
1181         set ld_extra_opt "$ld_elf_shared_opt"
1182     } else {
1183         set ld_extra_opt ""
1184     }
1185
1186     foreach testitem $ldtests {
1187         set testname [lindex $testitem 0]
1188
1189         if ![runtest_file_p $runtests $testname] then {
1190             continue
1191         }
1192
1193         foreach target $args {
1194             setup_xfail $target
1195         }
1196
1197         set ld_options [lindex $testitem 1]
1198         set ld_after [lindex $testitem 2]
1199         set as_options [lindex $testitem 3]
1200         set src_files  [lindex $testitem 4]
1201         set actions [lindex $testitem 5]
1202         set binfile tmpdir/[lindex $testitem 6]
1203         set cflags [lindex $testitem 7]
1204         set objfiles {}
1205         set is_unresolved 0
1206         set failed 0
1207         set maybe_failed 0
1208         set ld_output ""
1209
1210 #       verbose -log "Testname is $testname"
1211 #       verbose -log "ld_options is $ld_options"
1212 #       verbose -log "ld_after is $ld_after"
1213 #       verbose -log "as_options is $as_options"
1214 #       verbose -log "src_files is $src_files"
1215 #       verbose -log "actions is $actions"
1216 #       verbose -log "binfile is $binfile"
1217
1218         # Assemble each file in the test.
1219         foreach src_file $src_files {
1220             set fileroot "[file rootname [file tail $src_file]]"
1221             set objfile "tmpdir/$fileroot.o"
1222             lappend objfiles $objfile
1223
1224             if { [file extension $src_file] == ".c" } {
1225                 set as_file "tmpdir/$fileroot.s"
1226                 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1227                     set is_unresolved 1
1228                     break
1229                 }
1230             } else {
1231                 set as_file "$srcdir/$subdir/$src_file"
1232             }
1233             if ![ld_assemble $as "$as_options $as_file" $objfile] {
1234                 set is_unresolved 1
1235                 break
1236             }
1237         }
1238
1239         # Catch assembler errors.
1240         if { $is_unresolved } {
1241             unresolved $testname
1242             continue
1243         }
1244
1245         if { $binfile eq "tmpdir/" } {
1246             # compile only
1247         } elseif { [regexp ".*\\.a$" $binfile] } {
1248             if { ![ar_simple_create $ar $ld_options $binfile "$objfiles $ld_after"] } {
1249                 set failed 1
1250             }
1251         } elseif { ![ld_simple_link $ld $binfile "$ld_extra_opt -L$srcdir/$subdir $ld_options $objfiles $ld_after"] } {
1252             set maybe_failed 1
1253             set ld_output "$exec_output"
1254         }
1255
1256         if { !$failed } {
1257             foreach actionlist $actions {
1258                 set action [lindex $actionlist 0]
1259                 set progopts [lindex $actionlist 1]
1260
1261                 # There are actions where we run regexp_diff on the
1262                 # output, and there are other actions (presumably).
1263                 # Handling of the former look the same.
1264                 set dump_prog ""
1265                 switch -- $action {
1266                     objdump
1267                         { set dump_prog $objdump }
1268                     nm
1269                         { set dump_prog $nm }
1270                     readelf
1271                         { set dump_prog $READELF }
1272                     ld
1273                         { set dump_prog "ld" }
1274                     default
1275                         {
1276                             perror "Unrecognized action $action"
1277                             set is_unresolved 1
1278                             break
1279                         }
1280                     }
1281
1282                 if { $action == "ld" } {
1283                     set regexpfile $progopts
1284                     verbose "regexpfile is $srcdir/$subdir/$regexpfile"
1285                     set_file_contents "tmpdir/ld.messages" "$ld_output"
1286                     verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
1287                     if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$regexpfile"] } then {
1288                         verbose "output is $ld_output" 2
1289                         set failed 1
1290                         break
1291                     }
1292                     set maybe_failed 0
1293                 } elseif { !$maybe_failed && $dump_prog != "" } {
1294                     set dumpfile [lindex $actionlist 2]
1295                     set binary $dump_prog
1296
1297                     # Ensure consistent sorting of symbols
1298                     if {[info exists env(LC_ALL)]} {
1299                         set old_lc_all $env(LC_ALL)
1300                     }
1301                     set env(LC_ALL) "C"
1302                     set cmd "$binary $progopts $binfile"
1303                     set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
1304                     send_log "$cmd\n"
1305                     remote_upload host "ld.stderr"
1306                     set comp_output [prune_warnings [file_contents "ld.stderr"]]
1307                     remote_file host delete "ld.stderr"
1308                     remote_file build delete "ld.stderr"
1309
1310                     if {[info exists old_lc_all]} {
1311                         set env(LC_ALL) $old_lc_all
1312                     } else {
1313                         unset env(LC_ALL)
1314                     }
1315
1316                     if ![string match "" $comp_output] then {
1317                         send_log "$comp_output\n"
1318                         set failed 1
1319                         break
1320                     }
1321
1322                     remote_upload host "dump.out"
1323
1324                     if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1325                         verbose "output is [file_contents "dump.out"]" 2
1326                         set failed 1
1327                         remote_file build delete "dump.out"
1328                         remote_file host delete "dump.out"
1329                         break
1330                     }
1331                     remote_file build delete "dump.out"
1332                     remote_file host delete "dump.out"
1333                 }
1334             }
1335         }
1336
1337         if { $is_unresolved } {
1338             unresolved $testname
1339         } elseif { $maybe_failed || $failed } {
1340             fail $testname
1341         } else {
1342             pass $testname
1343         }
1344     }
1345 }
1346
1347 # This definition is taken from an unreleased version of DejaGnu.  Once
1348 # that version gets released, and has been out in the world for a few
1349 # months at least, it may be safe to delete this copy.
1350 if ![string length [info proc prune_warnings]] {
1351     #
1352     # prune_warnings -- delete various system verbosities from TEXT
1353     #
1354     # An example is:
1355     # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1356     #
1357     # Sites with particular verbose os's may wish to override this in site.exp.
1358     #
1359     proc prune_warnings { text } {
1360         # This is from sun4's.  Do it for all machines for now.
1361         # The "\\1" is to try to preserve a "\n" but only if necessary.
1362         regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1363
1364         # It might be tempting to get carried away and delete blank lines, etc.
1365         # Just delete *exactly* what we're ask to, and that's it.
1366         return $text
1367     }
1368 }
1369
1370 # ldtests contains test-items with 3 items followed by 1 lists, 2 items
1371 # and 3 optional items:
1372 #   0:name
1373 #   1:ld options
1374 #   2:assembler options
1375 #   3:filenames of source files
1376 #   4:name of output file
1377 #   5:expected output
1378 #   6:compiler flags (optional)
1379 #   7:language (optional)
1380 #   8:linker warning (optional)
1381 # args is an optional list of target triplets to be xfailed.
1382
1383 proc run_ld_link_exec_tests { ldtests args } {
1384     global ld
1385     global as
1386     global srcdir
1387     global subdir
1388     global env
1389     global CC
1390     global CXX
1391     global CFLAGS
1392     global CXXFLAGS
1393     global errcnt
1394     global exec_output
1395
1396     foreach testitem $ldtests {
1397         foreach target $args {
1398             setup_xfail $target
1399         }
1400         set testname [lindex $testitem 0]
1401         set ld_options [lindex $testitem 1]
1402         set as_options [lindex $testitem 2]
1403         set src_files  [lindex $testitem 3]
1404         set binfile tmpdir/[lindex $testitem 4]
1405         set expfile [lindex $testitem 5]
1406         set cflags [lindex $testitem 6]
1407         set lang [lindex $testitem 7]
1408         set warning [lindex $testitem 8]
1409         set objfiles {}
1410         set failed 0
1411
1412 #       verbose -log "Testname is $testname"
1413 #       verbose -log "ld_options is $ld_options"
1414 #       verbose -log "as_options is $as_options"
1415 #       verbose -log "src_files is $src_files"
1416 #       verbose -log "binfile is $binfile"
1417
1418         # Assemble each file in the test.
1419         foreach src_file $src_files {
1420             set fileroot "[file rootname [file tail $src_file]]"
1421             set objfile "tmpdir/$fileroot.o"
1422             lappend objfiles $objfile
1423
1424             # We ignore warnings since some compilers may generate
1425             # incorrect section attributes and the assembler will warn
1426             # them.
1427             if { [ string match "c++" $lang ] } {
1428                 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1429             } else {
1430                 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1431             }
1432         }
1433
1434         # We have to use $CC to build PIE and shared library.
1435         if { [ string match "c" $lang ] } {
1436             set link_proc ld_simple_link
1437             set link_cmd $CC
1438         } elseif { [ string match "c++" $lang ] } {
1439             set link_proc ld_simple_link
1440             set link_cmd $CXX
1441         } elseif { [ string match "-shared" $ld_options ] \
1442                    || [ string match "-pie" $ld_options ] } {
1443             set link_proc ld_simple_link
1444             set link_cmd $CC
1445         } else {
1446             set link_proc ld_link
1447             set link_cmd $ld
1448         }
1449
1450         if { $binfile eq "tmpdir/" } {
1451             # compile only
1452             pass $testname
1453             continue;
1454         } elseif ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1455             set failed 1
1456         }
1457
1458         # Check if exec_output is expected.
1459         if { $warning != "" } then {
1460             verbose -log "returned with: <$exec_output>, expected: <$warning>"
1461             if { [regexp $warning $exec_output] } then {
1462                 set failed 0
1463             } else {
1464                 set failed 1
1465             }
1466         }
1467
1468         if { $failed == 0 } {
1469             send_log "Running: $binfile > $binfile.out\n"
1470             verbose "Running: $binfile > $binfile.out"
1471             catch "exec $binfile > $binfile.out" exec_output
1472
1473             if ![string match "" $exec_output] then {
1474                 send_log "$exec_output\n"
1475                 verbose "$exec_output" 1
1476                 set failed 1
1477             } else {
1478                 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1479                 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1480                 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1481                 set exec_output [prune_warnings $exec_output]
1482
1483                 if ![string match "" $exec_output] then {
1484                     send_log "$exec_output\n"
1485                     verbose "$exec_output" 1
1486                     set failed 1
1487                 }
1488             }
1489         }
1490
1491         if { $failed != 0 } {
1492             fail $testname
1493         } else {
1494             set errcnt 0
1495             pass $testname
1496         }
1497     }
1498 }
1499
1500 # List contains test-items with 3 items followed by 2 lists, one item and
1501 # one optional item:
1502 #  0:name
1503 #  1:ld or ar options
1504 #  2:compile options
1505 #  3:filenames of source files
1506 #  4:action and options.
1507 #  5:name of output file
1508 #  6:language (optional)
1509 #  7:linker warnings (optional)
1510 #
1511 # Actions:
1512 # objdump: Apply objdump options on result.  Compare with regex (last arg).
1513 # nm: Apply nm options on result.  Compare with regex (last arg).
1514 # readelf: Apply readelf options on result.  Compare with regex (last arg).
1515 #
1516 proc run_cc_link_tests { ldtests } {
1517     global nm
1518     global objdump
1519     global READELF
1520     global srcdir
1521     global subdir
1522     global env
1523     global CC
1524     global CXX
1525     global CFLAGS
1526     global CXXFLAGS
1527     global ar
1528     global exec_output
1529     global board_cflags
1530
1531     if [board_info [target_info name] exists cflags] {
1532         set board_cflags " [board_info [target_info name] cflags]"
1533     } else {
1534         set board_cflags ""
1535     }
1536
1537     foreach testitem $ldtests {
1538         set testname [lindex $testitem 0]
1539         set ldflags [lindex $testitem 1]
1540         set cflags [lindex $testitem 2]
1541         set src_files  [lindex $testitem 3]
1542         set actions [lindex $testitem 4]
1543         set binfile tmpdir/[lindex $testitem 5]
1544         set lang [lindex $testitem 6]
1545         set warnings [lindex $testitem 7]
1546         set objfiles {}
1547         set is_unresolved 0
1548         set failed 0
1549
1550         #verbose -log "testname  is $testname"
1551         #verbose -log "ldflags   is $ldflags"
1552         #verbose -log "cflags    is $cflags"
1553         #verbose -log "src_files is $src_files"
1554         #verbose -log "actions   is $actions"
1555         #verbose -log "binfile   is $binfile"
1556         #verbose -log "lang      is $lang"
1557         #verbose -log "warnings  is $warnings"
1558
1559         # Compile each file in the test.
1560         foreach src_file $src_files {
1561             set fileroot "[file rootname [file tail $src_file]]"
1562             set objfile "tmpdir/$fileroot.o"
1563             lappend objfiles $objfile
1564
1565             # We ignore warnings since some compilers may generate
1566             # incorrect section attributes and the assembler will warn
1567             # them.
1568             if { [ string match "c++" $lang ] } {
1569                 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1570             } else {
1571                 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1572             }
1573         }
1574
1575         # Clear error and warning counts.
1576         reset_vars
1577
1578         if { [ string match "c++" $lang ] } {
1579             set cc_cmd $CXX
1580         } else {
1581             set cc_cmd $CC
1582         }
1583
1584         if { $binfile eq "tmpdir/" } {
1585             # compile only
1586         } elseif { [regexp ".*\\.a$" $binfile] } {
1587             if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
1588                 fail $testname
1589                 set failed 1
1590             }
1591         } else {
1592             if { ![ld_simple_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"] } {
1593                 set failed 1
1594             }
1595
1596             # Check if exec_output is expected.
1597             if { $warnings != "" } then {
1598                 verbose -log "returned with: <$exec_output>, expected: <$warnings>"
1599                 if { [regexp $warnings $exec_output] } then {
1600                     set failed 0
1601                 } else {
1602                     set failed 1
1603                 }
1604             }
1605
1606             if { $failed == 1 } {
1607                 fail $testname
1608             }
1609         }
1610
1611         if { $failed == 0 } {
1612             foreach actionlist $actions {
1613                 set action [lindex $actionlist 0]
1614                 set progopts [lindex $actionlist 1]
1615
1616                 # There are actions where we run regexp_diff on the
1617                 # output, and there are other actions (presumably).
1618                 # Handling of the former look the same.
1619                 set dump_prog ""
1620                 switch -- $action {
1621                     objdump
1622                         { set dump_prog $objdump }
1623                     nm
1624                         { set dump_prog $nm }
1625                     readelf
1626                         { set dump_prog $READELF }
1627                     default
1628                         {
1629                             perror "Unrecognized action $action"
1630                             set is_unresolved 1
1631                             break
1632                         }
1633                     }
1634
1635                 if { $dump_prog != "" } {
1636                     set dumpfile [lindex $actionlist 2]
1637                     set binary $dump_prog
1638
1639                     # Ensure consistent sorting of symbols
1640                     if {[info exists env(LC_ALL)]} {
1641                         set old_lc_all $env(LC_ALL)
1642                     }
1643                     set env(LC_ALL) "C"
1644                     set cmd "$binary $progopts $binfile > dump.out"
1645                     send_log "$cmd\n"
1646                     catch "exec $cmd" comp_output
1647                     if {[info exists old_lc_all]} {
1648                         set env(LC_ALL) $old_lc_all
1649                     } else {
1650                         unset env(LC_ALL)
1651                     }
1652                     set comp_output [prune_warnings $comp_output]
1653
1654                     if ![string match "" $comp_output] then {
1655                         send_log "$comp_output\n"
1656                         set failed 1
1657                         break
1658                     }
1659
1660                     if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1661                         verbose "output is [file_contents "dump.out"]" 2
1662                         set failed 1
1663                         break
1664                     }
1665                 }
1666             }
1667         }
1668
1669         if { $failed != 0 } {
1670             fail $testname
1671         } elseif { $is_unresolved == 0 } {
1672             pass $testname
1673         } else {
1674             unresolved $testname
1675             continue
1676         }
1677     }
1678 }
1679
1680 # Returns true if --gc-sections is supported on the target.
1681
1682 proc check_gc_sections_available { } {
1683     global gc_sections_available_saved
1684     global ld
1685
1686     if {![info exists gc_sections_available_saved]} {
1687         # Some targets don't support gc-sections despite whatever's
1688         # advertised by ld's options.
1689         if {   [istarget d30v-*-*]
1690             || [istarget dlx-*-*]
1691             || [istarget i960-*-*]
1692             || [istarget pj*-*-*]
1693             || [istarget alpha-*-*]
1694             || [istarget hppa*64-*-*]
1695             || [istarget i370-*-*]
1696             || [istarget i860-*-*]
1697             || [istarget ia64-*-*]
1698             || [istarget mep-*-*]
1699             || [istarget mn10200-*-*] } {
1700             set gc_sections_available_saved 0
1701             return 0
1702         }
1703
1704         # elf2flt uses -q (--emit-relocs), which is incompatible with
1705         # --gc-sections.
1706         if { [board_info target exists ldflags]
1707              && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1708             set gc_sections_available_saved 0
1709             return 0
1710         }
1711
1712         # Check if the ld used by gcc supports --gc-sections.
1713         # FIXME: this test is useless since ld --help always says
1714         # --gc-sections is available
1715         set ld_output [remote_exec host $ld "--help"]
1716         if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1717             set gc_sections_available_saved 1
1718         } else {
1719             set gc_sections_available_saved 0
1720         }
1721     }
1722     return $gc_sections_available_saved
1723 }
1724
1725 # Returns true if -shared is supported on the target
1726 # Only used and accurate for ELF targets at the moment
1727
1728 proc check_shared_lib_support { } {
1729     if {![istarget aarch64*-*-elf]
1730          && ![istarget arc*-*-elf*]
1731          && ![istarget arm*-*-elf]
1732          && ![istarget avr-*-*]
1733          && ![istarget cr16-*-*]
1734          && ![istarget cris*-*-elf]
1735          && ![istarget crx-*-*]
1736          && ![istarget d10v-*-*]
1737          && ![istarget d30v-*-*]
1738          && ![istarget dlx-*-*]
1739          && ![istarget epiphany-*-*]
1740          && ![istarget fr30-*-*]
1741          && ![istarget frv-*-*]
1742          && ![istarget ft32-*-*]
1743          && ![istarget h8300-*-*]
1744          && ![istarget i860-*-*]
1745          && ![istarget i960-*-*]
1746          && ![istarget ip2k-*-*]
1747          && ![istarget iq2000-*-*]
1748          && ![istarget lm32-*-*]
1749          && ![istarget m32c-*-*]
1750          && ![istarget m32r-*-*]
1751          && ![istarget m6811-*-*]
1752          && ![istarget m6812-*-*]
1753          && ![istarget m68hc1*-*-*]
1754          && ![istarget mcore*-*-*]
1755          && ![istarget mep-*-*]
1756          && ![istarget microblaze-*-*]
1757          && ![istarget mips*-*-elf]
1758          && ![istarget mn10200-*-*]
1759          && ![istarget moxie-*-*]
1760          && ![istarget msp430-*-*]
1761          && ![istarget mt-*-*]
1762          && ![istarget nds32*-*-*]
1763          && ![istarget or1k*-*-*]
1764          && ![istarget pj-*-*]
1765          && ![istarget rl78-*-*]
1766          && ![istarget rx-*-*]
1767          && ![istarget spu-*-*]
1768          && ![istarget v850*-*-*]
1769          && ![istarget visium-*-*]
1770          && ![istarget xgate-*-*]
1771          && ![istarget xstormy16-*-*]
1772          && ![istarget *-*-irix*]
1773          && ![istarget *-*-rtems] } {
1774         return 1
1775     }
1776     return 0
1777 }
1778
1779 # Returns true if the target ld supports the plugin API.
1780 proc check_plugin_api_available { } {
1781     global plugin_api_available_saved
1782     global ld
1783     if {![info exists plugin_api_available_saved]} {
1784         # Check if the ld used by gcc supports --plugin.
1785         set ld_output [remote_exec host $ld "--help"]
1786         if { [ string first "-plugin PLUGIN" $ld_output ] >= 0 } {
1787             set plugin_api_available_saved 1
1788         } else {
1789             set plugin_api_available_saved 0
1790         }
1791     }
1792     return $plugin_api_available_saved
1793 }
1794
1795 # Sets ld_sysroot to the current sysroot (empty if not supported) and
1796 # returns true if the target ld supports sysroot.
1797 proc check_sysroot_available { } {
1798     global ld_sysroot_available_saved ld ld_sysroot
1799     if {![info exists ld_sysroot_available_saved]} {
1800         # Check if ld supports --sysroot *other* than empty.
1801         set ld_sysroot [string trimright [lindex [remote_exec host $ld "--print-sysroot"] 1]]
1802         if { $ld_sysroot == "" } {
1803             set ld_sysroot_available_saved 0
1804         } else {
1805             set ld_sysroot_available_saved 1
1806         }
1807     }
1808     return $ld_sysroot_available_saved
1809 }
1810
1811 # Returns true if the target compiler supports LTO
1812 proc check_lto_available { } {
1813     global lto_available_saved
1814     global CC
1815
1816     if {![info exists lto_available_saved]} {
1817         if { [which $CC] == 0 } {
1818             set lto_available_saved 0
1819             return 0
1820         }
1821         # This test will hide LTO bugs in ld.  Since GCC 4.9 adds
1822         # -ffat-lto-objects, we always run LTO tests on Linux with
1823         # GCC 4.9 or newer.
1824         if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1825             set lto_available_saved 1
1826             return 1
1827         }
1828         # Check if gcc supports -flto -fuse-linker-plugin
1829         set flags ""
1830         if [board_info [target_info name] exists cflags] {
1831             append flags " [board_info [target_info name] cflags]"
1832         }
1833         if [board_info [target_info name] exists ldflags] {
1834             append flags " [board_info [target_info name] ldflags]"
1835         }
1836
1837         set basename "tmpdir/lto[pid]"
1838         set src ${basename}.c
1839         set output ${basename}.out
1840         set f [open $src "w"]
1841         puts $f "int main() { return 0; }"
1842         close $f
1843         if [is_remote host] {
1844             set src [remote_download host $src]
1845         }
1846         set lto_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -fuse-linker-plugin $src -o $output"]
1847         remote_file host delete $src
1848         remote_file host delete $output
1849         file delete $src
1850     }
1851     return $lto_available_saved
1852 }
1853
1854 # Returns true if the target compiler supports LTO  -ffat-lto-objects
1855 proc check_lto_fat_available { } {
1856     global lto_fat_available_saved
1857     global CC
1858
1859     if {![info exists lto_fat_available_saved]} {
1860         if { [which $CC] == 0 } {
1861             set lto_fat_available_saved 0
1862             return 0
1863         }
1864         # This test will hide LTO bugs in ld.  Since GCC 4.9 adds
1865         # -ffat-lto-objects, we always run LTO tests on Linux with
1866         # GCC 4.9 or newer.
1867         if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1868             set lto_fat_available_saved 1
1869             return 1
1870         }
1871         # Check if gcc supports -flto -fuse-linker-plugin
1872         set flags ""
1873         if [board_info [target_info name] exists cflags] {
1874             append flags " [board_info [target_info name] cflags]"
1875         }
1876         if [board_info [target_info name] exists ldflags] {
1877             append flags " [board_info [target_info name] ldflags]"
1878         }
1879
1880         set basename "tmpdir/lto[pid]"
1881         set src ${basename}.c
1882         set output ${basename}.out
1883         set f [open $src "w"]
1884         puts $f "int main() { return 0; }"
1885         close $f
1886         if [is_remote host] {
1887             set src [remote_download host $src]
1888         }
1889         set lto_fat_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -ffat-lto-objects -fuse-linker-plugin $src -o $output"]
1890         remote_file host delete $src
1891         remote_file host delete $output
1892         file delete $src
1893     }
1894     return $lto_fat_available_saved
1895 }
1896
1897 # Returns true if the target compiler supports LTO and -shared
1898 proc check_lto_shared_available { } {
1899     global lto_shared_available_saved
1900     global CC
1901
1902     if {![info exists lto_shared_available_saved]} {
1903         if { [which $CC] == 0 } {
1904             set lto_shared_available_saved 0
1905             return 0
1906         }
1907         # This test will hide LTO bugs in ld.  Since GCC 4.9 adds
1908         # -ffat-lto-objects, we always run LTO tests on Linux with
1909         # GCC 4.9 or newer.
1910         if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1911             set lto_shared_available_saved 1
1912             return 1
1913         }
1914         # Check if gcc supports -flto -fuse-linker-plugin -shared
1915         set flags ""
1916         if [board_info [target_info name] exists cflags] {
1917             append flags " [board_info [target_info name] cflags]"
1918         }
1919         if [board_info [target_info name] exists ldflags] {
1920             append flags " [board_info [target_info name] ldflags]"
1921         }
1922
1923         set basename "tmpdir/lto_shared[pid]"
1924         set src ${basename}.c
1925         set output ${basename}.so
1926         set f [open $src "w"]
1927         puts $f ""
1928         close $f
1929         if [is_remote host] {
1930             set src [remote_download host $src]
1931         }
1932         set lto_shared_available_saved [run_host_cmd_yesno "$CC" "$flags -shared -fPIC -flto -fuse-linker-plugin $src -o $output"]
1933         remote_file host delete $src
1934         remote_file host delete $output
1935         file delete $src
1936     }
1937     return $lto_shared_available_saved
1938 }
1939
1940 # Check if the assembler supports CFI statements.
1941
1942 proc check_as_cfi { } {
1943     global check_as_cfi_result
1944     global as
1945     if [info exists check_as_cfi_result] {
1946         return $check_as_cfi_result
1947     }
1948     set as_file "tmpdir/check_as_cfi.s"
1949     set as_fh [open $as_file w 0666]
1950     puts $as_fh "# Generated file. DO NOT EDIT"
1951     puts $as_fh "\t.cfi_startproc"
1952     puts $as_fh "\t.cfi_endproc"
1953     close $as_fh
1954     remote_download host $as_file
1955     verbose -log "Checking CFI support:"
1956     rename "perror" "check_as_cfi_perror"
1957     proc perror { args } { }
1958     set success [ld_assemble $as $as_file "/dev/null"]
1959     rename "perror" ""
1960     rename "check_as_cfi_perror" "perror"
1961     #remote_file host delete $as_file
1962     set check_as_cfi_result $success
1963     return $success
1964 }
1965
1966 # Returns true if IFUNC works.
1967
1968 proc check_ifunc_available { } {
1969     global ifunc_available_saved
1970     global CC
1971
1972     if {![info exists ifunc_available_saved]} {
1973         if { [which $CC] == 0 } {
1974             set ifunc_available_saved 0
1975             return 0
1976         }
1977         # Check if gcc supports -flto -fuse-linker-plugin
1978         set flags ""
1979         if [board_info [target_info name] exists cflags] {
1980             append flags " [board_info [target_info name] cflags]"
1981         }
1982         if [board_info [target_info name] exists ldflags] {
1983             append flags " [board_info [target_info name] ldflags]"
1984         }
1985
1986         set basename "tmpdir/ifunc[pid]"
1987         set src ${basename}.c
1988         set output ${basename}.out
1989         set f [open $src "w"]
1990         puts $f "extern int library_func2 (void);"
1991         puts $f "int main (void)"
1992         puts $f "{"
1993         puts $f "  if (library_func2 () != 2) __builtin_abort ();"
1994         puts $f "  return 0; "
1995         puts $f "}"
1996         puts $f "static int library_func1 (void) {return 2; }"
1997         puts $f "void *foo (void) __asm__ (\"library_func2\");"
1998         puts $f "void *foo (void) { return library_func1; }"
1999         puts $f "__asm__(\".type library_func2, %gnu_indirect_function\");"
2000         close $f
2001         if [is_remote host] {
2002             set src [remote_download host $src]
2003         }
2004         set ifunc_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
2005         if { $ifunc_available_saved == 1 } {
2006           set ifunc_available_saved [run_host_cmd_yesno "$output" ""]
2007         }
2008         remote_file host delete $src
2009         remote_file host delete $output
2010         file delete $src
2011     }
2012     return $ifunc_available_saved
2013 }
2014
2015 # Returns true if ifunc attribute works.
2016
2017 proc check_ifunc_attribute_available { } {
2018     global ifunc_attribute_available_saved
2019     global CC
2020
2021     if {![info exists ifunc_attribute_available_saved]} {
2022         if { [which $CC] == 0 } {
2023             set ifunc_attribute_available_saved 0
2024             return 0
2025         }
2026         # Check if gcc supports -flto -fuse-linker-plugin
2027         set flags ""
2028         if [board_info [target_info name] exists cflags] {
2029             append flags " [board_info [target_info name] cflags]"
2030         }
2031         if [board_info [target_info name] exists ldflags] {
2032             append flags " [board_info [target_info name] ldflags]"
2033         }
2034
2035         set basename "tmpdir/ifunc[pid]"
2036         set src ${basename}.c
2037         set output ${basename}.out
2038         set f [open $src "w"]
2039         puts $f "extern int library_func2 (void) __attribute__ ((ifunc (\"foo\")));"
2040         puts $f "int main (void)"
2041         puts $f "{"
2042         puts $f "  if (library_func2 () != 2) __builtin_abort ();"
2043         puts $f "  return 0; "
2044         puts $f "}"
2045         puts $f "static int library_func1 (void) {return 2; }"
2046         puts $f "void *foo (void) { return library_func1; }"
2047         close $f
2048         if [is_remote host] {
2049             set src [remote_download host $src]
2050         }
2051         set ifunc_attribute_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
2052         if { $ifunc_attribute_available_saved == 1 } {
2053           set ifunc_attribute_available_saved [run_host_cmd_yesno "$output" ""]
2054         }
2055         remote_file host delete $src
2056         remote_file host delete $output
2057         file delete $src
2058     }
2059     return $ifunc_attribute_available_saved
2060 }
2061
2062 # Provide virtual target "cfi" for targets supporting CFI.
2063
2064 rename "istarget" "istarget_ld"
2065 proc istarget { target } {
2066     if {$target == "cfi"} {
2067         return [check_as_cfi]
2068     }
2069     return [istarget_ld $target]
2070 }