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