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