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