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