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