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