PR 9682
[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#
d6e0b160
HPN
567# ld_after_inputfiles: FLAGS
568# Similar to "ld", but put after all input files.
569#
cfe5266f
HPN
570# objcopy_linked_file: FLAGS
571# Run objcopy on the linked file with the specified flags.
572# This lets you transform the linked file using objcopy, before the
573# result is analyzed by an analyzer program specified below (which
574# may in turn *also* be objcopy).
575#
261def70
HPN
576# PROG: PROGRAM-NAME
577# The name of the program to run to analyze the .o file produced
578# by the assembler or the linker output. This can be omitted;
579# run_dump_test will guess which program to run by seeing which of
580# the flags options below is present.
581#
582# objdump: FLAGS
583# nm: FLAGS
584# objcopy: FLAGS
585# Use the specified program to analyze the assembler or linker
586# output file, and pass it FLAGS, in addition to the output name.
3e8cba19
AM
587# Note that they are run with LC_ALL=C in the environment to give
588# consistent sorting of symbols.
261def70
HPN
589#
590# source: SOURCE [FLAGS]
591# Assemble the file SOURCE.s using the flags in the "as" directive
592# and the (optional) FLAGS. If omitted, the source defaults to
593# FILE.s.
594# This is useful if several .d files want to share a .s file.
595# More than one "source" directive can be given, which is useful
596# when testing linking.
597#
598# xfail: TARGET
599# The test is expected to fail on TARGET. This may occur more than
600# once.
601#
602# target: TARGET
603# Only run the test for TARGET. This may occur more than once; the
33aa234e
JK
604# target being tested must match at least one. You may provide target
605# name "cfi" for any target supporting the CFI statements.
261def70
HPN
606#
607# notarget: TARGET
608# Do not run the test for TARGET. This may occur more than once;
609# the target being tested must not match any of them.
610#
611# error: REGEX
612# An error with message matching REGEX must be emitted for the test
613# to pass. The PROG, objdump, nm and objcopy options have no
614# meaning and need not supplied if this is present.
615#
bb00e284
HPN
616# warning: REGEX
617# Expect a linker warning matching REGEX. It is an error to issue
618# both "error" and "warning".
619#
261def70
HPN
620# Each option may occur at most once unless otherwise mentioned.
621#
622# After the option lines come regexp lines. `run_dump_test' calls
623# `regexp_diff' to compare the output of the dumping tool against the
624# regexps in FILE.d. `regexp_diff' is defined later in this file; see
625# further comments there.
3b6fe0cc 626#
261def70
HPN
627proc run_dump_test { name } {
628 global subdir srcdir
629 global OBJDUMP NM AS OBJCOPY READELF LD
630 global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
631 global host_triplet runtests
3e8cba19 632 global env
261def70
HPN
633
634 if [string match "*/*" $name] {
635 set file $name
636 set name [file tail $name]
637 } else {
638 set file "$srcdir/$subdir/$name"
639 }
640
641 if ![runtest_file_p $runtests $name] then {
642 return
643 }
644
645 set opt_array [slurp_options "${file}.d"]
646 if { $opt_array == -1 } {
647 perror "error reading options from $file.d"
648 unresolved $subdir/$name
649 return
650 }
651 set dumpfile tmpdir/dump.out
652 set run_ld 0
cfe5266f 653 set run_objcopy 0
261def70
HPN
654 set opts(as) {}
655 set opts(ld) {}
d6e0b160 656 set opts(ld_after_inputfiles) {}
261def70
HPN
657 set opts(xfail) {}
658 set opts(target) {}
659 set opts(notarget) {}
660 set opts(objdump) {}
661 set opts(nm) {}
662 set opts(objcopy) {}
663 set opts(readelf) {}
664 set opts(name) {}
665 set opts(PROG) {}
666 set opts(source) {}
667 set opts(error) {}
bb00e284 668 set opts(warning) {}
cfe5266f 669 set opts(objcopy_linked_file) {}
b2da51b6 670 set asflags(${file}.s) {}
261def70
HPN
671
672 foreach i $opt_array {
673 set opt_name [lindex $i 0]
674 set opt_val [lindex $i 1]
675 if ![info exists opts($opt_name)] {
676 perror "unknown option $opt_name in file $file.d"
677 unresolved $subdir/$name
678 return
679 }
680
681 switch -- $opt_name {
682 xfail {}
683 target {}
684 notarget {}
685 source {
686 # Move any source-specific as-flags to a separate array to
687 # simplify processing.
688 if { [llength $opt_val] > 1 } {
689 set asflags([lindex $opt_val 0]) [lrange $opt_val 1 end]
690 set opt_val [lindex $opt_val 0]
691 } else {
692 set asflags($opt_val) {}
693 }
694 }
695 default {
696 if [string length $opts($opt_name)] {
697 perror "option $opt_name multiply set in $file.d"
698 unresolved $subdir/$name
699 return
700 }
701
702 # A single "# ld:" with no options should do the right thing.
703 if { $opt_name == "ld" } {
704 set run_ld 1
705 }
cfe5266f
HPN
706 # Likewise objcopy_linked_file.
707 if { $opt_name == "objcopy_linked_file" } {
708 set run_objcopy 1
709 }
261def70
HPN
710 }
711 }
7f6a71ff
JM
712 if { $opt_name == "as" || $opt_name == "ld" } {
713 set opt_val [subst $opt_val]
714 }
261def70
HPN
715 set opts($opt_name) [concat $opts($opt_name) $opt_val]
716 }
3935e1af
RS
717 foreach opt { as ld } {
718 regsub {\[big_or_little_endian\]} $opts($opt) \
719 [big_or_little_endian] opts($opt)
720 }
261def70
HPN
721
722 # Decide early whether we should run the test for this target.
723 if { [llength $opts(target)] > 0 } {
724 set targmatch 0
725 foreach targ $opts(target) {
726 if [istarget $targ] {
727 set targmatch 1
728 break
729 }
730 }
731 if { $targmatch == 0 } {
732 return
733 }
734 }
735 foreach targ $opts(notarget) {
736 if [istarget $targ] {
737 return
738 }
739 }
740
f364d1ca
AM
741 set program ""
742 # It's meaningless to require an output-testing method when we
743 # expect an error.
744 if { $opts(error) == "" } {
745 if {$opts(PROG) != ""} {
746 switch -- $opts(PROG) {
747 objdump { set program objdump }
748 nm { set program nm }
749 objcopy { set program objcopy }
750 readelf { set program readelf }
751 default
261def70
HPN
752 { perror "unrecognized program option $opts(PROG) in $file.d"
753 unresolved $subdir/$name
754 return }
f364d1ca
AM
755 }
756 } else {
261def70 757 # Guess which program to run, by seeing which option was specified.
f364d1ca
AM
758 foreach p {objdump objcopy nm readelf} {
759 if {$opts($p) != ""} {
760 if {$program != ""} {
761 perror "ambiguous dump program in $file.d"
762 unresolved $subdir/$name
763 return
764 } else {
765 set program $p
766 }
261def70
HPN
767 }
768 }
769 }
f364d1ca 770 if { $program == "" && $opts(warning) == "" } {
261def70
HPN
771 perror "dump program unspecified in $file.d"
772 unresolved $subdir/$name
773 return
774 }
775 }
776
261def70
HPN
777 if { $opts(name) == "" } {
778 set testname "$subdir/$name"
779 } else {
780 set testname $opts(name)
781 }
782
783 if { $opts(source) == "" } {
784 set sourcefiles [list ${file}.s]
785 } else {
786 set sourcefiles {}
787 foreach sf $opts(source) {
b7b0b729
HPN
788 if { [string match "/*" $sf] } {
789 lappend sourcefiles "$sf"
f364d1ca 790 } else {
b7b0b729
HPN
791 lappend sourcefiles "$srcdir/$subdir/$sf"
792 }
261def70
HPN
793 # Must have asflags indexed on source name.
794 set asflags($srcdir/$subdir/$sf) $asflags($sf)
795 }
796 }
797
798 # Time to setup xfailures.
799 foreach targ $opts(xfail) {
800 setup_xfail $targ
801 }
802
803 # Assemble each file.
804 set objfiles {}
805 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
806 set sourcefile [lindex $sourcefiles $i]
807
808 set objfile "tmpdir/dump$i.o"
30dabe8a 809 catch "exec rm -f $objfile" exec_output
261def70
HPN
810 lappend objfiles $objfile
811 set cmd "$AS $ASFLAGS $opts(as) $asflags($sourcefile) -o $objfile $sourcefile"
812
813 send_log "$cmd\n"
7f6a71ff
JM
814 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
815 remote_upload host "ld.tmp"
816 set comp_output [prune_warnings [file_contents "ld.tmp"]]
817 remote_file host delete "ld.tmp"
818 remote_file build delete "ld.tmp"
261def70 819
7f6a71ff 820 if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
261def70
HPN
821 send_log "$comp_output\n"
822 verbose "$comp_output" 3
f364d1ca
AM
823
824 set exitstat "succeeded"
825 if { $cmdret != 0 } { set exitstat "failed" }
826 verbose -log "$exitstat with: <$comp_output>"
261def70
HPN
827 fail $testname
828 return
829 }
830 }
831
f364d1ca
AM
832 set expmsg $opts(error)
833 if { $opts(warning) != "" } {
834 if { $expmsg != "" } {
835 perror "$testname: mixing error and warning test-directives"
836 return
837 }
838 set expmsg $opts(warning)
839 }
840
261def70
HPN
841 # Perhaps link the file(s).
842 if { $run_ld } {
843 set objfile "tmpdir/dump"
30dabe8a 844 catch "exec rm -f $objfile" exec_output
3e3f011f
RS
845
846 # Add -L$srcdir/$subdir so that the linker command can use
847 # linker scripts in the source directory.
848 set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
d6e0b160 849 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
261def70
HPN
850
851 send_log "$cmd\n"
7f6a71ff
JM
852 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
853 remote_upload host "ld.tmp"
d3746675 854 set comp_output [file_contents "ld.tmp"]
7f6a71ff
JM
855 remote_file host delete "ld.tmp"
856 remote_file build delete "ld.tmp"
857 set cmdret [lindex $cmdret 0]
cfe5266f 858
f364d1ca 859 if { $cmdret == 0 && $run_objcopy } {
cfe5266f
HPN
860 set infile $objfile
861 set objfile "tmpdir/dump1"
7f6a71ff 862 remote_file host delete $objfile
cfe5266f
HPN
863
864 # Note that we don't use OBJCOPYFLAGS here; any flags must be
865 # explicitly specified.
866 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
867
868 send_log "$cmd\n"
7f6a71ff
JM
869 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
870 remote_upload host "ld.tmp"
d3746675 871 append comp_output [file_contents "ld.tmp"]
7f6a71ff
JM
872 remote_file host delete "ld.tmp"
873 remote_file build delete "ld.tmp"
874 set cmdret [lindex $cmdret 0]
f364d1ca
AM
875 }
876
7f6a71ff 877 regsub "\n$" $comp_output "" comp_output
f364d1ca
AM
878 if { $cmdret != 0 || $comp_output != "" || $expmsg != "" } then {
879 set exitstat "succeeded"
880 if { $cmdret != 0 } { set exitstat "failed" }
881 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
882 send_log "$comp_output\n"
883 verbose "$comp_output" 3
884
885 if { [regexp $expmsg $comp_output] \
886 && (($cmdret == 0) == ($opts(warning) != "")) } {
887 # We have the expected output from ld.
888 if { $opts(error) != "" || $program == "" } {
889 pass $testname
890 return
cfe5266f 891 }
f364d1ca
AM
892 } else {
893 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
cfe5266f
HPN
894 fail $testname
895 return
896 }
897 }
261def70
HPN
898 } else {
899 set objfile "tmpdir/dump0.o"
900 }
901
902 # We must not have expected failure if we get here.
903 if { $opts(error) != "" } {
904 fail $testname
cfe5266f 905 return
261def70
HPN
906 }
907
f364d1ca
AM
908 set progopts1 $opts($program)
909 eval set progopts \$[string toupper $program]FLAGS
910 eval set binary \$[string toupper $program]
911
7f6a71ff 912 if { ![is_remote host] && [which $binary] == 0 } {
261def70
HPN
913 untested $testname
914 return
915 }
916
917 if { $progopts1 == "" } { set $progopts1 "-r" }
918 verbose "running $binary $progopts $progopts1" 3
919
920 # Objcopy, unlike the other two, won't send its output to stdout,
921 # so we have to run it specially.
3e8cba19 922 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
261def70
HPN
923 if { $program == "objcopy" } {
924 set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
3e8cba19
AM
925 }
926
927 # Ensure consistent sorting of symbols
928 if {[info exists env(LC_ALL)]} {
929 set old_lc_all $env(LC_ALL)
930 }
931 set env(LC_ALL) "C"
932 send_log "$cmd\n"
7f6a71ff
JM
933 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
934 remote_upload host "ld.tmp"
935 set comp_output [prune_warnings [file_contents "ld.tmp"]]
936 remote_file host delete "ld.tmp"
937 remote_file build delete "ld.tmp"
3e8cba19
AM
938 if {[info exists old_lc_all]} {
939 set env(LC_ALL) $old_lc_all
261def70 940 } else {
3e8cba19
AM
941 unset env(LC_ALL)
942 }
3e8cba19
AM
943 if ![string match "" $comp_output] then {
944 send_log "$comp_output\n"
945 fail $testname
946 return
261def70
HPN
947 }
948
949 verbose_eval {[file_contents $dumpfile]} 3
950 if { [regexp_diff $dumpfile "${file}.d"] } then {
951 fail $testname
952 verbose "output is [file_contents $dumpfile]" 2
953 return
954 }
955
956 pass $testname
957}
958
959proc slurp_options { file } {
960 if [catch { set f [open $file r] } x] {
961 #perror "couldn't open `$file': $x"
962 perror "$x"
963 return -1
964 }
965 set opt_array {}
966 # whitespace expression
967 set ws {[ ]*}
968 set nws {[^ ]*}
969 # whitespace is ignored anywhere except within the options list;
cfe5266f
HPN
970 # option names are alphabetic plus underscore only.
971 set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
261def70
HPN
972 while { [gets $f line] != -1 } {
973 set line [string trim $line]
974 # Whitespace here is space-tab.
975 if [regexp $pat $line xxx opt_name opt_val] {
976 # match!
977 lappend opt_array [list $opt_name $opt_val]
978 } else {
979 break
980 }
981 }
982 close $f
983 return $opt_array
984}
985
986# regexp_diff, copied from gas, based on simple_diff above.
987# compares two files line-by-line
988# file1 contains strings, file2 contains regexps and #-comments
989# blank lines are ignored in either file
990# returns non-zero if differences exist
991#
992proc regexp_diff { file_1 file_2 } {
993
994 set eof -1
995 set end_1 0
996 set end_2 0
997 set differences 0
998 set diff_pass 0
999
1000 if [file exists $file_1] then {
1001 set file_a [open $file_1 r]
1002 } else {
1003 warning "$file_1 doesn't exist"
1004 return 1
1005 }
1006
1007 if [file exists $file_2] then {
1008 set file_b [open $file_2 r]
1009 } else {
1010 fail "$file_2 doesn't exist"
1011 close $file_a
1012 return 1
1013 }
1014
1015 verbose " Regexp-diff'ing: $file_1 $file_2" 2
1016
1017 while { 1 } {
1018 set line_a ""
1019 set line_b ""
1020 while { [string length $line_a] == 0 } {
1021 if { [gets $file_a line_a] == $eof } {
1022 set end_1 1
1023 break
1024 }
1025 }
1026 while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
1027 if [ string match "#pass" $line_b ] {
1028 set end_2 1
1029 set diff_pass 1
1030 break
1031 } elseif [ string match "#..." $line_b ] {
1032 if { [gets $file_b line_b] == $eof } {
1033 set end_2 1
5cfd5a0c 1034 set diff_pass 1
261def70
HPN
1035 break
1036 }
1037 verbose "looking for \"^$line_b$\"" 3
1038 while { ![regexp "^$line_b$" "$line_a"] } {
1039 verbose "skipping \"$line_a\"" 3
1040 if { [gets $file_a line_a] == $eof } {
1041 set end_1 1
1042 break
1043 }
1044 }
1045 break
1046 }
1047 if { [gets $file_b line_b] == $eof } {
1048 set end_2 1
1049 break
1050 }
1051 }
1052
3e8cba19
AM
1053 if { $diff_pass } {
1054 break
1055 } elseif { $end_1 && $end_2 } {
261def70
HPN
1056 break
1057 } elseif { $end_1 } {
1058 send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
1059 verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
1060 set differences 1
1061 break
1062 } elseif { $end_2 } {
1063 send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
1064 verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
1065 set differences 1
1066 break
1067 } else {
1068 verbose "regexp \"^$line_b$\"\nline \"$line_a\"" 3
1069 if ![regexp "^$line_b$" "$line_a"] {
1070 send_log "regexp_diff match failure\n"
1071 send_log "regexp \"^$line_b$\"\nline \"$line_a\"\n"
1072 set differences 1
1073 }
1074 }
1075 }
1076
1077 if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
1078 send_log "$file_1 and $file_2 are different lengths\n"
1079 verbose "$file_1 and $file_2 are different lengths" 3
1080 set differences 1
1081 }
1082
1083 close $file_a
1084 close $file_b
1085
1086 return $differences
1087}
1088
1089proc file_contents { filename } {
1090 set file [open $filename r]
1091 set contents [read $file]
1092 close $file
1093 return $contents
1094}
bffbf940 1095
9147e853
JJ
1096# List contains test-items with 3 items followed by 2 lists, one item and
1097# one optional item:
bffbf940
JJ
1098# 0:name 1:ld options 2:assembler options
1099# 3:filenames of assembler files 4: action and options. 5: name of output file
9147e853 1100# 6:compiler flags (optional)
3b6fe0cc 1101#
bffbf940
JJ
1102# Actions:
1103# objdump: Apply objdump options on result. Compare with regex (last arg).
1104# nm: Apply nm options on result. Compare with regex (last arg).
1105# readelf: Apply readelf options on result. Compare with regex (last arg).
3b6fe0cc 1106#
bffbf940
JJ
1107proc run_ld_link_tests { ldtests } {
1108 global ld
1109 global as
1110 global nm
1111 global objdump
1112 global READELF
1113 global srcdir
1114 global subdir
1115 global env
9147e853
JJ
1116 global CC
1117 global CFLAGS
bffbf940
JJ
1118
1119 foreach testitem $ldtests {
1120 set testname [lindex $testitem 0]
1121 set ld_options [lindex $testitem 1]
1122 set as_options [lindex $testitem 2]
9147e853 1123 set src_files [lindex $testitem 3]
bffbf940
JJ
1124 set actions [lindex $testitem 4]
1125 set binfile tmpdir/[lindex $testitem 5]
9147e853 1126 set cflags [lindex $testitem 6]
bffbf940
JJ
1127 set objfiles {}
1128 set is_unresolved 0
1129 set failed 0
1130
1131# verbose -log "Testname is $testname"
1132# verbose -log "ld_options is $ld_options"
1133# verbose -log "as_options is $as_options"
9147e853 1134# verbose -log "src_files is $src_files"
bffbf940
JJ
1135# verbose -log "actions is $actions"
1136# verbose -log "binfile is $binfile"
1137
1138 # Assemble each file in the test.
9147e853
JJ
1139 foreach src_file $src_files {
1140 set objfile "tmpdir/[file rootname $src_file].o"
bffbf940
JJ
1141 lappend objfiles $objfile
1142
9147e853
JJ
1143 if { [file extension $src_file] == ".c" } {
1144 set as_file "tmpdir/[file rootname $src_file].s"
1145 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1146 set is_unresolved 1
1147 break
1148 }
1149 } else {
1150 set as_file "$srcdir/$subdir/$src_file"
1151 }
1152 if ![ld_assemble $as "$as_options $as_file" $objfile] {
bffbf940
JJ
1153 set is_unresolved 1
1154 break
1155 }
1156 }
1157
1158 # Catch assembler errors.
1159 if { $is_unresolved != 0 } {
1160 unresolved $testname
1161 continue
1162 }
1163
1164 if ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1165 fail $testname
1166 } else {
1167 set failed 0
1168 foreach actionlist $actions {
1169 set action [lindex $actionlist 0]
1170 set progopts [lindex $actionlist 1]
1171
1172 # There are actions where we run regexp_diff on the
1173 # output, and there are other actions (presumably).
1174 # Handling of the former look the same.
1175 set dump_prog ""
1176 switch -- $action {
1177 objdump
1178 { set dump_prog $objdump }
1179 nm
1180 { set dump_prog $nm }
1181 readelf
1182 { set dump_prog $READELF }
1183 default
1184 {
1185 perror "Unrecognized action $action"
1186 set is_unresolved 1
1187 break
1188 }
1189 }
1190
1191 if { $dump_prog != "" } {
1192 set dumpfile [lindex $actionlist 2]
1193 set binary $dump_prog
1194
1195 # Ensure consistent sorting of symbols
1196 if {[info exists env(LC_ALL)]} {
1197 set old_lc_all $env(LC_ALL)
1198 }
1199 set env(LC_ALL) "C"
7f6a71ff
JM
1200 set cmd "$binary $progopts $binfile"
1201 set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
bffbf940 1202 send_log "$cmd\n"
7f6a71ff
JM
1203 remote_upload host "ld.stderr"
1204 set comp_output [prune_warnings [file_contents "ld.stderr"]]
1205 remote_file host delete "ld.stderr"
1206 remote_file build delete "ld.stderr"
1207
bffbf940
JJ
1208 if {[info exists old_lc_all]} {
1209 set env(LC_ALL) $old_lc_all
1210 } else {
1211 unset env(LC_ALL)
1212 }
bffbf940
JJ
1213
1214 if ![string match "" $comp_output] then {
1215 send_log "$comp_output\n"
1216 set failed 1
1217 break
1218 }
1219
7f6a71ff
JM
1220 remote_upload host "dump.out"
1221
bffbf940
JJ
1222 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1223 verbose "output is [file_contents "dump.out"]" 2
1224 set failed 1
7f6a71ff
JM
1225 remote_file build delete "dump.out"
1226 remote_file host delete "dump.out"
bffbf940
JJ
1227 break
1228 }
7f6a71ff
JM
1229 remote_file build delete "dump.out"
1230 remote_file host delete "dump.out"
bffbf940
JJ
1231 }
1232 }
1233
1234 if { $failed != 0 } {
1235 fail $testname
1236 } else { if { $is_unresolved == 0 } {
1237 pass $testname
1238 } }
1239 }
1240
1241 # Catch action errors.
1242 if { $is_unresolved != 0 } {
1243 unresolved $testname
1244 continue
1245 }
1246 }
1247}
1248
261def70
HPN
1249
1250proc verbose_eval { expr { level 1 } } {
1251 global verbose
1252 if $verbose>$level then { eval verbose "$expr" $level }
1253}
1254
252b5132
RH
1255# This definition is taken from an unreleased version of DejaGnu. Once
1256# that version gets released, and has been out in the world for a few
1257# months at least, it may be safe to delete this copy.
1258if ![string length [info proc prune_warnings]] {
1259 #
1260 # prune_warnings -- delete various system verbosities from TEXT
1261 #
1262 # An example is:
1263 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1264 #
1265 # Sites with particular verbose os's may wish to override this in site.exp.
1266 #
1267 proc prune_warnings { text } {
1268 # This is from sun4's. Do it for all machines for now.
1269 # The "\\1" is to try to preserve a "\n" but only if necessary.
1270 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1271
1272 # It might be tempting to get carried away and delete blank lines, etc.
1273 # Just delete *exactly* what we're ask to, and that's it.
1274 return $text
1275 }
1276}
24edc24d 1277
c8c140d9
BE
1278# targets_to_xfail is a list of target triplets to be xfailed.
1279# ldtests contains test-items with 3 items followed by 1 lists, 2 items
fab4a87f 1280# and 3 optional items:
c8c140d9
BE
1281# 0:name
1282# 1:ld options
1283# 2:assembler options
55255dae 1284# 3:filenames of source files
c8c140d9
BE
1285# 4:name of output file
1286# 5:expected output
1287# 6:compiler flags (optional)
55255dae 1288# 7:language (optional)
fab4a87f 1289# 8:linker warning (optional)
c8c140d9
BE
1290
1291proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
24edc24d
L
1292 global ld
1293 global as
1294 global srcdir
1295 global subdir
1296 global env
1297 global CC
55255dae 1298 global CXX
24edc24d 1299 global CFLAGS
58ffc3bd 1300 global CXXFLAGS
22ec3bd1 1301 global errcnt
fab4a87f 1302 global exec_output
24edc24d
L
1303
1304 foreach testitem $ldtests {
c8c140d9
BE
1305 foreach target $targets_to_xfail {
1306 setup_xfail $target
1307 }
24edc24d
L
1308 set testname [lindex $testitem 0]
1309 set ld_options [lindex $testitem 1]
1310 set as_options [lindex $testitem 2]
1311 set src_files [lindex $testitem 3]
1312 set binfile tmpdir/[lindex $testitem 4]
1313 set expfile [lindex $testitem 5]
1314 set cflags [lindex $testitem 6]
55255dae 1315 set lang [lindex $testitem 7]
fab4a87f 1316 set warning [lindex $testitem 8]
24edc24d 1317 set objfiles {}
24edc24d
L
1318 set failed 0
1319
1320# verbose -log "Testname is $testname"
1321# verbose -log "ld_options is $ld_options"
1322# verbose -log "as_options is $as_options"
1323# verbose -log "src_files is $src_files"
1324# verbose -log "actions is $actions"
1325# verbose -log "binfile is $binfile"
1326
1327 # Assemble each file in the test.
1328 foreach src_file $src_files {
1329 set objfile "tmpdir/[file rootname $src_file].o"
1330 lappend objfiles $objfile
1331
a10e6b21
L
1332 # We ignore warnings since some compilers may generate
1333 # incorrect section attributes and the assembler will warn
1334 # them.
58ffc3bd
MF
1335 if { [ string match "c++" $lang ] } {
1336 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1337 } else {
1338 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1339 }
a10e6b21
L
1340
1341 # We have to use $CC to build PIE and shared library.
55255dae
L
1342 if { [ string match "c" $lang ] } {
1343 set link_proc ld_simple_link
1344 set link_cmd $CC
1345 } elseif { [ string match "c++" $lang ] } {
1346 set link_proc ld_simple_link
1347 set link_cmd $CXX
1348 } elseif { [ string match "-shared" $ld_options ] \
a10e6b21
L
1349 || [ string match "-pie" $ld_options ] } {
1350 set link_proc ld_simple_link
1351 set link_cmd $CC
1352 } else {
1353 set link_proc ld_link
1354 set link_cmd $ld
1355 }
24edc24d 1356
a10e6b21 1357 if ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
24edc24d
L
1358 set failed 1
1359 } else {
a10e6b21 1360 set failed 0
fab4a87f
L
1361 }
1362
1363 # Check if exec_output is expected.
1364 if { $warning != "" } then {
1365 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1366 if { [regexp $warning $exec_output] } then {
1367 set failed 0
1368 } else {
1369 set failed 1
1370 }
1371 }
1372
1373 if { $failed == 0 } {
a10e6b21
L
1374 send_log "Running: $binfile > $binfile.out\n"
1375 verbose "Running: $binfile > $binfile.out"
1376 catch "exec $binfile > $binfile.out" exec_output
1377
24edc24d
L
1378 if ![string match "" $exec_output] then {
1379 send_log "$exec_output\n"
1380 verbose "$exec_output" 1
1381 set failed 1
a10e6b21
L
1382 } else {
1383 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1384 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1385 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1386 set exec_output [prune_warnings $exec_output]
1387
1388 if ![string match "" $exec_output] then {
1389 send_log "$exec_output\n"
1390 verbose "$exec_output" 1
1391 set failed 1
1392 }
24edc24d
L
1393 }
1394 }
1395
1396 if { $failed != 0 } {
1397 fail $testname
22ec3bd1
L
1398 } else {
1399 set errcnt 0
24edc24d 1400 pass $testname
a10e6b21 1401 }
24edc24d 1402 }
24edc24d
L
1403 }
1404}
d2dee3b2
L
1405
1406# List contains test-items with 3 items followed by 2 lists, one item and
1407# one optional item:
55255dae
L
1408# 0:name
1409# 1:link options
1410# 2:compile options
1411# 3:filenames of source files
1412# 4:action and options.
1413# 5:name of output file
1414# 6:language (optional)
d2dee3b2
L
1415#
1416# Actions:
1417# objdump: Apply objdump options on result. Compare with regex (last arg).
1418# nm: Apply nm options on result. Compare with regex (last arg).
1419# readelf: Apply readelf options on result. Compare with regex (last arg).
1420#
1421proc run_cc_link_tests { ldtests } {
1422 global nm
1423 global objdump
1424 global READELF
1425 global srcdir
1426 global subdir
1427 global env
1428 global CC
55255dae 1429 global CXX
d2dee3b2 1430 global CFLAGS
58ffc3bd 1431 global CXXFLAGS
d2dee3b2
L
1432
1433 foreach testitem $ldtests {
1434 set testname [lindex $testitem 0]
1435 set ldflags [lindex $testitem 1]
1436 set cflags [lindex $testitem 2]
1437 set src_files [lindex $testitem 3]
1438 set actions [lindex $testitem 4]
1439 set binfile tmpdir/[lindex $testitem 5]
55255dae 1440 set lang [lindex $testitem 6]
d2dee3b2
L
1441 set objfiles {}
1442 set is_unresolved 0
1443 set failed 0
1444
1445 # Compile each file in the test.
1446 foreach src_file $src_files {
1447 set objfile "tmpdir/[file rootname $src_file].o"
1448 lappend objfiles $objfile
1449
1450 # We ignore warnings since some compilers may generate
1451 # incorrect section attributes and the assembler will warn
1452 # them.
58ffc3bd
MF
1453 if { [ string match "c++" $lang ] } {
1454 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1455 } else {
1456 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1457 }
d2dee3b2
L
1458 }
1459
1460 # Clear error and warning counts.
1461 reset_vars
1462
55255dae
L
1463 if { [ string match "c++" $lang ] } {
1464 set cc_cmd $CXX
1465 } else {
1466 set cc_cmd $CC
1467 }
1468
1469 if ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] {
d2dee3b2
L
1470 fail $testname
1471 } else {
1472 set failed 0
1473 foreach actionlist $actions {
1474 set action [lindex $actionlist 0]
1475 set progopts [lindex $actionlist 1]
1476
1477 # There are actions where we run regexp_diff on the
1478 # output, and there are other actions (presumably).
1479 # Handling of the former look the same.
1480 set dump_prog ""
1481 switch -- $action {
1482 objdump
1483 { set dump_prog $objdump }
1484 nm
1485 { set dump_prog $nm }
1486 readelf
1487 { set dump_prog $READELF }
1488 default
1489 {
1490 perror "Unrecognized action $action"
1491 set is_unresolved 1
1492 break
1493 }
1494 }
1495
1496 if { $dump_prog != "" } {
1497 set dumpfile [lindex $actionlist 2]
1498 set binary $dump_prog
1499
1500 # Ensure consistent sorting of symbols
1501 if {[info exists env(LC_ALL)]} {
1502 set old_lc_all $env(LC_ALL)
1503 }
1504 set env(LC_ALL) "C"
1505 set cmd "$binary $progopts $binfile > dump.out"
1506 send_log "$cmd\n"
1507 catch "exec $cmd" comp_output
1508 if {[info exists old_lc_all]} {
1509 set env(LC_ALL) $old_lc_all
1510 } else {
1511 unset env(LC_ALL)
1512 }
1513 set comp_output [prune_warnings $comp_output]
1514
1515 if ![string match "" $comp_output] then {
1516 send_log "$comp_output\n"
1517 set failed 1
1518 break
1519 }
1520
1521 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1522 verbose "output is [file_contents "dump.out"]" 2
1523 set failed 1
1524 break
1525 }
1526 }
1527 }
1528
1529 if { $failed != 0 } {
1530 fail $testname
1531 } else { if { $is_unresolved == 0 } {
1532 pass $testname
1533 } }
1534 }
1535
1536 # Catch action errors.
1537 if { $is_unresolved != 0 } {
1538 unresolved $testname
1539 continue
1540 }
1541 }
1542}
430a16a5
NC
1543
1544# Returns true if --gc-sections is supported on the target.
1545
1546proc check_gc_sections_available { } {
1547 global gc_sections_available_saved
1548 global ld
1549
1550 if {![info exists gc_sections_available_saved]} {
1551 # Some targets don't support gc-sections despite whatever's
1552 # advertised by ld's options.
1553 if { [istarget alpha*-*-*]
1554 || [istarget ia64-*-*] } {
1555 set gc_sections_available_saved 0
1556 return 0
1557 }
1558
1559 # elf2flt uses -q (--emit-relocs), which is incompatible with
1560 # --gc-sections.
1561 if { [board_info target exists ldflags]
1562 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1563 set gc_sections_available_saved 0
1564 return 0
1565 }
1566
430a16a5
NC
1567 # Check if the ld used by gcc supports --gc-sections.
1568 set ld_output [remote_exec host $ld "--help"]
1569 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1570 set gc_sections_available_saved 1
1571 } else {
1572 set gc_sections_available_saved 0
1573 }
1574 }
1575 return $gc_sections_available_saved
1576}
33aa234e
JK
1577
1578# Check if the assembler supports CFI statements.
1579
1580proc check_as_cfi { } {
1581 global check_as_cfi_result
1582 global as
1583 if [info exists check_as_cfi_result] {
1584 return $check_as_cfi_result
1585 }
1586 set as_file "tmpdir/check_as_cfi.s"
1587 set as_fh [open $as_file w 0666]
1588 puts $as_fh "# Generated file. DO NOT EDIT"
1589 puts $as_fh "\t.cfi_startproc"
1590 puts $as_fh "\t.cfi_endproc"
1591 close $as_fh
1592 remote_download host $as_file
1593 verbose -log "Checking CFI support:"
1594 rename "perror" "check_as_cfi_perror"
1595 proc perror { args } { }
1596 set success [ld_assemble $as $as_file "/dev/null"]
1597 rename "perror" ""
1598 rename "check_as_cfi_perror" "perror"
1599 #remote_file host delete $as_file
1600 set check_as_cfi_result $success
1601 return $success
1602}
1603
1604# Provide virtual target "cfi" for targets supporting CFI.
1605
1606rename "istarget" "istarget_ld"
1607proc istarget { target } {
1608 if {$target == "cfi"} {
1609 return [check_as_cfi]
1610 }
1611 return [istarget_ld $target]
1612}
This page took 0.463256 seconds and 4 git commands to generate.