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