Emit a warning when -z relro is unsupported
[deliverable/binutils-gdb.git] / ld / testsuite / lib / ld-lib.exp
1 # Support routines for LD testsuite.
2 # Copyright (C) 1994-2020 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
467 set ld_extra_opt ""
468 if [check_relro_support] {
469 set ld_extra_opt "-z norelro"
470 }
471
472 foreach testitem $ldtests {
473 set testname [lindex $testitem 0]
474
475 if ![runtest_file_p $runtests $testname] then {
476 continue
477 }
478
479 foreach target $args {
480 if [match_target $target] {
481 setup_xfail "*-*-*"
482 break
483 }
484 }
485
486 set ld_options [lindex $testitem 1]
487 set ld_after [lindex $testitem 2]
488 set as_options [lindex $testitem 3]
489 set src_files [lindex $testitem 4]
490 set actions [lindex $testitem 5]
491 set binfile tmpdir/[lindex $testitem 6]
492 set cflags [lindex $testitem 7]
493 set objfiles {}
494 set is_unresolved 0
495 set failed 0
496 set maybe_failed 0
497 set ld_output ""
498
499 # verbose -log "Testname is $testname"
500 # verbose -log "ld_options is $ld_options"
501 # verbose -log "ld_after is $ld_after"
502 # verbose -log "as_options is $as_options"
503 # verbose -log "src_files is $src_files"
504 # verbose -log "actions is $actions"
505 # verbose -log "binfile is $binfile"
506
507 # Assemble each file in the test.
508 foreach src_file $src_files {
509 set fileroot "[file rootname [file tail $src_file]]"
510 set objfile "tmpdir/$fileroot.o"
511 lappend objfiles $objfile
512
513 if { [file extension $src_file] == ".c" } {
514 set as_file "tmpdir/$fileroot.s"
515 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
516 set is_unresolved 1
517 break
518 }
519 } else {
520 set as_file "$srcdir/$subdir/$src_file"
521 }
522 if ![ld_assemble $as "$as_options $as_file" $objfile] {
523 set is_unresolved 1
524 break
525 }
526 }
527
528 # Catch assembler errors.
529 if { $is_unresolved } {
530 unresolved $testname
531 continue
532 }
533
534 if { $binfile eq "tmpdir/" } {
535 # compile only
536 } elseif { [regexp ".*\\.a$" $binfile] } {
537 if { ![ar_simple_create $ar $ld_options $binfile "$objfiles $ld_after"] } {
538 set failed 1
539 }
540 } elseif { ![ld_link $ld $binfile "$ld_extra_opt -L$srcdir/$subdir $ld_options $objfiles $ld_after"] } {
541 set maybe_failed 1
542 set ld_output "$exec_output"
543 }
544
545 if { !$failed } {
546 foreach actionlist $actions {
547 set action [lindex $actionlist 0]
548 set progopts [lindex $actionlist 1]
549
550 # There are actions where we run regexp_diff on the
551 # output, and there are other actions (presumably).
552 # Handling of the former look the same.
553 set dump_prog ""
554 switch -- $action {
555 objdump
556 { set dump_prog $objdump }
557 nm
558 { set dump_prog $nm }
559 readelf
560 { set dump_prog $READELF }
561 ld
562 { set dump_prog "ld" }
563 default
564 {
565 perror "Unrecognized action $action"
566 set is_unresolved 1
567 break
568 }
569 }
570
571 if { $action == "ld" } {
572 set regexpfile $progopts
573 verbose "regexpfile is $srcdir/$subdir/$regexpfile"
574 set_file_contents "tmpdir/ld.messages" "$ld_output"
575 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
576 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$regexpfile"] } then {
577 verbose "output is $ld_output" 2
578 set failed 1
579 break
580 }
581 set maybe_failed 0
582 } elseif { !$maybe_failed && $dump_prog != "" } {
583 set dumpfile [lindex $actionlist 2]
584 set binary $dump_prog
585
586 # Ensure consistent sorting of symbols
587 if {[info exists env(LC_ALL)]} {
588 set old_lc_all $env(LC_ALL)
589 }
590 set env(LC_ALL) "C"
591 set cmd "$binary $progopts $binfile"
592 set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
593 send_log "$cmd\n"
594 remote_upload host "ld.stderr"
595 set comp_output [prune_warnings [file_contents "ld.stderr"]]
596 remote_file host delete "ld.stderr"
597 remote_file build delete "ld.stderr"
598
599 if {[info exists old_lc_all]} {
600 set env(LC_ALL) $old_lc_all
601 } else {
602 unset env(LC_ALL)
603 }
604
605 if ![string match "" $comp_output] then {
606 send_log "$comp_output\n"
607 set failed 1
608 break
609 }
610
611 remote_upload host "dump.out"
612
613 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
614 verbose "output is [file_contents "dump.out"]" 2
615 set failed 1
616 remote_file build delete "dump.out"
617 remote_file host delete "dump.out"
618 break
619 }
620 remote_file build delete "dump.out"
621 remote_file host delete "dump.out"
622 }
623 }
624 }
625
626 if { $is_unresolved } {
627 unresolved $testname
628 } elseif { $maybe_failed || $failed } {
629 fail $testname
630 } else {
631 pass $testname
632 }
633 }
634 }
635
636 # ldtests contains test-items with 3 items followed by 1 lists, 2 items
637 # and 3 optional items:
638 # 0:name
639 # 1:ld leading options, placed before object files
640 # 2:assembler options
641 # 3:filenames of source files
642 # 4:name of output file
643 # 5:expected output
644 # 6:compiler flags (optional)
645 # 7:language (optional)
646 # 8:linker warning (optional)
647 # 9:ld trailing options, placed after object files (optional)
648 # args is an optional list of target triplets to be xfailed.
649
650 proc run_ld_link_exec_tests { ldtests args } {
651 global ld
652 global as
653 global srcdir
654 global subdir
655 global env
656 global CC
657 global CXX
658 global CFLAGS
659 global CXXFLAGS
660 global errcnt
661 global exec_output
662 global board_cflags
663 global STATIC_LDFLAGS
664
665 # When using GCC as the linker driver, we need to specify board cflags when
666 # linking because cflags may contain linker options. For example when
667 # linker options are included in GCC spec files then we need the -specs
668 # option.
669 if [board_info [target_info name] exists cflags] {
670 set board_cflags " [board_info [target_info name] cflags]"
671 } else {
672 set board_cflags ""
673 }
674
675 foreach testitem $ldtests {
676 set testname [lindex $testitem 0]
677 set ld_options [lindex $testitem 1]
678 set as_options [lindex $testitem 2]
679 set src_files [lindex $testitem 3]
680 set binfile tmpdir/[lindex $testitem 4]
681 set expfile [lindex $testitem 5]
682 set cflags [lindex $testitem 6]
683 set lang [lindex $testitem 7]
684 set warning [lindex $testitem 8]
685 set ld_after [lindex $testitem 9]
686 set objfiles {}
687 set failed 0
688
689 if { ![check_compiler_available] } {
690 unsupported $testname
691 continue
692 }
693
694 foreach target $args {
695 if [match_target $target] {
696 setup_xfail "*-*-*"
697 break
698 }
699 }
700
701 # verbose -log "Testname is $testname"
702 # verbose -log "ld_options is $ld_options"
703 # verbose -log "as_options is $as_options"
704 # verbose -log "src_files is $src_files"
705 # verbose -log "binfile is $binfile"
706
707 # Assemble each file in the test.
708 foreach src_file $src_files {
709 set fileroot "[file rootname [file tail $src_file]]"
710 set objfile "tmpdir/$fileroot.o"
711 lappend objfiles $objfile
712
713 if { [ string match "c++" $lang ] } {
714 set cmd "$CXX -c $CXXFLAGS $cflags"
715 } else {
716 set cmd "$CC -c $CFLAGS $cflags"
717 }
718 if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] {
719 set failed 1
720 break
721 }
722 }
723 if { $failed != 0 } {
724 unresolved $testname
725 continue
726 }
727
728 if { [ string match "asm" $lang ] } {
729 set link_proc ld_link
730 set link_cmd $ld
731 } elseif { [ string match "c++" $lang ] } {
732 set link_proc ld_link
733 set link_cmd $CXX
734 } else {
735 set link_proc ld_link
736 set link_cmd $CC
737 }
738
739 if { $binfile eq "tmpdir/" } {
740 # compile only
741 pass $testname
742 continue;
743 } else {
744 if { [string match "" $STATIC_LDFLAGS] \
745 && [regexp -- ".* \[-\]+static .*" " $board_cflags $ld_options $objfiles $ld_after "] } {
746 untested $testname
747 continue
748 }
749 if ![$link_proc $link_cmd $binfile "$board_cflags -L$srcdir/$subdir $ld_options $objfiles $ld_after"] {
750 set failed 1
751 }
752 }
753
754 # Check if exec_output is expected.
755 if { $warning != "" } then {
756 verbose -log "returned with: <$exec_output>, expected: <$warning>"
757 if { [regexp $warning $exec_output] } then {
758 set failed 0
759 } else {
760 set failed 1
761 }
762 }
763
764 if { $failed == 0 && [isnative] } {
765 send_log "Running: $binfile > $binfile.out\n"
766 verbose "Running: $binfile > $binfile.out"
767 catch "exec $binfile > $binfile.out" 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 } else {
774 send_log [file_contents $binfile.out]
775 verbose [file_contents $binfile.out] 2
776 if [regexp_diff "$binfile.out" "$srcdir/$subdir/$expfile"] {
777 set failed 1
778 }
779 }
780 }
781
782 if { $failed != 0 } {
783 fail $testname
784 } elseif ![isnative] {
785 unsupported $testname
786 } else {
787 set errcnt 0
788 pass $testname
789 }
790 }
791 }
792
793 # List contains test-items with 3 items followed by 2 lists, one item and
794 # one optional item:
795 # 0:name
796 # 1:ld or ar options
797 # 2:compile options
798 # 3:filenames of source files
799 # 4:action and options.
800 # 5:name of output file
801 # 6:language (optional)
802 #
803 # Actions:
804 # objdump: Apply objdump options on result. Compare with regex (last arg).
805 # nm: Apply nm options on result. Compare with regex (last arg).
806 # readelf: Apply readelf options on result. Compare with regex (last arg).
807 # warning: Check linker output against regex (last arg).
808 # error: Like 'warning' but checking output in error case.
809 # warning_output: Check linker output against regex in a file (last arg).
810 # error_output: Like 'warning_output' but checking output in error case.
811 #
812 proc run_cc_link_tests { ldtests } {
813 global nm
814 global objdump
815 global READELF
816 global srcdir
817 global subdir
818 global env
819 global CC
820 global CXX
821 global CFLAGS
822 global CXXFLAGS
823 global ar
824 global exec_output
825 global board_cflags
826 global STATIC_LDFLAGS
827
828 if [board_info [target_info name] exists cflags] {
829 set board_cflags " [board_info [target_info name] cflags]"
830 } else {
831 set board_cflags ""
832 }
833
834 foreach testitem $ldtests {
835 set testname [lindex $testitem 0]
836 set ldflags [lindex $testitem 1]
837 set cflags [lindex $testitem 2]
838 set src_files [lindex $testitem 3]
839 set actions [lindex $testitem 4]
840 set binfile tmpdir/[lindex $testitem 5]
841 set lang [lindex $testitem 6]
842 set objfiles {}
843 set is_unresolved 0
844 set failed 0
845 set check_ld(terminal) 0
846 set check_ld(source) ""
847
848 if { ![check_compiler_available] } {
849 unsupported $testname
850 continue
851 }
852
853 #verbose -log "testname is $testname"
854 #verbose -log "ldflags is $ldflags"
855 #verbose -log "cflags is $cflags"
856 #verbose -log "src_files is $src_files"
857 #verbose -log "actions is $actions"
858 #verbose -log "binfile is $binfile"
859 #verbose -log "lang is $lang"
860
861 foreach actionlist $actions {
862 set action [lindex $actionlist 0]
863 set progopts [lindex $actionlist 1]
864
865 # Find actions related to error/warning processing.
866 switch -- $action {
867 error
868 {
869 set check_ld(source) "regexp"
870 set check_ld(regexp) $progopts
871 set check_ld(terminal) 1
872 }
873 warning
874 {
875 set check_ld(source) "regexp"
876 set check_ld(regexp) $progopts
877 }
878 error_output
879 {
880 set check_ld(source) "file"
881 set check_ld(file) $progopts
882 set check_ld(terminal) 1
883 }
884 warning_output
885 {
886 set check_ld(source) "file"
887 set check_ld(file) $progopts
888 }
889 }
890 }
891
892 # Compile each file in the test.
893 foreach src_file $src_files {
894 set fileroot "[file rootname [file tail $src_file]]"
895 set objfile "tmpdir/$fileroot.o"
896 lappend objfiles $objfile
897
898 if { [ string match "c++" $lang ] } {
899 set cmd "$CXX -c $CXXFLAGS $cflags"
900 } else {
901 set cmd "$CC -c $CFLAGS $cflags"
902 }
903 if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] {
904 set failed 1
905 break
906 }
907 }
908 if { $failed != 0 } {
909 unresolved $testname
910 continue
911 }
912
913 # Clear error and warning counts.
914 reset_vars
915
916 if { [ string match "c++" $lang ] } {
917 set cc_cmd $CXX
918 } else {
919 set cc_cmd $CC
920 }
921
922 if { $binfile eq "tmpdir/" } {
923 # compile only
924 set binfile $objfile
925 } elseif { [regexp ".*\\.a$" $binfile] } {
926 if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
927 set failed 1
928 }
929 } else {
930 if { [string match "" $STATIC_LDFLAGS] \
931 && [regexp -- ".* \[-\]+static .*" " $board_cflags $ldflags $objfiles "] } {
932 untested $testname
933 continue
934 }
935 ld_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"
936 set ld_output "$exec_output"
937
938 if { $check_ld(source) == "regexp" } then {
939 # Match output against regexp argument.
940 verbose -log "returned with: <$ld_output>, expected: <$check_ld(regexp)>"
941 if { ![regexp $check_ld(regexp) $ld_output] } then {
942 set failed 1
943 }
944 } elseif { $check_ld(source) == "file" } then {
945 # Match output against patterns in a file.
946 set_file_contents "tmpdir/ld.messages" "$ld_output"
947 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
948 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$check_ld(file)"] } then {
949 verbose "output is $ld_output" 2
950 set failed 1
951 }
952 }
953
954 if { $check_ld(source) != "" } then {
955 if { $ld_output == "" } then {
956 verbose -log "Linker was expected to give error or warning"
957 set failed 1
958 }
959 } else {
960 if { $ld_output != "" } then {
961 verbose -log "Unexpected linker warning or error"
962 set failed 1
963 }
964 }
965 }
966
967 if { $failed == 0 } {
968 foreach actionlist $actions {
969 set action [lindex $actionlist 0]
970 set progopts [lindex $actionlist 1]
971
972 # There are actions where we run regexp_diff on the
973 # output, and there are other actions (presumably).
974 # Handling of the former look the same.
975 set dump_prog ""
976 switch -- $action {
977 objdump
978 { set dump_prog $objdump }
979 nm
980 { set dump_prog $nm }
981 readelf
982 { set dump_prog $READELF }
983 error {}
984 warning {}
985 error_output {}
986 warning_output {}
987 default
988 {
989 perror "Unrecognized action $action"
990 set is_unresolved 1
991 break
992 }
993 }
994
995 if { $dump_prog != "" } {
996 set dumpfile [lindex $actionlist 2]
997 set binary $dump_prog
998
999 # Ensure consistent sorting of symbols
1000 if {[info exists env(LC_ALL)]} {
1001 set old_lc_all $env(LC_ALL)
1002 }
1003 set env(LC_ALL) "C"
1004 set cmd "$binary $progopts $binfile > dump.out"
1005 send_log "$cmd\n"
1006 catch "exec $cmd" comp_output
1007 if {[info exists old_lc_all]} {
1008 set env(LC_ALL) $old_lc_all
1009 } else {
1010 unset env(LC_ALL)
1011 }
1012 set comp_output [prune_warnings $comp_output]
1013
1014 if ![string match "" $comp_output] then {
1015 send_log "$comp_output\n"
1016 set failed 1
1017 break
1018 }
1019
1020 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1021 verbose "output is [file_contents "dump.out"]" 2
1022 set failed 1
1023 break
1024 }
1025 }
1026 }
1027 }
1028
1029 if { $failed } {
1030 fail $testname
1031 } elseif { $is_unresolved } {
1032 unresolved $testname
1033 } else {
1034 pass $testname
1035 }
1036 }
1037 }
1038
1039 # Returns true if --gc-sections is supported on the target.
1040
1041 proc check_gc_sections_available { } {
1042 global gc_sections_available_saved
1043 global ld
1044
1045 if {![info exists gc_sections_available_saved]} {
1046 # Some targets don't support gc-sections despite whatever's
1047 # advertised by ld's options.
1048 if { [istarget alpha-*-*]
1049 || [istarget bpf-*-*]
1050 || [istarget d30v-*-*]
1051 || [istarget dlx-*-*]
1052 || [istarget hppa*64-*-*]
1053 || [istarget ia64-*-*]
1054 || [istarget mep-*-*]
1055 || [istarget mn10200-*-*]
1056 || [istarget pj*-*-*]
1057 || [istarget pru*-*-*]
1058 || [istarget s12z-*-*]
1059 || [istarget xgate-*-*]
1060 || [istarget z80-*-*] } {
1061 set gc_sections_available_saved 0
1062 return 0
1063 }
1064
1065 # elf2flt uses -q (--emit-relocs), which is incompatible with
1066 # --gc-sections.
1067 if { [board_info target exists ldflags]
1068 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1069 set gc_sections_available_saved 0
1070 return 0
1071 }
1072
1073 # Check if the ld used by gcc supports --gc-sections.
1074 # FIXME: this test is useless since ld --help always says
1075 # --gc-sections is available
1076 set ld_output [remote_exec host $ld "--help"]
1077 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1078 set gc_sections_available_saved 1
1079 } else {
1080 set gc_sections_available_saved 0
1081 }
1082 }
1083 return $gc_sections_available_saved
1084 }
1085
1086 # Return true if target uses genelf.em.
1087 proc uses_genelf { } {
1088 if { [istarget "d30v-*-*"]
1089 || [istarget "dlx-*-*"]
1090 || [istarget "fr30-*-*"]
1091 || ([istarget "frv-*-*"] && ![istarget "frv-*-linux*"])
1092 || [istarget "ft32-*-*"]
1093 || [istarget "iq2000-*-*"]
1094 || [istarget "mn10200-*-*"]
1095 || [istarget "msp430-*-*"]
1096 || [istarget "mt-*-*"]
1097 || [istarget "pj*-*-*"]
1098 || [istarget "s12z-*-*"]
1099 || [istarget "xgate-*-*"] } {
1100 return 1
1101 }
1102 return 0
1103 }
1104
1105 proc is_underscore_target { } {
1106 global is_underscore_target_saved
1107 global target_triplet
1108 global srcdir
1109
1110 if { ![info exists is_underscore_target_saved] } {
1111 set cmd "targ=$target_triplet . $srcdir/../../bfd/config.bfd &&"
1112 append cmd { echo "$targ_underscore"}
1113 verbose -log "$cmd"
1114 set status [catch {exec sh -c $cmd} result]
1115 if { $status == 0 && [string match "yes" $result] } {
1116 set is_underscore_target_saved 1
1117 } else {
1118 set is_underscore_target_saved 0
1119 }
1120 }
1121 return $is_underscore_target_saved
1122 }
1123
1124 # Returns true if the target ld supports the plugin API.
1125 proc check_plugin_api_available { } {
1126 global plugin_api_available_saved
1127 global ld
1128 if {![info exists plugin_api_available_saved]} {
1129 # Check if the ld used by gcc supports --plugin.
1130 set ld_output [remote_exec host $ld "--help"]
1131 if { [regexp -- "-plugin PLUGIN \[^\n\r\]*" $ld_output line]
1132 && ![regexp "ignored" $line] } {
1133 set plugin_api_available_saved 1
1134 } else {
1135 set plugin_api_available_saved 0
1136 }
1137 }
1138 return $plugin_api_available_saved
1139 }
1140
1141 # Sets ld_sysroot to the current sysroot (empty if not supported) and
1142 # returns true if the target ld supports sysroot.
1143 proc check_sysroot_available { } {
1144 global ld_sysroot_available_saved ld ld_sysroot
1145 if {![info exists ld_sysroot_available_saved]} {
1146 # Check if ld supports --sysroot *other* than empty.
1147 set ld_sysroot [string trimright [lindex [remote_exec host $ld "--print-sysroot"] 1]]
1148 if { $ld_sysroot == "" } {
1149 set ld_sysroot_available_saved 0
1150 } else {
1151 set ld_sysroot_available_saved 1
1152 }
1153 }
1154 return $ld_sysroot_available_saved
1155 }
1156
1157 # Return true if we can build a program with the compiler.
1158 # On some targets, CC might be defined, but libraries and startup
1159 # code might be missing or require special options that the ld test
1160 # harness doesn't know about.
1161
1162 proc check_compiler_available { } {
1163 global compiler_available_saved
1164 global CC
1165
1166 if {![info exists compiler_available_saved]} {
1167 if { [which $CC] == 0 } {
1168 set compiler_available_saved 0
1169 return 0
1170 }
1171
1172 set flags ""
1173 if [board_info [target_info name] exists cflags] {
1174 append flags " [board_info [target_info name] cflags]"
1175 }
1176 if [board_info [target_info name] exists ldflags] {
1177 append flags " [board_info [target_info name] ldflags]"
1178 }
1179
1180 set basename "tmpdir/compiler[pid]"
1181 set src ${basename}.c
1182 set output ${basename}.out
1183 set f [open $src "w"]
1184 puts $f "int main (void)"
1185 puts $f "{"
1186 puts $f " return 0; "
1187 puts $f "}"
1188 close $f
1189 if [is_remote host] {
1190 set src [remote_download host $src]
1191 }
1192 set compiler_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
1193 remote_file host delete $src
1194 remote_file host delete $output
1195 file delete $src
1196 }
1197 return $compiler_available_saved
1198 }
1199
1200 # Returns 1 if plugin is enabled in gcc. Returns 0 otherwise.
1201 proc check_gcc_plugin_enabled { } {
1202 global CC
1203
1204 if {![info exists CC]} {
1205 set CC [find_gcc]
1206 }
1207 if { $CC == ""} {
1208 return 0
1209 }
1210 set state [remote_exec host $CC -v]
1211 if { [lindex $state 0] != 0 } {
1212 return 0;
1213 }
1214 for { set i 1 } { $i < [llength $state] } { incr i } {
1215 set v [lindex $state $i]
1216 if { [ string match "*--disable-plugin*" $v ] } {
1217 verbose "plugin is disabled by $v"
1218 return 0;
1219 }
1220 }
1221
1222 return 1;
1223 }
1224
1225 # Returns true if the target compiler supports LTO
1226 proc check_lto_available { } {
1227 global lto_available_saved
1228 global CC
1229
1230 if {![info exists lto_available_saved]} {
1231 if { ![check_gcc_plugin_enabled] } {
1232 set lto_available_saved 0
1233 return 0
1234 }
1235 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1236 # -ffat-lto-objects, we always run LTO tests on Linux with
1237 # GCC 4.9 or newer.
1238 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1239 set lto_available_saved 1
1240 return 1
1241 }
1242 # Check if gcc supports -flto -fuse-linker-plugin
1243 set flags ""
1244 if [board_info [target_info name] exists cflags] {
1245 append flags " [board_info [target_info name] cflags]"
1246 }
1247 if [board_info [target_info name] exists ldflags] {
1248 append flags " [board_info [target_info name] ldflags]"
1249 }
1250
1251 set basename "tmpdir/lto[pid]"
1252 set src ${basename}.c
1253 set output ${basename}.out
1254 set f [open $src "w"]
1255 puts $f "int main() { return 0; }"
1256 close $f
1257 if [is_remote host] {
1258 set src [remote_download host $src]
1259 }
1260 set lto_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -fuse-linker-plugin $src -o $output"]
1261 remote_file host delete $src
1262 remote_file host delete $output
1263 file delete $src
1264 }
1265 return $lto_available_saved
1266 }
1267
1268 # Returns true if the target compiler supports LTO -ffat-lto-objects
1269 proc check_lto_fat_available { } {
1270 global lto_fat_available_saved
1271 global CC
1272
1273 if {![info exists lto_fat_available_saved]} {
1274 if { ![check_gcc_plugin_enabled] } {
1275 set lto_fat_available_saved 0
1276 return 0
1277 }
1278 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1279 # -ffat-lto-objects, we always run LTO tests on Linux with
1280 # GCC 4.9 or newer.
1281 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1282 set lto_fat_available_saved 1
1283 return 1
1284 }
1285 # Check if gcc supports -flto -fuse-linker-plugin
1286 set flags ""
1287 if [board_info [target_info name] exists cflags] {
1288 append flags " [board_info [target_info name] cflags]"
1289 }
1290 if [board_info [target_info name] exists ldflags] {
1291 append flags " [board_info [target_info name] ldflags]"
1292 }
1293
1294 set basename "tmpdir/lto[pid]"
1295 set src ${basename}.c
1296 set output ${basename}.out
1297 set f [open $src "w"]
1298 puts $f "int main() { return 0; }"
1299 close $f
1300 if [is_remote host] {
1301 set src [remote_download host $src]
1302 }
1303 set lto_fat_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -ffat-lto-objects -fuse-linker-plugin $src -o $output"]
1304 remote_file host delete $src
1305 remote_file host delete $output
1306 file delete $src
1307 }
1308 return $lto_fat_available_saved
1309 }
1310
1311 # Returns true if the target compiler supports LTO and -shared
1312 proc check_lto_shared_available { } {
1313 global lto_shared_available_saved
1314 global CC
1315
1316 if {![info exists lto_shared_available_saved]} {
1317 if { ![check_gcc_plugin_enabled] } {
1318 set lto_shared_available_saved 0
1319 return 0
1320 }
1321 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1322 # -ffat-lto-objects, we always run LTO tests on Linux with
1323 # GCC 4.9 or newer.
1324 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1325 set lto_shared_available_saved 1
1326 return 1
1327 }
1328 # Check if gcc supports -flto -fuse-linker-plugin -shared
1329 set flags ""
1330 if [board_info [target_info name] exists cflags] {
1331 append flags " [board_info [target_info name] cflags]"
1332 }
1333 if [board_info [target_info name] exists ldflags] {
1334 append flags " [board_info [target_info name] ldflags]"
1335 }
1336
1337 set basename "tmpdir/lto_shared[pid]"
1338 set src ${basename}.c
1339 set output ${basename}.so
1340 set f [open $src "w"]
1341 puts $f ""
1342 close $f
1343 if [is_remote host] {
1344 set src [remote_download host $src]
1345 }
1346 set lto_shared_available_saved [run_host_cmd_yesno "$CC" "$flags -shared -fPIC -flto -fuse-linker-plugin $src -o $output"]
1347 remote_file host delete $src
1348 remote_file host delete $output
1349 file delete $src
1350 }
1351 return $lto_shared_available_saved
1352 }
1353
1354 # Check if the assembler supports CFI statements.
1355
1356 proc check_as_cfi { } {
1357 global check_as_cfi_result
1358 global as
1359 if [info exists check_as_cfi_result] {
1360 return $check_as_cfi_result
1361 }
1362 set as_file "tmpdir/check_as_cfi.s"
1363 set as_fh [open $as_file w 0666]
1364 puts $as_fh "# Generated file. DO NOT EDIT"
1365 puts $as_fh "\t.cfi_startproc"
1366 puts $as_fh "\t.cfi_endproc"
1367 close $as_fh
1368 remote_download host $as_file
1369 verbose -log "Checking CFI support:"
1370 rename "perror" "check_as_cfi_perror"
1371 proc perror { args } { }
1372 set success [ld_assemble $as $as_file "/dev/null"]
1373 rename "perror" ""
1374 rename "check_as_cfi_perror" "perror"
1375 #remote_file host delete $as_file
1376 set check_as_cfi_result $success
1377 return $success
1378 }
1379
1380 # Returns true if IFUNC works.
1381
1382 proc check_ifunc_available { } {
1383 global ifunc_available_saved
1384 global CC
1385
1386 if {![info exists ifunc_available_saved]} {
1387 if { ![check_compiler_available] } {
1388 set ifunc_available_saved 0
1389 return 0
1390 }
1391 # Check if gcc supports -flto -fuse-linker-plugin
1392 set flags ""
1393 if [board_info [target_info name] exists cflags] {
1394 append flags " [board_info [target_info name] cflags]"
1395 }
1396 if [board_info [target_info name] exists ldflags] {
1397 append flags " [board_info [target_info name] ldflags]"
1398 }
1399
1400 set basename "tmpdir/ifunc[pid]"
1401 set src ${basename}.c
1402 set output ${basename}.out
1403 set f [open $src "w"]
1404 puts $f "extern int library_func2 (void);"
1405 puts $f "int main (void)"
1406 puts $f "{"
1407 puts $f " if (library_func2 () != 2) __builtin_abort ();"
1408 puts $f " return 0; "
1409 puts $f "}"
1410 puts $f "static int library_func1 (void) {return 2; }"
1411 puts $f "void *foo (void) __asm__ (\"library_func2\");"
1412 puts $f "void *foo (void) { return library_func1; }"
1413 puts $f "__asm__(\".type library_func2, %gnu_indirect_function\");"
1414 close $f
1415 if [is_remote host] {
1416 set src [remote_download host $src]
1417 }
1418 set ifunc_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
1419 if { [isnative] && $ifunc_available_saved == 1 } {
1420 set ifunc_available_saved [run_host_cmd_yesno "$output" ""]
1421 }
1422 remote_file host delete $src
1423 remote_file host delete $output
1424 file delete $src
1425 }
1426 return $ifunc_available_saved
1427 }
1428
1429 # Returns true if ifunc attribute works.
1430
1431 proc check_ifunc_attribute_available { } {
1432 global ifunc_attribute_available_saved
1433 global CC
1434
1435 if {![info exists ifunc_attribute_available_saved]} {
1436 if { ![check_compiler_available] } {
1437 set ifunc_attribute_available_saved 0
1438 return 0
1439 }
1440 # Check if gcc supports -flto -fuse-linker-plugin
1441 set flags ""
1442 if [board_info [target_info name] exists cflags] {
1443 append flags " [board_info [target_info name] cflags]"
1444 }
1445 if [board_info [target_info name] exists ldflags] {
1446 append flags " [board_info [target_info name] ldflags]"
1447 }
1448
1449 set basename "tmpdir/ifunc[pid]"
1450 set src ${basename}.c
1451 set output ${basename}.out
1452 set f [open $src "w"]
1453 puts $f "extern int library_func2 (void) __attribute__ ((ifunc (\"foo\")));"
1454 puts $f "int main (void)"
1455 puts $f "{"
1456 puts $f " if (library_func2 () != 2) __builtin_abort ();"
1457 puts $f " return 0; "
1458 puts $f "}"
1459 puts $f "static int library_func1 (void) {return 2; }"
1460 puts $f "void *foo (void) { return library_func1; }"
1461 close $f
1462 if [is_remote host] {
1463 set src [remote_download host $src]
1464 }
1465 set ifunc_attribute_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
1466 if { [isnative] && $ifunc_attribute_available_saved == 1 } {
1467 set ifunc_attribute_available_saved [run_host_cmd_yesno "$output" ""]
1468 }
1469 remote_file host delete $src
1470 remote_file host delete $output
1471 file delete $src
1472 }
1473 return $ifunc_attribute_available_saved
1474 }
1475
1476 # Return true if libdl is supported.
1477
1478 proc check_libdl_available { } {
1479 global libdl_available_saved
1480 global CC
1481
1482 if {![info exists libdl_available_saved]} {
1483 if { ![check_compiler_available] } {
1484 set libdl_available_saved 0
1485 return 0
1486 }
1487
1488 set basename "tmpdir/dl_avail_test[pid]"
1489 set src ${basename}.c
1490 set output ${basename}.out
1491 set f [open $src "w"]
1492 # Sample test file.
1493 puts $f "#include <dlfcn.h>"
1494 puts $f "int main (void)"
1495 puts $f "{"
1496 puts $f " dlopen (\"dummy.so\", RTLD_NOW);"
1497 puts $f " return 0; "
1498 puts $f "}"
1499 close $f
1500 if [is_remote host] {
1501 set src [remote_download host $src]
1502 }
1503 set libdl_available_saved [run_host_cmd_yesno "$CC" "$src -o $output -ldl"]
1504 remote_file host delete $src
1505 remote_file host delete $output
1506 file delete $src
1507 }
1508 return $libdl_available_saved
1509 }
1510
1511 # Returns true if GNU2 TLS works.
1512
1513 proc check_gnu2_tls_available { } {
1514 global gnu2_tls_available_saved
1515 global CC
1516 global GNU2_CFLAGS
1517
1518 if {![info exists gnu2_tls_available_saved]} {
1519 if { ![check_compiler_available] || "$GNU2_CFLAGS" == "" } {
1520 set gnu2_tls_available_saved 0
1521 return 0
1522 }
1523 # Check if GNU2 TLS works.
1524 set flags "$GNU2_CFLAGS"
1525 if [board_info [target_info name] exists cflags] {
1526 append flags " [board_info [target_info name] cflags]"
1527 }
1528 if [board_info [target_info name] exists ldflags] {
1529 append flags " [board_info [target_info name] ldflags]"
1530 }
1531
1532 set basename "tmpdir/gnu2_tls[pid]"
1533 set src1 ${basename}1.c
1534 set output1 ${basename}.so
1535 set f [open $src1 "w"]
1536 puts $f "extern __thread int zzz;"
1537 puts $f "int foo (void)"
1538 puts $f "{"
1539 puts $f " return zzz;"
1540 puts $f "}"
1541 close $f
1542 if [is_remote host] {
1543 set src1 [remote_download host $src1]
1544 }
1545 set src2 ${basename}2.c
1546 set output2 ${basename}.exe
1547 set f [open $src2 "w"]
1548 puts $f "__thread int zzz = 20;"
1549 puts $f "extern int foo (void);"
1550 puts $f "int main (void)"
1551 puts $f "{"
1552 puts $f " if (foo () != 20) __builtin_abort ();"
1553 puts $f " return 0; "
1554 puts $f "}"
1555 close $f
1556 if [is_remote host] {
1557 set src2 [remote_download host $src2]
1558 }
1559 set gnu2_tls_available_saved [run_host_cmd_yesno "$CC" "-fPIC -shared $flags $src1 -o $output1"]
1560 if { $gnu2_tls_available_saved == 1 } {
1561 set gnu2_tls_available_saved [run_host_cmd_yesno "$CC" "$flags $src2 $output1 -o $output2"]
1562 if { $gnu2_tls_available_saved == 1 } {
1563 set gnu2_tls_available_saved [run_host_cmd_yesno "$output2" ""]
1564 }
1565 }
1566 remote_file host delete $src1
1567 remote_file host delete $output1
1568 remote_file host delete $src2
1569 remote_file host delete $output2
1570 file delete $src1 $src2
1571 }
1572 return $gnu2_tls_available_saved
1573 }
This page took 0.063775 seconds and 4 git commands to generate.