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