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