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