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