Use better test for usable compiler in ld testsuite.
[deliverable/binutils-gdb.git] / ld / testsuite / lib / ld-lib.exp
CommitLineData
a2b64bed 1# Support routines for LD testsuite.
82704155 2# Copyright (C) 1994-2019 Free Software Foundation, Inc.
a2b64bed 3#
f96b4a7b
NC
4# This file is part of the GNU Binutils.
5#
a2b64bed
NC
6# This file is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
f96b4a7b 8# the Free Software Foundation; either version 3 of the License, or
a2b64bed 9# (at your option) any later version.
3e8cba19 10#
a2b64bed
NC
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
3e8cba19 15#
a2b64bed
NC
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
f96b4a7b
NC
18# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19# MA 02110-1301, USA.
3b6fe0cc 20
f3097f33
RS
21proc load_common_lib { name } {
22 global srcdir
23 load_file $srcdir/../../binutils/testsuite/lib/$name
24}
25
26load_common_lib binutils-common.exp
27
fb35d3d8
DD
28# Returns 1 if the gcc for the target is at least version MAJOR.MINOR
29# Returns 0 otherwise.
30#
31proc at_least_gcc_version { major minor } {
68bce020 32 global CC
5a68afcf 33
fb35d3d8
DD
34 if {![info exists CC]} {
35 set CC [find_gcc]
36 }
37 if { $CC == "" } {
8be1e369 38 return 0
fb35d3d8
DD
39 }
40 set state [remote_exec host $CC --version]
8be1e369
AM
41 if { [lindex $state 0] != 0 } {
42 return 0;
43 }
fb35d3d8
DD
44 set tmp "[lindex $state 1]\n"
45 # Look for (eg) 4.6.1 in the version output.
8b5b2228
MR
46 set ver_re "\[^\\.0-9\]+(\[1-9\]\[0-9\]*)\\.(\[0-9\]+)(?:\\.\[0-9\]+)?"
47 regexp $ver_re $tmp fred maj min
fb35d3d8 48 verbose "gcc version: $tmp"
8b5b2228
MR
49 if { ![info exists maj] || ![info exists min] } then {
50 perror "can't decipher gcc version number, fix the framework!"
51 return 0
52 }
fb35d3d8
DD
53 verbose "major gcc version is $maj, want at least $major"
54 if { $maj == $major } then {
55 verbose "minor gcc version is $min, want at least $minor"
8b5b2228 56 return [expr $min >= $minor]
fb35d3d8 57 } else {
8b5b2228 58 return [expr $maj > $major]
fb35d3d8
DD
59 }
60}
61
3b6fe0cc 62# Extract and print the version number of ld.
252b5132
RH
63#
64proc default_ld_version { ld } {
65 global host_triplet
66
7f6a71ff 67 if { ![is_remote host] && [which $ld] == 0 } then {
252b5132
RH
68 perror "$ld does not exist"
69 exit 1
70 }
3e8cba19 71
7f6a71ff
JM
72 remote_exec host "$ld --version" "" "/dev/null" "ld.version"
73 remote_upload host "ld.version"
74 set tmp [prune_warnings [file_contents "ld.version"]]
75 remote_file build delete "ld.version"
76 remote_file host delete "ld.version"
77
252b5132
RH
78 regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number
79 if [info exists number] then {
80 clone_output "$ld $number\n"
81 }
82}
83
7f6a71ff
JM
84proc run_host_cmd { prog command } {
85 global link_output
f1d7f4a6
AM
86 global gcc_B_opt
87 global ld_L_opt
5a8edf8e
AM
88 global gcc_ld_B_opt_tested
89 global ld
3e8cba19 90
7f6a71ff
JM
91 if { ![is_remote host] && [which "$prog"] == 0 } then {
92 perror "$prog does not exist"
252b5132
RH
93 return 0
94 }
3e8cba19 95
f1d7f4a6
AM
96 # If we are compiling with gcc, we want to add gcc_B_opt and
97 # ld_L_opt to flags. However, if $prog already has -B options,
98 # which might be the case when running gcc out of a build
99 # directory, we want our -B options to come first.
100 set gccexe $prog
101 set gccparm [string first " " $gccexe]
102 set gccflags ""
103 if { $gccparm > 0 } then {
104 set gccflags [string range $gccexe $gccparm end]
105 set gccexe [string range $gccexe 0 $gccparm]
106 set prog $gccexe
107 }
108 set gccexe [string replace $gccexe 0 [string last "/" $gccexe] ""]
109 if {[string match "*cc*" $gccexe] || [string match "*++*" $gccexe]} then {
110 set gccflags "$gcc_B_opt $gccflags $ld_L_opt"
5a8edf8e
AM
111 if {![info exists gcc_ld_B_opt_tested]} {
112 set gcc_ld_B_opt_tested 1
113 set ld_version_message [run_host_cmd "$ld" "--version"]
114 set gcc_ld_version_message [run_host_cmd "$prog" "$gccflags -Wl,--version"]
115 if {[string first $ld_version_message $gcc_ld_version_message] < 0} {
116 perror "************************************************************************"
117 perror "Your compiler driver ignores -B when choosing ld."
118 perror "You will not be testing the new ld in many of the following tests."
119 set gcc_ld_version [run_host_cmd "$prog" "$gccflags --print-prog-name=ld"]
120 if {![string match "" $gcc_ld_version] && ![string match "ld" $gcc_ld_version]} {
121
122 perror "It seems you will be testing $gcc_ld_version instead."
123 }
124 perror "************************************************************************"
125 }
126 }
f1d7f4a6
AM
127 }
128
129 verbose -log "$prog $gccflags $command"
130 set status [remote_exec host [concat sh -c [list "$prog $gccflags $command 2>&1"]] "" "/dev/null" "ld.tmp"]
7f6a71ff
JM
131 remote_upload host "ld.tmp"
132 set link_output [file_contents "ld.tmp"]
133 regsub "\n$" $link_output "" link_output
134 if { [lindex $status 0] != 0 && [string match "" $link_output] } then {
135 append link_output "child process exited abnormally"
136 }
137 remote_file build delete ld.tmp
138 remote_file host delete ld.tmp
fab4a87f 139
7f6a71ff
JM
140 if [string match "" $link_output] then {
141 return ""
142 }
3e8cba19 143
7f6a71ff
JM
144 verbose -log "$link_output"
145 return "$link_output"
146}
147
148proc run_host_cmd_yesno { prog command } {
149 global exec_output
d76b6207 150 global errcnt warncnt
7f6a71ff
JM
151
152 set exec_output [prune_warnings [run_host_cmd "$prog" "$command"]]
d76b6207
L
153 # Ignore error and warning.
154 set errcnt 0
155 set warncnt 0
252b5132 156 if [string match "" $exec_output] then {
7f6a71ff 157 return 1;
252b5132 158 }
7f6a71ff
JM
159 return 0;
160}
161
162# Link an object using relocation.
163#
164proc default_ld_relocate { ld target objects } {
165 global HOSTING_EMU
166
167 remote_file host delete $target
168 return [run_host_cmd_yesno "$ld" "$HOSTING_EMU -o $target -r $objects"]
252b5132
RH
169}
170
1688b748 171# Check to see if ld is being invoked with a non-endian output format
3b6fe0cc 172#
1688b748
MH
173proc is_endian_output_format { object_flags } {
174
175 if {[string match "*-oformat binary*" $object_flags] || \
176 [string match "*-oformat ieee*" $object_flags] || \
177 [string match "*-oformat ihex*" $object_flags] || \
178 [string match "*-oformat netbsd-core*" $object_flags] || \
179 [string match "*-oformat srec*" $object_flags] || \
180 [string match "*-oformat tekhex*" $object_flags] || \
181 [string match "*-oformat trad-core*" $object_flags] } then {
182 return 0
183 } else {
184 return 1
185 }
186}
187
d9816402 188# Link a program using ld
252b5132
RH
189#
190proc default_ld_link { ld target objects } {
252b5132 191 global host_triplet
fab4a87f 192 global exec_output
7cda33a1 193
f1d7f4a6 194 set flags ""
1688b748
MH
195 if [is_endian_output_format $objects] then {
196 set flags [big_or_little_endian]
b765d4e3
L
197 }
198
7f6a71ff 199 remote_file host delete $target
f1d7f4a6 200 set exec_output [run_host_cmd "$ld" "$flags -o $target $objects"]
7f6a71ff 201 set exec_output [prune_warnings $exec_output]
252b5132
RH
202
203 # We don't care if we get a warning about a non-existent start
204 # symbol, since the default linker script might use ENTRY.
205 regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
206
f1d7f4a6 207 return [string match "" $exec_output]
252b5132
RH
208}
209
3b6fe0cc 210# Compile an object using cc.
252b5132
RH
211#
212proc default_ld_compile { cc source object } {
213 global CFLAGS
58ffc3bd 214 global CXXFLAGS
252b5132
RH
215 global srcdir
216 global subdir
217 global host_triplet
f1d7f4a6 218 global gcc_B_opt
252b5132
RH
219
220 set cc_prog $cc
221 if {[llength $cc_prog] > 1} then {
222 set cc_prog [lindex $cc_prog 0]
223 }
7f6a71ff 224 if {![is_remote host] && [which $cc_prog] == 0} then {
252b5132
RH
225 perror "$cc_prog does not exist"
226 return 0
227 }
228
7f6a71ff
JM
229 remote_file build delete "$object"
230 remote_file host delete "$object"
252b5132 231
f1d7f4a6 232 set flags "$gcc_B_opt -I$srcdir/$subdir"
252b5132 233
f1d7f4a6
AM
234 # If we are compiling with gcc, we want to add gcc_B_opt to flags.
235 # However, if $prog already has -B options, which might be the
236 # case when running gcc out of a build directory, we want our -B
237 # options to come first.
b0fe1bf3
AM
238 set ccexe $cc
239 set ccparm [string first " " $cc]
dec20c9e 240 set ccflags ""
b0fe1bf3 241 if { $ccparm > 0 } then {
dec20c9e 242 set ccflags [string range $cc $ccparm end]
b0fe1bf3 243 set ccexe [string range $cc 0 $ccparm]
dec20c9e 244 set cc $ccexe
b0fe1bf3 245 }
252b5132 246
f1d7f4a6 247 set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""]
58ffc3bd 248 if {[string match "*++*" $ccexe]} {
f1d7f4a6 249 append flags " $CXXFLAGS"
58ffc3bd 250 } else {
f1d7f4a6 251 append flags " $CFLAGS"
58ffc3bd
MF
252 }
253
3046b3d3
VP
254 if [board_info [target_info name] exists cflags] {
255 append flags " [board_info [target_info name] cflags]"
256 }
257
38e31547 258 if [board_info [target_info name] exists multilib_flags] {
b24f926d 259 append flags " [board_info [target_info name] multilib_flags]"
38e31547
NC
260 }
261
f1d7f4a6
AM
262 set cmd "$cc $flags $ccflags -c $source -o $object"
263 verbose -log "$cmd"
252b5132 264
f1d7f4a6 265 set status [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
7f6a71ff
JM
266 remote_upload host "ld.tmp"
267 set exec_output [file_contents "ld.tmp"]
268 remote_file build delete "ld.tmp"
269 remote_file host delete "ld.tmp"
252b5132 270 set exec_output [prune_warnings $exec_output]
6f9dbcd4
AM
271 # Versions of gcc up to and including pre-release gcc-7, at least on
272 # some targets, generate .section directives with incorrect type.
273 # Ignore warnings from the assembler about this.
274 regsub -all "(^|\n)\[^\n\]*: ignoring incorrect section type \[^\n\]*" $exec_output "" exec_output
275 regsub -all "^\[^\n\]*: Assembler messages:\n" $exec_output "" exec_output
252b5132
RH
276 if [string match "" $exec_output] then {
277 if {![file exists $object]} then {
278 regexp ".*/(\[^/\]*)$" $source all dobj
279 regsub "\\.c" $dobj ".o" realobj
280 verbose "looking for $realobj"
7f6a71ff 281 if {[remote_file host exists $realobj]} then {
252b5132 282 verbose -log "mv $realobj $object"
7f6a71ff 283 remote_upload "$realobj" "$object"
252b5132
RH
284 } else {
285 perror "$object not found after compilation"
286 return 0
287 }
288 }
289 return 1
290 } else {
291 verbose -log "$exec_output"
292 perror "$source: compilation failed"
293 return 0
294 }
295}
296
3b6fe0cc 297# Assemble a file.
252b5132 298#
de1491f0 299proc default_ld_assemble { as in_flags source object } {
252b5132
RH
300 global ASFLAGS
301 global host_triplet
690f47bf
RS
302 global srcdir
303 global subdir
3e8cba19 304
252b5132
RH
305 if ![info exists ASFLAGS] { set ASFLAGS "" }
306
690f47bf 307 set flags "[big_or_little_endian] -I$srcdir/$subdir"
de1491f0 308 set exec_output [run_host_cmd "$as" "$flags $in_flags $ASFLAGS -o $object $source"]
252b5132
RH
309 set exec_output [prune_warnings $exec_output]
310 if [string match "" $exec_output] then {
311 return 1
312 } else {
252b5132
RH
313 perror "$source: assembly failed"
314 return 0
315 }
316}
317
3b6fe0cc 318# Run nm on a file, putting the result in the array nm_output.
252b5132 319#
992c450d 320proc default_ld_nm { nm nmflags object } {
252b5132
RH
321 global NMFLAGS
322 global nm_output
323 global host_triplet
324
77e0b0ef
ILT
325 if {[info exists nm_output]} {
326 unset nm_output
327 }
328
252b5132
RH
329 if ![info exists NMFLAGS] { set NMFLAGS "" }
330
3e8cba19
AM
331 # Ensure consistent sorting of symbols
332 if {[info exists env(LC_ALL)]} {
333 set old_lc_all $env(LC_ALL)
334 }
335 set env(LC_ALL) "C"
7f6a71ff 336
992c450d 337 verbose -log "$nm $NMFLAGS $nmflags $object >tmpdir/nm.out"
252b5132 338
7f6a71ff 339 set status [remote_exec host [concat sh -c [list "$nm $NMFLAGS $nmflags $object 2>ld.stderr"]] "" "/dev/null" "tmpdir/nm.out"]
3e8cba19
AM
340 if {[info exists old_lc_all]} {
341 set env(LC_ALL) $old_lc_all
342 } else {
343 unset env(LC_ALL)
344 }
7f6a71ff
JM
345 remote_upload host "ld.stderr"
346 remote_upload host "tmpdir/nm.out" "tmpdir/nm.out"
347 set exec_output [prune_warnings [file_contents "ld.stderr"]]
348 remote_file host delete "ld.stderr"
349 remote_file build delete "ld.stderr"
252b5132
RH
350 if [string match "" $exec_output] then {
351 set file [open tmpdir/nm.out r]
352 while { [gets $file line] != -1 } {
353 verbose "$line" 2
dbc37f89 354 if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] \\.*(.+)$" $line whole value name] {
252b5132
RH
355 set name [string trimleft $name "_"]
356 verbose "Setting nm_output($name) to 0x$value" 2
357 set nm_output($name) 0x$value
358 }
359 }
360 close $file
361 return 1
362 } else {
363 verbose -log "$exec_output"
364 perror "$object: nm failed"
365 return 0
366 }
367}
368
1b662205
AM
369# Define various symbols needed when not linking against all
370# target libs.
d9816402 371proc ld_link_defsyms {} {
1b662205
AM
372
373 set flags "--defsym __stack_chk_fail=0"
374
375 # ARM targets call __gccmain
8c5fc800 376 if {[istarget arm*-*-*]} {
1b662205
AM
377 append flags " --defsym __gccmain=0"
378 }
379
5a1431e6 380 # Windows targets need __main, some prefixed with underscore.
36fe835f 381 if {[istarget *-*-cygwin* ] || [istarget *-*-mingw*]} {
5a1431e6 382 append flags " --defsym __main=0 --defsym ___main=0"
36fe835f
DK
383 }
384
1b662205
AM
385 # PowerPC EABI code calls __eabi.
386 if {[istarget powerpc*-*-eabi*] || [istarget powerpc*-*-rtems*]} {
387 append flags " --defsym __eabi=0"
388 }
389
390 # mn10200 code calls __truncsipsi2_d0_d2.
391 if {[istarget mn10200*-*-*]} then {
392 append flags " --defsym __truncsipsi2_d0_d2=0"
393 }
394
395 # m6811/m6812 code has references to soft registers.
32d79e68 396 if {[istarget m6811-*-*] || [istarget m6812-*-*] || [istarget m68hc1*-*-*]} {
1b662205
AM
397 append flags " --defsym _.frame=0 --defsym _.d1=0 --defsym _.d2=0"
398 append flags " --defsym _.d3=0 --defsym _.d4=0"
399 append flags " --defsym _.tmp=0 --defsym _.xy=0 --defsym _.z=0"
400 }
401
402 # Some OpenBSD targets have ProPolice and reference __guard and
403 # __stack_smash_handler.
404 if [istarget *-*-openbsd*] {
405 append flags " --defsym __guard=0"
406 append flags " --defsym __stack_smash_handler=0"
407 }
408
409 return $flags
410}
411
d8880531
L
412# Create an archive using ar
413#
fa0a16b1 414proc ar_simple_create { ar aropts target objects } {
d8880531
L
415 remote_file host delete $target
416
1a215085 417 set exec_output [run_host_cmd "$ar" "-rc $aropts $target $objects"]
d8880531
L
418 set exec_output [prune_warnings $exec_output]
419
420 if [string match "" $exec_output] then {
421 send_log "$exec_output\n"
422 return 1
423 } else {
424 return 0
425 }
426}
427
9147e853
JJ
428# List contains test-items with 3 items followed by 2 lists, one item and
429# one optional item:
894891db 430# 0:name
897aea50
MR
431# 1:ld/ar leading options, placed before object files
432# 2:ld/ar trailing options, placed after object files
433# 3:assembler options
434# 4:filenames of assembler files
435# 5:list of actions, options and expected outputs.
436# 6:name of output file
437# 7:compiler flags (optional)
3b6fe0cc 438#
894891db
NC
439# Actions: { command command-line-options file-containg-expected-output-regexps }
440# Commands:
441# objdump: Apply objdump options on result.
442# nm: Apply nm options on result.
443# readelf: Apply readelf options on result.
5a68afcf 444# ld: Don't apply anything on result. Compare output during linking with
894891db
NC
445# the file containing regexps (which is the second arg, not the third).
446# Note that this *must* be the first action if it is to be used at all;
447# in all other cases, any output from the linker during linking is
448# treated as a sign of an error and FAILs the test.
3b6fe0cc 449#
5df1bc57
AM
450# args is an optional list of target triplets to be xfailed.
451#
452proc run_ld_link_tests { ldtests args } {
bffbf940
JJ
453 global ld
454 global as
455 global nm
d8880531 456 global ar
bffbf940
JJ
457 global objdump
458 global READELF
459 global srcdir
460 global subdir
461 global env
9147e853
JJ
462 global CC
463 global CFLAGS
eca41774 464 global runtests
5d3236ee 465 global exec_output
647e4d46
L
466 global ld_elf_shared_opt
467
468 if { [is_elf_format] && [check_shared_lib_support] } {
469 set ld_extra_opt "$ld_elf_shared_opt"
470 } else {
471 set ld_extra_opt ""
472 }
bffbf940
JJ
473
474 foreach testitem $ldtests {
475 set testname [lindex $testitem 0]
eca41774
DK
476
477 if ![runtest_file_p $runtests $testname] then {
478 continue
479 }
480
5df1bc57
AM
481 foreach target $args {
482 setup_xfail $target
483 }
484
bffbf940 485 set ld_options [lindex $testitem 1]
897aea50
MR
486 set ld_after [lindex $testitem 2]
487 set as_options [lindex $testitem 3]
488 set src_files [lindex $testitem 4]
489 set actions [lindex $testitem 5]
490 set binfile tmpdir/[lindex $testitem 6]
491 set cflags [lindex $testitem 7]
bffbf940
JJ
492 set objfiles {}
493 set is_unresolved 0
494 set failed 0
5d3236ee
DK
495 set maybe_failed 0
496 set ld_output ""
bffbf940
JJ
497
498# verbose -log "Testname is $testname"
499# verbose -log "ld_options is $ld_options"
897aea50 500# verbose -log "ld_after is $ld_after"
bffbf940 501# verbose -log "as_options is $as_options"
9147e853 502# verbose -log "src_files is $src_files"
bffbf940
JJ
503# verbose -log "actions is $actions"
504# verbose -log "binfile is $binfile"
505
506 # Assemble each file in the test.
9147e853 507 foreach src_file $src_files {
74d44110
MR
508 set fileroot "[file rootname [file tail $src_file]]"
509 set objfile "tmpdir/$fileroot.o"
bffbf940
JJ
510 lappend objfiles $objfile
511
9147e853 512 if { [file extension $src_file] == ".c" } {
74d44110 513 set as_file "tmpdir/$fileroot.s"
9147e853
JJ
514 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
515 set is_unresolved 1
516 break
517 }
518 } else {
519 set as_file "$srcdir/$subdir/$src_file"
520 }
521 if ![ld_assemble $as "$as_options $as_file" $objfile] {
bffbf940
JJ
522 set is_unresolved 1
523 break
524 }
525 }
526
527 # Catch assembler errors.
77c56f44 528 if { $is_unresolved } {
bffbf940
JJ
529 unresolved $testname
530 continue
531 }
532
abc868c6
AM
533 if { $binfile eq "tmpdir/" } {
534 # compile only
535 } elseif { [regexp ".*\\.a$" $binfile] } {
897aea50 536 if { ![ar_simple_create $ar $ld_options $binfile "$objfiles $ld_after"] } {
d8880531 537 set failed 1
d8880531 538 }
d9816402 539 } elseif { ![ld_link $ld $binfile "$ld_extra_opt -L$srcdir/$subdir $ld_options $objfiles $ld_after"] } {
5d3236ee
DK
540 set maybe_failed 1
541 set ld_output "$exec_output"
d8880531
L
542 }
543
77c56f44 544 if { !$failed } {
bffbf940
JJ
545 foreach actionlist $actions {
546 set action [lindex $actionlist 0]
547 set progopts [lindex $actionlist 1]
548
549 # There are actions where we run regexp_diff on the
550 # output, and there are other actions (presumably).
551 # Handling of the former look the same.
552 set dump_prog ""
553 switch -- $action {
554 objdump
555 { set dump_prog $objdump }
556 nm
557 { set dump_prog $nm }
558 readelf
559 { set dump_prog $READELF }
5d3236ee
DK
560 ld
561 { set dump_prog "ld" }
bffbf940
JJ
562 default
563 {
564 perror "Unrecognized action $action"
565 set is_unresolved 1
566 break
567 }
568 }
569
5d3236ee 570 if { $action == "ld" } {
894891db
NC
571 set regexpfile $progopts
572 verbose "regexpfile is $srcdir/$subdir/$regexpfile"
5d3236ee
DK
573 set_file_contents "tmpdir/ld.messages" "$ld_output"
574 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
894891db 575 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$regexpfile"] } then {
5d3236ee
DK
576 verbose "output is $ld_output" 2
577 set failed 1
578 break
579 }
580 set maybe_failed 0
77c56f44 581 } elseif { !$maybe_failed && $dump_prog != "" } {
bffbf940
JJ
582 set dumpfile [lindex $actionlist 2]
583 set binary $dump_prog
584
585 # Ensure consistent sorting of symbols
586 if {[info exists env(LC_ALL)]} {
587 set old_lc_all $env(LC_ALL)
588 }
589 set env(LC_ALL) "C"
7f6a71ff
JM
590 set cmd "$binary $progopts $binfile"
591 set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
bffbf940 592 send_log "$cmd\n"
7f6a71ff
JM
593 remote_upload host "ld.stderr"
594 set comp_output [prune_warnings [file_contents "ld.stderr"]]
595 remote_file host delete "ld.stderr"
596 remote_file build delete "ld.stderr"
5a68afcf 597
bffbf940
JJ
598 if {[info exists old_lc_all]} {
599 set env(LC_ALL) $old_lc_all
600 } else {
601 unset env(LC_ALL)
602 }
bffbf940
JJ
603
604 if ![string match "" $comp_output] then {
605 send_log "$comp_output\n"
606 set failed 1
607 break
608 }
609
7f6a71ff
JM
610 remote_upload host "dump.out"
611
bffbf940
JJ
612 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
613 verbose "output is [file_contents "dump.out"]" 2
614 set failed 1
7f6a71ff
JM
615 remote_file build delete "dump.out"
616 remote_file host delete "dump.out"
bffbf940
JJ
617 break
618 }
7f6a71ff
JM
619 remote_file build delete "dump.out"
620 remote_file host delete "dump.out"
bffbf940
JJ
621 }
622 }
bffbf940
JJ
623 }
624
77c56f44 625 if { $is_unresolved } {
bffbf940 626 unresolved $testname
77c56f44
RS
627 } elseif { $maybe_failed || $failed } {
628 fail $testname
629 } else {
630 pass $testname
bffbf940
JJ
631 }
632 }
633}
634
c8c140d9 635# ldtests contains test-items with 3 items followed by 1 lists, 2 items
fab4a87f 636# and 3 optional items:
c8c140d9 637# 0:name
fef75122 638# 1:ld leading options, placed before object files
c8c140d9 639# 2:assembler options
55255dae 640# 3:filenames of source files
c8c140d9
BE
641# 4:name of output file
642# 5:expected output
643# 6:compiler flags (optional)
55255dae 644# 7:language (optional)
fab4a87f 645# 8:linker warning (optional)
fef75122 646# 9:ld trailing options, placed after object files (optional)
982c6f26 647# args is an optional list of target triplets to be xfailed.
c8c140d9 648
982c6f26 649proc run_ld_link_exec_tests { ldtests args } {
24edc24d
L
650 global ld
651 global as
652 global srcdir
653 global subdir
654 global env
655 global CC
55255dae 656 global CXX
24edc24d 657 global CFLAGS
58ffc3bd 658 global CXXFLAGS
22ec3bd1 659 global errcnt
fab4a87f 660 global exec_output
9966f7ee 661 global board_cflags
98d72909 662 global STATIC_LDFLAGS
9966f7ee
JW
663
664 # When using GCC as the linker driver, we need to specify board cflags when
665 # linking because cflags may contain linker options. For example when
666 # linker options are included in GCC spec files then we need the -specs
667 # option.
668 if [board_info [target_info name] exists cflags] {
669 set board_cflags " [board_info [target_info name] cflags]"
670 } else {
671 set board_cflags ""
672 }
24edc24d
L
673
674 foreach testitem $ldtests {
982c6f26 675 foreach target $args {
c8c140d9
BE
676 setup_xfail $target
677 }
24edc24d
L
678 set testname [lindex $testitem 0]
679 set ld_options [lindex $testitem 1]
680 set as_options [lindex $testitem 2]
681 set src_files [lindex $testitem 3]
682 set binfile tmpdir/[lindex $testitem 4]
683 set expfile [lindex $testitem 5]
684 set cflags [lindex $testitem 6]
55255dae 685 set lang [lindex $testitem 7]
fab4a87f 686 set warning [lindex $testitem 8]
fef75122 687 set ld_after [lindex $testitem 9]
24edc24d 688 set objfiles {}
24edc24d
L
689 set failed 0
690
44ed8092
SL
691 if { ![check_compiler_available] } {
692 unsupported $testname
693 continue
694 }
695
24edc24d
L
696# verbose -log "Testname is $testname"
697# verbose -log "ld_options is $ld_options"
698# verbose -log "as_options is $as_options"
699# verbose -log "src_files is $src_files"
24edc24d
L
700# verbose -log "binfile is $binfile"
701
702 # Assemble each file in the test.
703 foreach src_file $src_files {
74d44110
MR
704 set fileroot "[file rootname [file tail $src_file]]"
705 set objfile "tmpdir/$fileroot.o"
24edc24d
L
706 lappend objfiles $objfile
707
58ffc3bd 708 if { [ string match "c++" $lang ] } {
a44d0bd7 709 set cmd "$CXX -c $CXXFLAGS $cflags"
58ffc3bd 710 } else {
a44d0bd7 711 set cmd "$CC -c $CFLAGS $cflags"
58ffc3bd 712 }
a44d0bd7
AM
713 if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] {
714 set failed 1
715 break
716 }
717 }
718 if { $failed != 0 } {
719 unresolved $testname
720 continue
cb5ab6c8 721 }
a10e6b21 722
241e64e3
L
723 if { [ string match "asm" $lang ] } {
724 set link_proc ld_link
725 set link_cmd $ld
726 } elseif { [ string match "c++" $lang ] } {
d9816402 727 set link_proc ld_link
cb5ab6c8 728 set link_cmd $CXX
cb5ab6c8
L
729 } else {
730 set link_proc ld_link
d9816402 731 set link_cmd $CC
cb5ab6c8 732 }
24edc24d 733
abc868c6
AM
734 if { $binfile eq "tmpdir/" } {
735 # compile only
736 pass $testname
737 continue;
98d72909
L
738 } else {
739 if { [string match "" $STATIC_LDFLAGS] \
740 && [regexp -- ".* \[-\]+static .*" " $board_cflags $ld_options $objfiles $ld_after "] } {
741 untested $testname
742 continue
743 }
744 if ![$link_proc $link_cmd $binfile "$board_cflags -L$srcdir/$subdir $ld_options $objfiles $ld_after"] {
745 set failed 1
746 }
cb5ab6c8
L
747 }
748
749 # Check if exec_output is expected.
750 if { $warning != "" } then {
751 verbose -log "returned with: <$exec_output>, expected: <$warning>"
752 if { [regexp $warning $exec_output] } then {
a10e6b21 753 set failed 0
cb5ab6c8
L
754 } else {
755 set failed 1
fab4a87f 756 }
cb5ab6c8 757 }
fab4a87f 758
d9816402 759 if { $failed == 0 && [isnative] } {
cb5ab6c8
L
760 send_log "Running: $binfile > $binfile.out\n"
761 verbose "Running: $binfile > $binfile.out"
762 catch "exec $binfile > $binfile.out" exec_output
fab4a87f 763
cb5ab6c8
L
764 if ![string match "" $exec_output] then {
765 send_log "$exec_output\n"
766 verbose "$exec_output" 1
767 set failed 1
768 } else {
769 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
770 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
771 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
772 set exec_output [prune_warnings $exec_output]
5a68afcf 773
24edc24d
L
774 if ![string match "" $exec_output] then {
775 send_log "$exec_output\n"
776 verbose "$exec_output" 1
777 set failed 1
778 }
779 }
cb5ab6c8 780 }
24edc24d 781
cb5ab6c8
L
782 if { $failed != 0 } {
783 fail $testname
d9816402
AM
784 } elseif ![isnative] {
785 unsupported $testname
cb5ab6c8
L
786 } else {
787 set errcnt 0
788 pass $testname
24edc24d 789 }
24edc24d
L
790 }
791}
d2dee3b2
L
792
793# List contains test-items with 3 items followed by 2 lists, one item and
794# one optional item:
55255dae 795# 0:name
fa0a16b1 796# 1:ld or ar options
55255dae
L
797# 2:compile options
798# 3:filenames of source files
799# 4:action and options.
800# 5:name of output file
801# 6:language (optional)
d2dee3b2
L
802#
803# Actions:
804# objdump: Apply objdump options on result. Compare with regex (last arg).
805# nm: Apply nm options on result. Compare with regex (last arg).
806# readelf: Apply readelf options on result. Compare with regex (last arg).
2bd7f877
AB
807# warning: Check linker output against regex (last arg).
808# error: Like 'warning' but checking output in error case.
809# warning_output: Check linker output against regex in a file (last arg).
810# error_output: Like 'warning_output' but checking output in error case.
d2dee3b2
L
811#
812proc run_cc_link_tests { ldtests } {
813 global nm
814 global objdump
815 global READELF
816 global srcdir
817 global subdir
818 global env
819 global CC
55255dae 820 global CXX
d2dee3b2 821 global CFLAGS
58ffc3bd 822 global CXXFLAGS
d8880531 823 global ar
dd98f8d2 824 global exec_output
603c4399 825 global board_cflags
98d72909 826 global STATIC_LDFLAGS
603c4399
JW
827
828 if [board_info [target_info name] exists cflags] {
829 set board_cflags " [board_info [target_info name] cflags]"
830 } else {
831 set board_cflags ""
832 }
d2dee3b2
L
833
834 foreach testitem $ldtests {
835 set testname [lindex $testitem 0]
836 set ldflags [lindex $testitem 1]
837 set cflags [lindex $testitem 2]
838 set src_files [lindex $testitem 3]
839 set actions [lindex $testitem 4]
840 set binfile tmpdir/[lindex $testitem 5]
55255dae 841 set lang [lindex $testitem 6]
d2dee3b2
L
842 set objfiles {}
843 set is_unresolved 0
844 set failed 0
2bd7f877
AB
845 set check_ld(terminal) 0
846 set check_ld(source) ""
d2dee3b2 847
44ed8092
SL
848 if { ![check_compiler_available] } {
849 unsupported $testname
850 continue
851 }
852
c3e11cbe
AM
853 #verbose -log "testname is $testname"
854 #verbose -log "ldflags is $ldflags"
855 #verbose -log "cflags is $cflags"
856 #verbose -log "src_files is $src_files"
857 #verbose -log "actions is $actions"
858 #verbose -log "binfile is $binfile"
859 #verbose -log "lang is $lang"
2bd7f877
AB
860
861 foreach actionlist $actions {
862 set action [lindex $actionlist 0]
863 set progopts [lindex $actionlist 1]
864
865 # Find actions related to error/warning processing.
866 switch -- $action {
867 error
868 {
869 set check_ld(source) "regexp"
870 set check_ld(regexp) $progopts
871 set check_ld(terminal) 1
872 }
873 warning
874 {
875 set check_ld(source) "regexp"
876 set check_ld(regexp) $progopts
877 }
878 error_output
879 {
880 set check_ld(source) "file"
881 set check_ld(file) $progopts
882 set check_ld(terminal) 1
883 }
884 warning_output
885 {
886 set check_ld(source) "file"
887 set check_ld(file) $progopts
888 }
889 }
890 }
c3e11cbe 891
d2dee3b2
L
892 # Compile each file in the test.
893 foreach src_file $src_files {
74d44110
MR
894 set fileroot "[file rootname [file tail $src_file]]"
895 set objfile "tmpdir/$fileroot.o"
d2dee3b2
L
896 lappend objfiles $objfile
897
58ffc3bd 898 if { [ string match "c++" $lang ] } {
a44d0bd7 899 set cmd "$CXX -c $CXXFLAGS $cflags"
58ffc3bd 900 } else {
a44d0bd7 901 set cmd "$CC -c $CFLAGS $cflags"
58ffc3bd 902 }
a44d0bd7
AM
903 if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] {
904 set failed 1
905 break
906 }
907 }
908 if { $failed != 0 } {
909 unresolved $testname
910 continue
d2dee3b2
L
911 }
912
913 # Clear error and warning counts.
914 reset_vars
915
55255dae
L
916 if { [ string match "c++" $lang ] } {
917 set cc_cmd $CXX
918 } else {
919 set cc_cmd $CC
920 }
921
abc868c6
AM
922 if { $binfile eq "tmpdir/" } {
923 # compile only
924 } elseif { [regexp ".*\\.a$" $binfile] } {
fa0a16b1 925 if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
d8880531 926 set failed 1
d8880531 927 }
741e0128 928 } else {
98d72909
L
929 if { [string match "" $STATIC_LDFLAGS] \
930 && [regexp -- ".* \[-\]+static .*" " $board_cflags $ldflags $objfiles "] } {
931 untested $testname
932 continue
933 }
2bd7f877
AB
934 ld_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"
935 set ld_output "$exec_output"
741e0128 936
2bd7f877
AB
937 if { $check_ld(source) == "regexp" } then {
938 # Match output against regexp argument.
939 verbose -log "returned with: <$ld_output>, expected: <$check_ld(regexp)>"
940 if { ![regexp $check_ld(regexp) $ld_output] } then {
dd98f8d2
NC
941 set failed 1
942 }
2bd7f877
AB
943 } elseif { $check_ld(source) == "file" } then {
944 # Match output against patterns in a file.
945 set_file_contents "tmpdir/ld.messages" "$ld_output"
946 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
947 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$check_ld(file)"] } then {
948 verbose "output is $ld_output" 2
949 set failed 1
950 }
951 }
952
953 if { $check_ld(source) != "" } then {
954 if { $ld_output == "" } then {
955 verbose -log "Linker was expected to give error or warning"
956 set failed 1
957 }
958 } else {
959 if { $ld_output != "" } then {
960 verbose -log "Unexpected linker warning or error"
961 set failed 1
962 }
741e0128 963 }
d8880531
L
964 }
965
966 if { $failed == 0 } {
d2dee3b2
L
967 foreach actionlist $actions {
968 set action [lindex $actionlist 0]
969 set progopts [lindex $actionlist 1]
970
971 # There are actions where we run regexp_diff on the
972 # output, and there are other actions (presumably).
973 # Handling of the former look the same.
974 set dump_prog ""
975 switch -- $action {
976 objdump
977 { set dump_prog $objdump }
978 nm
979 { set dump_prog $nm }
980 readelf
981 { set dump_prog $READELF }
2bd7f877
AB
982 error {}
983 warning {}
984 error_output {}
985 warning_output {}
d2dee3b2
L
986 default
987 {
988 perror "Unrecognized action $action"
989 set is_unresolved 1
990 break
991 }
992 }
993
994 if { $dump_prog != "" } {
995 set dumpfile [lindex $actionlist 2]
996 set binary $dump_prog
997
998 # Ensure consistent sorting of symbols
999 if {[info exists env(LC_ALL)]} {
1000 set old_lc_all $env(LC_ALL)
1001 }
1002 set env(LC_ALL) "C"
1003 set cmd "$binary $progopts $binfile > dump.out"
1004 send_log "$cmd\n"
1005 catch "exec $cmd" comp_output
1006 if {[info exists old_lc_all]} {
1007 set env(LC_ALL) $old_lc_all
1008 } else {
1009 unset env(LC_ALL)
1010 }
1011 set comp_output [prune_warnings $comp_output]
1012
1013 if ![string match "" $comp_output] then {
1014 send_log "$comp_output\n"
1015 set failed 1
1016 break
1017 }
1018
1019 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1020 verbose "output is [file_contents "dump.out"]" 2
1021 set failed 1
1022 break
1023 }
1024 }
1025 }
d2dee3b2
L
1026 }
1027
d44ea5d0 1028 if { $failed } {
abc868c6 1029 fail $testname
d44ea5d0 1030 } elseif { $is_unresolved } {
d2dee3b2 1031 unresolved $testname
d44ea5d0
AM
1032 } else {
1033 pass $testname
d2dee3b2
L
1034 }
1035 }
1036}
430a16a5
NC
1037
1038# Returns true if --gc-sections is supported on the target.
1039
1040proc check_gc_sections_available { } {
1041 global gc_sections_available_saved
1042 global ld
5a68afcf 1043
430a16a5
NC
1044 if {![info exists gc_sections_available_saved]} {
1045 # Some targets don't support gc-sections despite whatever's
1046 # advertised by ld's options.
be570f06
AM
1047 if { [istarget alpha-*-*]
1048 || [istarget d30v-*-*]
59c108f7 1049 || [istarget dlx-*-*]
59c108f7 1050 || [istarget hppa*64-*-*]
59c108f7
NC
1051 || [istarget ia64-*-*]
1052 || [istarget mep-*-*]
be570f06
AM
1053 || [istarget mn10200-*-*]
1054 || [istarget pj*-*-*]
1055 || [istarget pru*-*-*]
fce97736 1056 || [istarget s12z-*-*]
be570f06 1057 || [istarget xgate-*-*] } {
430a16a5
NC
1058 set gc_sections_available_saved 0
1059 return 0
1060 }
1061
1062 # elf2flt uses -q (--emit-relocs), which is incompatible with
1063 # --gc-sections.
1064 if { [board_info target exists ldflags]
1065 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1066 set gc_sections_available_saved 0
1067 return 0
1068 }
1069
430a16a5 1070 # Check if the ld used by gcc supports --gc-sections.
1d5316ab
AM
1071 # FIXME: this test is useless since ld --help always says
1072 # --gc-sections is available
430a16a5
NC
1073 set ld_output [remote_exec host $ld "--help"]
1074 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1075 set gc_sections_available_saved 1
1076 } else {
1077 set gc_sections_available_saved 0
1078 }
1079 }
1080 return $gc_sections_available_saved
1081}
33aa234e 1082
b62b1f71
AM
1083# Return true if target uses genelf.em (assuming it is ELF).
1084proc is_generic_elf { } {
1085 if { [istarget "d30v-*-*"]
1086 || [istarget "dlx-*-*"]
1087 || [istarget "fr30-*-*"]
1088 || ([istarget "frv-*-*"] && ![istarget "frv-*-linux*"])
1089 || [istarget "ft32-*-*"]
b62b1f71
AM
1090 || [istarget "iq2000-*-*"]
1091 || [istarget "mn10200-*-*"]
1092 || [istarget "moxie-*-*"]
1093 || [istarget "msp430-*-*"]
1094 || [istarget "mt-*-*"]
be570f06
AM
1095 || [istarget "pj*-*-*"]
1096 || [istarget "xgate-*-*"] } {
b62b1f71
AM
1097 return 1;
1098 }
1099 return 0;
1100}
1101
bdd32e03
AM
1102proc is_underscore_target { } {
1103 global is_underscore_target_saved
1104 global target_triplet
1105 global srcdir
1106
1107 if { ![info exists is_underscore_target_saved] } {
1108 set cmd "targ=$target_triplet . $srcdir/../../bfd/config.bfd &&"
1109 append cmd { echo "$targ_underscore"}
1110 verbose -log "$cmd"
1111 set status [catch {exec sh -c $cmd} result]
1112 if { $status == 0 && [string match "yes" $result] } {
1113 set is_underscore_target_saved 1
1114 } else {
1115 set is_underscore_target_saved 0
1116 }
1117 }
1118 return $is_underscore_target_saved
1119}
1120
5d3236ee
DK
1121# Returns true if the target ld supports the plugin API.
1122proc check_plugin_api_available { } {
1123 global plugin_api_available_saved
1124 global ld
1125 if {![info exists plugin_api_available_saved]} {
1126 # Check if the ld used by gcc supports --plugin.
1127 set ld_output [remote_exec host $ld "--help"]
2d03dd2f 1128 if { [ string first "-plugin PLUGIN" $ld_output ] >= 0 } {
5d3236ee
DK
1129 set plugin_api_available_saved 1
1130 } else {
1131 set plugin_api_available_saved 0
1132 }
1133 }
1134 return $plugin_api_available_saved
1135}
1136
3f730821
HPN
1137# Sets ld_sysroot to the current sysroot (empty if not supported) and
1138# returns true if the target ld supports sysroot.
bdd65db9 1139proc check_sysroot_available { } {
3f730821 1140 global ld_sysroot_available_saved ld ld_sysroot
bdd65db9 1141 if {![info exists ld_sysroot_available_saved]} {
3f730821
HPN
1142 # Check if ld supports --sysroot *other* than empty.
1143 set ld_sysroot [string trimright [lindex [remote_exec host $ld "--print-sysroot"] 1]]
1144 if { $ld_sysroot == "" } {
bdd65db9
HPN
1145 set ld_sysroot_available_saved 0
1146 } else {
1147 set ld_sysroot_available_saved 1
1148 }
1149 }
1150 return $ld_sysroot_available_saved
1151}
1152
44ed8092
SL
1153# Return true if we can build a program with the compiler.
1154# On some targets, CC might be defined, but libraries and startup
1155# code might be missing or require special options that the ld test
1156# harness doesn't know about.
1157
1158proc check_compiler_available { } {
1159 global compiler_available_saved
1160 global CC
1161
1162 if {![info exists compiler_available_saved]} {
1163 if { [which $CC] == 0 } {
1164 set compiler_available_saved 0
1165 return 0
1166 }
1167
1168 set flags ""
1169 if [board_info [target_info name] exists cflags] {
1170 append flags " [board_info [target_info name] cflags]"
1171 }
1172 if [board_info [target_info name] exists ldflags] {
1173 append flags " [board_info [target_info name] ldflags]"
1174 }
1175
1176 set basename "tmpdir/compiler[pid]"
1177 set src ${basename}.c
1178 set output ${basename}.out
1179 set f [open $src "w"]
1180 puts $f "int main (void)"
1181 puts $f "{"
1182 puts $f " return 0; "
1183 puts $f "}"
1184 close $f
1185 if [is_remote host] {
1186 set src [remote_download host $src]
1187 }
1188 set compiler_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
1189 remote_file host delete $src
1190 remote_file host delete $output
1191 file delete $src
1192 }
1193 return $compiler_available_saved
1194}
1195
5ff55910
L
1196# Returns 1 if plugin is enabled in gcc. Returns 0 otherwise.
1197proc check_gcc_plugin_enabled { } {
1198 global CC
1199
1200 if {![info exists CC]} {
1201 set CC [find_gcc]
1202 }
7f6bf02d 1203 if { $CC == ""} {
8be1e369 1204 return 0
5ff55910
L
1205 }
1206 set state [remote_exec host $CC -v]
8be1e369
AM
1207 if { [lindex $state 0] != 0 } {
1208 return 0;
1209 }
1210 for { set i 1 } { $i < [llength $state] } { incr i } {
5ff55910
L
1211 set v [lindex $state $i]
1212 if { [ string match "*--disable-plugin*" $v ] } {
1213 verbose "plugin is disabled by $v"
1214 return 0;
1215 }
1216 }
1217
1218 return 1;
1219}
1220
3bd58fbe
L
1221# Returns true if the target compiler supports LTO
1222proc check_lto_available { } {
1223 global lto_available_saved
1224 global CC
7174e19f 1225
3bd58fbe 1226 if {![info exists lto_available_saved]} {
5ff55910 1227 if { ![check_gcc_plugin_enabled] } {
19aef622
NC
1228 set lto_available_saved 0
1229 return 0
1230 }
00f4a602
L
1231 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1232 # -ffat-lto-objects, we always run LTO tests on Linux with
1233 # GCC 4.9 or newer.
1234 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1235 set lto_available_saved 1
1236 return 1
1237 }
3bd58fbe 1238 # Check if gcc supports -flto -fuse-linker-plugin
f1d7f4a6
AM
1239 set flags ""
1240 if [board_info [target_info name] exists cflags] {
1241 append flags " [board_info [target_info name] cflags]"
1242 }
1243 if [board_info [target_info name] exists ldflags] {
1244 append flags " [board_info [target_info name] ldflags]"
3bd58fbe 1245 }
f1d7f4a6
AM
1246
1247 set basename "tmpdir/lto[pid]"
1248 set src ${basename}.c
1249 set output ${basename}.out
3bd58fbe 1250 set f [open $src "w"]
7174e19f 1251 puts $f "int main() { return 0; }"
3bd58fbe 1252 close $f
010f98a5
L
1253 if [is_remote host] {
1254 set src [remote_download host $src]
1255 }
c3e11cbe 1256 set lto_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -fuse-linker-plugin $src -o $output"]
f1d7f4a6
AM
1257 remote_file host delete $src
1258 remote_file host delete $output
3bd58fbe 1259 file delete $src
3bd58fbe
L
1260 }
1261 return $lto_available_saved
1262}
1263
c3e11cbe
AM
1264# Returns true if the target compiler supports LTO -ffat-lto-objects
1265proc check_lto_fat_available { } {
1266 global lto_fat_available_saved
1267 global CC
1268
1269 if {![info exists lto_fat_available_saved]} {
5ff55910 1270 if { ![check_gcc_plugin_enabled] } {
c3e11cbe
AM
1271 set lto_fat_available_saved 0
1272 return 0
1273 }
00f4a602
L
1274 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1275 # -ffat-lto-objects, we always run LTO tests on Linux with
1276 # GCC 4.9 or newer.
1277 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1278 set lto_fat_available_saved 1
1279 return 1
1280 }
c3e11cbe
AM
1281 # Check if gcc supports -flto -fuse-linker-plugin
1282 set flags ""
1283 if [board_info [target_info name] exists cflags] {
1284 append flags " [board_info [target_info name] cflags]"
1285 }
1286 if [board_info [target_info name] exists ldflags] {
1287 append flags " [board_info [target_info name] ldflags]"
1288 }
1289
1290 set basename "tmpdir/lto[pid]"
1291 set src ${basename}.c
1292 set output ${basename}.out
1293 set f [open $src "w"]
1294 puts $f "int main() { return 0; }"
1295 close $f
010f98a5
L
1296 if [is_remote host] {
1297 set src [remote_download host $src]
1298 }
c3e11cbe
AM
1299 set lto_fat_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -ffat-lto-objects -fuse-linker-plugin $src -o $output"]
1300 remote_file host delete $src
1301 remote_file host delete $output
1302 file delete $src
1303 }
1304 return $lto_fat_available_saved
1305}
1306
92c09111
L
1307# Returns true if the target compiler supports LTO and -shared
1308proc check_lto_shared_available { } {
1309 global lto_shared_available_saved
1310 global CC
1311
92c09111 1312 if {![info exists lto_shared_available_saved]} {
5ff55910 1313 if { ![check_gcc_plugin_enabled] } {
3bb9e7b4
AM
1314 set lto_shared_available_saved 0
1315 return 0
1316 }
00f4a602
L
1317 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1318 # -ffat-lto-objects, we always run LTO tests on Linux with
1319 # GCC 4.9 or newer.
1320 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1321 set lto_shared_available_saved 1
1322 return 1
1323 }
92c09111 1324 # Check if gcc supports -flto -fuse-linker-plugin -shared
f1d7f4a6
AM
1325 set flags ""
1326 if [board_info [target_info name] exists cflags] {
1327 append flags " [board_info [target_info name] cflags]"
1328 }
1329 if [board_info [target_info name] exists ldflags] {
1330 append flags " [board_info [target_info name] ldflags]"
92c09111 1331 }
f1d7f4a6
AM
1332
1333 set basename "tmpdir/lto_shared[pid]"
1334 set src ${basename}.c
1335 set output ${basename}.so
92c09111
L
1336 set f [open $src "w"]
1337 puts $f ""
1338 close $f
010f98a5
L
1339 if [is_remote host] {
1340 set src [remote_download host $src]
1341 }
f1d7f4a6
AM
1342 set lto_shared_available_saved [run_host_cmd_yesno "$CC" "$flags -shared -fPIC -flto -fuse-linker-plugin $src -o $output"]
1343 remote_file host delete $src
1344 remote_file host delete $output
92c09111 1345 file delete $src
92c09111
L
1346 }
1347 return $lto_shared_available_saved
1348}
1349
33aa234e
JK
1350# Check if the assembler supports CFI statements.
1351
1352proc check_as_cfi { } {
1353 global check_as_cfi_result
1354 global as
1355 if [info exists check_as_cfi_result] {
1356 return $check_as_cfi_result
1357 }
1358 set as_file "tmpdir/check_as_cfi.s"
1359 set as_fh [open $as_file w 0666]
1360 puts $as_fh "# Generated file. DO NOT EDIT"
1361 puts $as_fh "\t.cfi_startproc"
1362 puts $as_fh "\t.cfi_endproc"
1363 close $as_fh
1364 remote_download host $as_file
1365 verbose -log "Checking CFI support:"
1366 rename "perror" "check_as_cfi_perror"
1367 proc perror { args } { }
1368 set success [ld_assemble $as $as_file "/dev/null"]
1369 rename "perror" ""
1370 rename "check_as_cfi_perror" "perror"
1371 #remote_file host delete $as_file
1372 set check_as_cfi_result $success
1373 return $success
1374}
1375
c22ee0ad
L
1376# Returns true if IFUNC works.
1377
1378proc check_ifunc_available { } {
1379 global ifunc_available_saved
1380 global CC
1381
1382 if {![info exists ifunc_available_saved]} {
44ed8092 1383 if { ![check_compiler_available] } {
c22ee0ad
L
1384 set ifunc_available_saved 0
1385 return 0
1386 }
1387 # Check if gcc supports -flto -fuse-linker-plugin
1388 set flags ""
1389 if [board_info [target_info name] exists cflags] {
1390 append flags " [board_info [target_info name] cflags]"
1391 }
1392 if [board_info [target_info name] exists ldflags] {
1393 append flags " [board_info [target_info name] ldflags]"
1394 }
1395
1396 set basename "tmpdir/ifunc[pid]"
1397 set src ${basename}.c
1398 set output ${basename}.out
1399 set f [open $src "w"]
1400 puts $f "extern int library_func2 (void);"
1401 puts $f "int main (void)"
1402 puts $f "{"
1403 puts $f " if (library_func2 () != 2) __builtin_abort ();"
1404 puts $f " return 0; "
1405 puts $f "}"
1406 puts $f "static int library_func1 (void) {return 2; }"
1407 puts $f "void *foo (void) __asm__ (\"library_func2\");"
1408 puts $f "void *foo (void) { return library_func1; }"
1409 puts $f "__asm__(\".type library_func2, %gnu_indirect_function\");"
1410 close $f
010f98a5
L
1411 if [is_remote host] {
1412 set src [remote_download host $src]
1413 }
c22ee0ad 1414 set ifunc_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
77236b83 1415 if { [isnative] && $ifunc_available_saved == 1 } {
c22ee0ad
L
1416 set ifunc_available_saved [run_host_cmd_yesno "$output" ""]
1417 }
1418 remote_file host delete $src
1419 remote_file host delete $output
1420 file delete $src
1421 }
1422 return $ifunc_available_saved
1423}
1424
97dc35c8
L
1425# Returns true if ifunc attribute works.
1426
1427proc check_ifunc_attribute_available { } {
1428 global ifunc_attribute_available_saved
1429 global CC
1430
1431 if {![info exists ifunc_attribute_available_saved]} {
44ed8092 1432 if { ![check_compiler_available] } {
97dc35c8
L
1433 set ifunc_attribute_available_saved 0
1434 return 0
1435 }
1436 # Check if gcc supports -flto -fuse-linker-plugin
1437 set flags ""
1438 if [board_info [target_info name] exists cflags] {
1439 append flags " [board_info [target_info name] cflags]"
1440 }
1441 if [board_info [target_info name] exists ldflags] {
1442 append flags " [board_info [target_info name] ldflags]"
1443 }
1444
1445 set basename "tmpdir/ifunc[pid]"
1446 set src ${basename}.c
1447 set output ${basename}.out
1448 set f [open $src "w"]
1449 puts $f "extern int library_func2 (void) __attribute__ ((ifunc (\"foo\")));"
1450 puts $f "int main (void)"
1451 puts $f "{"
1452 puts $f " if (library_func2 () != 2) __builtin_abort ();"
1453 puts $f " return 0; "
1454 puts $f "}"
1455 puts $f "static int library_func1 (void) {return 2; }"
1456 puts $f "void *foo (void) { return library_func1; }"
1457 close $f
010f98a5
L
1458 if [is_remote host] {
1459 set src [remote_download host $src]
1460 }
97dc35c8 1461 set ifunc_attribute_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
77236b83 1462 if { [isnative] && $ifunc_attribute_available_saved == 1 } {
97dc35c8
L
1463 set ifunc_attribute_available_saved [run_host_cmd_yesno "$output" ""]
1464 }
1465 remote_file host delete $src
1466 remote_file host delete $output
1467 file delete $src
1468 }
1469 return $ifunc_attribute_available_saved
1470}
1471
fd121c5c
JW
1472# Return true if libdl is supported.
1473
1474proc check_libdl_available { } {
1475 global libdl_available_saved
1476 global CC
1477
1478 if {![info exists libdl_available_saved]} {
44ed8092 1479 if { ![check_compiler_available] } {
fd121c5c
JW
1480 set libdl_available_saved 0
1481 return 0
1482 }
1483
1484 set basename "tmpdir/dl_avail_test[pid]"
1485 set src ${basename}.c
1486 set output ${basename}.out
1487 set f [open $src "w"]
1488 # Sample test file.
1489 puts $f "#include <dlfcn.h>"
1490 puts $f "int main (void)"
1491 puts $f "{"
1492 puts $f " dlopen (\"dummy.so\", RTLD_NOW);"
1493 puts $f " return 0; "
1494 puts $f "}"
1495 close $f
1496 if [is_remote host] {
1497 set src [remote_download host $src]
1498 }
1499 set libdl_available_saved [run_host_cmd_yesno "$CC" "$src -o $output -ldl"]
1500 remote_file host delete $src
1501 remote_file host delete $output
1502 file delete $src
1503 }
1504 return $libdl_available_saved
1505}
0aae7e72
L
1506
1507# Returns true if GNU2 TLS works.
1508
1509proc check_gnu2_tls_available { } {
1510 global gnu2_tls_available_saved
1511 global CC
1512 global GNU2_CFLAGS
1513
1514 if {![info exists gnu2_tls_available_saved]} {
44ed8092 1515 if { ![check_compiler_available] || "$GNU2_CFLAGS" == "" } {
0aae7e72
L
1516 set gnu2_tls_available_saved 0
1517 return 0
1518 }
1519 # Check if GNU2 TLS works.
1520 set flags "$GNU2_CFLAGS"
1521 if [board_info [target_info name] exists cflags] {
1522 append flags " [board_info [target_info name] cflags]"
1523 }
1524 if [board_info [target_info name] exists ldflags] {
1525 append flags " [board_info [target_info name] ldflags]"
1526 }
1527
1528 set basename "tmpdir/gnu2_tls[pid]"
1529 set src1 ${basename}1.c
1530 set output1 ${basename}.so
1531 set f [open $src1 "w"]
1532 puts $f "extern __thread int zzz;"
1533 puts $f "int foo (void)"
1534 puts $f "{"
1535 puts $f " return zzz;"
1536 puts $f "}"
1537 close $f
1538 if [is_remote host] {
1539 set src1 [remote_download host $src1]
1540 }
1541 set src2 ${basename}2.c
1542 set output2 ${basename}.exe
1543 set f [open $src2 "w"]
1544 puts $f "__thread int zzz = 20;"
1545 puts $f "extern int foo (void);"
1546 puts $f "int main (void)"
1547 puts $f "{"
1548 puts $f " if (foo () != 20) __builtin_abort ();"
1549 puts $f " return 0; "
1550 puts $f "}"
1551 close $f
1552 if [is_remote host] {
1553 set src2 [remote_download host $src2]
1554 }
1555 set gnu2_tls_available_saved [run_host_cmd_yesno "$CC" "-fPIC -shared $flags $src1 -o $output1"]
1556 if { $gnu2_tls_available_saved == 1 } {
1557 set gnu2_tls_available_saved [run_host_cmd_yesno "$CC" "$flags $src2 $output1 -o $output2"]
1558 if { $gnu2_tls_available_saved == 1 } {
1559 set gnu2_tls_available_saved [run_host_cmd_yesno "$output2" ""]
1560 }
1561 }
1562 remote_file host delete $src1
1563 remote_file host delete $output1
1564 remote_file host delete $src2
1565 remote_file host delete $output2
1566 file delete $src1 $src2
1567 }
1568 return $gnu2_tls_available_saved
1569}
This page took 0.940012 seconds and 4 git commands to generate.