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