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