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