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