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