]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - ld/testsuite/lib/ld-lib.exp
Applied patch series for LD plugin interface (six parts).
[thirdparty/binutils-gdb.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 # PowerPC EABI code calls __eabi.
373 if {[istarget powerpc*-*-eabi*] || [istarget powerpc*-*-rtems*]} {
374 append flags " --defsym __eabi=0"
375 }
376
377 # mn10200 code calls __truncsipsi2_d0_d2.
378 if {[istarget mn10200*-*-*]} then {
379 append flags " --defsym __truncsipsi2_d0_d2=0"
380 }
381
382 # m6811/m6812 code has references to soft registers.
383 if {[istarget m6811-*-*] || [istarget m6812-*-*]} {
384 append flags " --defsym _.frame=0 --defsym _.d1=0 --defsym _.d2=0"
385 append flags " --defsym _.d3=0 --defsym _.d4=0"
386 append flags " --defsym _.tmp=0 --defsym _.xy=0 --defsym _.z=0"
387 }
388
389 # Some OpenBSD targets have ProPolice and reference __guard and
390 # __stack_smash_handler.
391 if [istarget *-*-openbsd*] {
392 append flags " --defsym __guard=0"
393 append flags " --defsym __stack_smash_handler=0"
394 }
395
396 return $flags
397 }
398
399 # True if the object format is known to be ELF.
400 #
401 proc is_elf_format {} {
402 if { ![istarget *-*-sysv4*]
403 && ![istarget *-*-unixware*]
404 && ![istarget *-*-elf*]
405 && ![istarget *-*-eabi*]
406 && ![istarget *-*-rtems*]
407 && ![istarget hppa*64*-*-hpux*]
408 && ![istarget ia64-*-hpux*]
409 && ![istarget *-*-linux*]
410 && ![istarget frv-*-uclinux*]
411 && ![istarget bfin-*-uclinux]
412 && ![istarget sh*-*-uclinux*]
413 && ![istarget *-*-irix5*]
414 && ![istarget *-*-irix6*]
415 && ![istarget *-*-netbsd*]
416 && ![istarget *-*-openbsd*]
417 && ![istarget *-*-solaris2*] } {
418 return 0
419 }
420
421 if { [istarget *-*-linux*aout*]
422 || [istarget *-*-linux*oldld*]
423 || [istarget h8500-*-rtems*]
424 || [istarget i960-*-rtems*]
425 || [istarget *-*-rtemscoff*] } {
426 return 0
427 }
428
429 if { ![istarget *-*-netbsdelf*]
430 && ([istarget *-*-netbsd*aout*]
431 || [istarget *-*-netbsdpe*]
432 || [istarget arm*-*-netbsd*]
433 || [istarget sparc-*-netbsd*]
434 || [istarget i*86-*-netbsd*]
435 || [istarget m68*-*-netbsd*]
436 || [istarget vax-*-netbsd*]
437 || [istarget ns32k-*-netbsd*]) } {
438 return 0
439 }
440
441 if { [istarget arm-*-openbsd*]
442 || [istarget i386-*-openbsd\[0-2\].*]
443 || [istarget i386-*-openbsd3.\[0-2\]]
444 || [istarget m68*-*-openbsd*]
445 || [istarget ns32k-*-openbsd*]
446 || [istarget sparc-*-openbsd\[0-2\].*]
447 || [istarget sparc-*-openbsd3.\[0-1\]]
448 || [istarget vax-*-openbsd*] } {
449 return 0
450 }
451
452 return 1
453 }
454
455 # True if the object format is known to be 64-bit ELF.
456 #
457 proc is_elf64 { binary_file } {
458 global READELF
459 global READELFFLAGS
460
461 set readelf_size ""
462 catch "exec $READELF $READELFFLAGS -h $binary_file > readelf.out" got
463
464 if ![string match "" $got] then {
465 return 0
466 }
467
468 if { ![regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \
469 [file_contents readelf.out] nil readelf_size] } {
470 return 0
471 }
472
473 if { $readelf_size == "64" } {
474 return 1
475 }
476
477 return 0
478 }
479
480 # True if the object format is known to be a.out.
481 #
482 proc is_aout_format {} {
483 if { [istarget *-*-netbsdelf]
484 || [istarget sparc64-*-netbsd*]
485 || [istarget sparc64-*-openbsd*] } {
486 return 0
487 }
488 if { [istarget *-*-*\[ab\]out*]
489 || [istarget *-*-linux*oldld*]
490 || [istarget *-*-bsd*]
491 || [istarget *-*-msdos*]
492 || [istarget arm-*-netbsd*]
493 || [istarget arm-*-openbsd*]
494 || [istarget arm-*-riscix*]
495 || [istarget i?86-*-freebsd\[12\]*]
496 || [istarget i?86-*-netbsd*]
497 || [istarget i?86-*-openbsd\[0-2\]*]
498 || [istarget i?86-*-openbsd3.\[0-2\]*]
499 || [istarget i?86-*-vsta]
500 || [istarget i?86-*-mach*]
501 || [istarget m68*-*-netbsd*]
502 || [istarget m68*-*-openbsd*]
503 || [istarget ns32k-*-*]
504 || [istarget pdp11-*-*]
505 || [istarget sparc*-*-sunos4*]
506 || [istarget sparc*-*-netbsd*]
507 || [istarget sparc*-*-openbsd\[0-2\]*]
508 || [istarget sparc*-*-openbsd3.\[0-1\]*]
509 || [istarget sparc*-fujitsu-none]
510 || [istarget vax-dec-ultrix*]
511 || [istarget vax-*-netbsd] } {
512 return 1
513 }
514 return 0
515 }
516
517 # True if the object format is known to be PE COFF.
518 #
519 proc is_pecoff_format {} {
520 if { ![istarget *-*-mingw*]
521 && ![istarget *-*-cygwin*]
522 && ![istarget *-*-cegcc*]
523 && ![istarget *-*-pe*] } {
524 return 0
525 }
526
527 return 1
528 }
529
530 # Compares two files line-by-line.
531 # Returns differences if exist.
532 # Returns null if file(s) cannot be opened.
533 #
534 proc simple_diff { file_1 file_2 } {
535 global target
536
537 set eof -1
538 set differences 0
539
540 if [file exists $file_1] then {
541 set file_a [open $file_1 r]
542 } else {
543 warning "$file_1 doesn't exist"
544 return
545 }
546
547 if [file exists $file_2] then {
548 set file_b [open $file_2 r]
549 } else {
550 fail "$file_2 doesn't exist"
551 return
552 }
553
554 verbose "# Diff'ing: $file_1 $file_2\n" 2
555
556 while { [gets $file_a line] != $eof } {
557 if [regexp "^#.*$" $line] then {
558 continue
559 } else {
560 lappend list_a $line
561 }
562 }
563 close $file_a
564
565 while { [gets $file_b line] != $eof } {
566 if [regexp "^#.*$" $line] then {
567 continue
568 } else {
569 lappend list_b $line
570 }
571 }
572 close $file_b
573
574 for { set i 0 } { $i < [llength $list_a] } { incr i } {
575 set line_a [lindex $list_a $i]
576 set line_b [lindex $list_b $i]
577
578 verbose "\t$file_1: $i: $line_a\n" 3
579 verbose "\t$file_2: $i: $line_b\n" 3
580 if [string compare $line_a $line_b] then {
581 verbose -log "\t$file_1: $i: $line_a\n"
582 verbose -log "\t$file_2: $i: $line_b\n"
583
584 fail "Test: $target"
585 return
586 }
587 }
588
589 if { [llength $list_a] != [llength $list_b] } {
590 fail "Test: $target"
591 return
592 }
593
594 if $differences<1 then {
595 pass "Test: $target"
596 }
597 }
598
599 # run_dump_test FILE
600 # Copied from gas testsuite, tweaked and further extended.
601 #
602 # Assemble a .s file, then run some utility on it and check the output.
603 #
604 # There should be an assembly language file named FILE.s in the test
605 # suite directory, and a pattern file called FILE.d. `run_dump_test'
606 # will assemble FILE.s, run some tool like `objdump', `objcopy', or
607 # `nm' on the .o file to produce textual output, and then analyze that
608 # with regexps. The FILE.d file specifies what program to run, and
609 # what to expect in its output.
610 #
611 # The FILE.d file begins with zero or more option lines, which specify
612 # flags to pass to the assembler, the program to run to dump the
613 # assembler's output, and the options it wants. The option lines have
614 # the syntax:
615 #
616 # # OPTION: VALUE
617 #
618 # OPTION is the name of some option, like "name" or "objdump", and
619 # VALUE is OPTION's value. The valid options are described below.
620 # Whitespace is ignored everywhere, except within VALUE. The option
621 # list ends with the first line that doesn't match the above syntax
622 # (hmm, not great for error detection).
623 #
624 # The interesting options are:
625 #
626 # name: TEST-NAME
627 # The name of this test, passed to DejaGNU's `pass' and `fail'
628 # commands. If omitted, this defaults to FILE, the root of the
629 # .s and .d files' names.
630 #
631 # as: FLAGS
632 # When assembling, pass FLAGS to the assembler.
633 # If assembling several files, you can pass different assembler
634 # options in the "source" directives. See below.
635 #
636 # ld: FLAGS
637 # Link assembled files using FLAGS, in the order of the "source"
638 # directives, when using multiple files.
639 #
640 # ld_after_inputfiles: FLAGS
641 # Similar to "ld", but put after all input files.
642 #
643 # objcopy_linked_file: FLAGS
644 # Run objcopy on the linked file with the specified flags.
645 # This lets you transform the linked file using objcopy, before the
646 # result is analyzed by an analyzer program specified below (which
647 # may in turn *also* be objcopy).
648 #
649 # PROG: PROGRAM-NAME
650 # The name of the program to run to analyze the .o file produced
651 # by the assembler or the linker output. This can be omitted;
652 # run_dump_test will guess which program to run by seeing which of
653 # the flags options below is present.
654 #
655 # objdump: FLAGS
656 # nm: FLAGS
657 # objcopy: FLAGS
658 # Use the specified program to analyze the assembler or linker
659 # output file, and pass it FLAGS, in addition to the output name.
660 # Note that they are run with LC_ALL=C in the environment to give
661 # consistent sorting of symbols.
662 #
663 # source: SOURCE [FLAGS]
664 # Assemble the file SOURCE.s using the flags in the "as" directive
665 # and the (optional) FLAGS. If omitted, the source defaults to
666 # FILE.s.
667 # This is useful if several .d files want to share a .s file.
668 # More than one "source" directive can be given, which is useful
669 # when testing linking.
670 #
671 # xfail: TARGET
672 # The test is expected to fail on TARGET. This may occur more than
673 # once.
674 #
675 # target: TARGET
676 # Only run the test for TARGET. This may occur more than once; the
677 # target being tested must match at least one. You may provide target
678 # name "cfi" for any target supporting the CFI statements.
679 #
680 # notarget: TARGET
681 # Do not run the test for TARGET. This may occur more than once;
682 # the target being tested must not match any of them.
683 #
684 # error: REGEX
685 # An error with message matching REGEX must be emitted for the test
686 # to pass. The PROG, objdump, nm and objcopy options have no
687 # meaning and need not supplied if this is present. Multiple "error"
688 # directives append to the expected linker error message.
689 #
690 # warning: REGEX
691 # Expect a linker warning matching REGEX. It is an error to issue
692 # both "error" and "warning". Multiple "warning" directives
693 # append to the expected linker warning message.
694 #
695 # Each option may occur at most once unless otherwise mentioned.
696 #
697 # After the option lines come regexp lines. `run_dump_test' calls
698 # `regexp_diff' to compare the output of the dumping tool against the
699 # regexps in FILE.d. `regexp_diff' is defined later in this file; see
700 # further comments there.
701 #
702 proc run_dump_test { name } {
703 global subdir srcdir
704 global OBJDUMP NM AS OBJCOPY READELF LD
705 global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
706 global host_triplet runtests
707 global env verbose
708
709 if [string match "*/*" $name] {
710 set file $name
711 set name [file tail $name]
712 } else {
713 set file "$srcdir/$subdir/$name"
714 }
715
716 if ![runtest_file_p $runtests $name] then {
717 return
718 }
719
720 set opt_array [slurp_options "${file}.d"]
721 if { $opt_array == -1 } {
722 perror "error reading options from $file.d"
723 unresolved $subdir/$name
724 return
725 }
726 set dumpfile tmpdir/dump.out
727 set run_ld 0
728 set run_objcopy 0
729 set opts(as) {}
730 set opts(ld) {}
731 set opts(ld_after_inputfiles) {}
732 set opts(xfail) {}
733 set opts(target) {}
734 set opts(notarget) {}
735 set opts(objdump) {}
736 set opts(nm) {}
737 set opts(objcopy) {}
738 set opts(readelf) {}
739 set opts(name) {}
740 set opts(PROG) {}
741 set opts(source) {}
742 set opts(error) {}
743 set opts(warning) {}
744 set opts(objcopy_linked_file) {}
745 set asflags(${file}.s) {}
746
747 foreach i $opt_array {
748 set opt_name [lindex $i 0]
749 set opt_val [lindex $i 1]
750 if ![info exists opts($opt_name)] {
751 perror "unknown option $opt_name in file $file.d"
752 unresolved $subdir/$name
753 return
754 }
755
756 switch -- $opt_name {
757 xfail {}
758 target {}
759 notarget {}
760 warning {}
761 error {}
762 source {
763 # Move any source-specific as-flags to a separate array to
764 # simplify processing.
765 if { [llength $opt_val] > 1 } {
766 set asflags([lindex $opt_val 0]) [lrange $opt_val 1 end]
767 set opt_val [lindex $opt_val 0]
768 } else {
769 set asflags($opt_val) {}
770 }
771 }
772 default {
773 if [string length $opts($opt_name)] {
774 perror "option $opt_name multiply set in $file.d"
775 unresolved $subdir/$name
776 return
777 }
778
779 # A single "# ld:" with no options should do the right thing.
780 if { $opt_name == "ld" } {
781 set run_ld 1
782 }
783 # Likewise objcopy_linked_file.
784 if { $opt_name == "objcopy_linked_file" } {
785 set run_objcopy 1
786 }
787 }
788 }
789 if { $opt_name == "as" || $opt_name == "ld" } {
790 set opt_val [subst $opt_val]
791 }
792 set opts($opt_name) [concat $opts($opt_name) $opt_val]
793 }
794 foreach opt { as ld } {
795 regsub {\[big_or_little_endian\]} $opts($opt) \
796 [big_or_little_endian] opts($opt)
797 }
798
799 # Decide early whether we should run the test for this target.
800 if { [llength $opts(target)] > 0 } {
801 set targmatch 0
802 foreach targ $opts(target) {
803 if [istarget $targ] {
804 set targmatch 1
805 break
806 }
807 }
808 if { $targmatch == 0 } {
809 return
810 }
811 }
812 foreach targ $opts(notarget) {
813 if [istarget $targ] {
814 return
815 }
816 }
817
818 set program ""
819 # It's meaningless to require an output-testing method when we
820 # expect an error.
821 if { $opts(error) == "" } {
822 if {$opts(PROG) != ""} {
823 switch -- $opts(PROG) {
824 objdump { set program objdump }
825 nm { set program nm }
826 objcopy { set program objcopy }
827 readelf { set program readelf }
828 default
829 { perror "unrecognized program option $opts(PROG) in $file.d"
830 unresolved $subdir/$name
831 return }
832 }
833 } else {
834 # Guess which program to run, by seeing which option was specified.
835 foreach p {objdump objcopy nm readelf} {
836 if {$opts($p) != ""} {
837 if {$program != ""} {
838 perror "ambiguous dump program in $file.d"
839 unresolved $subdir/$name
840 return
841 } else {
842 set program $p
843 }
844 }
845 }
846 }
847 if { $program == "" && $opts(warning) == "" } {
848 perror "dump program unspecified in $file.d"
849 unresolved $subdir/$name
850 return
851 }
852 }
853
854 if { $opts(name) == "" } {
855 set testname "$subdir/$name"
856 } else {
857 set testname $opts(name)
858 }
859
860 if { $opts(source) == "" } {
861 set sourcefiles [list ${file}.s]
862 } else {
863 set sourcefiles {}
864 foreach sf $opts(source) {
865 if { [string match "/*" $sf] } {
866 lappend sourcefiles "$sf"
867 } else {
868 lappend sourcefiles "$srcdir/$subdir/$sf"
869 }
870 # Must have asflags indexed on source name.
871 set asflags($srcdir/$subdir/$sf) $asflags($sf)
872 }
873 }
874
875 # Time to setup xfailures.
876 foreach targ $opts(xfail) {
877 setup_xfail $targ
878 }
879
880 # Assemble each file.
881 set objfiles {}
882 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
883 set sourcefile [lindex $sourcefiles $i]
884
885 set objfile "tmpdir/dump$i.o"
886 catch "exec rm -f $objfile" exec_output
887 lappend objfiles $objfile
888 set cmd "$AS $ASFLAGS $opts(as) $asflags($sourcefile) -o $objfile $sourcefile"
889
890 send_log "$cmd\n"
891 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
892 remote_upload host "ld.tmp"
893 set comp_output [prune_warnings [file_contents "ld.tmp"]]
894 remote_file host delete "ld.tmp"
895 remote_file build delete "ld.tmp"
896
897 if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
898 send_log "$comp_output\n"
899 verbose "$comp_output" 3
900
901 set exitstat "succeeded"
902 if { $cmdret != 0 } { set exitstat "failed" }
903 verbose -log "$exitstat with: <$comp_output>"
904 fail $testname
905 return
906 }
907 }
908
909 set expmsg $opts(error)
910 if { $opts(warning) != "" } {
911 if { $expmsg != "" } {
912 perror "$testname: mixing error and warning test-directives"
913 return
914 }
915 set expmsg $opts(warning)
916 }
917
918 # Perhaps link the file(s).
919 if { $run_ld } {
920 set objfile "tmpdir/dump"
921 catch "exec rm -f $objfile" exec_output
922
923 # Add -L$srcdir/$subdir so that the linker command can use
924 # linker scripts in the source directory.
925 set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
926 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
927
928 send_log "$cmd\n"
929 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
930 remote_upload host "ld.tmp"
931 set comp_output [file_contents "ld.tmp"]
932 remote_file host delete "ld.tmp"
933 remote_file build delete "ld.tmp"
934 set cmdret [lindex $cmdret 0]
935
936 if { $cmdret == 0 && $run_objcopy } {
937 set infile $objfile
938 set objfile "tmpdir/dump1"
939 remote_file host delete $objfile
940
941 # Note that we don't use OBJCOPYFLAGS here; any flags must be
942 # explicitly specified.
943 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
944
945 send_log "$cmd\n"
946 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
947 remote_upload host "ld.tmp"
948 append comp_output [file_contents "ld.tmp"]
949 remote_file host delete "ld.tmp"
950 remote_file build delete "ld.tmp"
951 set cmdret [lindex $cmdret 0]
952 }
953
954 regsub "\n$" $comp_output "" comp_output
955 if { $cmdret != 0 || $comp_output != "" || $expmsg != "" } then {
956 set exitstat "succeeded"
957 if { $cmdret != 0 } { set exitstat "failed" }
958 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
959 send_log "$comp_output\n"
960 verbose "$comp_output" 3
961
962 if { ($expmsg == "") == ($comp_output == "") \
963 && [regexp $expmsg $comp_output] \
964 && (($cmdret == 0) == ($opts(error) == "")) } {
965 # We have the expected output from ld.
966 if { $opts(error) != "" || $program == "" } {
967 pass $testname
968 return
969 }
970 } else {
971 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
972 fail $testname
973 return
974 }
975 }
976 } else {
977 set objfile "tmpdir/dump0.o"
978 }
979
980 # We must not have expected failure if we get here.
981 if { $opts(error) != "" } {
982 fail $testname
983 return
984 }
985
986 set progopts1 $opts($program)
987 eval set progopts \$[string toupper $program]FLAGS
988 eval set binary \$[string toupper $program]
989
990 if { ![is_remote host] && [which $binary] == 0 } {
991 untested $testname
992 return
993 }
994
995 if { $progopts1 == "" } { set $progopts1 "-r" }
996 verbose "running $binary $progopts $progopts1" 3
997
998 # Objcopy, unlike the other two, won't send its output to stdout,
999 # so we have to run it specially.
1000 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
1001 if { $program == "objcopy" } {
1002 set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
1003 }
1004
1005 # Ensure consistent sorting of symbols
1006 if {[info exists env(LC_ALL)]} {
1007 set old_lc_all $env(LC_ALL)
1008 }
1009 set env(LC_ALL) "C"
1010 send_log "$cmd\n"
1011 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
1012 set cmdret [lindex $cmdret 0]
1013 remote_upload host "ld.tmp"
1014 set comp_output [prune_warnings [file_contents "ld.tmp"]]
1015 remote_file host delete "ld.tmp"
1016 remote_file build delete "ld.tmp"
1017 if {[info exists old_lc_all]} {
1018 set env(LC_ALL) $old_lc_all
1019 } else {
1020 unset env(LC_ALL)
1021 }
1022 if { $cmdret != 0 || $comp_output != "" } {
1023 send_log "exited abnormally with $cmdret, output:$comp_output\n"
1024 fail $testname
1025 return
1026 }
1027
1028 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
1029 if { [regexp_diff $dumpfile "${file}.d"] } then {
1030 fail $testname
1031 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
1032 return
1033 }
1034
1035 pass $testname
1036 }
1037
1038 proc slurp_options { file } {
1039 if [catch { set f [open $file r] } x] {
1040 #perror "couldn't open `$file': $x"
1041 perror "$x"
1042 return -1
1043 }
1044 set opt_array {}
1045 # whitespace expression
1046 set ws {[ ]*}
1047 set nws {[^ ]*}
1048 # whitespace is ignored anywhere except within the options list;
1049 # option names are alphabetic plus underscore only.
1050 set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
1051 while { [gets $f line] != -1 } {
1052 set line [string trim $line]
1053 # Whitespace here is space-tab.
1054 if [regexp $pat $line xxx opt_name opt_val] {
1055 # match!
1056 lappend opt_array [list $opt_name $opt_val]
1057 } else {
1058 break
1059 }
1060 }
1061 close $f
1062 return $opt_array
1063 }
1064
1065 # regexp_diff, copied from gas, based on simple_diff above.
1066 # compares two files line-by-line
1067 # file1 contains strings, file2 contains regexps and #-comments
1068 # blank lines are ignored in either file
1069 # returns non-zero if differences exist
1070 #
1071 proc regexp_diff { file_1 file_2 } {
1072
1073 set eof -1
1074 set end_1 0
1075 set end_2 0
1076 set differences 0
1077 set diff_pass 0
1078 set fail_if_match 0
1079
1080 if [file exists $file_1] then {
1081 set file_a [open $file_1 r]
1082 } else {
1083 warning "$file_1 doesn't exist"
1084 return 1
1085 }
1086
1087 if [file exists $file_2] then {
1088 set file_b [open $file_2 r]
1089 } else {
1090 fail "$file_2 doesn't exist"
1091 close $file_a
1092 return 1
1093 }
1094
1095 verbose " Regexp-diff'ing: $file_1 $file_2" 2
1096
1097 while { 1 } {
1098 set line_a ""
1099 set line_b ""
1100 while { [string length $line_a] == 0 } {
1101 if { [gets $file_a line_a] == $eof } {
1102 set end_1 1
1103 break
1104 }
1105 }
1106 while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
1107 if [ string match "#pass" $line_b ] {
1108 set end_2 1
1109 set diff_pass 1
1110 break
1111 } elseif [ string match "#failif" $line_b ] {
1112 send_log "fail if no difference\n"
1113 verbose "fail if no difference" 3
1114 set fail_if_match 1
1115 } elseif [ string match "#..." $line_b ] {
1116 if { [gets $file_b line_b] == $eof } {
1117 set end_2 1
1118 set diff_pass 1
1119 break
1120 }
1121 verbose "looking for \"^$line_b$\"" 3
1122 while { ![regexp "^$line_b$" "$line_a"] } {
1123 verbose "skipping \"$line_a\"" 3
1124 if { [gets $file_a line_a] == $eof } {
1125 set end_1 1
1126 break
1127 }
1128 }
1129 break
1130 }
1131 if { [gets $file_b line_b] == $eof } {
1132 set end_2 1
1133 break
1134 }
1135 }
1136
1137 if { $diff_pass } {
1138 break
1139 } elseif { $end_1 && $end_2 } {
1140 break
1141 } elseif { $end_1 } {
1142 send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
1143 verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
1144 set differences 1
1145 break
1146 } elseif { $end_2 } {
1147 send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
1148 verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
1149 set differences 1
1150 break
1151 } else {
1152 verbose "regexp \"^$line_b$\"\nline \"$line_a\"" 3
1153 if ![regexp "^$line_b$" "$line_a"] {
1154 verbose "regexp_diff match failure\n" 3
1155 send_log "regexp_diff match failure\n"
1156 send_log "regexp \"^$line_b$\"\nline \"$line_a\"\n"
1157 set differences 1
1158 }
1159 }
1160 }
1161
1162 if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
1163 send_log "$file_1 and $file_2 are different lengths\n"
1164 verbose "$file_1 and $file_2 are different lengths" 3
1165 set differences 1
1166 }
1167
1168 if { $fail_if_match } {
1169 if { $differences == 0 } {
1170 set differences 1
1171 } else {
1172 set differences 0
1173 }
1174 }
1175
1176 close $file_a
1177 close $file_b
1178
1179 return $differences
1180 }
1181
1182 proc file_contents { filename } {
1183 set file [open $filename r]
1184 set contents [read $file]
1185 close $file
1186 return $contents
1187 }
1188
1189 proc set_file_contents { filename contents } {
1190 set file [open $filename w]
1191 puts $file "$contents"
1192 close $file
1193 }
1194
1195 # Create an archive using ar
1196 #
1197 proc ar_simple_create { ar aropts target objects } {
1198 remote_file host delete $target
1199
1200 set exec_output [run_host_cmd "$ar" "$aropts rc $target $objects"]
1201 set exec_output [prune_warnings $exec_output]
1202
1203 if [string match "" $exec_output] then {
1204 send_log "$exec_output\n"
1205 return 1
1206 } else {
1207 return 0
1208 }
1209 }
1210
1211 # List contains test-items with 3 items followed by 2 lists, one item and
1212 # one optional item:
1213 # 0:name 1:ld/ar options 2:assembler options
1214 # 3:filenames of assembler files 4: action and options. 5: name of output file
1215 # 6:compiler flags (optional)
1216 #
1217 # Actions:
1218 # objdump: Apply objdump options on result. Compare with regex (last arg).
1219 # nm: Apply nm options on result. Compare with regex (last arg).
1220 # readelf: Apply readelf options on result. Compare with regex (last arg).
1221 # ld: Don't apply anything on result. Compare output during linking with
1222 # regex (second arg). Note that this *must* be the first action if it
1223 # is to be used at all; in all other cases, any output from the linker
1224 # during linking is treated as a sign of an error and FAILs the test.
1225 #
1226 proc run_ld_link_tests { ldtests } {
1227 global ld
1228 global as
1229 global nm
1230 global ar
1231 global objdump
1232 global READELF
1233 global srcdir
1234 global subdir
1235 global env
1236 global CC
1237 global CFLAGS
1238 global runtests
1239 global exec_output
1240
1241 foreach testitem $ldtests {
1242 set testname [lindex $testitem 0]
1243
1244 if ![runtest_file_p $runtests $testname] then {
1245 continue
1246 }
1247
1248 set ld_options [lindex $testitem 1]
1249 set as_options [lindex $testitem 2]
1250 set src_files [lindex $testitem 3]
1251 set actions [lindex $testitem 4]
1252 set binfile tmpdir/[lindex $testitem 5]
1253 set cflags [lindex $testitem 6]
1254 set objfiles {}
1255 set is_unresolved 0
1256 set failed 0
1257 set maybe_failed 0
1258 set ld_output ""
1259
1260 # verbose -log "Testname is $testname"
1261 # verbose -log "ld_options is $ld_options"
1262 # verbose -log "as_options is $as_options"
1263 # verbose -log "src_files is $src_files"
1264 # verbose -log "actions is $actions"
1265 # verbose -log "binfile is $binfile"
1266
1267 # Assemble each file in the test.
1268 foreach src_file $src_files {
1269 set objfile "tmpdir/[file rootname $src_file].o"
1270 lappend objfiles $objfile
1271
1272 if { [file extension $src_file] == ".c" } {
1273 set as_file "tmpdir/[file rootname $src_file].s"
1274 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1275 set is_unresolved 1
1276 break
1277 }
1278 } else {
1279 set as_file "$srcdir/$subdir/$src_file"
1280 }
1281 if ![ld_assemble $as "$as_options $as_file" $objfile] {
1282 set is_unresolved 1
1283 break
1284 }
1285 }
1286
1287 # Catch assembler errors.
1288 if { $is_unresolved != 0 } {
1289 unresolved $testname
1290 continue
1291 }
1292
1293 if { [regexp ".*\\.a$" $binfile] } {
1294 if { ![ar_simple_create $ar $ld_options $binfile "$objfiles"] } {
1295 fail $testname
1296 set failed 1
1297 } else {
1298 set failed 0
1299 }
1300 } elseif { ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] } {
1301 set maybe_failed 1
1302 set ld_output "$exec_output"
1303 } else {
1304 set failed 0
1305 }
1306
1307 if { $failed == 0 } {
1308 foreach actionlist $actions {
1309 set action [lindex $actionlist 0]
1310 set progopts [lindex $actionlist 1]
1311
1312 # There are actions where we run regexp_diff on the
1313 # output, and there are other actions (presumably).
1314 # Handling of the former look the same.
1315 set dump_prog ""
1316 switch -- $action {
1317 objdump
1318 { set dump_prog $objdump }
1319 nm
1320 { set dump_prog $nm }
1321 readelf
1322 { set dump_prog $READELF }
1323 ld
1324 { set dump_prog "ld" }
1325 default
1326 {
1327 perror "Unrecognized action $action"
1328 set is_unresolved 1
1329 break
1330 }
1331 }
1332
1333 if { $action == "ld" } {
1334 set dumpfile [lindex $actionlist 1]
1335 verbose "dumpfile is $dumpfile"
1336 set_file_contents "tmpdir/ld.messages" "$ld_output"
1337 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
1338 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$dumpfile"] } then {
1339 verbose "output is $ld_output" 2
1340 set failed 1
1341 break
1342 }
1343 set maybe_failed 0
1344 } elseif { $maybe_failed != 0 } {
1345 set failed 1
1346 break
1347 } elseif { $dump_prog != "" } {
1348 set dumpfile [lindex $actionlist 2]
1349 set binary $dump_prog
1350
1351 # Ensure consistent sorting of symbols
1352 if {[info exists env(LC_ALL)]} {
1353 set old_lc_all $env(LC_ALL)
1354 }
1355 set env(LC_ALL) "C"
1356 set cmd "$binary $progopts $binfile"
1357 set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
1358 send_log "$cmd\n"
1359 remote_upload host "ld.stderr"
1360 set comp_output [prune_warnings [file_contents "ld.stderr"]]
1361 remote_file host delete "ld.stderr"
1362 remote_file build delete "ld.stderr"
1363
1364 if {[info exists old_lc_all]} {
1365 set env(LC_ALL) $old_lc_all
1366 } else {
1367 unset env(LC_ALL)
1368 }
1369
1370 if ![string match "" $comp_output] then {
1371 send_log "$comp_output\n"
1372 set failed 1
1373 break
1374 }
1375
1376 remote_upload host "dump.out"
1377
1378 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1379 verbose "output is [file_contents "dump.out"]" 2
1380 set failed 1
1381 remote_file build delete "dump.out"
1382 remote_file host delete "dump.out"
1383 break
1384 }
1385 remote_file build delete "dump.out"
1386 remote_file host delete "dump.out"
1387 }
1388 }
1389
1390 if { $failed != 0 } {
1391 fail $testname
1392 } else { if { $is_unresolved == 0 } {
1393 pass $testname
1394 } }
1395 }
1396
1397 # Catch action errors.
1398 if { $is_unresolved != 0 } {
1399 unresolved $testname
1400 continue
1401 }
1402 }
1403 }
1404
1405 # This definition is taken from an unreleased version of DejaGnu. Once
1406 # that version gets released, and has been out in the world for a few
1407 # months at least, it may be safe to delete this copy.
1408 if ![string length [info proc prune_warnings]] {
1409 #
1410 # prune_warnings -- delete various system verbosities from TEXT
1411 #
1412 # An example is:
1413 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1414 #
1415 # Sites with particular verbose os's may wish to override this in site.exp.
1416 #
1417 proc prune_warnings { text } {
1418 # This is from sun4's. Do it for all machines for now.
1419 # The "\\1" is to try to preserve a "\n" but only if necessary.
1420 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1421
1422 # It might be tempting to get carried away and delete blank lines, etc.
1423 # Just delete *exactly* what we're ask to, and that's it.
1424 return $text
1425 }
1426 }
1427
1428 # targets_to_xfail is a list of target triplets to be xfailed.
1429 # ldtests contains test-items with 3 items followed by 1 lists, 2 items
1430 # and 3 optional items:
1431 # 0:name
1432 # 1:ld options
1433 # 2:assembler options
1434 # 3:filenames of source files
1435 # 4:name of output file
1436 # 5:expected output
1437 # 6:compiler flags (optional)
1438 # 7:language (optional)
1439 # 8:linker warning (optional)
1440
1441 proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
1442 global ld
1443 global as
1444 global srcdir
1445 global subdir
1446 global env
1447 global CC
1448 global CXX
1449 global CFLAGS
1450 global CXXFLAGS
1451 global errcnt
1452 global exec_output
1453
1454 foreach testitem $ldtests {
1455 foreach target $targets_to_xfail {
1456 setup_xfail $target
1457 }
1458 set testname [lindex $testitem 0]
1459 set ld_options [lindex $testitem 1]
1460 set as_options [lindex $testitem 2]
1461 set src_files [lindex $testitem 3]
1462 set binfile tmpdir/[lindex $testitem 4]
1463 set expfile [lindex $testitem 5]
1464 set cflags [lindex $testitem 6]
1465 set lang [lindex $testitem 7]
1466 set warning [lindex $testitem 8]
1467 set objfiles {}
1468 set failed 0
1469
1470 # verbose -log "Testname is $testname"
1471 # verbose -log "ld_options is $ld_options"
1472 # verbose -log "as_options is $as_options"
1473 # verbose -log "src_files is $src_files"
1474 # verbose -log "actions is $actions"
1475 # verbose -log "binfile is $binfile"
1476
1477 # Assemble each file in the test.
1478 foreach src_file $src_files {
1479 set objfile "tmpdir/[file rootname $src_file].o"
1480 lappend objfiles $objfile
1481
1482 # We ignore warnings since some compilers may generate
1483 # incorrect section attributes and the assembler will warn
1484 # them.
1485 if { [ string match "c++" $lang ] } {
1486 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1487 } else {
1488 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1489 }
1490
1491 # We have to use $CC to build PIE and shared library.
1492 if { [ string match "c" $lang ] } {
1493 set link_proc ld_simple_link
1494 set link_cmd $CC
1495 } elseif { [ string match "c++" $lang ] } {
1496 set link_proc ld_simple_link
1497 set link_cmd $CXX
1498 } elseif { [ string match "-shared" $ld_options ] \
1499 || [ string match "-pie" $ld_options ] } {
1500 set link_proc ld_simple_link
1501 set link_cmd $CC
1502 } else {
1503 set link_proc ld_link
1504 set link_cmd $ld
1505 }
1506
1507 if ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1508 set failed 1
1509 } else {
1510 set failed 0
1511 }
1512
1513 # Check if exec_output is expected.
1514 if { $warning != "" } then {
1515 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1516 if { [regexp $warning $exec_output] } then {
1517 set failed 0
1518 } else {
1519 set failed 1
1520 }
1521 }
1522
1523 if { $failed == 0 } {
1524 send_log "Running: $binfile > $binfile.out\n"
1525 verbose "Running: $binfile > $binfile.out"
1526 catch "exec $binfile > $binfile.out" exec_output
1527
1528 if ![string match "" $exec_output] then {
1529 send_log "$exec_output\n"
1530 verbose "$exec_output" 1
1531 set failed 1
1532 } else {
1533 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1534 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1535 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1536 set exec_output [prune_warnings $exec_output]
1537
1538 if ![string match "" $exec_output] then {
1539 send_log "$exec_output\n"
1540 verbose "$exec_output" 1
1541 set failed 1
1542 }
1543 }
1544 }
1545
1546 if { $failed != 0 } {
1547 fail $testname
1548 } else {
1549 set errcnt 0
1550 pass $testname
1551 }
1552 }
1553 }
1554 }
1555
1556 # List contains test-items with 3 items followed by 2 lists, one item and
1557 # one optional item:
1558 # 0:name
1559 # 1:ld or ar options
1560 # 2:compile options
1561 # 3:filenames of source files
1562 # 4:action and options.
1563 # 5:name of output file
1564 # 6:language (optional)
1565 #
1566 # Actions:
1567 # objdump: Apply objdump options on result. Compare with regex (last arg).
1568 # nm: Apply nm options on result. Compare with regex (last arg).
1569 # readelf: Apply readelf options on result. Compare with regex (last arg).
1570 #
1571 proc run_cc_link_tests { ldtests } {
1572 global nm
1573 global objdump
1574 global READELF
1575 global srcdir
1576 global subdir
1577 global env
1578 global CC
1579 global CXX
1580 global CFLAGS
1581 global CXXFLAGS
1582 global ar
1583
1584 foreach testitem $ldtests {
1585 set testname [lindex $testitem 0]
1586 set ldflags [lindex $testitem 1]
1587 set cflags [lindex $testitem 2]
1588 set src_files [lindex $testitem 3]
1589 set actions [lindex $testitem 4]
1590 set binfile tmpdir/[lindex $testitem 5]
1591 set lang [lindex $testitem 6]
1592 set objfiles {}
1593 set is_unresolved 0
1594 set failed 0
1595
1596 # Compile each file in the test.
1597 foreach src_file $src_files {
1598 set objfile "tmpdir/[file rootname $src_file].o"
1599 lappend objfiles $objfile
1600
1601 # We ignore warnings since some compilers may generate
1602 # incorrect section attributes and the assembler will warn
1603 # them.
1604 if { [ string match "c++" $lang ] } {
1605 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1606 } else {
1607 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1608 }
1609 }
1610
1611 # Clear error and warning counts.
1612 reset_vars
1613
1614 if { [ string match "c++" $lang ] } {
1615 set cc_cmd $CXX
1616 } else {
1617 set cc_cmd $CC
1618 }
1619
1620 if { [regexp ".*\\.a$" $binfile] } {
1621 if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
1622 fail $testname
1623 set failed 1
1624 } else {
1625 set failed 0
1626 }
1627 } elseif { ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] } {
1628 fail $testname
1629 set failed 1
1630 } else {
1631 set failed 0
1632 }
1633
1634 if { $failed == 0 } {
1635 foreach actionlist $actions {
1636 set action [lindex $actionlist 0]
1637 set progopts [lindex $actionlist 1]
1638
1639 # There are actions where we run regexp_diff on the
1640 # output, and there are other actions (presumably).
1641 # Handling of the former look the same.
1642 set dump_prog ""
1643 switch -- $action {
1644 objdump
1645 { set dump_prog $objdump }
1646 nm
1647 { set dump_prog $nm }
1648 readelf
1649 { set dump_prog $READELF }
1650 default
1651 {
1652 perror "Unrecognized action $action"
1653 set is_unresolved 1
1654 break
1655 }
1656 }
1657
1658 if { $dump_prog != "" } {
1659 set dumpfile [lindex $actionlist 2]
1660 set binary $dump_prog
1661
1662 # Ensure consistent sorting of symbols
1663 if {[info exists env(LC_ALL)]} {
1664 set old_lc_all $env(LC_ALL)
1665 }
1666 set env(LC_ALL) "C"
1667 set cmd "$binary $progopts $binfile > dump.out"
1668 send_log "$cmd\n"
1669 catch "exec $cmd" comp_output
1670 if {[info exists old_lc_all]} {
1671 set env(LC_ALL) $old_lc_all
1672 } else {
1673 unset env(LC_ALL)
1674 }
1675 set comp_output [prune_warnings $comp_output]
1676
1677 if ![string match "" $comp_output] then {
1678 send_log "$comp_output\n"
1679 set failed 1
1680 break
1681 }
1682
1683 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1684 verbose "output is [file_contents "dump.out"]" 2
1685 set failed 1
1686 break
1687 }
1688 }
1689 }
1690
1691 if { $failed != 0 } {
1692 fail $testname
1693 } else { if { $is_unresolved == 0 } {
1694 pass $testname
1695 } }
1696 }
1697
1698 # Catch action errors.
1699 if { $is_unresolved != 0 } {
1700 unresolved $testname
1701 continue
1702 }
1703 }
1704 }
1705
1706 # Returns true if --gc-sections is supported on the target.
1707
1708 proc check_gc_sections_available { } {
1709 global gc_sections_available_saved
1710 global ld
1711
1712 if {![info exists gc_sections_available_saved]} {
1713 # Some targets don't support gc-sections despite whatever's
1714 # advertised by ld's options.
1715 if {[istarget arc-*-*]
1716 || [istarget d30v-*-*]
1717 || [istarget dlx-*-*]
1718 || [istarget i960-*-*]
1719 || [istarget or32-*-*]
1720 || [istarget pj*-*-*]
1721 || [istarget alpha-*-*]
1722 || [istarget hppa64-*-*]
1723 || [istarget i370-*-*]
1724 || [istarget i860-*-*]
1725 || [istarget ia64-*-*]
1726 || [istarget mep-*-*]
1727 || [istarget mn10200-*-*]
1728 || [istarget *-*-cygwin]
1729 || [istarget *-*-mingw*] } {
1730 set gc_sections_available_saved 0
1731 return 0
1732 }
1733
1734 # elf2flt uses -q (--emit-relocs), which is incompatible with
1735 # --gc-sections.
1736 if { [board_info target exists ldflags]
1737 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1738 set gc_sections_available_saved 0
1739 return 0
1740 }
1741
1742 # Check if the ld used by gcc supports --gc-sections.
1743 set ld_output [remote_exec host $ld "--help"]
1744 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1745 set gc_sections_available_saved 1
1746 } else {
1747 set gc_sections_available_saved 0
1748 }
1749 }
1750 return $gc_sections_available_saved
1751 }
1752
1753 # Returns true if the target ld supports the plugin API.
1754 proc check_plugin_api_available { } {
1755 global plugin_api_available_saved
1756 global ld
1757 if {![info exists plugin_api_available_saved]} {
1758 # Check if the ld used by gcc supports --plugin.
1759 set ld_output [remote_exec host $ld "--help"]
1760 if { [ string first "-plugin" $ld_output ] >= 0 } {
1761 set plugin_api_available_saved 1
1762 } else {
1763 set plugin_api_available_saved 0
1764 }
1765 }
1766 return $plugin_api_available_saved
1767 }
1768
1769 # Check if the assembler supports CFI statements.
1770
1771 proc check_as_cfi { } {
1772 global check_as_cfi_result
1773 global as
1774 if [info exists check_as_cfi_result] {
1775 return $check_as_cfi_result
1776 }
1777 set as_file "tmpdir/check_as_cfi.s"
1778 set as_fh [open $as_file w 0666]
1779 puts $as_fh "# Generated file. DO NOT EDIT"
1780 puts $as_fh "\t.cfi_startproc"
1781 puts $as_fh "\t.cfi_endproc"
1782 close $as_fh
1783 remote_download host $as_file
1784 verbose -log "Checking CFI support:"
1785 rename "perror" "check_as_cfi_perror"
1786 proc perror { args } { }
1787 set success [ld_assemble $as $as_file "/dev/null"]
1788 rename "perror" ""
1789 rename "check_as_cfi_perror" "perror"
1790 #remote_file host delete $as_file
1791 set check_as_cfi_result $success
1792 return $success
1793 }
1794
1795 # Provide virtual target "cfi" for targets supporting CFI.
1796
1797 rename "istarget" "istarget_ld"
1798 proc istarget { target } {
1799 if {$target == "cfi"} {
1800 return [check_as_cfi]
1801 }
1802 return [istarget_ld $target]
1803 }