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