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