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