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