* lib/ld-lib.exp (default_ld_simple_link): Trim ld parms before
[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 # Free Software Foundation, Inc.
4 #
5 # This file is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 #
19 #
20 # default_ld_version
21 # extract and print the version number of ld
22 #
23 proc default_ld_version { ld } {
24 global host_triplet
25
26 if { [which $ld] == 0 } then {
27 perror "$ld does not exist"
28 exit 1
29 }
30
31 catch "exec $ld --version" tmp
32 set tmp [prune_warnings $tmp]
33 regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number
34 if [info exists number] then {
35 clone_output "$ld $number\n"
36 }
37 }
38
39 #
40 # default_ld_relocate
41 # link an object using relocation
42 #
43 proc default_ld_relocate { ld target objects } {
44 global HOSTING_EMU
45 global host_triplet
46
47 if { [which $ld] == 0 } then {
48 perror "$ld does not exist"
49 return 0
50 }
51
52 verbose -log "$ld $HOSTING_EMU -o $target -r $objects"
53
54 catch "exec $ld $HOSTING_EMU -o $target -r $objects" exec_output
55 set exec_output [prune_warnings $exec_output]
56 if [string match "" $exec_output] then {
57 return 1
58 } else {
59 verbose -log "$exec_output"
60 return 0
61 }
62 }
63
64 # Check to see if ld is being invoked with a non-endian output format
65
66 proc is_endian_output_format { object_flags } {
67
68 if {[string match "*-oformat binary*" $object_flags] || \
69 [string match "*-oformat ieee*" $object_flags] || \
70 [string match "*-oformat ihex*" $object_flags] || \
71 [string match "*-oformat netbsd-core*" $object_flags] || \
72 [string match "*-oformat srec*" $object_flags] || \
73 [string match "*-oformat tekhex*" $object_flags] || \
74 [string match "*-oformat trad-core*" $object_flags] } then {
75 return 0
76 } else {
77 return 1
78 }
79 }
80
81 # Look for big-endian or little-endian switches in the multlib
82 # options and translate these into a -EB or -EL switch. Note
83 # we cannot rely upon proc process_multilib_options to do this
84 # for us because for some targets the compiler does not support
85 # -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
86 # the site.exp file will include the switch "-mbig-endian"
87 # (rather than "big-endian") which is not detected by proc
88 # process_multilib_options.
89
90 proc big_or_little_endian {} {
91
92 if [board_info [target_info name] exists multilib_flags] {
93 set tmp_flags " [board_info [target_info name] multilib_flags]";
94
95 foreach x $tmp_flags {
96 case $x in {
97 {*big*endian eb EB -eb -EB -mb} {
98 set flags " -EB"
99 return $flags
100 }
101 {*little*endian el EL -el -EL -ml} {
102 set flags " -EL"
103 return $flags
104 }
105 }
106 }
107 }
108
109 set flags ""
110 return $flags
111 }
112
113 #
114 # default_ld_link
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
125 set objs "$HOSTING_CRT0 $objects"
126 set libs "$LIBS $HOSTING_LIBS"
127
128 if { [which $ld] == 0 } then {
129 perror "$ld does not exist"
130 return 0
131 }
132
133 if [is_endian_output_format $objects] then {
134 set flags [big_or_little_endian]
135 } else {
136 set flags ""
137 }
138 verbose -log "$ld $HOSTING_EMU $flags -o $target $objs $libs"
139
140 catch "exec $ld $HOSTING_EMU $flags -o $target $objs $libs" link_output
141 set exec_output [prune_warnings $link_output]
142 if [string match "" $link_output] then {
143 return 1
144 } else {
145 verbose -log "$link_output"
146 return 0
147 }
148 }
149
150 #
151 # default_ld_simple_link
152 # link a program using ld, without including any libraries
153 #
154 proc default_ld_simple_link { ld target objects } {
155 global host_triplet
156 global link_output
157 global gcc_ld_flag
158
159 if { [which $ld] == 0 } then {
160 perror "$ld does not exist"
161 return 0
162 }
163
164 if [is_endian_output_format $objects] then {
165 set flags [big_or_little_endian]
166 } else {
167 set flags ""
168 }
169
170 # If we are compiling with gcc, we want to add gcc_ld_flag to
171 # flags. Rather than determine this in some complex way, we guess
172 # based on the name of the compiler.
173 set ldexe $ld
174 set ldparm [string first " " $ld]
175 if { $ldparm > 0 } then {
176 set ldexe [string range $ld 0 $ldparm]
177 }
178 set ldexe [string replace $ldexe 0 [string last "/" $ldexe] ""]
179 if {[string match "*gcc*" $ldexe] || [string match "*++*" $ldexe]} then {
180 set flags "$gcc_ld_flag $flags"
181 }
182
183 verbose -log "$ld $flags -o $target $objects"
184
185 catch "exec $ld $flags -o $target $objects" link_output
186 set exec_output [prune_warnings $link_output]
187
188 # We don't care if we get a warning about a non-existent start
189 # symbol, since the default linker script might use ENTRY.
190 regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
191
192 if [string match "" $exec_output] then {
193 return 1
194 } else {
195 verbose -log "$exec_output"
196 return 0
197 }
198 }
199
200 #
201 # default_ld_compile
202 # compile an object using cc
203 #
204 proc default_ld_compile { cc source object } {
205 global CFLAGS
206 global srcdir
207 global subdir
208 global host_triplet
209 global gcc_gas_flag
210
211 set cc_prog $cc
212 if {[llength $cc_prog] > 1} then {
213 set cc_prog [lindex $cc_prog 0]
214 }
215 if {[which $cc_prog] == 0} then {
216 perror "$cc_prog does not exist"
217 return 0
218 }
219
220 catch "exec rm -f $object" exec_output
221
222 set flags "-I$srcdir/$subdir $CFLAGS"
223
224 # If we are compiling with gcc, we want to add gcc_gas_flag to
225 # flags. Rather than determine this in some complex way, we guess
226 # based on the name of the compiler.
227 set ccexe $cc
228 set ccparm [string first " " $cc]
229 if { $ccparm > 0 } then {
230 set ccexe [string range $cc 0 $ccparm]
231 }
232 set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""]
233 if {[string match "*gcc*" $ccexe] || [string match "*++*" $ccexe]} then {
234 set flags "$gcc_gas_flag $flags"
235 }
236
237 if [board_info [target_info name] exists multilib_flags] {
238 append flags " [board_info [target_info name] multilib_flags]";
239 }
240
241 verbose -log "$cc $flags -c $source -o $object"
242
243 catch "exec $cc $flags -c $source -o $object" exec_output
244 set exec_output [prune_warnings $exec_output]
245 if [string match "" $exec_output] then {
246 if {![file exists $object]} then {
247 regexp ".*/(\[^/\]*)$" $source all dobj
248 regsub "\\.c" $dobj ".o" realobj
249 verbose "looking for $realobj"
250 if {[file exists $realobj]} then {
251 verbose -log "mv $realobj $object"
252 catch "exec mv $realobj $object" exec_output
253 set exec_output [prune_warnings $exec_output]
254 if {![string match "" $exec_output]} then {
255 verbose -log "$exec_output"
256 perror "could not move $realobj to $object"
257 return 0
258 }
259 } else {
260 perror "$object not found after compilation"
261 return 0
262 }
263 }
264 return 1
265 } else {
266 verbose -log "$exec_output"
267 perror "$source: compilation failed"
268 return 0
269 }
270 }
271
272 #
273 # default_ld_assemble
274 # assemble a file
275 #
276 proc default_ld_assemble { as source object } {
277 global ASFLAGS
278 global host_triplet
279
280 if {[which $as] == 0} then {
281 perror "$as does not exist"
282 return 0
283 }
284
285 if ![info exists ASFLAGS] { set ASFLAGS "" }
286
287 set flags [big_or_little_endian]
288
289 verbose -log "$as $flags $ASFLAGS -o $object $source"
290
291 catch "exec $as $flags $ASFLAGS -o $object $source" exec_output
292 set exec_output [prune_warnings $exec_output]
293 if [string match "" $exec_output] then {
294 return 1
295 } else {
296 verbose -log "$exec_output"
297 perror "$source: assembly failed"
298 return 0
299 }
300 }
301
302 #
303 # default_ld_nm
304 # run nm on a file, putting the result in the array nm_output
305 #
306 proc default_ld_nm { nm nmflags object } {
307 global NMFLAGS
308 global nm_output
309 global host_triplet
310
311 if {[which $nm] == 0} then {
312 perror "$nm does not exist"
313 return 0
314 }
315
316 if {[info exists nm_output]} {
317 unset nm_output
318 }
319
320 if ![info exists NMFLAGS] { set NMFLAGS "" }
321
322 # Ensure consistent sorting of symbols
323 if {[info exists env(LC_ALL)]} {
324 set old_lc_all $env(LC_ALL)
325 }
326 set env(LC_ALL) "C"
327 verbose -log "$nm $NMFLAGS $nmflags $object >tmpdir/nm.out"
328
329 catch "exec $nm $NMFLAGS $nmflags $object >tmpdir/nm.out" exec_output
330 if {[info exists old_lc_all]} {
331 set env(LC_ALL) $old_lc_all
332 } else {
333 unset env(LC_ALL)
334 }
335 set exec_output [prune_warnings $exec_output]
336 if [string match "" $exec_output] then {
337 set file [open tmpdir/nm.out r]
338 while { [gets $file line] != -1 } {
339 verbose "$line" 2
340 if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] \\.*(.+)$" $line whole value name] {
341 set name [string trimleft $name "_"]
342 verbose "Setting nm_output($name) to 0x$value" 2
343 set nm_output($name) 0x$value
344 }
345 }
346 close $file
347 return 1
348 } else {
349 verbose -log "$exec_output"
350 perror "$object: nm failed"
351 return 0
352 }
353 }
354
355 #
356 # is_elf_format
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 *-*-irix5*] \
367 && ![istarget *-*-irix6*] \
368 && ![istarget *-*-netbsd*] \
369 && ![istarget *-*-solaris2*] } {
370 return 0
371 }
372
373 if { [istarget *-*-linux*aout*] \
374 || [istarget *-*-linux*oldld*] } {
375 return 0
376 }
377
378 if { ![istarget *-*-netbsdelf*] \
379 && ([istarget *-*-netbsd*aout*] \
380 || [istarget *-*-netbsdpe*] \
381 || [istarget arm*-*-netbsd*] \
382 || [istarget sparc-*-netbsd*] \
383 || [istarget i*86-*-netbsd*] \
384 || [istarget m68*-*-netbsd*] \
385 || [istarget vax-*-netbsd*] \
386 || [istarget ns32k-*-netbsd*]) } {
387 return 0
388 }
389 return 1
390 }
391
392 #
393 # simple_diff
394 # compares two files line-by-line
395 # returns differences if exist
396 # returns null if file(s) cannot be opened
397 #
398 proc simple_diff { file_1 file_2 } {
399 global target
400
401 set eof -1
402 set differences 0
403
404 if [file exists $file_1] then {
405 set file_a [open $file_1 r]
406 } else {
407 warning "$file_1 doesn't exist"
408 return
409 }
410
411 if [file exists $file_2] then {
412 set file_b [open $file_2 r]
413 } else {
414 fail "$file_2 doesn't exist"
415 return
416 }
417
418 verbose "# Diff'ing: $file_1 $file_2\n" 2
419
420 while { [gets $file_a line] != $eof } {
421 if [regexp "^#.*$" $line] then {
422 continue
423 } else {
424 lappend list_a $line
425 }
426 }
427 close $file_a
428
429 while { [gets $file_b line] != $eof } {
430 if [regexp "^#.*$" $line] then {
431 continue
432 } else {
433 lappend list_b $line
434 }
435 }
436 close $file_b
437
438 for { set i 0 } { $i < [llength $list_a] } { incr i } {
439 set line_a [lindex $list_a $i]
440 set line_b [lindex $list_b $i]
441
442 verbose "\t$file_1: $i: $line_a\n" 3
443 verbose "\t$file_2: $i: $line_b\n" 3
444 if [string compare $line_a $line_b] then {
445 verbose -log "\t$file_1: $i: $line_a\n"
446 verbose -log "\t$file_2: $i: $line_b\n"
447
448 fail "Test: $target"
449 return
450 }
451 }
452
453 if { [llength $list_a] != [llength $list_b] } {
454 fail "Test: $target"
455 return
456 }
457
458 if $differences<1 then {
459 pass "Test: $target"
460 }
461 }
462
463 # run_dump_test FILE
464 # Copied from gas testsuite, tweaked and further extended.
465 #
466 # Assemble a .s file, then run some utility on it and check the output.
467 #
468 # There should be an assembly language file named FILE.s in the test
469 # suite directory, and a pattern file called FILE.d. `run_dump_test'
470 # will assemble FILE.s, run some tool like `objdump', `objcopy', or
471 # `nm' on the .o file to produce textual output, and then analyze that
472 # with regexps. The FILE.d file specifies what program to run, and
473 # what to expect in its output.
474 #
475 # The FILE.d file begins with zero or more option lines, which specify
476 # flags to pass to the assembler, the program to run to dump the
477 # assembler's output, and the options it wants. The option lines have
478 # the syntax:
479 #
480 # # OPTION: VALUE
481 #
482 # OPTION is the name of some option, like "name" or "objdump", and
483 # VALUE is OPTION's value. The valid options are described below.
484 # Whitespace is ignored everywhere, except within VALUE. The option
485 # list ends with the first line that doesn't match the above syntax
486 # (hmm, not great for error detection).
487 #
488 # The interesting options are:
489 #
490 # name: TEST-NAME
491 # The name of this test, passed to DejaGNU's `pass' and `fail'
492 # commands. If omitted, this defaults to FILE, the root of the
493 # .s and .d files' names.
494 #
495 # as: FLAGS
496 # When assembling, pass FLAGS to the assembler.
497 # If assembling several files, you can pass different assembler
498 # options in the "source" directives. See below.
499 #
500 # ld: FLAGS
501 # Link assembled files using FLAGS, in the order of the "source"
502 # directives, when using multiple files.
503 #
504 # objcopy_linked_file: FLAGS
505 # Run objcopy on the linked file with the specified flags.
506 # This lets you transform the linked file using objcopy, before the
507 # result is analyzed by an analyzer program specified below (which
508 # may in turn *also* be objcopy).
509 #
510 # PROG: PROGRAM-NAME
511 # The name of the program to run to analyze the .o file produced
512 # by the assembler or the linker output. This can be omitted;
513 # run_dump_test will guess which program to run by seeing which of
514 # the flags options below is present.
515 #
516 # objdump: FLAGS
517 # nm: FLAGS
518 # objcopy: FLAGS
519 # Use the specified program to analyze the assembler or linker
520 # output file, and pass it FLAGS, in addition to the output name.
521 # Note that they are run with LC_ALL=C in the environment to give
522 # consistent sorting of symbols.
523 #
524 # source: SOURCE [FLAGS]
525 # Assemble the file SOURCE.s using the flags in the "as" directive
526 # and the (optional) FLAGS. If omitted, the source defaults to
527 # FILE.s.
528 # This is useful if several .d files want to share a .s file.
529 # More than one "source" directive can be given, which is useful
530 # when testing linking.
531 #
532 # xfail: TARGET
533 # The test is expected to fail on TARGET. This may occur more than
534 # once.
535 #
536 # target: TARGET
537 # Only run the test for TARGET. This may occur more than once; the
538 # target being tested must match at least one.
539 #
540 # notarget: TARGET
541 # Do not run the test for TARGET. This may occur more than once;
542 # the target being tested must not match any of them.
543 #
544 # error: REGEX
545 # An error with message matching REGEX must be emitted for the test
546 # to pass. The PROG, objdump, nm and objcopy options have no
547 # meaning and need not supplied if this is present.
548 #
549 # Each option may occur at most once unless otherwise mentioned.
550 #
551 # After the option lines come regexp lines. `run_dump_test' calls
552 # `regexp_diff' to compare the output of the dumping tool against the
553 # regexps in FILE.d. `regexp_diff' is defined later in this file; see
554 # further comments there.
555
556 proc run_dump_test { name } {
557 global subdir srcdir
558 global OBJDUMP NM AS OBJCOPY READELF LD
559 global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
560 global host_triplet runtests
561 global env
562
563 if [string match "*/*" $name] {
564 set file $name
565 set name [file tail $name]
566 } else {
567 set file "$srcdir/$subdir/$name"
568 }
569
570 if ![runtest_file_p $runtests $name] then {
571 return
572 }
573
574 set opt_array [slurp_options "${file}.d"]
575 if { $opt_array == -1 } {
576 perror "error reading options from $file.d"
577 unresolved $subdir/$name
578 return
579 }
580 set dumpfile tmpdir/dump.out
581 set run_ld 0
582 set run_objcopy 0
583 set opts(as) {}
584 set opts(ld) {}
585 set opts(xfail) {}
586 set opts(target) {}
587 set opts(notarget) {}
588 set opts(objdump) {}
589 set opts(nm) {}
590 set opts(objcopy) {}
591 set opts(readelf) {}
592 set opts(name) {}
593 set opts(PROG) {}
594 set opts(source) {}
595 set opts(error) {}
596 set opts(objcopy_linked_file) {}
597 set asflags(${file}.s) {}
598
599 foreach i $opt_array {
600 set opt_name [lindex $i 0]
601 set opt_val [lindex $i 1]
602 if ![info exists opts($opt_name)] {
603 perror "unknown option $opt_name in file $file.d"
604 unresolved $subdir/$name
605 return
606 }
607
608 switch -- $opt_name {
609 xfail {}
610 target {}
611 notarget {}
612 source {
613 # Move any source-specific as-flags to a separate array to
614 # simplify processing.
615 if { [llength $opt_val] > 1 } {
616 set asflags([lindex $opt_val 0]) [lrange $opt_val 1 end]
617 set opt_val [lindex $opt_val 0]
618 } else {
619 set asflags($opt_val) {}
620 }
621 }
622 default {
623 if [string length $opts($opt_name)] {
624 perror "option $opt_name multiply set in $file.d"
625 unresolved $subdir/$name
626 return
627 }
628
629 # A single "# ld:" with no options should do the right thing.
630 if { $opt_name == "ld" } {
631 set run_ld 1
632 }
633 # Likewise objcopy_linked_file.
634 if { $opt_name == "objcopy_linked_file" } {
635 set run_objcopy 1
636 }
637 }
638 }
639 set opts($opt_name) [concat $opts($opt_name) $opt_val]
640 }
641
642 # Decide early whether we should run the test for this target.
643 if { [llength $opts(target)] > 0 } {
644 set targmatch 0
645 foreach targ $opts(target) {
646 if [istarget $targ] {
647 set targmatch 1
648 break
649 }
650 }
651 if { $targmatch == 0 } {
652 return
653 }
654 }
655 foreach targ $opts(notarget) {
656 if [istarget $targ] {
657 return
658 }
659 }
660
661 if {$opts(PROG) != ""} {
662 switch -- $opts(PROG) {
663 objdump
664 { set program objdump }
665 nm
666 { set program nm }
667 objcopy
668 { set program objcopy }
669 readelf
670 { set program readelf }
671 default
672 { perror "unrecognized program option $opts(PROG) in $file.d"
673 unresolved $subdir/$name
674 return }
675 }
676 } elseif { $opts(error) != "" } {
677 # It's meaningless to require an output-testing method when we
678 # expect an error. For simplicity, we fake an arbitrary method.
679 set program "nm"
680 } else {
681 # Guess which program to run, by seeing which option was specified.
682 set program ""
683 foreach p {objdump objcopy nm readelf} {
684 if {$opts($p) != ""} {
685 if {$program != ""} {
686 perror "ambiguous dump program in $file.d"
687 unresolved $subdir/$name
688 return
689 } else {
690 set program $p
691 }
692 }
693 }
694 if {$program == ""} {
695 perror "dump program unspecified in $file.d"
696 unresolved $subdir/$name
697 return
698 }
699 }
700
701 set progopts1 $opts($program)
702 eval set progopts \$[string toupper $program]FLAGS
703 eval set binary \$[string toupper $program]
704 if { $opts(name) == "" } {
705 set testname "$subdir/$name"
706 } else {
707 set testname $opts(name)
708 }
709
710 if { $opts(source) == "" } {
711 set sourcefiles [list ${file}.s]
712 } else {
713 set sourcefiles {}
714 foreach sf $opts(source) {
715 if { [string match "/*" $sf] } {
716 lappend sourcefiles "$sf"
717 } {
718 lappend sourcefiles "$srcdir/$subdir/$sf"
719 }
720 # Must have asflags indexed on source name.
721 set asflags($srcdir/$subdir/$sf) $asflags($sf)
722 }
723 }
724
725 # Time to setup xfailures.
726 foreach targ $opts(xfail) {
727 setup_xfail $targ
728 }
729
730 # Assemble each file.
731 set objfiles {}
732 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
733 set sourcefile [lindex $sourcefiles $i]
734
735 set objfile "tmpdir/dump$i.o"
736 lappend objfiles $objfile
737 set cmd "$AS $ASFLAGS $opts(as) $asflags($sourcefile) -o $objfile $sourcefile"
738
739 send_log "$cmd\n"
740 set cmdret [catch "exec $cmd" comp_output]
741 set comp_output [prune_warnings $comp_output]
742
743 # We accept errors at assembly stage too, unless we're supposed to
744 # link something.
745 if { $cmdret != 0 || ![string match "" $comp_output] } then {
746 send_log "$comp_output\n"
747 verbose "$comp_output" 3
748 if { $opts(error) != "" && $run_ld == 0 } {
749 if [regexp $opts(error) $comp_output] {
750 pass $testname
751 return
752 }
753 }
754 fail $testname
755 return
756 }
757 }
758
759 # Perhaps link the file(s).
760 if { $run_ld } {
761 set objfile "tmpdir/dump"
762
763 # Add -L$srcdir/$subdir so that the linker command can use
764 # linker scripts in the source directory.
765 set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
766 $opts(ld) -o $objfile $objfiles"
767
768 send_log "$cmd\n"
769 set cmdret [catch "exec $cmd" comp_output]
770 set comp_output [prune_warnings $comp_output]
771
772 if { $cmdret != 0 || ![string match "" $comp_output] } then {
773 verbose -log "failed with: <$comp_output>, expected: <$opts(error)>"
774 send_log "$comp_output\n"
775 verbose "$comp_output" 3
776 if { $opts(error) != "" && $run_objcopy == 0 } {
777 if [regexp $opts(error) $comp_output] {
778 pass $testname
779 return
780 }
781 }
782 fail $testname
783 return
784 }
785
786 if { $run_objcopy } {
787 set infile $objfile
788 set objfile "tmpdir/dump1"
789
790 # Note that we don't use OBJCOPYFLAGS here; any flags must be
791 # explicitly specified.
792 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
793
794 send_log "$cmd\n"
795 set cmdret [catch "exec $cmd" comp_output]
796 set comp_output [prune_warnings $comp_output]
797
798 if { $cmdret != 0 || ![string match "" $comp_output] } then {
799 verbose -log "failed with: <$comp_output>, expected: <$opts(error)>"
800 send_log "$comp_output\n"
801 verbose "$comp_output" 3
802 if { $opts(error) != "" } {
803 if [regexp $opts(error) $comp_output] {
804 pass $testname
805 return
806 }
807 }
808 fail $testname
809 return
810 }
811 }
812 } else {
813 set objfile "tmpdir/dump0.o"
814 }
815
816 # We must not have expected failure if we get here.
817 if { $opts(error) != "" } {
818 fail $testname
819 return
820 }
821
822 if { [which $binary] == 0 } {
823 untested $testname
824 return
825 }
826
827 if { $progopts1 == "" } { set $progopts1 "-r" }
828 verbose "running $binary $progopts $progopts1" 3
829
830 # Objcopy, unlike the other two, won't send its output to stdout,
831 # so we have to run it specially.
832 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
833 if { $program == "objcopy" } {
834 set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
835 }
836
837 # Ensure consistent sorting of symbols
838 if {[info exists env(LC_ALL)]} {
839 set old_lc_all $env(LC_ALL)
840 }
841 set env(LC_ALL) "C"
842 send_log "$cmd\n"
843 catch "exec $cmd" comp_output
844 if {[info exists old_lc_all]} {
845 set env(LC_ALL) $old_lc_all
846 } else {
847 unset env(LC_ALL)
848 }
849 set comp_output [prune_warnings $comp_output]
850 if ![string match "" $comp_output] then {
851 send_log "$comp_output\n"
852 fail $testname
853 return
854 }
855
856 verbose_eval {[file_contents $dumpfile]} 3
857 if { [regexp_diff $dumpfile "${file}.d"] } then {
858 fail $testname
859 verbose "output is [file_contents $dumpfile]" 2
860 return
861 }
862
863 pass $testname
864 }
865
866 proc slurp_options { file } {
867 if [catch { set f [open $file r] } x] {
868 #perror "couldn't open `$file': $x"
869 perror "$x"
870 return -1
871 }
872 set opt_array {}
873 # whitespace expression
874 set ws {[ ]*}
875 set nws {[^ ]*}
876 # whitespace is ignored anywhere except within the options list;
877 # option names are alphabetic plus underscore only.
878 set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
879 while { [gets $f line] != -1 } {
880 set line [string trim $line]
881 # Whitespace here is space-tab.
882 if [regexp $pat $line xxx opt_name opt_val] {
883 # match!
884 lappend opt_array [list $opt_name $opt_val]
885 } else {
886 break
887 }
888 }
889 close $f
890 return $opt_array
891 }
892
893 # regexp_diff, copied from gas, based on simple_diff above.
894 # compares two files line-by-line
895 # file1 contains strings, file2 contains regexps and #-comments
896 # blank lines are ignored in either file
897 # returns non-zero if differences exist
898 #
899 proc regexp_diff { file_1 file_2 } {
900
901 set eof -1
902 set end_1 0
903 set end_2 0
904 set differences 0
905 set diff_pass 0
906
907 if [file exists $file_1] then {
908 set file_a [open $file_1 r]
909 } else {
910 warning "$file_1 doesn't exist"
911 return 1
912 }
913
914 if [file exists $file_2] then {
915 set file_b [open $file_2 r]
916 } else {
917 fail "$file_2 doesn't exist"
918 close $file_a
919 return 1
920 }
921
922 verbose " Regexp-diff'ing: $file_1 $file_2" 2
923
924 while { 1 } {
925 set line_a ""
926 set line_b ""
927 while { [string length $line_a] == 0 } {
928 if { [gets $file_a line_a] == $eof } {
929 set end_1 1
930 break
931 }
932 }
933 while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
934 if [ string match "#pass" $line_b ] {
935 set end_2 1
936 set diff_pass 1
937 break
938 } elseif [ string match "#..." $line_b ] {
939 if { [gets $file_b line_b] == $eof } {
940 set end_2 1
941 break
942 }
943 verbose "looking for \"^$line_b$\"" 3
944 while { ![regexp "^$line_b$" "$line_a"] } {
945 verbose "skipping \"$line_a\"" 3
946 if { [gets $file_a line_a] == $eof } {
947 set end_1 1
948 break
949 }
950 }
951 break
952 }
953 if { [gets $file_b line_b] == $eof } {
954 set end_2 1
955 break
956 }
957 }
958
959 if { $diff_pass } {
960 break
961 } elseif { $end_1 && $end_2 } {
962 break
963 } elseif { $end_1 } {
964 send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
965 verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
966 set differences 1
967 break
968 } elseif { $end_2 } {
969 send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
970 verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
971 set differences 1
972 break
973 } else {
974 verbose "regexp \"^$line_b$\"\nline \"$line_a\"" 3
975 if ![regexp "^$line_b$" "$line_a"] {
976 send_log "regexp_diff match failure\n"
977 send_log "regexp \"^$line_b$\"\nline \"$line_a\"\n"
978 set differences 1
979 }
980 }
981 }
982
983 if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
984 send_log "$file_1 and $file_2 are different lengths\n"
985 verbose "$file_1 and $file_2 are different lengths" 3
986 set differences 1
987 }
988
989 close $file_a
990 close $file_b
991
992 return $differences
993 }
994
995 proc file_contents { filename } {
996 set file [open $filename r]
997 set contents [read $file]
998 close $file
999 return $contents
1000 }
1001
1002 # List contains test-items with 3 items followed by 2 lists, one item and
1003 # one optional item:
1004 # 0:name 1:ld options 2:assembler options
1005 # 3:filenames of assembler files 4: action and options. 5: name of output file
1006 # 6:compiler flags (optional)
1007
1008 # Actions:
1009 # objdump: Apply objdump options on result. Compare with regex (last arg).
1010 # nm: Apply nm options on result. Compare with regex (last arg).
1011 # readelf: Apply readelf options on result. Compare with regex (last arg).
1012
1013 proc run_ld_link_tests { ldtests } {
1014 global ld
1015 global as
1016 global nm
1017 global objdump
1018 global READELF
1019 global srcdir
1020 global subdir
1021 global env
1022 global CC
1023 global CFLAGS
1024
1025 foreach testitem $ldtests {
1026 set testname [lindex $testitem 0]
1027 set ld_options [lindex $testitem 1]
1028 set as_options [lindex $testitem 2]
1029 set src_files [lindex $testitem 3]
1030 set actions [lindex $testitem 4]
1031 set binfile tmpdir/[lindex $testitem 5]
1032 set cflags [lindex $testitem 6]
1033 set objfiles {}
1034 set is_unresolved 0
1035 set failed 0
1036
1037 # verbose -log "Testname is $testname"
1038 # verbose -log "ld_options is $ld_options"
1039 # verbose -log "as_options is $as_options"
1040 # verbose -log "src_files is $src_files"
1041 # verbose -log "actions is $actions"
1042 # verbose -log "binfile is $binfile"
1043
1044 # Assemble each file in the test.
1045 foreach src_file $src_files {
1046 set objfile "tmpdir/[file rootname $src_file].o"
1047 lappend objfiles $objfile
1048
1049 if { [file extension $src_file] == ".c" } {
1050 set as_file "tmpdir/[file rootname $src_file].s"
1051 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1052 set is_unresolved 1
1053 break
1054 }
1055 } else {
1056 set as_file "$srcdir/$subdir/$src_file"
1057 }
1058 if ![ld_assemble $as "$as_options $as_file" $objfile] {
1059 set is_unresolved 1
1060 break
1061 }
1062 }
1063
1064 # Catch assembler errors.
1065 if { $is_unresolved != 0 } {
1066 unresolved $testname
1067 continue
1068 }
1069
1070 if ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1071 fail $testname
1072 } else {
1073 set failed 0
1074 foreach actionlist $actions {
1075 set action [lindex $actionlist 0]
1076 set progopts [lindex $actionlist 1]
1077
1078 # There are actions where we run regexp_diff on the
1079 # output, and there are other actions (presumably).
1080 # Handling of the former look the same.
1081 set dump_prog ""
1082 switch -- $action {
1083 objdump
1084 { set dump_prog $objdump }
1085 nm
1086 { set dump_prog $nm }
1087 readelf
1088 { set dump_prog $READELF }
1089 default
1090 {
1091 perror "Unrecognized action $action"
1092 set is_unresolved 1
1093 break
1094 }
1095 }
1096
1097 if { $dump_prog != "" } {
1098 set dumpfile [lindex $actionlist 2]
1099 set binary $dump_prog
1100
1101 # Ensure consistent sorting of symbols
1102 if {[info exists env(LC_ALL)]} {
1103 set old_lc_all $env(LC_ALL)
1104 }
1105 set env(LC_ALL) "C"
1106 set cmd "$binary $progopts $binfile > dump.out"
1107 send_log "$cmd\n"
1108 catch "exec $cmd" comp_output
1109 if {[info exists old_lc_all]} {
1110 set env(LC_ALL) $old_lc_all
1111 } else {
1112 unset env(LC_ALL)
1113 }
1114 set comp_output [prune_warnings $comp_output]
1115
1116 if ![string match "" $comp_output] then {
1117 send_log "$comp_output\n"
1118 set failed 1
1119 break
1120 }
1121
1122 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1123 verbose "output is [file_contents "dump.out"]" 2
1124 set failed 1
1125 break
1126 }
1127 }
1128 }
1129
1130 if { $failed != 0 } {
1131 fail $testname
1132 } else { if { $is_unresolved == 0 } {
1133 pass $testname
1134 } }
1135 }
1136
1137 # Catch action errors.
1138 if { $is_unresolved != 0 } {
1139 unresolved $testname
1140 continue
1141 }
1142 }
1143 }
1144
1145
1146 proc verbose_eval { expr { level 1 } } {
1147 global verbose
1148 if $verbose>$level then { eval verbose "$expr" $level }
1149 }
1150
1151 # This definition is taken from an unreleased version of DejaGnu. Once
1152 # that version gets released, and has been out in the world for a few
1153 # months at least, it may be safe to delete this copy.
1154 if ![string length [info proc prune_warnings]] {
1155 #
1156 # prune_warnings -- delete various system verbosities from TEXT
1157 #
1158 # An example is:
1159 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1160 #
1161 # Sites with particular verbose os's may wish to override this in site.exp.
1162 #
1163 proc prune_warnings { text } {
1164 # This is from sun4's. Do it for all machines for now.
1165 # The "\\1" is to try to preserve a "\n" but only if necessary.
1166 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1167
1168 # It might be tempting to get carried away and delete blank lines, etc.
1169 # Just delete *exactly* what we're ask to, and that's it.
1170 return $text
1171 }
1172 }