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