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