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