LD/testsuite: ld-lib.exp: Fix a typo, s/regexp/regex/
[deliverable/binutils-gdb.git] / ld / testsuite / lib / ld-lib.exp
1 # Support routines for LD testsuite.
2 # Copyright (C) 1994-2017 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
89 if { ![is_remote host] && [which "$prog"] == 0 } then {
90 perror "$prog does not exist"
91 return 0
92 }
93
94 # If we are compiling with gcc, we want to add gcc_B_opt and
95 # ld_L_opt to flags. However, if $prog already has -B options,
96 # which might be the case when running gcc out of a build
97 # directory, we want our -B options to come first.
98 set gccexe $prog
99 set gccparm [string first " " $gccexe]
100 set gccflags ""
101 if { $gccparm > 0 } then {
102 set gccflags [string range $gccexe $gccparm end]
103 set gccexe [string range $gccexe 0 $gccparm]
104 set prog $gccexe
105 }
106 set gccexe [string replace $gccexe 0 [string last "/" $gccexe] ""]
107 if {[string match "*cc*" $gccexe] || [string match "*++*" $gccexe]} then {
108 set gccflags "$gcc_B_opt $gccflags $ld_L_opt"
109 }
110
111 verbose -log "$prog $gccflags $command"
112 set status [remote_exec host [concat sh -c [list "$prog $gccflags $command 2>&1"]] "" "/dev/null" "ld.tmp"]
113 remote_upload host "ld.tmp"
114 set link_output [file_contents "ld.tmp"]
115 regsub "\n$" $link_output "" link_output
116 if { [lindex $status 0] != 0 && [string match "" $link_output] } then {
117 append link_output "child process exited abnormally"
118 }
119 remote_file build delete ld.tmp
120 remote_file host delete ld.tmp
121
122 if [string match "" $link_output] then {
123 return ""
124 }
125
126 verbose -log "$link_output"
127 return "$link_output"
128 }
129
130 proc run_host_cmd_yesno { prog command } {
131 global exec_output
132 global errcnt warncnt
133
134 set exec_output [prune_warnings [run_host_cmd "$prog" "$command"]]
135 # Ignore error and warning.
136 set errcnt 0
137 set warncnt 0
138 if [string match "" $exec_output] then {
139 return 1;
140 }
141 return 0;
142 }
143
144 # Link an object using relocation.
145 #
146 proc default_ld_relocate { ld target objects } {
147 global HOSTING_EMU
148
149 remote_file host delete $target
150 return [run_host_cmd_yesno "$ld" "$HOSTING_EMU -o $target -r $objects"]
151 }
152
153 # Check to see if ld is being invoked with a non-endian output format
154 #
155 proc is_endian_output_format { object_flags } {
156
157 if {[string match "*-oformat binary*" $object_flags] || \
158 [string match "*-oformat ieee*" $object_flags] || \
159 [string match "*-oformat ihex*" $object_flags] || \
160 [string match "*-oformat netbsd-core*" $object_flags] || \
161 [string match "*-oformat srec*" $object_flags] || \
162 [string match "*-oformat tekhex*" $object_flags] || \
163 [string match "*-oformat trad-core*" $object_flags] } then {
164 return 0
165 } else {
166 return 1
167 }
168 }
169
170 # Look for big-endian or little-endian switches in the multlib
171 # options and translate these into a -EB or -EL switch. Note
172 # we cannot rely upon proc process_multilib_options to do this
173 # for us because for some targets the compiler does not support
174 # -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
175 # the site.exp file will include the switch "-mbig-endian"
176 # (rather than "big-endian") which is not detected by proc
177 # process_multilib_options.
178 #
179 proc big_or_little_endian {} {
180
181 if [board_info [target_info name] exists multilib_flags] {
182 set tmp_flags " [board_info [target_info name] multilib_flags]"
183
184 foreach x $tmp_flags {
185 case $x in {
186 {*big*endian eb EB -eb -EB -mb -meb} {
187 set flags " -EB"
188 return $flags
189 }
190 {*little*endian el EL -el -EL -ml -mel} {
191 set flags " -EL"
192 return $flags
193 }
194 }
195 }
196 }
197
198 set flags ""
199 return $flags
200 }
201
202 # Link a program using ld
203 #
204 proc default_ld_link { ld target objects } {
205 global host_triplet
206 global exec_output
207
208 set flags ""
209 if [is_endian_output_format $objects] then {
210 set flags [big_or_little_endian]
211 }
212
213 remote_file host delete $target
214 set exec_output [run_host_cmd "$ld" "$flags -o $target $objects"]
215 set exec_output [prune_warnings $exec_output]
216
217 # We don't care if we get a warning about a non-existent start
218 # symbol, since the default linker script might use ENTRY.
219 regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
220
221 return [string match "" $exec_output]
222 }
223
224 # Compile an object using cc.
225 #
226 proc default_ld_compile { cc source object } {
227 global CFLAGS
228 global CXXFLAGS
229 global srcdir
230 global subdir
231 global host_triplet
232 global gcc_B_opt
233
234 set cc_prog $cc
235 if {[llength $cc_prog] > 1} then {
236 set cc_prog [lindex $cc_prog 0]
237 }
238 if {![is_remote host] && [which $cc_prog] == 0} then {
239 perror "$cc_prog does not exist"
240 return 0
241 }
242
243 remote_file build delete "$object"
244 remote_file host delete "$object"
245
246 set flags "$gcc_B_opt -I$srcdir/$subdir"
247
248 # If we are compiling with gcc, we want to add gcc_B_opt to flags.
249 # However, if $prog already has -B options, which might be the
250 # case when running gcc out of a build directory, we want our -B
251 # options to come first.
252 set ccexe $cc
253 set ccparm [string first " " $cc]
254 set ccflags ""
255 if { $ccparm > 0 } then {
256 set ccflags [string range $cc $ccparm end]
257 set ccexe [string range $cc 0 $ccparm]
258 set cc $ccexe
259 }
260
261 set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""]
262 if {[string match "*++*" $ccexe]} {
263 append flags " $CXXFLAGS"
264 } else {
265 append flags " $CFLAGS"
266 }
267
268 if [board_info [target_info name] exists cflags] {
269 append flags " [board_info [target_info name] cflags]"
270 }
271
272 if [board_info [target_info name] exists multilib_flags] {
273 append flags " [board_info [target_info name] multilib_flags]"
274 }
275
276 set cmd "$cc $flags $ccflags -c $source -o $object"
277 verbose -log "$cmd"
278
279 set status [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
280 remote_upload host "ld.tmp"
281 set exec_output [file_contents "ld.tmp"]
282 remote_file build delete "ld.tmp"
283 remote_file host delete "ld.tmp"
284 set exec_output [prune_warnings $exec_output]
285 if [string match "" $exec_output] then {
286 if {![file exists $object]} then {
287 regexp ".*/(\[^/\]*)$" $source all dobj
288 regsub "\\.c" $dobj ".o" realobj
289 verbose "looking for $realobj"
290 if {[remote_file host exists $realobj]} then {
291 verbose -log "mv $realobj $object"
292 remote_upload "$realobj" "$object"
293 } else {
294 perror "$object not found after compilation"
295 return 0
296 }
297 }
298 return 1
299 } else {
300 verbose -log "$exec_output"
301 perror "$source: compilation failed"
302 return 0
303 }
304 }
305
306 # Assemble a file.
307 #
308 proc default_ld_assemble { as in_flags source object } {
309 global ASFLAGS
310 global host_triplet
311 global srcdir
312 global subdir
313
314 if ![info exists ASFLAGS] { set ASFLAGS "" }
315
316 set flags "[big_or_little_endian] -I$srcdir/$subdir"
317 set exec_output [run_host_cmd "$as" "$flags $in_flags $ASFLAGS -o $object $source"]
318 set exec_output [prune_warnings $exec_output]
319 if [string match "" $exec_output] then {
320 return 1
321 } else {
322 perror "$source: assembly failed"
323 return 0
324 }
325 }
326
327 # Run nm on a file, putting the result in the array nm_output.
328 #
329 proc default_ld_nm { nm nmflags object } {
330 global NMFLAGS
331 global nm_output
332 global host_triplet
333
334 if {[info exists nm_output]} {
335 unset nm_output
336 }
337
338 if ![info exists NMFLAGS] { set NMFLAGS "" }
339
340 # Ensure consistent sorting of symbols
341 if {[info exists env(LC_ALL)]} {
342 set old_lc_all $env(LC_ALL)
343 }
344 set env(LC_ALL) "C"
345
346 verbose -log "$nm $NMFLAGS $nmflags $object >tmpdir/nm.out"
347
348 set status [remote_exec host [concat sh -c [list "$nm $NMFLAGS $nmflags $object 2>ld.stderr"]] "" "/dev/null" "tmpdir/nm.out"]
349 if {[info exists old_lc_all]} {
350 set env(LC_ALL) $old_lc_all
351 } else {
352 unset env(LC_ALL)
353 }
354 remote_upload host "ld.stderr"
355 remote_upload host "tmpdir/nm.out" "tmpdir/nm.out"
356 set exec_output [prune_warnings [file_contents "ld.stderr"]]
357 remote_file host delete "ld.stderr"
358 remote_file build delete "ld.stderr"
359 if [string match "" $exec_output] then {
360 set file [open tmpdir/nm.out r]
361 while { [gets $file line] != -1 } {
362 verbose "$line" 2
363 if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] \\.*(.+)$" $line whole value name] {
364 set name [string trimleft $name "_"]
365 verbose "Setting nm_output($name) to 0x$value" 2
366 set nm_output($name) 0x$value
367 }
368 }
369 close $file
370 return 1
371 } else {
372 verbose -log "$exec_output"
373 perror "$object: nm failed"
374 return 0
375 }
376 }
377
378 # Define various symbols needed when not linking against all
379 # target libs.
380 proc ld_link_defsyms {} {
381
382 set flags "--defsym __stack_chk_fail=0"
383
384 # ARM targets call __gccmain
385 if {[istarget arm*-*-*]} {
386 append flags " --defsym __gccmain=0"
387 }
388
389 # Windows targets need __main, some prefixed with underscore.
390 if {[istarget *-*-cygwin* ] || [istarget *-*-mingw*]} {
391 append flags " --defsym __main=0 --defsym ___main=0"
392 }
393
394 # PowerPC EABI code calls __eabi.
395 if {[istarget powerpc*-*-eabi*] || [istarget powerpc*-*-rtems*]} {
396 append flags " --defsym __eabi=0"
397 }
398
399 # mn10200 code calls __truncsipsi2_d0_d2.
400 if {[istarget mn10200*-*-*]} then {
401 append flags " --defsym __truncsipsi2_d0_d2=0"
402 }
403
404 # m6811/m6812 code has references to soft registers.
405 if {[istarget m6811-*-*] || [istarget m6812-*-*] || [istarget m68hc1*-*-*]} {
406 append flags " --defsym _.frame=0 --defsym _.d1=0 --defsym _.d2=0"
407 append flags " --defsym _.d3=0 --defsym _.d4=0"
408 append flags " --defsym _.tmp=0 --defsym _.xy=0 --defsym _.z=0"
409 }
410
411 # Some OpenBSD targets have ProPolice and reference __guard and
412 # __stack_smash_handler.
413 if [istarget *-*-openbsd*] {
414 append flags " --defsym __guard=0"
415 append flags " --defsym __stack_smash_handler=0"
416 }
417
418 return $flags
419 }
420
421 # run_dump_test FILE (optional:) EXTRA_OPTIONS
422 # Copied from gas testsuite, tweaked and further extended.
423 #
424 # Assemble a .s file, then run some utility on it and check the output.
425 #
426 # There should be an assembly language file named FILE.s in the test
427 # suite directory, and a pattern file called FILE.d. `run_dump_test'
428 # will assemble FILE.s, run some tool like `objdump', `objcopy', or
429 # `nm' on the .o file to produce textual output, and then analyze that
430 # with regexps. The FILE.d file specifies what program to run, and
431 # what to expect in its output.
432 #
433 # The FILE.d file begins with zero or more option lines, which specify
434 # flags to pass to the assembler, the program to run to dump the
435 # assembler's output, and the options it wants. The option lines have
436 # the syntax:
437 #
438 # # OPTION: VALUE
439 #
440 # OPTION is the name of some option, like "name" or "objdump", and
441 # VALUE is OPTION's value. The valid options are described below.
442 # Whitespace is ignored everywhere, except within VALUE. The option
443 # list ends with the first line that doesn't match the above syntax
444 # (hmm, not great for error detection).
445 #
446 # The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of
447 # two-element lists. The first element of each is an option name, and
448 # the second additional arguments to be added on to the end of the
449 # option list as given in FILE.d. (If omitted, no additional options
450 # are added.)
451 #
452 # The interesting options are:
453 #
454 # name: TEST-NAME
455 # The name of this test, passed to DejaGNU's `pass' and `fail'
456 # commands. If omitted, this defaults to FILE, the root of the
457 # .s and .d files' names.
458 #
459 # as: FLAGS
460 # When assembling, pass FLAGS to the assembler.
461 # If assembling several files, you can pass different assembler
462 # options in the "source" directives. See below.
463 #
464 # ld: FLAGS
465 # Link assembled files using FLAGS, in the order of the "source"
466 # directives, when using multiple files.
467 #
468 # ld_after_inputfiles: FLAGS
469 # Similar to "ld", but put after all input files.
470 #
471 # objcopy_objects: FLAGS
472 # Run objcopy with the specified flags after assembling any source
473 # that has the special marker RUN_OBJCOPY in the source specific
474 # flags.
475 #
476 # objcopy_linked_file: FLAGS
477 # Run objcopy on the linked file with the specified flags.
478 # This lets you transform the linked file using objcopy, before the
479 # result is analyzed by an analyzer program specified below (which
480 # may in turn *also* be objcopy).
481 #
482 # PROG: PROGRAM-NAME
483 # The name of the program to run to analyze the .o file produced
484 # by the assembler or the linker output. This can be omitted;
485 # run_dump_test will guess which program to run by seeing which of
486 # the flags options below is present.
487 #
488 # readelf: FLAGS
489 # objdump: FLAGS
490 # nm: FLAGS
491 # objcopy: FLAGS
492 # Use the specified program to analyze the assembler or linker
493 # output file, and pass it FLAGS, in addition to the output name.
494 # Note that they are run with LC_ALL=C in the environment to give
495 # consistent sorting of symbols.
496 #
497 # source: SOURCE [FLAGS]
498 # Assemble the file SOURCE.s using the flags in the "as" directive
499 # and the (optional) FLAGS. If omitted, the source defaults to
500 # FILE.s.
501 # This is useful if several .d files want to share a .s file.
502 # More than one "source" directive can be given, which is useful
503 # when testing linking.
504 #
505 # dump: DUMP
506 # Match against DUMP.d. If omitted, this defaults to FILE.d. This
507 # is useful if several .d files differ by options only. Options are
508 # always read from FILE.d.
509 #
510 # xfail: TARGET
511 # The test is expected to fail on TARGET. This may occur more than
512 # once.
513 #
514 # target: TARGET
515 # Only run the test for TARGET. This may occur more than once; the
516 # target being tested must match at least one. You may provide target
517 # name "cfi" for any target supporting the CFI statements.
518 #
519 # notarget: TARGET
520 # Do not run the test for TARGET. This may occur more than once;
521 # the target being tested must not match any of them.
522 #
523 # error: REGEX
524 # An error with message matching REGEX must be emitted for the test
525 # to pass. The PROG, readelf, objdump, nm and objcopy options have
526 # no meaning and need not be supplied if this is present. Multiple
527 # "error" directives append to the expected linker error message.
528 #
529 # error_output: FILE
530 # Means the same as 'error', except the regular expression lines
531 # are contains in FILE.
532 #
533 # warning: REGEX
534 # Expect a linker warning matching REGEX. It is an error to issue
535 # both "error" and "warning". Multiple "warning" directives
536 # append to the expected linker warning message.
537 #
538 # warning_output: FILE
539 # Means the same as 'warning', except the regular expression
540 # lines are contains in FILE.
541 #
542 # map: FILE
543 # Adding this option will cause the linker to generate a linker
544 # map file, using the -Map=MAPFILE command line option. If
545 # there is no -Map=MAPFILE in the 'ld: FLAGS' then one will be
546 # added to the linker command line. The contents of the
547 # generated MAPFILE are then compared against the regexp lines
548 # in FILE using `regexp_diff' (see below for details).
549 #
550 # Each option may occur at most once unless otherwise mentioned.
551 #
552 # After the option lines come regexp lines. `run_dump_test' calls
553 # `regexp_diff' to compare the output of the dumping tool against the
554 # regexps in FILE.d. `regexp_diff' is defined in binutils-common.exp;
555 # see further comments there.
556 #
557 proc run_dump_test { name {extra_options {}} } {
558 global subdir srcdir
559 global OBJDUMP NM AS OBJCOPY READELF LD
560 global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
561 global host_triplet runtests
562 global env verbose
563 global ld_elf_shared_opt
564
565 if { [is_elf_format] && [check_shared_lib_support] } {
566 set ld_extra_opt "$ld_elf_shared_opt"
567 } else {
568 set ld_extra_opt ""
569 }
570
571 if [string match "*/*" $name] {
572 set file $name
573 set name [file tail $name]
574 } else {
575 set file "$srcdir/$subdir/$name"
576 }
577
578 if ![runtest_file_p $runtests $name] then {
579 return
580 }
581
582 set opt_array [slurp_options "${file}.d"]
583 if { $opt_array == -1 } {
584 perror "error reading options from $file.d"
585 unresolved $subdir/$name
586 return
587 }
588 set dumpfile tmpdir/dump.out
589 set run_ld 0
590 set run_objcopy 0
591 set objfile_names {}
592 set opts(as) {}
593 set opts(ld) {}
594 set opts(ld_after_inputfiles) {}
595 set opts(xfail) {}
596 set opts(target) {}
597 set opts(notarget) {}
598 set opts(objdump) {}
599 set opts(nm) {}
600 set opts(objcopy) {}
601 set opts(readelf) {}
602 set opts(name) {}
603 set opts(PROG) {}
604 set opts(source) {}
605 set opts(dump) {}
606 set opts(error) {}
607 set opts(warning) {}
608 set opts(error_output) {}
609 set opts(warning_output) {}
610 set opts(objcopy_linked_file) {}
611 set opts(objcopy_objects) {}
612 set opts(map) {}
613
614 foreach i $opt_array {
615 set opt_name [lindex $i 0]
616 set opt_val [lindex $i 1]
617 if ![info exists opts($opt_name)] {
618 perror "unknown option $opt_name in file $file.d"
619 unresolved $subdir/$name
620 return
621 }
622
623 switch -- $opt_name {
624 xfail {}
625 target {}
626 notarget {}
627 warning {}
628 error {}
629 source {
630 # Move any source-specific as-flags to a separate list to
631 # simplify processing.
632 if { [llength $opt_val] > 1 } {
633 lappend asflags [lrange $opt_val 1 end]
634 set opt_val [lindex $opt_val 0]
635 } else {
636 lappend asflags {}
637 }
638
639 # Create the object file name based on nothing but the source
640 # file name.
641 set new_objfile \
642 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]].o]
643 # But, sometimes, we have the exact same source filename in
644 # different directories (foo/src.s bar/src.s) which would lead
645 # us to try and create two src.o files. We detect this
646 # conflict here, and instead create src.o and src1.o.
647 set j 0
648 while { [lsearch $objfile_names $new_objfile] != -1 } {
649 incr j
650 set new_objfile \
651 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]]${j}.o]
652 }
653 lappend objfile_names $new_objfile
654 }
655 default {
656 if [string length $opts($opt_name)] {
657 perror "option $opt_name multiply set in $file.d"
658 unresolved $subdir/$name
659 return
660 }
661
662 # A single "# ld:" with no options should do the right thing.
663 if { $opt_name == "ld" } {
664 set run_ld 1
665 }
666 # Likewise objcopy_linked_file.
667 if { $opt_name == "objcopy_linked_file" } {
668 set run_objcopy 1
669 }
670 }
671 }
672 if { $opt_name == "as" || $opt_name == "ld" } {
673 set opt_val [subst $opt_val]
674 }
675
676 # Append differently whether it's a message (without space) or
677 # an option or list (with space).
678 switch -- $opt_name {
679 warning -
680 error {
681 append opts($opt_name) $opt_val
682 }
683 default {
684 set opts($opt_name) [concat $opts($opt_name) $opt_val]
685 }
686 }
687 }
688
689 foreach i $extra_options {
690 set opt_name [lindex $i 0]
691 set opt_val [lindex $i 1]
692 if ![info exists opts($opt_name)] {
693 perror "unknown option $opt_name given in extra_opts"
694 unresolved $subdir/$name
695 return
696 }
697 # Add extra option to end of existing option, adding space
698 # if necessary.
699 if { ![regexp "warning|error" $opt_name]
700 && [string length $opts($opt_name)] } {
701 append opts($opt_name) " "
702 }
703 append opts($opt_name) $opt_val
704 }
705
706 foreach opt { as ld } {
707 regsub {\[big_or_little_endian\]} $opts($opt) \
708 [big_or_little_endian] opts($opt)
709 }
710
711 # Decide early whether we should run the test for this target.
712 if { [llength $opts(target)] > 0 } {
713 set targmatch 0
714 foreach targ $opts(target) {
715 if [istarget $targ] {
716 set targmatch 1
717 break
718 }
719 }
720 if { $targmatch == 0 } {
721 return
722 }
723 }
724 foreach targ $opts(notarget) {
725 if [istarget $targ] {
726 return
727 }
728 }
729
730 set program ""
731 # It's meaningless to require an output-testing method when we
732 # expect an error.
733 if { $opts(error) == "" && $opts(error_output) == "" } {
734 if {$opts(PROG) != ""} {
735 switch -- $opts(PROG) {
736 objdump { set program objdump }
737 nm { set program nm }
738 objcopy { set program objcopy }
739 readelf { set program readelf }
740 default
741 { perror "unrecognized program option $opts(PROG) in $file.d"
742 unresolved $subdir/$name
743 return }
744 }
745 } else {
746 # Guess which program to run, by seeing which option was specified.
747 foreach p {objdump objcopy nm readelf} {
748 if {$opts($p) != ""} {
749 if {$program != ""} {
750 perror "ambiguous dump program in $file.d"
751 unresolved $subdir/$name
752 return
753 } else {
754 set program $p
755 }
756 }
757 }
758 }
759 if { $program == "" \
760 && $opts(map) == "" \
761 && $opts(warning) == "" \
762 && $opts(warning_output) == "" \
763 && $opts(error) == "" \
764 && $opts(error_output) == "" } {
765 perror "dump program unspecified in $file.d"
766 unresolved $subdir/$name
767 return
768 }
769 }
770
771 if { $opts(name) == "" } {
772 set testname "$subdir/$name"
773 } else {
774 set testname $opts(name)
775 }
776
777 if { $opts(source) == "" } {
778 set sourcefiles [list ${file}.s]
779 set asflags [list ""]
780 set objfile_names [list tmpdir/[file tail ${file}].o]
781 } else {
782 set sourcefiles {}
783 foreach sf $opts(source) {
784 if { [string match "/*" $sf] } {
785 lappend sourcefiles "$sf"
786 } else {
787 lappend sourcefiles "$srcdir/$subdir/$sf"
788 }
789 }
790 }
791
792 if { $opts(dump) == "" } {
793 set dfile ${file}.d
794 } else {
795 set dfile $srcdir/$subdir/$opts(dump)
796 }
797
798 # Time to setup xfailures.
799 foreach targ $opts(xfail) {
800 setup_xfail $targ
801 }
802
803 # Assemble each file.
804 set objfiles {}
805 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
806 set sourcefile [lindex $sourcefiles $i]
807 set sourceasflags [lindex $asflags $i]
808 set run_objcopy_objects 0
809
810 if { [string match "*RUN_OBJCOPY*" $sourceasflags] } {
811 set run_objcopy_objects 1
812 }
813 regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
814
815 set objfile [lindex $objfile_names $i]
816 catch "exec rm -f $objfile" exec_output
817 lappend objfiles $objfile
818 set cmd "$AS $ASFLAGS $opts(as) $sourceasflags -o $objfile $sourcefile"
819
820 send_log "$cmd\n"
821 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
822 remote_upload host "ld.tmp"
823 set comp_output [prune_warnings [file_contents "ld.tmp"]]
824 remote_file host delete "ld.tmp"
825 remote_file build delete "ld.tmp"
826
827 if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
828 send_log -- "$comp_output\n"
829 verbose "$comp_output" 3
830
831 set exitstat "succeeded"
832 if { $cmdret != 0 } { set exitstat "failed" }
833 verbose -log "$exitstat with: <$comp_output>"
834 fail $testname
835 return
836 }
837
838 if { $run_objcopy_objects } {
839 set cmd "$OBJCOPY $opts(objcopy_objects) $objfile"
840
841 send_log "$cmd\n"
842 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \
843 "" "/dev/null" "objcopy.tmp"]
844 remote_upload host "objcopy.tmp"
845 set comp_output [prune_warnings [file_contents "objcopy.tmp"]]
846 remote_file host delete "objcopy.tmp"
847 remote_file build delete "objcopy.tmp"
848
849 if { [lindex $cmdret 0] != 0 \
850 || ![string match "" $comp_output] } {
851 send_log -- "$comp_output\n"
852 verbose "$comp_output" 3
853
854 set exitstat "succeeded"
855 if { $cmdret != 0 } { set exitstat "failed" }
856 verbose -log "$exitstat with: <$comp_output>"
857 fail $testname
858 return
859 }
860 }
861 }
862
863 if { (($opts(warning) != "") && ($opts(error) != "")) \
864 || (($opts(warning) != "") && ($opts(error_output) != "")) \
865 || (($opts(warning) != "") && ($opts(warning_output) != "")) \
866 || (($opts(error) != "") && ($opts(warning_output) != "")) \
867 || (($opts(error) != "") && ($opts(error_output) != "")) \
868 || (($opts(warning_output) != "") && ($opts(error_output) != "")) } {
869 perror "$testname: bad mix of warning, error, warning_output, and error_output test-directives"
870 unresolved $testname
871 return
872 }
873
874 set check_ld(source) ""
875 set check_ld(terminal) 0
876 if { $opts(error) != "" \
877 || $opts(warning) != "" \
878 || $opts(error_output) != "" \
879 || $opts(warning_output) != "" } {
880
881 if { $opts(error) != "" || $opts(error_output) != "" } {
882 set check_ld(terminal) 1
883 } else {
884 set check_ld(terminal) 0
885 }
886
887 if { $opts(error) != "" || $opts(warning) != "" } {
888 set check_ld(source) "regex"
889 if { $opts(error) != "" } {
890 set check_ld(regex) $opts(error)
891 } else {
892 set check_ld(regex) $opts(warning)
893 }
894 } else {
895 set check_ld(source) "file"
896 if { $opts(error_output) != "" } {
897 set check_ld(file) $opts(error_output)
898 } else {
899 set check_ld(file) $opts(warning_output)
900 }
901 }
902 }
903
904 # Perhaps link the file(s).
905 if { $run_ld } {
906 set objfile "tmpdir/dump"
907 catch "exec rm -f $objfile" exec_output
908
909 # Add -L$srcdir/$subdir so that the linker command can use
910 # linker scripts in the source directory.
911 set cmd "$LD $ld_extra_opt $LDFLAGS -L$srcdir/$subdir \
912 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
913
914 # If needed then check for, or add a -Map option.
915 set mapfile ""
916 if { $opts(map) != "" } then {
917 if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then {
918 # Found existing mapfile option
919 verbose -log "Existing mapfile '$mapfile' found"
920 } else {
921 # No mapfile option.
922 set mapfile "tmpdir/dump.map"
923 verbose -log "Adding mapfile '$mapfile'"
924 set cmd "$cmd -Map=$mapfile"
925 }
926 }
927
928 send_log "$cmd\n"
929 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
930 remote_upload host "ld.tmp"
931 set comp_output [file_contents "ld.tmp"]
932 remote_file host delete "ld.tmp"
933 remote_file build delete "ld.tmp"
934 set cmdret [lindex $cmdret 0]
935
936 if { $cmdret == 0 && $run_objcopy } {
937 set infile $objfile
938 set objfile "tmpdir/dump1"
939 remote_file host delete $objfile
940
941 # Note that we don't use OBJCOPYFLAGS here; any flags must be
942 # explicitly specified.
943 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
944
945 send_log "$cmd\n"
946 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
947 remote_upload host "ld.tmp"
948 append comp_output [file_contents "ld.tmp"]
949 remote_file host delete "ld.tmp"
950 remote_file build delete "ld.tmp"
951 set cmdret [lindex $cmdret 0]
952 }
953
954 regsub "\n$" $comp_output "" comp_output
955 if { $cmdret != 0 || $comp_output != "" || $check_ld(source) != "" } then {
956 set exitstat "succeeded"
957 if { $cmdret != 0 } { set exitstat "failed" }
958
959 if { $check_ld(source) == "regex" } {
960 verbose -log "$exitstat with: <$comp_output>, expected: <$check_ld(regex)>"
961 } elseif { $check_ld(source) == "file" } {
962 verbose -log "$exitstat with: <$comp_output>, expected in file $check_ld(file)"
963 set_file_contents "tmpdir/ld.messages" "$comp_output"
964 } else {
965 verbose -log "$exitstat with: <$comp_output>, no expected output"
966 }
967 send_log -- "$comp_output\n"
968 verbose "$comp_output" 3
969
970 if { (($check_ld(source) == "") == ($comp_output == "")) \
971 && (($cmdret == 0) == ($check_ld(terminal) == 0)) \
972 && ((($check_ld(source) == "regex") \
973 && ($check_ld(regex) == "") == ($comp_output == "") \
974 && [regexp $check_ld(regex) $comp_output]) \
975 || (($check_ld(source) == "file") \
976 && (![regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$check_ld(file)"]))) } {
977 # We have the expected output from ld.
978 if { $check_ld(terminal) || $program == "" } {
979 pass $testname
980 return
981 }
982 } else {
983 fail $testname
984 return
985 }
986 }
987
988 if { $opts(map) != "" } then {
989 # Check the map file matches.
990 set map_pattern_file $srcdir/$subdir/$opts(map)
991 verbose -log "Compare '$mapfile' against '$map_pattern_file'"
992 if { [regexp_diff $mapfile $map_pattern_file] } then {
993 fail "$testname (map file check)"
994 } else {
995 pass "$testname (map file check)"
996 }
997
998 if { $program == "" } then {
999 return
1000 }
1001 }
1002 } else {
1003 set objfile [lindex $objfiles 0]
1004 }
1005
1006 # We must not have expected failure if we get here.
1007 if { $opts(error) != "" } {
1008 fail $testname
1009 return
1010 }
1011
1012 set progopts1 $opts($program)
1013 eval set progopts \$[string toupper $program]FLAGS
1014 eval set binary \$[string toupper $program]
1015
1016 if { ![is_remote host] && [which $binary] == 0 } {
1017 untested $testname
1018 return
1019 }
1020
1021 if { $progopts1 == "" } { set $progopts1 "-r" }
1022 verbose "running $binary $progopts $progopts1" 3
1023
1024 # Objcopy, unlike the other two, won't send its output to stdout,
1025 # so we have to run it specially.
1026 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
1027 if { $program == "objcopy" } {
1028 set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
1029 }
1030
1031 # Ensure consistent sorting of symbols
1032 if {[info exists env(LC_ALL)]} {
1033 set old_lc_all $env(LC_ALL)
1034 }
1035 set env(LC_ALL) "C"
1036 send_log "$cmd\n"
1037 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
1038 set cmdret [lindex $cmdret 0]
1039 remote_upload host "ld.tmp"
1040 set comp_output [prune_warnings [file_contents "ld.tmp"]]
1041 remote_file host delete "ld.tmp"
1042 remote_file build delete "ld.tmp"
1043 if {[info exists old_lc_all]} {
1044 set env(LC_ALL) $old_lc_all
1045 } else {
1046 unset env(LC_ALL)
1047 }
1048 if { $cmdret != 0 || $comp_output != "" } {
1049 send_log "exited abnormally with $cmdret, output:$comp_output\n"
1050 fail $testname
1051 return
1052 }
1053
1054 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
1055 if { [regexp_diff $dumpfile "${dfile}"] } then {
1056 fail $testname
1057 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
1058 return
1059 }
1060
1061 pass $testname
1062 }
1063
1064 proc slurp_options { file } {
1065 # If options_regsub(foo) is set to {a b}, then the contents of a
1066 # "#foo:" line will have regsub -all applied to replace a with b.
1067 global options_regsub
1068
1069 if [catch { set f [open $file r] } x] {
1070 #perror "couldn't open `$file': $x"
1071 perror "$x"
1072 return -1
1073 }
1074 set opt_array {}
1075 # whitespace expression
1076 set ws {[ ]*}
1077 set nws {[^ ]*}
1078 # whitespace is ignored anywhere except within the options list;
1079 # option names are alphabetic plus underscore only.
1080 set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
1081 while { [gets $f line] != -1 } {
1082 set line [string trim $line]
1083 # Whitespace here is space-tab.
1084 if [regexp $pat $line xxx opt_name opt_val] {
1085 # match!
1086 if [info exists options_regsub($opt_name)] {
1087 set subst $options_regsub($opt_name)
1088 regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \
1089 opt_val
1090 }
1091 lappend opt_array [list $opt_name $opt_val]
1092 } else {
1093 break
1094 }
1095 }
1096 close $f
1097 return $opt_array
1098 }
1099
1100 proc file_contents { filename } {
1101 set file [open $filename r]
1102 set contents [read $file]
1103 close $file
1104 return $contents
1105 }
1106
1107 proc set_file_contents { filename contents } {
1108 set file [open $filename w]
1109 puts $file "$contents"
1110 close $file
1111 }
1112
1113 # Create an archive using ar
1114 #
1115 proc ar_simple_create { ar aropts target objects } {
1116 remote_file host delete $target
1117
1118 set exec_output [run_host_cmd "$ar" "-rc $aropts $target $objects"]
1119 set exec_output [prune_warnings $exec_output]
1120
1121 if [string match "" $exec_output] then {
1122 send_log "$exec_output\n"
1123 return 1
1124 } else {
1125 return 0
1126 }
1127 }
1128
1129 # List contains test-items with 3 items followed by 2 lists, one item and
1130 # one optional item:
1131 # 0:name
1132 # 1:ld/ar leading options, placed before object files
1133 # 2:ld/ar trailing options, placed after object files
1134 # 3:assembler options
1135 # 4:filenames of assembler files
1136 # 5:list of actions, options and expected outputs.
1137 # 6:name of output file
1138 # 7:compiler flags (optional)
1139 #
1140 # Actions: { command command-line-options file-containg-expected-output-regexps }
1141 # Commands:
1142 # objdump: Apply objdump options on result.
1143 # nm: Apply nm options on result.
1144 # readelf: Apply readelf options on result.
1145 # ld: Don't apply anything on result. Compare output during linking with
1146 # the file containing regexps (which is the second arg, not the third).
1147 # Note that this *must* be the first action if it is to be used at all;
1148 # in all other cases, any output from the linker during linking is
1149 # treated as a sign of an error and FAILs the test.
1150 #
1151 # args is an optional list of target triplets to be xfailed.
1152 #
1153 proc run_ld_link_tests { ldtests args } {
1154 global ld
1155 global as
1156 global nm
1157 global ar
1158 global objdump
1159 global READELF
1160 global srcdir
1161 global subdir
1162 global env
1163 global CC
1164 global CFLAGS
1165 global runtests
1166 global exec_output
1167 global ld_elf_shared_opt
1168
1169 if { [is_elf_format] && [check_shared_lib_support] } {
1170 set ld_extra_opt "$ld_elf_shared_opt"
1171 } else {
1172 set ld_extra_opt ""
1173 }
1174
1175 foreach testitem $ldtests {
1176 set testname [lindex $testitem 0]
1177
1178 if ![runtest_file_p $runtests $testname] then {
1179 continue
1180 }
1181
1182 foreach target $args {
1183 setup_xfail $target
1184 }
1185
1186 set ld_options [lindex $testitem 1]
1187 set ld_after [lindex $testitem 2]
1188 set as_options [lindex $testitem 3]
1189 set src_files [lindex $testitem 4]
1190 set actions [lindex $testitem 5]
1191 set binfile tmpdir/[lindex $testitem 6]
1192 set cflags [lindex $testitem 7]
1193 set objfiles {}
1194 set is_unresolved 0
1195 set failed 0
1196 set maybe_failed 0
1197 set ld_output ""
1198
1199 # verbose -log "Testname is $testname"
1200 # verbose -log "ld_options is $ld_options"
1201 # verbose -log "ld_after is $ld_after"
1202 # verbose -log "as_options is $as_options"
1203 # verbose -log "src_files is $src_files"
1204 # verbose -log "actions is $actions"
1205 # verbose -log "binfile is $binfile"
1206
1207 # Assemble each file in the test.
1208 foreach src_file $src_files {
1209 set fileroot "[file rootname [file tail $src_file]]"
1210 set objfile "tmpdir/$fileroot.o"
1211 lappend objfiles $objfile
1212
1213 if { [file extension $src_file] == ".c" } {
1214 set as_file "tmpdir/$fileroot.s"
1215 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1216 set is_unresolved 1
1217 break
1218 }
1219 } else {
1220 set as_file "$srcdir/$subdir/$src_file"
1221 }
1222 if ![ld_assemble $as "$as_options $as_file" $objfile] {
1223 set is_unresolved 1
1224 break
1225 }
1226 }
1227
1228 # Catch assembler errors.
1229 if { $is_unresolved } {
1230 unresolved $testname
1231 continue
1232 }
1233
1234 if { $binfile eq "tmpdir/" } {
1235 # compile only
1236 } elseif { [regexp ".*\\.a$" $binfile] } {
1237 if { ![ar_simple_create $ar $ld_options $binfile "$objfiles $ld_after"] } {
1238 set failed 1
1239 }
1240 } elseif { ![ld_link $ld $binfile "$ld_extra_opt -L$srcdir/$subdir $ld_options $objfiles $ld_after"] } {
1241 set maybe_failed 1
1242 set ld_output "$exec_output"
1243 }
1244
1245 if { !$failed } {
1246 foreach actionlist $actions {
1247 set action [lindex $actionlist 0]
1248 set progopts [lindex $actionlist 1]
1249
1250 # There are actions where we run regexp_diff on the
1251 # output, and there are other actions (presumably).
1252 # Handling of the former look the same.
1253 set dump_prog ""
1254 switch -- $action {
1255 objdump
1256 { set dump_prog $objdump }
1257 nm
1258 { set dump_prog $nm }
1259 readelf
1260 { set dump_prog $READELF }
1261 ld
1262 { set dump_prog "ld" }
1263 default
1264 {
1265 perror "Unrecognized action $action"
1266 set is_unresolved 1
1267 break
1268 }
1269 }
1270
1271 if { $action == "ld" } {
1272 set regexpfile $progopts
1273 verbose "regexpfile is $srcdir/$subdir/$regexpfile"
1274 set_file_contents "tmpdir/ld.messages" "$ld_output"
1275 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
1276 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$regexpfile"] } then {
1277 verbose "output is $ld_output" 2
1278 set failed 1
1279 break
1280 }
1281 set maybe_failed 0
1282 } elseif { !$maybe_failed && $dump_prog != "" } {
1283 set dumpfile [lindex $actionlist 2]
1284 set binary $dump_prog
1285
1286 # Ensure consistent sorting of symbols
1287 if {[info exists env(LC_ALL)]} {
1288 set old_lc_all $env(LC_ALL)
1289 }
1290 set env(LC_ALL) "C"
1291 set cmd "$binary $progopts $binfile"
1292 set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
1293 send_log "$cmd\n"
1294 remote_upload host "ld.stderr"
1295 set comp_output [prune_warnings [file_contents "ld.stderr"]]
1296 remote_file host delete "ld.stderr"
1297 remote_file build delete "ld.stderr"
1298
1299 if {[info exists old_lc_all]} {
1300 set env(LC_ALL) $old_lc_all
1301 } else {
1302 unset env(LC_ALL)
1303 }
1304
1305 if ![string match "" $comp_output] then {
1306 send_log "$comp_output\n"
1307 set failed 1
1308 break
1309 }
1310
1311 remote_upload host "dump.out"
1312
1313 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1314 verbose "output is [file_contents "dump.out"]" 2
1315 set failed 1
1316 remote_file build delete "dump.out"
1317 remote_file host delete "dump.out"
1318 break
1319 }
1320 remote_file build delete "dump.out"
1321 remote_file host delete "dump.out"
1322 }
1323 }
1324 }
1325
1326 if { $is_unresolved } {
1327 unresolved $testname
1328 } elseif { $maybe_failed || $failed } {
1329 fail $testname
1330 } else {
1331 pass $testname
1332 }
1333 }
1334 }
1335
1336 # This definition is taken from an unreleased version of DejaGnu. Once
1337 # that version gets released, and has been out in the world for a few
1338 # months at least, it may be safe to delete this copy.
1339 if ![string length [info proc prune_warnings]] {
1340 #
1341 # prune_warnings -- delete various system verbosities from TEXT
1342 #
1343 # An example is:
1344 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1345 #
1346 # Sites with particular verbose os's may wish to override this in site.exp.
1347 #
1348 proc prune_warnings { text } {
1349 # This is from sun4's. Do it for all machines for now.
1350 # The "\\1" is to try to preserve a "\n" but only if necessary.
1351 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1352
1353 # It might be tempting to get carried away and delete blank lines, etc.
1354 # Just delete *exactly* what we're ask to, and that's it.
1355 return $text
1356 }
1357 }
1358
1359 # ldtests contains test-items with 3 items followed by 1 lists, 2 items
1360 # and 3 optional items:
1361 # 0:name
1362 # 1:ld options
1363 # 2:assembler options
1364 # 3:filenames of source files
1365 # 4:name of output file
1366 # 5:expected output
1367 # 6:compiler flags (optional)
1368 # 7:language (optional)
1369 # 8:linker warning (optional)
1370 # args is an optional list of target triplets to be xfailed.
1371
1372 proc run_ld_link_exec_tests { ldtests args } {
1373 global ld
1374 global as
1375 global srcdir
1376 global subdir
1377 global env
1378 global CC
1379 global CXX
1380 global CFLAGS
1381 global CXXFLAGS
1382 global errcnt
1383 global exec_output
1384 global board_cflags
1385
1386 # When using GCC as the linker driver, we need to specify board cflags when
1387 # linking because cflags may contain linker options. For example when
1388 # linker options are included in GCC spec files then we need the -specs
1389 # option.
1390 if [board_info [target_info name] exists cflags] {
1391 set board_cflags " [board_info [target_info name] cflags]"
1392 } else {
1393 set board_cflags ""
1394 }
1395
1396 foreach testitem $ldtests {
1397 foreach target $args {
1398 setup_xfail $target
1399 }
1400 set testname [lindex $testitem 0]
1401 set ld_options [lindex $testitem 1]
1402 set as_options [lindex $testitem 2]
1403 set src_files [lindex $testitem 3]
1404 set binfile tmpdir/[lindex $testitem 4]
1405 set expfile [lindex $testitem 5]
1406 set cflags [lindex $testitem 6]
1407 set lang [lindex $testitem 7]
1408 set warning [lindex $testitem 8]
1409 set objfiles {}
1410 set failed 0
1411
1412 # verbose -log "Testname is $testname"
1413 # verbose -log "ld_options is $ld_options"
1414 # verbose -log "as_options is $as_options"
1415 # verbose -log "src_files is $src_files"
1416 # verbose -log "binfile is $binfile"
1417
1418 # Assemble each file in the test.
1419 foreach src_file $src_files {
1420 set fileroot "[file rootname [file tail $src_file]]"
1421 set objfile "tmpdir/$fileroot.o"
1422 lappend objfiles $objfile
1423
1424 # We ignore warnings since some compilers may generate
1425 # incorrect section attributes and the assembler will warn
1426 # them.
1427 if { [ string match "c++" $lang ] } {
1428 set cmd "$CXX -c $CXXFLAGS $cflags"
1429 } else {
1430 set cmd "$CC -c $CFLAGS $cflags"
1431 }
1432 if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] {
1433 set failed 1
1434 break
1435 }
1436 }
1437 if { $failed != 0 } {
1438 unresolved $testname
1439 continue
1440 }
1441
1442 if { [ string match "c++" $lang ] } {
1443 set link_proc ld_link
1444 set link_cmd $CXX
1445 } else {
1446 set link_proc ld_link
1447 set link_cmd $CC
1448 }
1449
1450 if { $binfile eq "tmpdir/" } {
1451 # compile only
1452 pass $testname
1453 continue;
1454 } elseif ![$link_proc $link_cmd $binfile "$board_cflags -L$srcdir/$subdir $ld_options $objfiles"] {
1455 set failed 1
1456 }
1457
1458 # Check if exec_output is expected.
1459 if { $warning != "" } then {
1460 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1461 if { [regexp $warning $exec_output] } then {
1462 set failed 0
1463 } else {
1464 set failed 1
1465 }
1466 }
1467
1468 if { $failed == 0 && [isnative] } {
1469 send_log "Running: $binfile > $binfile.out\n"
1470 verbose "Running: $binfile > $binfile.out"
1471 catch "exec $binfile > $binfile.out" exec_output
1472
1473 if ![string match "" $exec_output] then {
1474 send_log "$exec_output\n"
1475 verbose "$exec_output" 1
1476 set failed 1
1477 } else {
1478 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1479 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1480 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1481 set exec_output [prune_warnings $exec_output]
1482
1483 if ![string match "" $exec_output] then {
1484 send_log "$exec_output\n"
1485 verbose "$exec_output" 1
1486 set failed 1
1487 }
1488 }
1489 }
1490
1491 if { $failed != 0 } {
1492 fail $testname
1493 } elseif ![isnative] {
1494 unsupported $testname
1495 } else {
1496 set errcnt 0
1497 pass $testname
1498 }
1499 }
1500 }
1501
1502 # List contains test-items with 3 items followed by 2 lists, one item and
1503 # one optional item:
1504 # 0:name
1505 # 1:ld or ar options
1506 # 2:compile options
1507 # 3:filenames of source files
1508 # 4:action and options.
1509 # 5:name of output file
1510 # 6:language (optional)
1511 # 7:linker warnings (optional)
1512 #
1513 # Actions:
1514 # objdump: Apply objdump options on result. Compare with regex (last arg).
1515 # nm: Apply nm options on result. Compare with regex (last arg).
1516 # readelf: Apply readelf options on result. Compare with regex (last arg).
1517 #
1518 proc run_cc_link_tests { ldtests } {
1519 global nm
1520 global objdump
1521 global READELF
1522 global srcdir
1523 global subdir
1524 global env
1525 global CC
1526 global CXX
1527 global CFLAGS
1528 global CXXFLAGS
1529 global ar
1530 global exec_output
1531 global board_cflags
1532
1533 if [board_info [target_info name] exists cflags] {
1534 set board_cflags " [board_info [target_info name] cflags]"
1535 } else {
1536 set board_cflags ""
1537 }
1538
1539 foreach testitem $ldtests {
1540 set testname [lindex $testitem 0]
1541 set ldflags [lindex $testitem 1]
1542 set cflags [lindex $testitem 2]
1543 set src_files [lindex $testitem 3]
1544 set actions [lindex $testitem 4]
1545 set binfile tmpdir/[lindex $testitem 5]
1546 set lang [lindex $testitem 6]
1547 set warnings [lindex $testitem 7]
1548 set objfiles {}
1549 set is_unresolved 0
1550 set failed 0
1551
1552 #verbose -log "testname is $testname"
1553 #verbose -log "ldflags is $ldflags"
1554 #verbose -log "cflags is $cflags"
1555 #verbose -log "src_files is $src_files"
1556 #verbose -log "actions is $actions"
1557 #verbose -log "binfile is $binfile"
1558 #verbose -log "lang is $lang"
1559 #verbose -log "warnings is $warnings"
1560
1561 # Compile each file in the test.
1562 foreach src_file $src_files {
1563 set fileroot "[file rootname [file tail $src_file]]"
1564 set objfile "tmpdir/$fileroot.o"
1565 lappend objfiles $objfile
1566
1567 # We ignore warnings since some compilers may generate
1568 # incorrect section attributes and the assembler will warn
1569 # them.
1570 if { [ string match "c++" $lang ] } {
1571 set cmd "$CXX -c $CXXFLAGS $cflags"
1572 } else {
1573 set cmd "$CC -c $CFLAGS $cflags"
1574 }
1575 if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] {
1576 set failed 1
1577 break
1578 }
1579 }
1580 if { $failed != 0 } {
1581 unresolved $testname
1582 continue
1583 }
1584
1585 # Clear error and warning counts.
1586 reset_vars
1587
1588 if { [ string match "c++" $lang ] } {
1589 set cc_cmd $CXX
1590 } else {
1591 set cc_cmd $CC
1592 }
1593
1594 if { $binfile eq "tmpdir/" } {
1595 # compile only
1596 } elseif { [regexp ".*\\.a$" $binfile] } {
1597 if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
1598 set failed 1
1599 }
1600 } else {
1601 if { ![ld_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"] } {
1602 set failed 1
1603 }
1604
1605 # Check if exec_output is expected.
1606 if { $warnings != "" } then {
1607 verbose -log "returned with: <$exec_output>, expected: <$warnings>"
1608 if { [regexp $warnings $exec_output] } then {
1609 set failed 0
1610 } else {
1611 set failed 1
1612 }
1613 }
1614 }
1615
1616 if { $failed == 0 } {
1617 foreach actionlist $actions {
1618 set action [lindex $actionlist 0]
1619 set progopts [lindex $actionlist 1]
1620
1621 # There are actions where we run regexp_diff on the
1622 # output, and there are other actions (presumably).
1623 # Handling of the former look the same.
1624 set dump_prog ""
1625 switch -- $action {
1626 objdump
1627 { set dump_prog $objdump }
1628 nm
1629 { set dump_prog $nm }
1630 readelf
1631 { set dump_prog $READELF }
1632 default
1633 {
1634 perror "Unrecognized action $action"
1635 set is_unresolved 1
1636 break
1637 }
1638 }
1639
1640 if { $dump_prog != "" } {
1641 set dumpfile [lindex $actionlist 2]
1642 set binary $dump_prog
1643
1644 # Ensure consistent sorting of symbols
1645 if {[info exists env(LC_ALL)]} {
1646 set old_lc_all $env(LC_ALL)
1647 }
1648 set env(LC_ALL) "C"
1649 set cmd "$binary $progopts $binfile > dump.out"
1650 send_log "$cmd\n"
1651 catch "exec $cmd" comp_output
1652 if {[info exists old_lc_all]} {
1653 set env(LC_ALL) $old_lc_all
1654 } else {
1655 unset env(LC_ALL)
1656 }
1657 set comp_output [prune_warnings $comp_output]
1658
1659 if ![string match "" $comp_output] then {
1660 send_log "$comp_output\n"
1661 set failed 1
1662 break
1663 }
1664
1665 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1666 verbose "output is [file_contents "dump.out"]" 2
1667 set failed 1
1668 break
1669 }
1670 }
1671 }
1672 }
1673
1674 if { $failed } {
1675 fail $testname
1676 } elseif { $is_unresolved } {
1677 unresolved $testname
1678 } else {
1679 pass $testname
1680 }
1681 }
1682 }
1683
1684 # Returns true if --gc-sections is supported on the target.
1685
1686 proc check_gc_sections_available { } {
1687 global gc_sections_available_saved
1688 global ld
1689
1690 if {![info exists gc_sections_available_saved]} {
1691 # Some targets don't support gc-sections despite whatever's
1692 # advertised by ld's options.
1693 if { [istarget d30v-*-*]
1694 || [istarget dlx-*-*]
1695 || [istarget i960-*-*]
1696 || [istarget pj*-*-*]
1697 || [istarget pru*-*-*]
1698 || [istarget alpha-*-*]
1699 || [istarget hppa*64-*-*]
1700 || [istarget i370-*-*]
1701 || [istarget i860-*-*]
1702 || [istarget ia64-*-*]
1703 || [istarget mep-*-*]
1704 || [istarget mn10200-*-*] } {
1705 set gc_sections_available_saved 0
1706 return 0
1707 }
1708
1709 # elf2flt uses -q (--emit-relocs), which is incompatible with
1710 # --gc-sections.
1711 if { [board_info target exists ldflags]
1712 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1713 set gc_sections_available_saved 0
1714 return 0
1715 }
1716
1717 # Check if the ld used by gcc supports --gc-sections.
1718 # FIXME: this test is useless since ld --help always says
1719 # --gc-sections is available
1720 set ld_output [remote_exec host $ld "--help"]
1721 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1722 set gc_sections_available_saved 1
1723 } else {
1724 set gc_sections_available_saved 0
1725 }
1726 }
1727 return $gc_sections_available_saved
1728 }
1729
1730 # Returns true if -shared is supported on the target
1731 # Only used and accurate for ELF targets at the moment
1732
1733 proc check_shared_lib_support { } {
1734 if {![istarget aarch64*-*-elf]
1735 && ![istarget arc*-*-elf*]
1736 && ![istarget arm*-*-elf]
1737 && ![istarget avr-*-*]
1738 && ![istarget cr16-*-*]
1739 && ![istarget cris*-*-elf]
1740 && ![istarget crx-*-*]
1741 && ![istarget d10v-*-*]
1742 && ![istarget d30v-*-*]
1743 && ![istarget dlx-*-*]
1744 && ![istarget epiphany-*-*]
1745 && ![istarget fr30-*-*]
1746 && ![istarget frv-*-*]
1747 && ![istarget ft32-*-*]
1748 && ![istarget h8300-*-*]
1749 && ![istarget i860-*-*]
1750 && ![istarget i960-*-*]
1751 && ![istarget ip2k-*-*]
1752 && ![istarget iq2000-*-*]
1753 && ![istarget lm32-*-*]
1754 && ![istarget m32c-*-*]
1755 && ![istarget m32r-*-*]
1756 && ![istarget m6811-*-*]
1757 && ![istarget m6812-*-*]
1758 && ![istarget m68hc1*-*-*]
1759 && ![istarget mcore*-*-*]
1760 && ![istarget mep-*-*]
1761 && ![istarget microblaze-*-*]
1762 && ![istarget mips*-*-elf]
1763 && ![istarget mn10200-*-*]
1764 && ![istarget moxie-*-*]
1765 && ![istarget msp430-*-*]
1766 && ![istarget mt-*-*]
1767 && ![istarget nds32*-*-*]
1768 && ![istarget or1k*-*-*]
1769 && ![istarget pj-*-*]
1770 && ![istarget pru-*-*]
1771 && ![istarget rl78-*-*]
1772 && ![istarget rx-*-*]
1773 && ![istarget spu-*-*]
1774 && ![istarget v850*-*-*]
1775 && ![istarget visium-*-*]
1776 && ![istarget xc16x-*-elf]
1777 && ![istarget xgate-*-*]
1778 && ![istarget xstormy16-*-*]
1779 && ![istarget *-*-irix*]
1780 && ![istarget *-*-rtems] } {
1781 return 1
1782 }
1783 return 0
1784 }
1785
1786 # Return true if target uses genelf.em (assuming it is ELF).
1787 proc is_generic_elf { } {
1788 if { [istarget "d30v-*-*"]
1789 || [istarget "dlx-*-*"]
1790 || [istarget "fr30-*-*"]
1791 || ([istarget "frv-*-*"] && ![istarget "frv-*-linux*"])
1792 || [istarget "ft32-*-*"]
1793 || [istarget "i860-*-*"]
1794 || [istarget "i960-*-*"]
1795 || [istarget "iq2000-*-*"]
1796 || [istarget "mn10200-*-*"]
1797 || [istarget "moxie-*-*"]
1798 || [istarget "msp430-*-*"]
1799 || [istarget "mt-*-*"]
1800 || [istarget "pj*-*-*"] } {
1801 return 1;
1802 }
1803 return 0;
1804 }
1805
1806 # Returns true if the target ld supports the plugin API.
1807 proc check_plugin_api_available { } {
1808 global plugin_api_available_saved
1809 global ld
1810 if {![info exists plugin_api_available_saved]} {
1811 # Check if the ld used by gcc supports --plugin.
1812 set ld_output [remote_exec host $ld "--help"]
1813 if { [ string first "-plugin PLUGIN" $ld_output ] >= 0 } {
1814 set plugin_api_available_saved 1
1815 } else {
1816 set plugin_api_available_saved 0
1817 }
1818 }
1819 return $plugin_api_available_saved
1820 }
1821
1822 # Sets ld_sysroot to the current sysroot (empty if not supported) and
1823 # returns true if the target ld supports sysroot.
1824 proc check_sysroot_available { } {
1825 global ld_sysroot_available_saved ld ld_sysroot
1826 if {![info exists ld_sysroot_available_saved]} {
1827 # Check if ld supports --sysroot *other* than empty.
1828 set ld_sysroot [string trimright [lindex [remote_exec host $ld "--print-sysroot"] 1]]
1829 if { $ld_sysroot == "" } {
1830 set ld_sysroot_available_saved 0
1831 } else {
1832 set ld_sysroot_available_saved 1
1833 }
1834 }
1835 return $ld_sysroot_available_saved
1836 }
1837
1838 # Returns 1 if plugin is enabled in gcc. Returns 0 otherwise.
1839 proc check_gcc_plugin_enabled { } {
1840 global CC
1841
1842 if {![info exists CC]} {
1843 set CC [find_gcc]
1844 }
1845 if { $CC == ""} {
1846 return 0
1847 }
1848 set state [remote_exec host $CC -v]
1849 if { [lindex $state 0] != 0 } {
1850 return 0;
1851 }
1852 for { set i 1 } { $i < [llength $state] } { incr i } {
1853 set v [lindex $state $i]
1854 if { [ string match "*--disable-plugin*" $v ] } {
1855 verbose "plugin is disabled by $v"
1856 return 0;
1857 }
1858 }
1859
1860 return 1;
1861 }
1862
1863 # Returns true if the target compiler supports LTO
1864 proc check_lto_available { } {
1865 global lto_available_saved
1866 global CC
1867
1868 if {![info exists lto_available_saved]} {
1869 if { ![check_gcc_plugin_enabled] } {
1870 set lto_available_saved 0
1871 return 0
1872 }
1873 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1874 # -ffat-lto-objects, we always run LTO tests on Linux with
1875 # GCC 4.9 or newer.
1876 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1877 set lto_available_saved 1
1878 return 1
1879 }
1880 # Check if gcc supports -flto -fuse-linker-plugin
1881 set flags ""
1882 if [board_info [target_info name] exists cflags] {
1883 append flags " [board_info [target_info name] cflags]"
1884 }
1885 if [board_info [target_info name] exists ldflags] {
1886 append flags " [board_info [target_info name] ldflags]"
1887 }
1888
1889 set basename "tmpdir/lto[pid]"
1890 set src ${basename}.c
1891 set output ${basename}.out
1892 set f [open $src "w"]
1893 puts $f "int main() { return 0; }"
1894 close $f
1895 if [is_remote host] {
1896 set src [remote_download host $src]
1897 }
1898 set lto_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -fuse-linker-plugin $src -o $output"]
1899 remote_file host delete $src
1900 remote_file host delete $output
1901 file delete $src
1902 }
1903 return $lto_available_saved
1904 }
1905
1906 # Returns true if the target compiler supports LTO -ffat-lto-objects
1907 proc check_lto_fat_available { } {
1908 global lto_fat_available_saved
1909 global CC
1910
1911 if {![info exists lto_fat_available_saved]} {
1912 if { ![check_gcc_plugin_enabled] } {
1913 set lto_fat_available_saved 0
1914 return 0
1915 }
1916 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1917 # -ffat-lto-objects, we always run LTO tests on Linux with
1918 # GCC 4.9 or newer.
1919 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1920 set lto_fat_available_saved 1
1921 return 1
1922 }
1923 # Check if gcc supports -flto -fuse-linker-plugin
1924 set flags ""
1925 if [board_info [target_info name] exists cflags] {
1926 append flags " [board_info [target_info name] cflags]"
1927 }
1928 if [board_info [target_info name] exists ldflags] {
1929 append flags " [board_info [target_info name] ldflags]"
1930 }
1931
1932 set basename "tmpdir/lto[pid]"
1933 set src ${basename}.c
1934 set output ${basename}.out
1935 set f [open $src "w"]
1936 puts $f "int main() { return 0; }"
1937 close $f
1938 if [is_remote host] {
1939 set src [remote_download host $src]
1940 }
1941 set lto_fat_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -ffat-lto-objects -fuse-linker-plugin $src -o $output"]
1942 remote_file host delete $src
1943 remote_file host delete $output
1944 file delete $src
1945 }
1946 return $lto_fat_available_saved
1947 }
1948
1949 # Returns true if the target compiler supports LTO and -shared
1950 proc check_lto_shared_available { } {
1951 global lto_shared_available_saved
1952 global CC
1953
1954 if {![info exists lto_shared_available_saved]} {
1955 if { ![check_gcc_plugin_enabled] } {
1956 set lto_shared_available_saved 0
1957 return 0
1958 }
1959 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1960 # -ffat-lto-objects, we always run LTO tests on Linux with
1961 # GCC 4.9 or newer.
1962 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1963 set lto_shared_available_saved 1
1964 return 1
1965 }
1966 # Check if gcc supports -flto -fuse-linker-plugin -shared
1967 set flags ""
1968 if [board_info [target_info name] exists cflags] {
1969 append flags " [board_info [target_info name] cflags]"
1970 }
1971 if [board_info [target_info name] exists ldflags] {
1972 append flags " [board_info [target_info name] ldflags]"
1973 }
1974
1975 set basename "tmpdir/lto_shared[pid]"
1976 set src ${basename}.c
1977 set output ${basename}.so
1978 set f [open $src "w"]
1979 puts $f ""
1980 close $f
1981 if [is_remote host] {
1982 set src [remote_download host $src]
1983 }
1984 set lto_shared_available_saved [run_host_cmd_yesno "$CC" "$flags -shared -fPIC -flto -fuse-linker-plugin $src -o $output"]
1985 remote_file host delete $src
1986 remote_file host delete $output
1987 file delete $src
1988 }
1989 return $lto_shared_available_saved
1990 }
1991
1992 # Check if the assembler supports CFI statements.
1993
1994 proc check_as_cfi { } {
1995 global check_as_cfi_result
1996 global as
1997 if [info exists check_as_cfi_result] {
1998 return $check_as_cfi_result
1999 }
2000 set as_file "tmpdir/check_as_cfi.s"
2001 set as_fh [open $as_file w 0666]
2002 puts $as_fh "# Generated file. DO NOT EDIT"
2003 puts $as_fh "\t.cfi_startproc"
2004 puts $as_fh "\t.cfi_endproc"
2005 close $as_fh
2006 remote_download host $as_file
2007 verbose -log "Checking CFI support:"
2008 rename "perror" "check_as_cfi_perror"
2009 proc perror { args } { }
2010 set success [ld_assemble $as $as_file "/dev/null"]
2011 rename "perror" ""
2012 rename "check_as_cfi_perror" "perror"
2013 #remote_file host delete $as_file
2014 set check_as_cfi_result $success
2015 return $success
2016 }
2017
2018 # Returns true if IFUNC works.
2019
2020 proc check_ifunc_available { } {
2021 global ifunc_available_saved
2022 global CC
2023
2024 if {![info exists ifunc_available_saved]} {
2025 if { [which $CC] == 0 } {
2026 set ifunc_available_saved 0
2027 return 0
2028 }
2029 # Check if gcc supports -flto -fuse-linker-plugin
2030 set flags ""
2031 if [board_info [target_info name] exists cflags] {
2032 append flags " [board_info [target_info name] cflags]"
2033 }
2034 if [board_info [target_info name] exists ldflags] {
2035 append flags " [board_info [target_info name] ldflags]"
2036 }
2037
2038 set basename "tmpdir/ifunc[pid]"
2039 set src ${basename}.c
2040 set output ${basename}.out
2041 set f [open $src "w"]
2042 puts $f "extern int library_func2 (void);"
2043 puts $f "int main (void)"
2044 puts $f "{"
2045 puts $f " if (library_func2 () != 2) __builtin_abort ();"
2046 puts $f " return 0; "
2047 puts $f "}"
2048 puts $f "static int library_func1 (void) {return 2; }"
2049 puts $f "void *foo (void) __asm__ (\"library_func2\");"
2050 puts $f "void *foo (void) { return library_func1; }"
2051 puts $f "__asm__(\".type library_func2, %gnu_indirect_function\");"
2052 close $f
2053 if [is_remote host] {
2054 set src [remote_download host $src]
2055 }
2056 set ifunc_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
2057 if { $ifunc_available_saved == 1 } {
2058 set ifunc_available_saved [run_host_cmd_yesno "$output" ""]
2059 }
2060 remote_file host delete $src
2061 remote_file host delete $output
2062 file delete $src
2063 }
2064 return $ifunc_available_saved
2065 }
2066
2067 # Returns true if ifunc attribute works.
2068
2069 proc check_ifunc_attribute_available { } {
2070 global ifunc_attribute_available_saved
2071 global CC
2072
2073 if {![info exists ifunc_attribute_available_saved]} {
2074 if { [which $CC] == 0 } {
2075 set ifunc_attribute_available_saved 0
2076 return 0
2077 }
2078 # Check if gcc supports -flto -fuse-linker-plugin
2079 set flags ""
2080 if [board_info [target_info name] exists cflags] {
2081 append flags " [board_info [target_info name] cflags]"
2082 }
2083 if [board_info [target_info name] exists ldflags] {
2084 append flags " [board_info [target_info name] ldflags]"
2085 }
2086
2087 set basename "tmpdir/ifunc[pid]"
2088 set src ${basename}.c
2089 set output ${basename}.out
2090 set f [open $src "w"]
2091 puts $f "extern int library_func2 (void) __attribute__ ((ifunc (\"foo\")));"
2092 puts $f "int main (void)"
2093 puts $f "{"
2094 puts $f " if (library_func2 () != 2) __builtin_abort ();"
2095 puts $f " return 0; "
2096 puts $f "}"
2097 puts $f "static int library_func1 (void) {return 2; }"
2098 puts $f "void *foo (void) { return library_func1; }"
2099 close $f
2100 if [is_remote host] {
2101 set src [remote_download host $src]
2102 }
2103 set ifunc_attribute_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
2104 if { $ifunc_attribute_available_saved == 1 } {
2105 set ifunc_attribute_available_saved [run_host_cmd_yesno "$output" ""]
2106 }
2107 remote_file host delete $src
2108 remote_file host delete $output
2109 file delete $src
2110 }
2111 return $ifunc_attribute_available_saved
2112 }
2113
2114 # Provide virtual target "cfi" for targets supporting CFI.
2115
2116 rename "istarget" "istarget_ld"
2117 proc istarget { target } {
2118 if {$target == "cfi"} {
2119 return [check_as_cfi]
2120 }
2121 return [istarget_ld $target]
2122 }
2123
2124 # Return true if libdl is supported.
2125
2126 proc check_libdl_available { } {
2127 global libdl_available_saved
2128 global CC
2129
2130 if {![info exists libdl_available_saved]} {
2131 if { [which $CC] == 0 } {
2132 set libdl_available_saved 0
2133 return 0
2134 }
2135
2136 set basename "tmpdir/dl_avail_test[pid]"
2137 set src ${basename}.c
2138 set output ${basename}.out
2139 set f [open $src "w"]
2140 # Sample test file.
2141 puts $f "#include <dlfcn.h>"
2142 puts $f "int main (void)"
2143 puts $f "{"
2144 puts $f " dlopen (\"dummy.so\", RTLD_NOW);"
2145 puts $f " return 0; "
2146 puts $f "}"
2147 close $f
2148 if [is_remote host] {
2149 set src [remote_download host $src]
2150 }
2151 set libdl_available_saved [run_host_cmd_yesno "$CC" "$src -o $output -ldl"]
2152 remote_file host delete $src
2153 remote_file host delete $output
2154 file delete $src
2155 }
2156 return $libdl_available_saved
2157 }
This page took 0.09775 seconds and 4 git commands to generate.