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