Update year range in copyright notice of binutils files
[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
691# verbose -log "Testname is $testname"
692# verbose -log "ld_options is $ld_options"
693# verbose -log "as_options is $as_options"
694# verbose -log "src_files is $src_files"
24edc24d
L
695# verbose -log "binfile is $binfile"
696
697 # Assemble each file in the test.
698 foreach src_file $src_files {
74d44110
MR
699 set fileroot "[file rootname [file tail $src_file]]"
700 set objfile "tmpdir/$fileroot.o"
24edc24d
L
701 lappend objfiles $objfile
702
58ffc3bd 703 if { [ string match "c++" $lang ] } {
a44d0bd7 704 set cmd "$CXX -c $CXXFLAGS $cflags"
58ffc3bd 705 } else {
a44d0bd7 706 set cmd "$CC -c $CFLAGS $cflags"
58ffc3bd 707 }
a44d0bd7
AM
708 if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] {
709 set failed 1
710 break
711 }
712 }
713 if { $failed != 0 } {
714 unresolved $testname
715 continue
cb5ab6c8 716 }
a10e6b21 717
241e64e3
L
718 if { [ string match "asm" $lang ] } {
719 set link_proc ld_link
720 set link_cmd $ld
721 } elseif { [ string match "c++" $lang ] } {
d9816402 722 set link_proc ld_link
cb5ab6c8 723 set link_cmd $CXX
cb5ab6c8
L
724 } else {
725 set link_proc ld_link
d9816402 726 set link_cmd $CC
cb5ab6c8 727 }
24edc24d 728
abc868c6
AM
729 if { $binfile eq "tmpdir/" } {
730 # compile only
731 pass $testname
732 continue;
98d72909
L
733 } else {
734 if { [string match "" $STATIC_LDFLAGS] \
735 && [regexp -- ".* \[-\]+static .*" " $board_cflags $ld_options $objfiles $ld_after "] } {
736 untested $testname
737 continue
738 }
739 if ![$link_proc $link_cmd $binfile "$board_cflags -L$srcdir/$subdir $ld_options $objfiles $ld_after"] {
740 set failed 1
741 }
cb5ab6c8
L
742 }
743
744 # Check if exec_output is expected.
745 if { $warning != "" } then {
746 verbose -log "returned with: <$exec_output>, expected: <$warning>"
747 if { [regexp $warning $exec_output] } then {
a10e6b21 748 set failed 0
cb5ab6c8
L
749 } else {
750 set failed 1
fab4a87f 751 }
cb5ab6c8 752 }
fab4a87f 753
d9816402 754 if { $failed == 0 && [isnative] } {
cb5ab6c8
L
755 send_log "Running: $binfile > $binfile.out\n"
756 verbose "Running: $binfile > $binfile.out"
757 catch "exec $binfile > $binfile.out" exec_output
fab4a87f 758
cb5ab6c8
L
759 if ![string match "" $exec_output] then {
760 send_log "$exec_output\n"
761 verbose "$exec_output" 1
762 set failed 1
763 } else {
764 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
765 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
766 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
767 set exec_output [prune_warnings $exec_output]
5a68afcf 768
24edc24d
L
769 if ![string match "" $exec_output] then {
770 send_log "$exec_output\n"
771 verbose "$exec_output" 1
772 set failed 1
773 }
774 }
cb5ab6c8 775 }
24edc24d 776
cb5ab6c8
L
777 if { $failed != 0 } {
778 fail $testname
d9816402
AM
779 } elseif ![isnative] {
780 unsupported $testname
cb5ab6c8
L
781 } else {
782 set errcnt 0
783 pass $testname
24edc24d 784 }
24edc24d
L
785 }
786}
d2dee3b2
L
787
788# List contains test-items with 3 items followed by 2 lists, one item and
789# one optional item:
55255dae 790# 0:name
fa0a16b1 791# 1:ld or ar options
55255dae
L
792# 2:compile options
793# 3:filenames of source files
794# 4:action and options.
795# 5:name of output file
796# 6:language (optional)
d2dee3b2
L
797#
798# Actions:
799# objdump: Apply objdump options on result. Compare with regex (last arg).
800# nm: Apply nm options on result. Compare with regex (last arg).
801# readelf: Apply readelf options on result. Compare with regex (last arg).
2bd7f877
AB
802# warning: Check linker output against regex (last arg).
803# error: Like 'warning' but checking output in error case.
804# warning_output: Check linker output against regex in a file (last arg).
805# error_output: Like 'warning_output' but checking output in error case.
d2dee3b2
L
806#
807proc run_cc_link_tests { ldtests } {
808 global nm
809 global objdump
810 global READELF
811 global srcdir
812 global subdir
813 global env
814 global CC
55255dae 815 global CXX
d2dee3b2 816 global CFLAGS
58ffc3bd 817 global CXXFLAGS
d8880531 818 global ar
dd98f8d2 819 global exec_output
603c4399 820 global board_cflags
98d72909 821 global STATIC_LDFLAGS
603c4399
JW
822
823 if [board_info [target_info name] exists cflags] {
824 set board_cflags " [board_info [target_info name] cflags]"
825 } else {
826 set board_cflags ""
827 }
d2dee3b2
L
828
829 foreach testitem $ldtests {
830 set testname [lindex $testitem 0]
831 set ldflags [lindex $testitem 1]
832 set cflags [lindex $testitem 2]
833 set src_files [lindex $testitem 3]
834 set actions [lindex $testitem 4]
835 set binfile tmpdir/[lindex $testitem 5]
55255dae 836 set lang [lindex $testitem 6]
d2dee3b2
L
837 set objfiles {}
838 set is_unresolved 0
839 set failed 0
2bd7f877
AB
840 set check_ld(terminal) 0
841 set check_ld(source) ""
d2dee3b2 842
c3e11cbe
AM
843 #verbose -log "testname is $testname"
844 #verbose -log "ldflags is $ldflags"
845 #verbose -log "cflags is $cflags"
846 #verbose -log "src_files is $src_files"
847 #verbose -log "actions is $actions"
848 #verbose -log "binfile is $binfile"
849 #verbose -log "lang is $lang"
2bd7f877
AB
850
851 foreach actionlist $actions {
852 set action [lindex $actionlist 0]
853 set progopts [lindex $actionlist 1]
854
855 # Find actions related to error/warning processing.
856 switch -- $action {
857 error
858 {
859 set check_ld(source) "regexp"
860 set check_ld(regexp) $progopts
861 set check_ld(terminal) 1
862 }
863 warning
864 {
865 set check_ld(source) "regexp"
866 set check_ld(regexp) $progopts
867 }
868 error_output
869 {
870 set check_ld(source) "file"
871 set check_ld(file) $progopts
872 set check_ld(terminal) 1
873 }
874 warning_output
875 {
876 set check_ld(source) "file"
877 set check_ld(file) $progopts
878 }
879 }
880 }
c3e11cbe 881
d2dee3b2
L
882 # Compile each file in the test.
883 foreach src_file $src_files {
74d44110
MR
884 set fileroot "[file rootname [file tail $src_file]]"
885 set objfile "tmpdir/$fileroot.o"
d2dee3b2
L
886 lappend objfiles $objfile
887
58ffc3bd 888 if { [ string match "c++" $lang ] } {
a44d0bd7 889 set cmd "$CXX -c $CXXFLAGS $cflags"
58ffc3bd 890 } else {
a44d0bd7 891 set cmd "$CC -c $CFLAGS $cflags"
58ffc3bd 892 }
a44d0bd7
AM
893 if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] {
894 set failed 1
895 break
896 }
897 }
898 if { $failed != 0 } {
899 unresolved $testname
900 continue
d2dee3b2
L
901 }
902
903 # Clear error and warning counts.
904 reset_vars
905
55255dae
L
906 if { [ string match "c++" $lang ] } {
907 set cc_cmd $CXX
908 } else {
909 set cc_cmd $CC
910 }
911
abc868c6
AM
912 if { $binfile eq "tmpdir/" } {
913 # compile only
914 } elseif { [regexp ".*\\.a$" $binfile] } {
fa0a16b1 915 if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
d8880531 916 set failed 1
d8880531 917 }
741e0128 918 } else {
98d72909
L
919 if { [string match "" $STATIC_LDFLAGS] \
920 && [regexp -- ".* \[-\]+static .*" " $board_cflags $ldflags $objfiles "] } {
921 untested $testname
922 continue
923 }
2bd7f877
AB
924 ld_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"
925 set ld_output "$exec_output"
741e0128 926
2bd7f877
AB
927 if { $check_ld(source) == "regexp" } then {
928 # Match output against regexp argument.
929 verbose -log "returned with: <$ld_output>, expected: <$check_ld(regexp)>"
930 if { ![regexp $check_ld(regexp) $ld_output] } then {
dd98f8d2
NC
931 set failed 1
932 }
2bd7f877
AB
933 } elseif { $check_ld(source) == "file" } then {
934 # Match output against patterns in a file.
935 set_file_contents "tmpdir/ld.messages" "$ld_output"
936 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
937 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$check_ld(file)"] } then {
938 verbose "output is $ld_output" 2
939 set failed 1
940 }
941 }
942
943 if { $check_ld(source) != "" } then {
944 if { $ld_output == "" } then {
945 verbose -log "Linker was expected to give error or warning"
946 set failed 1
947 }
948 } else {
949 if { $ld_output != "" } then {
950 verbose -log "Unexpected linker warning or error"
951 set failed 1
952 }
741e0128 953 }
d8880531
L
954 }
955
956 if { $failed == 0 } {
d2dee3b2
L
957 foreach actionlist $actions {
958 set action [lindex $actionlist 0]
959 set progopts [lindex $actionlist 1]
960
961 # There are actions where we run regexp_diff on the
962 # output, and there are other actions (presumably).
963 # Handling of the former look the same.
964 set dump_prog ""
965 switch -- $action {
966 objdump
967 { set dump_prog $objdump }
968 nm
969 { set dump_prog $nm }
970 readelf
971 { set dump_prog $READELF }
2bd7f877
AB
972 error {}
973 warning {}
974 error_output {}
975 warning_output {}
d2dee3b2
L
976 default
977 {
978 perror "Unrecognized action $action"
979 set is_unresolved 1
980 break
981 }
982 }
983
984 if { $dump_prog != "" } {
985 set dumpfile [lindex $actionlist 2]
986 set binary $dump_prog
987
988 # Ensure consistent sorting of symbols
989 if {[info exists env(LC_ALL)]} {
990 set old_lc_all $env(LC_ALL)
991 }
992 set env(LC_ALL) "C"
993 set cmd "$binary $progopts $binfile > dump.out"
994 send_log "$cmd\n"
995 catch "exec $cmd" comp_output
996 if {[info exists old_lc_all]} {
997 set env(LC_ALL) $old_lc_all
998 } else {
999 unset env(LC_ALL)
1000 }
1001 set comp_output [prune_warnings $comp_output]
1002
1003 if ![string match "" $comp_output] then {
1004 send_log "$comp_output\n"
1005 set failed 1
1006 break
1007 }
1008
1009 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1010 verbose "output is [file_contents "dump.out"]" 2
1011 set failed 1
1012 break
1013 }
1014 }
1015 }
d2dee3b2
L
1016 }
1017
d44ea5d0 1018 if { $failed } {
abc868c6 1019 fail $testname
d44ea5d0 1020 } elseif { $is_unresolved } {
d2dee3b2 1021 unresolved $testname
d44ea5d0
AM
1022 } else {
1023 pass $testname
d2dee3b2
L
1024 }
1025 }
1026}
430a16a5
NC
1027
1028# Returns true if --gc-sections is supported on the target.
1029
1030proc check_gc_sections_available { } {
1031 global gc_sections_available_saved
1032 global ld
5a68afcf 1033
430a16a5
NC
1034 if {![info exists gc_sections_available_saved]} {
1035 # Some targets don't support gc-sections despite whatever's
1036 # advertised by ld's options.
be570f06
AM
1037 if { [istarget alpha-*-*]
1038 || [istarget d30v-*-*]
59c108f7 1039 || [istarget dlx-*-*]
59c108f7 1040 || [istarget hppa*64-*-*]
59c108f7
NC
1041 || [istarget ia64-*-*]
1042 || [istarget mep-*-*]
be570f06
AM
1043 || [istarget mn10200-*-*]
1044 || [istarget pj*-*-*]
1045 || [istarget pru*-*-*]
1046 || [istarget xgate-*-*] } {
430a16a5
NC
1047 set gc_sections_available_saved 0
1048 return 0
1049 }
1050
1051 # elf2flt uses -q (--emit-relocs), which is incompatible with
1052 # --gc-sections.
1053 if { [board_info target exists ldflags]
1054 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1055 set gc_sections_available_saved 0
1056 return 0
1057 }
1058
430a16a5 1059 # Check if the ld used by gcc supports --gc-sections.
1d5316ab
AM
1060 # FIXME: this test is useless since ld --help always says
1061 # --gc-sections is available
430a16a5
NC
1062 set ld_output [remote_exec host $ld "--help"]
1063 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1064 set gc_sections_available_saved 1
1065 } else {
1066 set gc_sections_available_saved 0
1067 }
1068 }
1069 return $gc_sections_available_saved
1070}
33aa234e 1071
b62b1f71
AM
1072# Return true if target uses genelf.em (assuming it is ELF).
1073proc is_generic_elf { } {
1074 if { [istarget "d30v-*-*"]
1075 || [istarget "dlx-*-*"]
1076 || [istarget "fr30-*-*"]
1077 || ([istarget "frv-*-*"] && ![istarget "frv-*-linux*"])
1078 || [istarget "ft32-*-*"]
b62b1f71
AM
1079 || [istarget "iq2000-*-*"]
1080 || [istarget "mn10200-*-*"]
1081 || [istarget "moxie-*-*"]
1082 || [istarget "msp430-*-*"]
1083 || [istarget "mt-*-*"]
be570f06
AM
1084 || [istarget "pj*-*-*"]
1085 || [istarget "xgate-*-*"] } {
b62b1f71
AM
1086 return 1;
1087 }
1088 return 0;
1089}
1090
bdd32e03
AM
1091proc is_underscore_target { } {
1092 global is_underscore_target_saved
1093 global target_triplet
1094 global srcdir
1095
1096 if { ![info exists is_underscore_target_saved] } {
1097 set cmd "targ=$target_triplet . $srcdir/../../bfd/config.bfd &&"
1098 append cmd { echo "$targ_underscore"}
1099 verbose -log "$cmd"
1100 set status [catch {exec sh -c $cmd} result]
1101 if { $status == 0 && [string match "yes" $result] } {
1102 set is_underscore_target_saved 1
1103 } else {
1104 set is_underscore_target_saved 0
1105 }
1106 }
1107 return $is_underscore_target_saved
1108}
1109
5d3236ee
DK
1110# Returns true if the target ld supports the plugin API.
1111proc check_plugin_api_available { } {
1112 global plugin_api_available_saved
1113 global ld
1114 if {![info exists plugin_api_available_saved]} {
1115 # Check if the ld used by gcc supports --plugin.
1116 set ld_output [remote_exec host $ld "--help"]
2d03dd2f 1117 if { [ string first "-plugin PLUGIN" $ld_output ] >= 0 } {
5d3236ee
DK
1118 set plugin_api_available_saved 1
1119 } else {
1120 set plugin_api_available_saved 0
1121 }
1122 }
1123 return $plugin_api_available_saved
1124}
1125
3f730821
HPN
1126# Sets ld_sysroot to the current sysroot (empty if not supported) and
1127# returns true if the target ld supports sysroot.
bdd65db9 1128proc check_sysroot_available { } {
3f730821 1129 global ld_sysroot_available_saved ld ld_sysroot
bdd65db9 1130 if {![info exists ld_sysroot_available_saved]} {
3f730821
HPN
1131 # Check if ld supports --sysroot *other* than empty.
1132 set ld_sysroot [string trimright [lindex [remote_exec host $ld "--print-sysroot"] 1]]
1133 if { $ld_sysroot == "" } {
bdd65db9
HPN
1134 set ld_sysroot_available_saved 0
1135 } else {
1136 set ld_sysroot_available_saved 1
1137 }
1138 }
1139 return $ld_sysroot_available_saved
1140}
1141
5ff55910
L
1142# Returns 1 if plugin is enabled in gcc. Returns 0 otherwise.
1143proc check_gcc_plugin_enabled { } {
1144 global CC
1145
1146 if {![info exists CC]} {
1147 set CC [find_gcc]
1148 }
7f6bf02d 1149 if { $CC == ""} {
8be1e369 1150 return 0
5ff55910
L
1151 }
1152 set state [remote_exec host $CC -v]
8be1e369
AM
1153 if { [lindex $state 0] != 0 } {
1154 return 0;
1155 }
1156 for { set i 1 } { $i < [llength $state] } { incr i } {
5ff55910
L
1157 set v [lindex $state $i]
1158 if { [ string match "*--disable-plugin*" $v ] } {
1159 verbose "plugin is disabled by $v"
1160 return 0;
1161 }
1162 }
1163
1164 return 1;
1165}
1166
3bd58fbe
L
1167# Returns true if the target compiler supports LTO
1168proc check_lto_available { } {
1169 global lto_available_saved
1170 global CC
7174e19f 1171
3bd58fbe 1172 if {![info exists lto_available_saved]} {
5ff55910 1173 if { ![check_gcc_plugin_enabled] } {
19aef622
NC
1174 set lto_available_saved 0
1175 return 0
1176 }
00f4a602
L
1177 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1178 # -ffat-lto-objects, we always run LTO tests on Linux with
1179 # GCC 4.9 or newer.
1180 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1181 set lto_available_saved 1
1182 return 1
1183 }
3bd58fbe 1184 # Check if gcc supports -flto -fuse-linker-plugin
f1d7f4a6
AM
1185 set flags ""
1186 if [board_info [target_info name] exists cflags] {
1187 append flags " [board_info [target_info name] cflags]"
1188 }
1189 if [board_info [target_info name] exists ldflags] {
1190 append flags " [board_info [target_info name] ldflags]"
3bd58fbe 1191 }
f1d7f4a6
AM
1192
1193 set basename "tmpdir/lto[pid]"
1194 set src ${basename}.c
1195 set output ${basename}.out
3bd58fbe 1196 set f [open $src "w"]
7174e19f 1197 puts $f "int main() { return 0; }"
3bd58fbe 1198 close $f
010f98a5
L
1199 if [is_remote host] {
1200 set src [remote_download host $src]
1201 }
c3e11cbe 1202 set lto_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -fuse-linker-plugin $src -o $output"]
f1d7f4a6
AM
1203 remote_file host delete $src
1204 remote_file host delete $output
3bd58fbe 1205 file delete $src
3bd58fbe
L
1206 }
1207 return $lto_available_saved
1208}
1209
c3e11cbe
AM
1210# Returns true if the target compiler supports LTO -ffat-lto-objects
1211proc check_lto_fat_available { } {
1212 global lto_fat_available_saved
1213 global CC
1214
1215 if {![info exists lto_fat_available_saved]} {
5ff55910 1216 if { ![check_gcc_plugin_enabled] } {
c3e11cbe
AM
1217 set lto_fat_available_saved 0
1218 return 0
1219 }
00f4a602
L
1220 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1221 # -ffat-lto-objects, we always run LTO tests on Linux with
1222 # GCC 4.9 or newer.
1223 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1224 set lto_fat_available_saved 1
1225 return 1
1226 }
c3e11cbe
AM
1227 # Check if gcc supports -flto -fuse-linker-plugin
1228 set flags ""
1229 if [board_info [target_info name] exists cflags] {
1230 append flags " [board_info [target_info name] cflags]"
1231 }
1232 if [board_info [target_info name] exists ldflags] {
1233 append flags " [board_info [target_info name] ldflags]"
1234 }
1235
1236 set basename "tmpdir/lto[pid]"
1237 set src ${basename}.c
1238 set output ${basename}.out
1239 set f [open $src "w"]
1240 puts $f "int main() { return 0; }"
1241 close $f
010f98a5
L
1242 if [is_remote host] {
1243 set src [remote_download host $src]
1244 }
c3e11cbe
AM
1245 set lto_fat_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -ffat-lto-objects -fuse-linker-plugin $src -o $output"]
1246 remote_file host delete $src
1247 remote_file host delete $output
1248 file delete $src
1249 }
1250 return $lto_fat_available_saved
1251}
1252
92c09111
L
1253# Returns true if the target compiler supports LTO and -shared
1254proc check_lto_shared_available { } {
1255 global lto_shared_available_saved
1256 global CC
1257
92c09111 1258 if {![info exists lto_shared_available_saved]} {
5ff55910 1259 if { ![check_gcc_plugin_enabled] } {
3bb9e7b4
AM
1260 set lto_shared_available_saved 0
1261 return 0
1262 }
00f4a602
L
1263 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1264 # -ffat-lto-objects, we always run LTO tests on Linux with
1265 # GCC 4.9 or newer.
1266 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1267 set lto_shared_available_saved 1
1268 return 1
1269 }
92c09111 1270 # Check if gcc supports -flto -fuse-linker-plugin -shared
f1d7f4a6
AM
1271 set flags ""
1272 if [board_info [target_info name] exists cflags] {
1273 append flags " [board_info [target_info name] cflags]"
1274 }
1275 if [board_info [target_info name] exists ldflags] {
1276 append flags " [board_info [target_info name] ldflags]"
92c09111 1277 }
f1d7f4a6
AM
1278
1279 set basename "tmpdir/lto_shared[pid]"
1280 set src ${basename}.c
1281 set output ${basename}.so
92c09111
L
1282 set f [open $src "w"]
1283 puts $f ""
1284 close $f
010f98a5
L
1285 if [is_remote host] {
1286 set src [remote_download host $src]
1287 }
f1d7f4a6
AM
1288 set lto_shared_available_saved [run_host_cmd_yesno "$CC" "$flags -shared -fPIC -flto -fuse-linker-plugin $src -o $output"]
1289 remote_file host delete $src
1290 remote_file host delete $output
92c09111 1291 file delete $src
92c09111
L
1292 }
1293 return $lto_shared_available_saved
1294}
1295
33aa234e
JK
1296# Check if the assembler supports CFI statements.
1297
1298proc check_as_cfi { } {
1299 global check_as_cfi_result
1300 global as
1301 if [info exists check_as_cfi_result] {
1302 return $check_as_cfi_result
1303 }
1304 set as_file "tmpdir/check_as_cfi.s"
1305 set as_fh [open $as_file w 0666]
1306 puts $as_fh "# Generated file. DO NOT EDIT"
1307 puts $as_fh "\t.cfi_startproc"
1308 puts $as_fh "\t.cfi_endproc"
1309 close $as_fh
1310 remote_download host $as_file
1311 verbose -log "Checking CFI support:"
1312 rename "perror" "check_as_cfi_perror"
1313 proc perror { args } { }
1314 set success [ld_assemble $as $as_file "/dev/null"]
1315 rename "perror" ""
1316 rename "check_as_cfi_perror" "perror"
1317 #remote_file host delete $as_file
1318 set check_as_cfi_result $success
1319 return $success
1320}
1321
c22ee0ad
L
1322# Returns true if IFUNC works.
1323
1324proc check_ifunc_available { } {
1325 global ifunc_available_saved
1326 global CC
1327
1328 if {![info exists ifunc_available_saved]} {
1329 if { [which $CC] == 0 } {
1330 set ifunc_available_saved 0
1331 return 0
1332 }
1333 # Check if gcc supports -flto -fuse-linker-plugin
1334 set flags ""
1335 if [board_info [target_info name] exists cflags] {
1336 append flags " [board_info [target_info name] cflags]"
1337 }
1338 if [board_info [target_info name] exists ldflags] {
1339 append flags " [board_info [target_info name] ldflags]"
1340 }
1341
1342 set basename "tmpdir/ifunc[pid]"
1343 set src ${basename}.c
1344 set output ${basename}.out
1345 set f [open $src "w"]
1346 puts $f "extern int library_func2 (void);"
1347 puts $f "int main (void)"
1348 puts $f "{"
1349 puts $f " if (library_func2 () != 2) __builtin_abort ();"
1350 puts $f " return 0; "
1351 puts $f "}"
1352 puts $f "static int library_func1 (void) {return 2; }"
1353 puts $f "void *foo (void) __asm__ (\"library_func2\");"
1354 puts $f "void *foo (void) { return library_func1; }"
1355 puts $f "__asm__(\".type library_func2, %gnu_indirect_function\");"
1356 close $f
010f98a5
L
1357 if [is_remote host] {
1358 set src [remote_download host $src]
1359 }
c22ee0ad 1360 set ifunc_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
77236b83 1361 if { [isnative] && $ifunc_available_saved == 1 } {
c22ee0ad
L
1362 set ifunc_available_saved [run_host_cmd_yesno "$output" ""]
1363 }
1364 remote_file host delete $src
1365 remote_file host delete $output
1366 file delete $src
1367 }
1368 return $ifunc_available_saved
1369}
1370
97dc35c8
L
1371# Returns true if ifunc attribute works.
1372
1373proc check_ifunc_attribute_available { } {
1374 global ifunc_attribute_available_saved
1375 global CC
1376
1377 if {![info exists ifunc_attribute_available_saved]} {
1378 if { [which $CC] == 0 } {
1379 set ifunc_attribute_available_saved 0
1380 return 0
1381 }
1382 # Check if gcc supports -flto -fuse-linker-plugin
1383 set flags ""
1384 if [board_info [target_info name] exists cflags] {
1385 append flags " [board_info [target_info name] cflags]"
1386 }
1387 if [board_info [target_info name] exists ldflags] {
1388 append flags " [board_info [target_info name] ldflags]"
1389 }
1390
1391 set basename "tmpdir/ifunc[pid]"
1392 set src ${basename}.c
1393 set output ${basename}.out
1394 set f [open $src "w"]
1395 puts $f "extern int library_func2 (void) __attribute__ ((ifunc (\"foo\")));"
1396 puts $f "int main (void)"
1397 puts $f "{"
1398 puts $f " if (library_func2 () != 2) __builtin_abort ();"
1399 puts $f " return 0; "
1400 puts $f "}"
1401 puts $f "static int library_func1 (void) {return 2; }"
1402 puts $f "void *foo (void) { return library_func1; }"
1403 close $f
010f98a5
L
1404 if [is_remote host] {
1405 set src [remote_download host $src]
1406 }
97dc35c8 1407 set ifunc_attribute_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
77236b83 1408 if { [isnative] && $ifunc_attribute_available_saved == 1 } {
97dc35c8
L
1409 set ifunc_attribute_available_saved [run_host_cmd_yesno "$output" ""]
1410 }
1411 remote_file host delete $src
1412 remote_file host delete $output
1413 file delete $src
1414 }
1415 return $ifunc_attribute_available_saved
1416}
1417
fd121c5c
JW
1418# Return true if libdl is supported.
1419
1420proc check_libdl_available { } {
1421 global libdl_available_saved
1422 global CC
1423
1424 if {![info exists libdl_available_saved]} {
1425 if { [which $CC] == 0 } {
1426 set libdl_available_saved 0
1427 return 0
1428 }
1429
1430 set basename "tmpdir/dl_avail_test[pid]"
1431 set src ${basename}.c
1432 set output ${basename}.out
1433 set f [open $src "w"]
1434 # Sample test file.
1435 puts $f "#include <dlfcn.h>"
1436 puts $f "int main (void)"
1437 puts $f "{"
1438 puts $f " dlopen (\"dummy.so\", RTLD_NOW);"
1439 puts $f " return 0; "
1440 puts $f "}"
1441 close $f
1442 if [is_remote host] {
1443 set src [remote_download host $src]
1444 }
1445 set libdl_available_saved [run_host_cmd_yesno "$CC" "$src -o $output -ldl"]
1446 remote_file host delete $src
1447 remote_file host delete $output
1448 file delete $src
1449 }
1450 return $libdl_available_saved
1451}
0aae7e72
L
1452
1453# Returns true if GNU2 TLS works.
1454
1455proc check_gnu2_tls_available { } {
1456 global gnu2_tls_available_saved
1457 global CC
1458 global GNU2_CFLAGS
1459
1460 if {![info exists gnu2_tls_available_saved]} {
1461 if { [which $CC] == 0 || "$GNU2_CFLAGS" == "" } {
1462 set gnu2_tls_available_saved 0
1463 return 0
1464 }
1465 # Check if GNU2 TLS works.
1466 set flags "$GNU2_CFLAGS"
1467 if [board_info [target_info name] exists cflags] {
1468 append flags " [board_info [target_info name] cflags]"
1469 }
1470 if [board_info [target_info name] exists ldflags] {
1471 append flags " [board_info [target_info name] ldflags]"
1472 }
1473
1474 set basename "tmpdir/gnu2_tls[pid]"
1475 set src1 ${basename}1.c
1476 set output1 ${basename}.so
1477 set f [open $src1 "w"]
1478 puts $f "extern __thread int zzz;"
1479 puts $f "int foo (void)"
1480 puts $f "{"
1481 puts $f " return zzz;"
1482 puts $f "}"
1483 close $f
1484 if [is_remote host] {
1485 set src1 [remote_download host $src1]
1486 }
1487 set src2 ${basename}2.c
1488 set output2 ${basename}.exe
1489 set f [open $src2 "w"]
1490 puts $f "__thread int zzz = 20;"
1491 puts $f "extern int foo (void);"
1492 puts $f "int main (void)"
1493 puts $f "{"
1494 puts $f " if (foo () != 20) __builtin_abort ();"
1495 puts $f " return 0; "
1496 puts $f "}"
1497 close $f
1498 if [is_remote host] {
1499 set src2 [remote_download host $src2]
1500 }
1501 set gnu2_tls_available_saved [run_host_cmd_yesno "$CC" "-fPIC -shared $flags $src1 -o $output1"]
1502 if { $gnu2_tls_available_saved == 1 } {
1503 set gnu2_tls_available_saved [run_host_cmd_yesno "$CC" "$flags $src2 $output1 -o $output2"]
1504 if { $gnu2_tls_available_saved == 1 } {
1505 set gnu2_tls_available_saved [run_host_cmd_yesno "$output2" ""]
1506 }
1507 }
1508 remote_file host delete $src1
1509 remote_file host delete $output1
1510 remote_file host delete $src2
1511 remote_file host delete $output2
1512 file delete $src1 $src2
1513 }
1514 return $gnu2_tls_available_saved
1515}
This page took 0.921366 seconds and 4 git commands to generate.