daily update
[deliverable/binutils-gdb.git] / ld / testsuite / lib / ld-lib.exp
CommitLineData
a2b64bed 1# Support routines for LD testsuite.
25629536
AM
2# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3# 2004, 2005 Free Software Foundation, Inc.
a2b64bed
NC
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
75be928b 17# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
a2b64bed 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 92 if [board_info [target_info name] exists multilib_flags] {
b24f926d 93 set tmp_flags " [board_info [target_info name] multilib_flags]"
38e31547
NC
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]
dec20c9e 229 set ccflags ""
b0fe1bf3 230 if { $ccparm > 0 } then {
dec20c9e 231 set ccflags [string range $cc $ccparm end]
b0fe1bf3 232 set ccexe [string range $cc 0 $ccparm]
dec20c9e 233 set cc $ccexe
b0fe1bf3
AM
234 }
235 set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""]
0f84fde1 236 if {[string match "*gcc*" $ccexe] || [string match "*++*" $ccexe]} then {
252b5132
RH
237 set flags "$gcc_gas_flag $flags"
238 }
239
38e31547 240 if [board_info [target_info name] exists multilib_flags] {
b24f926d 241 append flags " [board_info [target_info name] multilib_flags]"
38e31547
NC
242 }
243
dec20c9e 244 verbose -log "$cc $flags $ccflags -c $source -o $object"
252b5132 245
dec20c9e 246 catch "exec $cc $flags $ccflags -c $source -o $object" exec_output
252b5132
RH
247 set exec_output [prune_warnings $exec_output]
248 if [string match "" $exec_output] then {
249 if {![file exists $object]} then {
250 regexp ".*/(\[^/\]*)$" $source all dobj
251 regsub "\\.c" $dobj ".o" realobj
252 verbose "looking for $realobj"
253 if {[file exists $realobj]} then {
254 verbose -log "mv $realobj $object"
255 catch "exec mv $realobj $object" exec_output
256 set exec_output [prune_warnings $exec_output]
257 if {![string match "" $exec_output]} then {
258 verbose -log "$exec_output"
259 perror "could not move $realobj to $object"
260 return 0
261 }
262 } else {
263 perror "$object not found after compilation"
264 return 0
265 }
266 }
267 return 1
268 } else {
269 verbose -log "$exec_output"
270 perror "$source: compilation failed"
271 return 0
272 }
273}
274
275#
276# default_ld_assemble
277# assemble a file
278#
279proc default_ld_assemble { as source object } {
280 global ASFLAGS
281 global host_triplet
3e8cba19 282
252b5132
RH
283 if {[which $as] == 0} then {
284 perror "$as does not exist"
285 return 0
286 }
287
288 if ![info exists ASFLAGS] { set ASFLAGS "" }
289
38e31547
NC
290 set flags [big_or_little_endian]
291
292 verbose -log "$as $flags $ASFLAGS -o $object $source"
252b5132 293
38e31547 294 catch "exec $as $flags $ASFLAGS -o $object $source" exec_output
252b5132
RH
295 set exec_output [prune_warnings $exec_output]
296 if [string match "" $exec_output] then {
297 return 1
298 } else {
299 verbose -log "$exec_output"
300 perror "$source: assembly failed"
301 return 0
302 }
303}
304
305#
306# default_ld_nm
307# run nm on a file, putting the result in the array nm_output
308#
992c450d 309proc default_ld_nm { nm nmflags object } {
252b5132
RH
310 global NMFLAGS
311 global nm_output
312 global host_triplet
313
314 if {[which $nm] == 0} then {
315 perror "$nm does not exist"
316 return 0
317 }
318
77e0b0ef
ILT
319 if {[info exists nm_output]} {
320 unset nm_output
321 }
322
252b5132
RH
323 if ![info exists NMFLAGS] { set NMFLAGS "" }
324
3e8cba19
AM
325 # Ensure consistent sorting of symbols
326 if {[info exists env(LC_ALL)]} {
327 set old_lc_all $env(LC_ALL)
328 }
329 set env(LC_ALL) "C"
992c450d 330 verbose -log "$nm $NMFLAGS $nmflags $object >tmpdir/nm.out"
252b5132 331
992c450d 332 catch "exec $nm $NMFLAGS $nmflags $object >tmpdir/nm.out" exec_output
3e8cba19
AM
333 if {[info exists old_lc_all]} {
334 set env(LC_ALL) $old_lc_all
335 } else {
336 unset env(LC_ALL)
337 }
252b5132
RH
338 set exec_output [prune_warnings $exec_output]
339 if [string match "" $exec_output] then {
340 set file [open tmpdir/nm.out r]
341 while { [gets $file line] != -1 } {
342 verbose "$line" 2
dbc37f89 343 if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] \\.*(.+)$" $line whole value name] {
252b5132
RH
344 set name [string trimleft $name "_"]
345 verbose "Setting nm_output($name) to 0x$value" 2
346 set nm_output($name) 0x$value
347 }
348 }
349 close $file
350 return 1
351 } else {
352 verbose -log "$exec_output"
353 perror "$object: nm failed"
354 return 0
355 }
356}
357
3e3f011f
RS
358#
359# is_elf_format
360# true if the object format is known to be ELF
361#
362proc is_elf_format {} {
363 if { ![istarget *-*-sysv4*] \
364 && ![istarget *-*-unixware*] \
365 && ![istarget *-*-elf*] \
366 && ![istarget *-*-eabi*] \
43f9d75b 367 && ![istarget hppa*64*-*-hpux*] \
3e3f011f 368 && ![istarget *-*-linux*] \
a9a704fc 369 && ![istarget frv-*-uclinux*] \
3e3f011f
RS
370 && ![istarget *-*-irix5*] \
371 && ![istarget *-*-irix6*] \
e06d9b45 372 && ![istarget *-*-netbsd*] \
3e3f011f
RS
373 && ![istarget *-*-solaris2*] } {
374 return 0
375 }
376
377 if { [istarget *-*-linux*aout*] \
378 || [istarget *-*-linux*oldld*] } {
379 return 0
380 }
e06d9b45
JT
381
382 if { ![istarget *-*-netbsdelf*] \
383 && ([istarget *-*-netbsd*aout*] \
384 || [istarget *-*-netbsdpe*] \
385 || [istarget arm*-*-netbsd*] \
386 || [istarget sparc-*-netbsd*] \
387 || [istarget i*86-*-netbsd*] \
388 || [istarget m68*-*-netbsd*] \
389 || [istarget vax-*-netbsd*] \
390 || [istarget ns32k-*-netbsd*]) } {
391 return 0
392 }
3e3f011f
RS
393 return 1
394}
395
7ed2b4e2
L
396#
397# is_elf64
398# true if the object format is known to be 64bit ELF
399proc is_elf64 { binary_file } {
400 global READELF
401 global READELFFLAGS
402
403 set readelf_size ""
404 catch "exec $READELF $READELFFLAGS -h $binary_file > readelf.out" got
405
406 if ![string match "" $got] then {
407 return 0
408 }
409
410 if { ![regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \
411 [file_contents readelf.out] nil readelf_size] } {
412 return 0
413 }
414
415 if { $readelf_size == "64" } {
416 return 1
417 }
418
419 return 0
420}
421
25629536
AM
422#
423# is_aout_format
424# true if the object format is known to be aout
425proc is_aout_format {} {
426 if { [istarget *-*-*\[ab\]out*] \
427 || [istarget *-*-linux*oldld*] \
428 || [istarget *-*-msdos*] \
429 || [istarget arm-*-netbsd] \
430 || [istarget i?86-*-netbsd] \
431 || [istarget i?86-*-mach*] \
432 || [istarget i?86-*-vsta] \
433 || [istarget pdp11-*-*] \
434 || [istarget m68*-ericsson-ose] \
435 || [istarget m68k-hp-bsd*] \
436 || [istarget m68*-*-hpux*] \
437 || [istarget m68*-*-netbsd] \
438 || [istarget m68*-*-netbsd*4k*] \
439 || [istarget m68k-sony-*] \
440 || [istarget m68*-sun-sunos\[34\]*] \
441 || [istarget m68*-wrs-vxworks*] \
442 || [istarget ns32k-*-*] \
443 || [istarget sparc*-*-netbsd] \
444 || [istarget sparc-sun-sunos4*] \
445 || [istarget vax-dec-ultrix*] \
446 || [istarget vax-*-netbsd] } {
447 return 1
448 }
449 return 0
450}
451
977cdf5a
NC
452#
453# is_pecoff_format
454# true if the object format is known to be PECOFF
455#
456proc is_pecoff_format {} {
457 if { ![istarget *-*-mingw32*] \
458 && ![istarget *-*-cygwin*] \
459 && ![istarget *-*-pe*] } {
460 return 0
461 }
462
463 return 1
464}
465
252b5132
RH
466#
467# simple_diff
468# compares two files line-by-line
469# returns differences if exist
470# returns null if file(s) cannot be opened
471#
472proc simple_diff { file_1 file_2 } {
473 global target
3e8cba19 474
252b5132
RH
475 set eof -1
476 set differences 0
3e8cba19 477
252b5132
RH
478 if [file exists $file_1] then {
479 set file_a [open $file_1 r]
480 } else {
481 warning "$file_1 doesn't exist"
482 return
483 }
3e8cba19 484
252b5132
RH
485 if [file exists $file_2] then {
486 set file_b [open $file_2 r]
487 } else {
488 fail "$file_2 doesn't exist"
489 return
490 }
3e8cba19 491
252b5132 492 verbose "# Diff'ing: $file_1 $file_2\n" 2
3e8cba19 493
252b5132
RH
494 while { [gets $file_a line] != $eof } {
495 if [regexp "^#.*$" $line] then {
496 continue
497 } else {
498 lappend list_a $line
499 }
500 }
501 close $file_a
3e8cba19 502
252b5132
RH
503 while { [gets $file_b line] != $eof } {
504 if [regexp "^#.*$" $line] then {
505 continue
506 } else {
507 lappend list_b $line
508 }
509 }
510 close $file_b
511
512 for { set i 0 } { $i < [llength $list_a] } { incr i } {
513 set line_a [lindex $list_a $i]
514 set line_b [lindex $list_b $i]
515
516 verbose "\t$file_1: $i: $line_a\n" 3
517 verbose "\t$file_2: $i: $line_b\n" 3
518 if [string compare $line_a $line_b] then {
519 verbose -log "\t$file_1: $i: $line_a\n"
520 verbose -log "\t$file_2: $i: $line_b\n"
521
522 fail "Test: $target"
523 return
524 }
525 }
3e8cba19 526
252b5132
RH
527 if { [llength $list_a] != [llength $list_b] } {
528 fail "Test: $target"
529 return
530 }
531
532 if $differences<1 then {
533 pass "Test: $target"
534 }
535}
536
3e8cba19 537# run_dump_test FILE
261def70
HPN
538# Copied from gas testsuite, tweaked and further extended.
539#
540# Assemble a .s file, then run some utility on it and check the output.
3e8cba19 541#
261def70
HPN
542# There should be an assembly language file named FILE.s in the test
543# suite directory, and a pattern file called FILE.d. `run_dump_test'
544# will assemble FILE.s, run some tool like `objdump', `objcopy', or
545# `nm' on the .o file to produce textual output, and then analyze that
546# with regexps. The FILE.d file specifies what program to run, and
547# what to expect in its output.
548#
549# The FILE.d file begins with zero or more option lines, which specify
550# flags to pass to the assembler, the program to run to dump the
551# assembler's output, and the options it wants. The option lines have
552# the syntax:
3e8cba19 553#
261def70 554# # OPTION: VALUE
3e8cba19 555#
261def70
HPN
556# OPTION is the name of some option, like "name" or "objdump", and
557# VALUE is OPTION's value. The valid options are described below.
558# Whitespace is ignored everywhere, except within VALUE. The option
559# list ends with the first line that doesn't match the above syntax
560# (hmm, not great for error detection).
561#
562# The interesting options are:
3e8cba19 563#
261def70
HPN
564# name: TEST-NAME
565# The name of this test, passed to DejaGNU's `pass' and `fail'
566# commands. If omitted, this defaults to FILE, the root of the
567# .s and .d files' names.
3e8cba19 568#
261def70
HPN
569# as: FLAGS
570# When assembling, pass FLAGS to the assembler.
571# If assembling several files, you can pass different assembler
572# options in the "source" directives. See below.
573#
574# ld: FLAGS
575# Link assembled files using FLAGS, in the order of the "source"
576# directives, when using multiple files.
577#
cfe5266f
HPN
578# objcopy_linked_file: FLAGS
579# Run objcopy on the linked file with the specified flags.
580# This lets you transform the linked file using objcopy, before the
581# result is analyzed by an analyzer program specified below (which
582# may in turn *also* be objcopy).
583#
261def70
HPN
584# PROG: PROGRAM-NAME
585# The name of the program to run to analyze the .o file produced
586# by the assembler or the linker output. This can be omitted;
587# run_dump_test will guess which program to run by seeing which of
588# the flags options below is present.
589#
590# objdump: FLAGS
591# nm: FLAGS
592# objcopy: FLAGS
593# Use the specified program to analyze the assembler or linker
594# output file, and pass it FLAGS, in addition to the output name.
3e8cba19
AM
595# Note that they are run with LC_ALL=C in the environment to give
596# consistent sorting of symbols.
261def70
HPN
597#
598# source: SOURCE [FLAGS]
599# Assemble the file SOURCE.s using the flags in the "as" directive
600# and the (optional) FLAGS. If omitted, the source defaults to
601# FILE.s.
602# This is useful if several .d files want to share a .s file.
603# More than one "source" directive can be given, which is useful
604# when testing linking.
605#
606# xfail: TARGET
607# The test is expected to fail on TARGET. This may occur more than
608# once.
609#
610# target: TARGET
611# Only run the test for TARGET. This may occur more than once; the
612# target being tested must match at least one.
613#
614# notarget: TARGET
615# Do not run the test for TARGET. This may occur more than once;
616# the target being tested must not match any of them.
617#
618# error: REGEX
619# An error with message matching REGEX must be emitted for the test
620# to pass. The PROG, objdump, nm and objcopy options have no
621# meaning and need not supplied if this is present.
622#
bb00e284
HPN
623# warning: REGEX
624# Expect a linker warning matching REGEX. It is an error to issue
625# both "error" and "warning".
626#
261def70
HPN
627# Each option may occur at most once unless otherwise mentioned.
628#
629# After the option lines come regexp lines. `run_dump_test' calls
630# `regexp_diff' to compare the output of the dumping tool against the
631# regexps in FILE.d. `regexp_diff' is defined later in this file; see
632# further comments there.
633
634proc run_dump_test { name } {
635 global subdir srcdir
636 global OBJDUMP NM AS OBJCOPY READELF LD
637 global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
638 global host_triplet runtests
3e8cba19 639 global env
261def70
HPN
640
641 if [string match "*/*" $name] {
642 set file $name
643 set name [file tail $name]
644 } else {
645 set file "$srcdir/$subdir/$name"
646 }
647
648 if ![runtest_file_p $runtests $name] then {
649 return
650 }
651
652 set opt_array [slurp_options "${file}.d"]
653 if { $opt_array == -1 } {
654 perror "error reading options from $file.d"
655 unresolved $subdir/$name
656 return
657 }
658 set dumpfile tmpdir/dump.out
659 set run_ld 0
cfe5266f 660 set run_objcopy 0
261def70
HPN
661 set opts(as) {}
662 set opts(ld) {}
663 set opts(xfail) {}
664 set opts(target) {}
665 set opts(notarget) {}
666 set opts(objdump) {}
667 set opts(nm) {}
668 set opts(objcopy) {}
669 set opts(readelf) {}
670 set opts(name) {}
671 set opts(PROG) {}
672 set opts(source) {}
673 set opts(error) {}
bb00e284 674 set opts(warning) {}
cfe5266f 675 set opts(objcopy_linked_file) {}
b2da51b6 676 set asflags(${file}.s) {}
261def70
HPN
677
678 foreach i $opt_array {
679 set opt_name [lindex $i 0]
680 set opt_val [lindex $i 1]
681 if ![info exists opts($opt_name)] {
682 perror "unknown option $opt_name in file $file.d"
683 unresolved $subdir/$name
684 return
685 }
686
687 switch -- $opt_name {
688 xfail {}
689 target {}
690 notarget {}
691 source {
692 # Move any source-specific as-flags to a separate array to
693 # simplify processing.
694 if { [llength $opt_val] > 1 } {
695 set asflags([lindex $opt_val 0]) [lrange $opt_val 1 end]
696 set opt_val [lindex $opt_val 0]
697 } else {
698 set asflags($opt_val) {}
699 }
700 }
701 default {
702 if [string length $opts($opt_name)] {
703 perror "option $opt_name multiply set in $file.d"
704 unresolved $subdir/$name
705 return
706 }
707
708 # A single "# ld:" with no options should do the right thing.
709 if { $opt_name == "ld" } {
710 set run_ld 1
711 }
cfe5266f
HPN
712 # Likewise objcopy_linked_file.
713 if { $opt_name == "objcopy_linked_file" } {
714 set run_objcopy 1
715 }
261def70
HPN
716 }
717 }
718 set opts($opt_name) [concat $opts($opt_name) $opt_val]
719 }
720
721 # Decide early whether we should run the test for this target.
722 if { [llength $opts(target)] > 0 } {
723 set targmatch 0
724 foreach targ $opts(target) {
725 if [istarget $targ] {
726 set targmatch 1
727 break
728 }
729 }
730 if { $targmatch == 0 } {
731 return
732 }
733 }
734 foreach targ $opts(notarget) {
735 if [istarget $targ] {
736 return
737 }
738 }
739
f364d1ca
AM
740 set program ""
741 # It's meaningless to require an output-testing method when we
742 # expect an error.
743 if { $opts(error) == "" } {
744 if {$opts(PROG) != ""} {
745 switch -- $opts(PROG) {
746 objdump { set program objdump }
747 nm { set program nm }
748 objcopy { set program objcopy }
749 readelf { set program readelf }
750 default
261def70
HPN
751 { perror "unrecognized program option $opts(PROG) in $file.d"
752 unresolved $subdir/$name
753 return }
f364d1ca
AM
754 }
755 } else {
261def70 756 # Guess which program to run, by seeing which option was specified.
f364d1ca
AM
757 foreach p {objdump objcopy nm readelf} {
758 if {$opts($p) != ""} {
759 if {$program != ""} {
760 perror "ambiguous dump program in $file.d"
761 unresolved $subdir/$name
762 return
763 } else {
764 set program $p
765 }
261def70
HPN
766 }
767 }
768 }
f364d1ca 769 if { $program == "" && $opts(warning) == "" } {
261def70
HPN
770 perror "dump program unspecified in $file.d"
771 unresolved $subdir/$name
772 return
773 }
774 }
775
261def70
HPN
776 if { $opts(name) == "" } {
777 set testname "$subdir/$name"
778 } else {
779 set testname $opts(name)
780 }
781
782 if { $opts(source) == "" } {
783 set sourcefiles [list ${file}.s]
784 } else {
785 set sourcefiles {}
786 foreach sf $opts(source) {
b7b0b729
HPN
787 if { [string match "/*" $sf] } {
788 lappend sourcefiles "$sf"
f364d1ca 789 } else {
b7b0b729
HPN
790 lappend sourcefiles "$srcdir/$subdir/$sf"
791 }
261def70
HPN
792 # Must have asflags indexed on source name.
793 set asflags($srcdir/$subdir/$sf) $asflags($sf)
794 }
795 }
796
797 # Time to setup xfailures.
798 foreach targ $opts(xfail) {
799 setup_xfail $targ
800 }
801
802 # Assemble each file.
803 set objfiles {}
804 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
805 set sourcefile [lindex $sourcefiles $i]
806
807 set objfile "tmpdir/dump$i.o"
808 lappend objfiles $objfile
809 set cmd "$AS $ASFLAGS $opts(as) $asflags($sourcefile) -o $objfile $sourcefile"
810
811 send_log "$cmd\n"
812 set cmdret [catch "exec $cmd" comp_output]
813 set comp_output [prune_warnings $comp_output]
814
261def70
HPN
815 if { $cmdret != 0 || ![string match "" $comp_output] } then {
816 send_log "$comp_output\n"
817 verbose "$comp_output" 3
f364d1ca
AM
818
819 set exitstat "succeeded"
820 if { $cmdret != 0 } { set exitstat "failed" }
821 verbose -log "$exitstat with: <$comp_output>"
261def70
HPN
822 fail $testname
823 return
824 }
825 }
826
f364d1ca
AM
827 set expmsg $opts(error)
828 if { $opts(warning) != "" } {
829 if { $expmsg != "" } {
830 perror "$testname: mixing error and warning test-directives"
831 return
832 }
833 set expmsg $opts(warning)
834 }
835
261def70
HPN
836 # Perhaps link the file(s).
837 if { $run_ld } {
838 set objfile "tmpdir/dump"
3e3f011f
RS
839
840 # Add -L$srcdir/$subdir so that the linker command can use
841 # linker scripts in the source directory.
842 set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
843 $opts(ld) -o $objfile $objfiles"
261def70
HPN
844
845 send_log "$cmd\n"
846 set cmdret [catch "exec $cmd" comp_output]
847 set comp_output [prune_warnings $comp_output]
848
f364d1ca 849 if { $cmdret != 0 } then {
bb00e284
HPN
850 # If the executed program writes to stderr and stderr is not
851 # redirected, exec *always* returns failure, regardless of the
852 # program exit code. Thankfully, we can retrieve the true
853 # return status from a special variable. Redirection would
854 # cause a tcl-specific message to be appended, and we'd rather
855 # not deal with that if we can help it.
856 global errorCode
f364d1ca 857 if { [lindex $errorCode 0] == "NONE" } {
bb00e284
HPN
858 set cmdret 0
859 }
261def70 860 }
cfe5266f 861
f364d1ca 862 if { $cmdret == 0 && $run_objcopy } {
cfe5266f
HPN
863 set infile $objfile
864 set objfile "tmpdir/dump1"
865
866 # Note that we don't use OBJCOPYFLAGS here; any flags must be
867 # explicitly specified.
868 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
869
870 send_log "$cmd\n"
871 set cmdret [catch "exec $cmd" comp_output]
f364d1ca
AM
872 append comp_output [prune_warnings $comp_output]
873
874 if { $cmdret != 0 } then {
875 global errorCode
876 if { [lindex $errorCode 0] == "NONE" } {
877 set cmdret 0
878 }
879 }
880 }
881
882 if { $cmdret != 0 || $comp_output != "" || $expmsg != "" } then {
883 set exitstat "succeeded"
884 if { $cmdret != 0 } { set exitstat "failed" }
885 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
886 send_log "$comp_output\n"
887 verbose "$comp_output" 3
888
889 if { [regexp $expmsg $comp_output] \
890 && (($cmdret == 0) == ($opts(warning) != "")) } {
891 # We have the expected output from ld.
892 if { $opts(error) != "" || $program == "" } {
893 pass $testname
894 return
cfe5266f 895 }
f364d1ca
AM
896 } else {
897 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
cfe5266f
HPN
898 fail $testname
899 return
900 }
901 }
261def70
HPN
902 } else {
903 set objfile "tmpdir/dump0.o"
904 }
905
906 # We must not have expected failure if we get here.
907 if { $opts(error) != "" } {
908 fail $testname
cfe5266f 909 return
261def70
HPN
910 }
911
f364d1ca
AM
912 set progopts1 $opts($program)
913 eval set progopts \$[string toupper $program]FLAGS
914 eval set binary \$[string toupper $program]
915
261def70
HPN
916 if { [which $binary] == 0 } {
917 untested $testname
918 return
919 }
920
921 if { $progopts1 == "" } { set $progopts1 "-r" }
922 verbose "running $binary $progopts $progopts1" 3
923
924 # Objcopy, unlike the other two, won't send its output to stdout,
925 # so we have to run it specially.
3e8cba19 926 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
261def70
HPN
927 if { $program == "objcopy" } {
928 set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
3e8cba19
AM
929 }
930
931 # Ensure consistent sorting of symbols
932 if {[info exists env(LC_ALL)]} {
933 set old_lc_all $env(LC_ALL)
934 }
935 set env(LC_ALL) "C"
936 send_log "$cmd\n"
937 catch "exec $cmd" comp_output
938 if {[info exists old_lc_all]} {
939 set env(LC_ALL) $old_lc_all
261def70 940 } else {
3e8cba19
AM
941 unset env(LC_ALL)
942 }
943 set comp_output [prune_warnings $comp_output]
944 if ![string match "" $comp_output] then {
945 send_log "$comp_output\n"
946 fail $testname
947 return
261def70
HPN
948 }
949
950 verbose_eval {[file_contents $dumpfile]} 3
951 if { [regexp_diff $dumpfile "${file}.d"] } then {
952 fail $testname
953 verbose "output is [file_contents $dumpfile]" 2
954 return
955 }
956
957 pass $testname
958}
959
960proc slurp_options { file } {
961 if [catch { set f [open $file r] } x] {
962 #perror "couldn't open `$file': $x"
963 perror "$x"
964 return -1
965 }
966 set opt_array {}
967 # whitespace expression
968 set ws {[ ]*}
969 set nws {[^ ]*}
970 # whitespace is ignored anywhere except within the options list;
cfe5266f
HPN
971 # option names are alphabetic plus underscore only.
972 set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
261def70
HPN
973 while { [gets $f line] != -1 } {
974 set line [string trim $line]
975 # Whitespace here is space-tab.
976 if [regexp $pat $line xxx opt_name opt_val] {
977 # match!
978 lappend opt_array [list $opt_name $opt_val]
979 } else {
980 break
981 }
982 }
983 close $f
984 return $opt_array
985}
986
987# regexp_diff, copied from gas, based on simple_diff above.
988# compares two files line-by-line
989# file1 contains strings, file2 contains regexps and #-comments
990# blank lines are ignored in either file
991# returns non-zero if differences exist
992#
993proc regexp_diff { file_1 file_2 } {
994
995 set eof -1
996 set end_1 0
997 set end_2 0
998 set differences 0
999 set diff_pass 0
1000
1001 if [file exists $file_1] then {
1002 set file_a [open $file_1 r]
1003 } else {
1004 warning "$file_1 doesn't exist"
1005 return 1
1006 }
1007
1008 if [file exists $file_2] then {
1009 set file_b [open $file_2 r]
1010 } else {
1011 fail "$file_2 doesn't exist"
1012 close $file_a
1013 return 1
1014 }
1015
1016 verbose " Regexp-diff'ing: $file_1 $file_2" 2
1017
1018 while { 1 } {
1019 set line_a ""
1020 set line_b ""
1021 while { [string length $line_a] == 0 } {
1022 if { [gets $file_a line_a] == $eof } {
1023 set end_1 1
1024 break
1025 }
1026 }
1027 while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
1028 if [ string match "#pass" $line_b ] {
1029 set end_2 1
1030 set diff_pass 1
1031 break
1032 } elseif [ string match "#..." $line_b ] {
1033 if { [gets $file_b line_b] == $eof } {
1034 set end_2 1
5cfd5a0c 1035 set diff_pass 1
261def70
HPN
1036 break
1037 }
1038 verbose "looking for \"^$line_b$\"" 3
1039 while { ![regexp "^$line_b$" "$line_a"] } {
1040 verbose "skipping \"$line_a\"" 3
1041 if { [gets $file_a line_a] == $eof } {
1042 set end_1 1
1043 break
1044 }
1045 }
1046 break
1047 }
1048 if { [gets $file_b line_b] == $eof } {
1049 set end_2 1
1050 break
1051 }
1052 }
1053
3e8cba19
AM
1054 if { $diff_pass } {
1055 break
1056 } elseif { $end_1 && $end_2 } {
261def70
HPN
1057 break
1058 } elseif { $end_1 } {
1059 send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
1060 verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
1061 set differences 1
1062 break
1063 } elseif { $end_2 } {
1064 send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
1065 verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
1066 set differences 1
1067 break
1068 } else {
1069 verbose "regexp \"^$line_b$\"\nline \"$line_a\"" 3
1070 if ![regexp "^$line_b$" "$line_a"] {
1071 send_log "regexp_diff match failure\n"
1072 send_log "regexp \"^$line_b$\"\nline \"$line_a\"\n"
1073 set differences 1
1074 }
1075 }
1076 }
1077
1078 if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
1079 send_log "$file_1 and $file_2 are different lengths\n"
1080 verbose "$file_1 and $file_2 are different lengths" 3
1081 set differences 1
1082 }
1083
1084 close $file_a
1085 close $file_b
1086
1087 return $differences
1088}
1089
1090proc file_contents { filename } {
1091 set file [open $filename r]
1092 set contents [read $file]
1093 close $file
1094 return $contents
1095}
bffbf940 1096
9147e853
JJ
1097# List contains test-items with 3 items followed by 2 lists, one item and
1098# one optional item:
bffbf940
JJ
1099# 0:name 1:ld options 2:assembler options
1100# 3:filenames of assembler files 4: action and options. 5: name of output file
9147e853 1101# 6:compiler flags (optional)
bffbf940
JJ
1102
1103# Actions:
1104# objdump: Apply objdump options on result. Compare with regex (last arg).
1105# nm: Apply nm options on result. Compare with regex (last arg).
1106# readelf: Apply readelf options on result. Compare with regex (last arg).
1107
1108proc run_ld_link_tests { ldtests } {
1109 global ld
1110 global as
1111 global nm
1112 global objdump
1113 global READELF
1114 global srcdir
1115 global subdir
1116 global env
9147e853
JJ
1117 global CC
1118 global CFLAGS
bffbf940
JJ
1119
1120 foreach testitem $ldtests {
1121 set testname [lindex $testitem 0]
1122 set ld_options [lindex $testitem 1]
1123 set as_options [lindex $testitem 2]
9147e853 1124 set src_files [lindex $testitem 3]
bffbf940
JJ
1125 set actions [lindex $testitem 4]
1126 set binfile tmpdir/[lindex $testitem 5]
9147e853 1127 set cflags [lindex $testitem 6]
bffbf940
JJ
1128 set objfiles {}
1129 set is_unresolved 0
1130 set failed 0
1131
1132# verbose -log "Testname is $testname"
1133# verbose -log "ld_options is $ld_options"
1134# verbose -log "as_options is $as_options"
9147e853 1135# verbose -log "src_files is $src_files"
bffbf940
JJ
1136# verbose -log "actions is $actions"
1137# verbose -log "binfile is $binfile"
1138
1139 # Assemble each file in the test.
9147e853
JJ
1140 foreach src_file $src_files {
1141 set objfile "tmpdir/[file rootname $src_file].o"
bffbf940
JJ
1142 lappend objfiles $objfile
1143
9147e853
JJ
1144 if { [file extension $src_file] == ".c" } {
1145 set as_file "tmpdir/[file rootname $src_file].s"
1146 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1147 set is_unresolved 1
1148 break
1149 }
1150 } else {
1151 set as_file "$srcdir/$subdir/$src_file"
1152 }
1153 if ![ld_assemble $as "$as_options $as_file" $objfile] {
bffbf940
JJ
1154 set is_unresolved 1
1155 break
1156 }
1157 }
1158
1159 # Catch assembler errors.
1160 if { $is_unresolved != 0 } {
1161 unresolved $testname
1162 continue
1163 }
1164
1165 if ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1166 fail $testname
1167 } else {
1168 set failed 0
1169 foreach actionlist $actions {
1170 set action [lindex $actionlist 0]
1171 set progopts [lindex $actionlist 1]
1172
1173 # There are actions where we run regexp_diff on the
1174 # output, and there are other actions (presumably).
1175 # Handling of the former look the same.
1176 set dump_prog ""
1177 switch -- $action {
1178 objdump
1179 { set dump_prog $objdump }
1180 nm
1181 { set dump_prog $nm }
1182 readelf
1183 { set dump_prog $READELF }
1184 default
1185 {
1186 perror "Unrecognized action $action"
1187 set is_unresolved 1
1188 break
1189 }
1190 }
1191
1192 if { $dump_prog != "" } {
1193 set dumpfile [lindex $actionlist 2]
1194 set binary $dump_prog
1195
1196 # Ensure consistent sorting of symbols
1197 if {[info exists env(LC_ALL)]} {
1198 set old_lc_all $env(LC_ALL)
1199 }
1200 set env(LC_ALL) "C"
1201 set cmd "$binary $progopts $binfile > dump.out"
1202 send_log "$cmd\n"
1203 catch "exec $cmd" comp_output
1204 if {[info exists old_lc_all]} {
1205 set env(LC_ALL) $old_lc_all
1206 } else {
1207 unset env(LC_ALL)
1208 }
1209 set comp_output [prune_warnings $comp_output]
1210
1211 if ![string match "" $comp_output] then {
1212 send_log "$comp_output\n"
1213 set failed 1
1214 break
1215 }
1216
1217 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1218 verbose "output is [file_contents "dump.out"]" 2
1219 set failed 1
1220 break
1221 }
1222 }
1223 }
1224
1225 if { $failed != 0 } {
1226 fail $testname
1227 } else { if { $is_unresolved == 0 } {
1228 pass $testname
1229 } }
1230 }
1231
1232 # Catch action errors.
1233 if { $is_unresolved != 0 } {
1234 unresolved $testname
1235 continue
1236 }
1237 }
1238}
1239
261def70
HPN
1240
1241proc verbose_eval { expr { level 1 } } {
1242 global verbose
1243 if $verbose>$level then { eval verbose "$expr" $level }
1244}
1245
252b5132
RH
1246# This definition is taken from an unreleased version of DejaGnu. Once
1247# that version gets released, and has been out in the world for a few
1248# months at least, it may be safe to delete this copy.
1249if ![string length [info proc prune_warnings]] {
1250 #
1251 # prune_warnings -- delete various system verbosities from TEXT
1252 #
1253 # An example is:
1254 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1255 #
1256 # Sites with particular verbose os's may wish to override this in site.exp.
1257 #
1258 proc prune_warnings { text } {
1259 # This is from sun4's. Do it for all machines for now.
1260 # The "\\1" is to try to preserve a "\n" but only if necessary.
1261 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1262
1263 # It might be tempting to get carried away and delete blank lines, etc.
1264 # Just delete *exactly* what we're ask to, and that's it.
1265 return $text
1266 }
1267}
24edc24d 1268
c8c140d9
BE
1269# targets_to_xfail is a list of target triplets to be xfailed.
1270# ldtests contains test-items with 3 items followed by 1 lists, 2 items
955057fc 1271# and one optional item:
c8c140d9
BE
1272# 0:name
1273# 1:ld options
1274# 2:assembler options
1275# 3:filenames of assembler files
1276# 4:name of output file
1277# 5:expected output
1278# 6:compiler flags (optional)
1279
1280proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
24edc24d
L
1281 global ld
1282 global as
1283 global srcdir
1284 global subdir
1285 global env
1286 global CC
1287 global CFLAGS
22ec3bd1 1288 global errcnt
24edc24d
L
1289
1290 foreach testitem $ldtests {
c8c140d9
BE
1291 foreach target $targets_to_xfail {
1292 setup_xfail $target
1293 }
24edc24d
L
1294 set testname [lindex $testitem 0]
1295 set ld_options [lindex $testitem 1]
1296 set as_options [lindex $testitem 2]
1297 set src_files [lindex $testitem 3]
1298 set binfile tmpdir/[lindex $testitem 4]
1299 set expfile [lindex $testitem 5]
1300 set cflags [lindex $testitem 6]
1301 set objfiles {}
24edc24d
L
1302 set failed 0
1303
1304# verbose -log "Testname is $testname"
1305# verbose -log "ld_options is $ld_options"
1306# verbose -log "as_options is $as_options"
1307# verbose -log "src_files is $src_files"
1308# verbose -log "actions is $actions"
1309# verbose -log "binfile is $binfile"
1310
1311 # Assemble each file in the test.
1312 foreach src_file $src_files {
1313 set objfile "tmpdir/[file rootname $src_file].o"
1314 lappend objfiles $objfile
1315
a10e6b21
L
1316 # We ignore warnings since some compilers may generate
1317 # incorrect section attributes and the assembler will warn
1318 # them.
1319 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1320
1321 # We have to use $CC to build PIE and shared library.
1322 if { [ string match "-shared" $ld_options ] \
1323 || [ string match "-pie" $ld_options ] } {
1324 set link_proc ld_simple_link
1325 set link_cmd $CC
1326 } else {
1327 set link_proc ld_link
1328 set link_cmd $ld
1329 }
24edc24d 1330
a10e6b21 1331 if ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
24edc24d
L
1332 set failed 1
1333 } else {
a10e6b21
L
1334 set failed 0
1335 send_log "Running: $binfile > $binfile.out\n"
1336 verbose "Running: $binfile > $binfile.out"
1337 catch "exec $binfile > $binfile.out" exec_output
1338
24edc24d
L
1339 if ![string match "" $exec_output] then {
1340 send_log "$exec_output\n"
1341 verbose "$exec_output" 1
1342 set failed 1
a10e6b21
L
1343 } else {
1344 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1345 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1346 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1347 set exec_output [prune_warnings $exec_output]
1348
1349 if ![string match "" $exec_output] then {
1350 send_log "$exec_output\n"
1351 verbose "$exec_output" 1
1352 set failed 1
1353 }
24edc24d
L
1354 }
1355 }
1356
1357 if { $failed != 0 } {
1358 fail $testname
22ec3bd1
L
1359 } else {
1360 set errcnt 0
24edc24d 1361 pass $testname
a10e6b21 1362 }
24edc24d 1363 }
24edc24d
L
1364 }
1365}
This page took 0.460089 seconds and 4 git commands to generate.