ld: Add file based error/warning regexp for run_dump_test.
[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 # error_output: FILE
558 # Means the same as 'error', except the regular expression lines
559 # are contains in FILE.
560 #
561 # warning: REGEX
562 # Expect a linker warning matching REGEX. It is an error to issue
563 # both "error" and "warning". Multiple "warning" directives
564 # append to the expected linker warning message.
565 #
566 # warning_output: FILE
567 # Means the same as 'warning', except the regular expression
568 # lines are contains in FILE.
569 #
570 # map: FILE
571 # Adding this option will cause the linker to generate a linker
572 # map file, using the -Map=MAPFILE command line option. If
573 # there is no -Map=MAPFILE in the 'ld: FLAGS' then one will be
574 # added to the linker command line. The contents of the
575 # generated MAPFILE are then compared against the regexp lines
576 # in FILE using `regexp_diff' (see below for details).
577 #
578 # Each option may occur at most once unless otherwise mentioned.
579 #
580 # After the option lines come regexp lines. `run_dump_test' calls
581 # `regexp_diff' to compare the output of the dumping tool against the
582 # regexps in FILE.d. `regexp_diff' is defined in binutils-common.exp;
583 # see further comments there.
584 #
585 proc run_dump_test { name {extra_options {}} } {
586 global subdir srcdir
587 global OBJDUMP NM AS OBJCOPY READELF LD
588 global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
589 global host_triplet runtests
590 global env verbose
591
592 if [string match "*/*" $name] {
593 set file $name
594 set name [file tail $name]
595 } else {
596 set file "$srcdir/$subdir/$name"
597 }
598
599 if ![runtest_file_p $runtests $name] then {
600 return
601 }
602
603 set opt_array [slurp_options "${file}.d"]
604 if { $opt_array == -1 } {
605 perror "error reading options from $file.d"
606 unresolved $subdir/$name
607 return
608 }
609 set dumpfile tmpdir/dump.out
610 set run_ld 0
611 set run_objcopy 0
612 set opts(as) {}
613 set opts(ld) {}
614 set opts(ld_after_inputfiles) {}
615 set opts(xfail) {}
616 set opts(target) {}
617 set opts(notarget) {}
618 set opts(objdump) {}
619 set opts(nm) {}
620 set opts(objcopy) {}
621 set opts(readelf) {}
622 set opts(name) {}
623 set opts(PROG) {}
624 set opts(source) {}
625 set opts(dump) {}
626 set opts(error) {}
627 set opts(warning) {}
628 set opts(error_output) {}
629 set opts(warning_output) {}
630 set opts(objcopy_linked_file) {}
631 set opts(objcopy_objects) {}
632 set opts(map) {}
633
634 foreach i $opt_array {
635 set opt_name [lindex $i 0]
636 set opt_val [lindex $i 1]
637 if ![info exists opts($opt_name)] {
638 perror "unknown option $opt_name in file $file.d"
639 unresolved $subdir/$name
640 return
641 }
642
643 switch -- $opt_name {
644 xfail {}
645 target {}
646 notarget {}
647 warning {}
648 error {}
649 source {
650 # Move any source-specific as-flags to a separate list to
651 # simplify processing.
652 if { [llength $opt_val] > 1 } {
653 lappend asflags [lrange $opt_val 1 end]
654 set opt_val [lindex $opt_val 0]
655 } else {
656 lappend asflags {}
657 }
658 }
659 default {
660 if [string length $opts($opt_name)] {
661 perror "option $opt_name multiply set in $file.d"
662 unresolved $subdir/$name
663 return
664 }
665
666 # A single "# ld:" with no options should do the right thing.
667 if { $opt_name == "ld" } {
668 set run_ld 1
669 }
670 # Likewise objcopy_linked_file.
671 if { $opt_name == "objcopy_linked_file" } {
672 set run_objcopy 1
673 }
674 }
675 }
676 if { $opt_name == "as" || $opt_name == "ld" } {
677 set opt_val [subst $opt_val]
678 }
679
680 # Append differently whether it's a message (without space) or
681 # an option or list (with space).
682 switch -- $opt_name {
683 warning -
684 error {
685 append opts($opt_name) $opt_val
686 }
687 default {
688 set opts($opt_name) [concat $opts($opt_name) $opt_val]
689 }
690 }
691 }
692
693 foreach i $extra_options {
694 set opt_name [lindex $i 0]
695 set opt_val [lindex $i 1]
696 if ![info exists opts($opt_name)] {
697 perror "unknown option $opt_name given in extra_opts"
698 unresolved $subdir/$name
699 return
700 }
701 # Add extra option to end of existing option, adding space
702 # if necessary.
703 if { ![regexp "warning|error" $opt_name]
704 && [string length $opts($opt_name)] } {
705 append opts($opt_name) " "
706 }
707 append opts($opt_name) $opt_val
708 }
709
710 foreach opt { as ld } {
711 regsub {\[big_or_little_endian\]} $opts($opt) \
712 [big_or_little_endian] opts($opt)
713 }
714
715 # Decide early whether we should run the test for this target.
716 if { [llength $opts(target)] > 0 } {
717 set targmatch 0
718 foreach targ $opts(target) {
719 if [istarget $targ] {
720 set targmatch 1
721 break
722 }
723 }
724 if { $targmatch == 0 } {
725 return
726 }
727 }
728 foreach targ $opts(notarget) {
729 if [istarget $targ] {
730 return
731 }
732 }
733
734 set program ""
735 # It's meaningless to require an output-testing method when we
736 # expect an error.
737 if { $opts(error) == "" && $opts(error_output) == "" } {
738 if {$opts(PROG) != ""} {
739 switch -- $opts(PROG) {
740 objdump { set program objdump }
741 nm { set program nm }
742 objcopy { set program objcopy }
743 readelf { set program readelf }
744 default
745 { perror "unrecognized program option $opts(PROG) in $file.d"
746 unresolved $subdir/$name
747 return }
748 }
749 } else {
750 # Guess which program to run, by seeing which option was specified.
751 foreach p {objdump objcopy nm readelf} {
752 if {$opts($p) != ""} {
753 if {$program != ""} {
754 perror "ambiguous dump program in $file.d"
755 unresolved $subdir/$name
756 return
757 } else {
758 set program $p
759 }
760 }
761 }
762 }
763 if { $program == "" \
764 && $opts(warning) == "" \
765 && $opts(warning_output) == "" \
766 && $opts(error) == "" \
767 && $opts(error_output) == "" } {
768 perror "dump program unspecified in $file.d"
769 unresolved $subdir/$name
770 return
771 }
772 }
773
774 if { $opts(name) == "" } {
775 set testname "$subdir/$name"
776 } else {
777 set testname $opts(name)
778 }
779
780 if { $opts(source) == "" } {
781 set sourcefiles [list ${file}.s]
782 set asflags [list ""]
783 } else {
784 set sourcefiles {}
785 foreach sf $opts(source) {
786 if { [string match "/*" $sf] } {
787 lappend sourcefiles "$sf"
788 } else {
789 lappend sourcefiles "$srcdir/$subdir/$sf"
790 }
791 }
792 }
793
794 if { $opts(dump) == "" } {
795 set dfile ${file}.d
796 } else {
797 set dfile $srcdir/$subdir/$opts(dump)
798 }
799
800 # Time to setup xfailures.
801 foreach targ $opts(xfail) {
802 setup_xfail $targ
803 }
804
805 # Assemble each file.
806 set objfiles {}
807 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
808 set sourcefile [lindex $sourcefiles $i]
809 set sourceasflags [lindex $asflags $i]
810 set run_objcopy_objects 0
811
812 if { [string match "*RUN_OBJCOPY*" $sourceasflags] } {
813 set run_objcopy_objects 1
814 }
815 regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
816
817 set objfile "tmpdir/dump$i.o"
818 catch "exec rm -f $objfile" exec_output
819 lappend objfiles $objfile
820 set cmd "$AS $ASFLAGS $opts(as) $sourceasflags -o $objfile $sourcefile"
821
822 send_log "$cmd\n"
823 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
824 remote_upload host "ld.tmp"
825 set comp_output [prune_warnings [file_contents "ld.tmp"]]
826 remote_file host delete "ld.tmp"
827 remote_file build delete "ld.tmp"
828
829 if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
830 send_log "$comp_output\n"
831 verbose "$comp_output" 3
832
833 set exitstat "succeeded"
834 if { $cmdret != 0 } { set exitstat "failed" }
835 verbose -log "$exitstat with: <$comp_output>"
836 fail $testname
837 return
838 }
839
840 if { $run_objcopy_objects } {
841 set cmd "$OBJCOPY $opts(objcopy_objects) $objfile"
842
843 send_log "$cmd\n"
844 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \
845 "" "/dev/null" "objcopy.tmp"]
846 remote_upload host "objcopy.tmp"
847 set comp_output [prune_warnings [file_contents "objcopy.tmp"]]
848 remote_file host delete "objcopy.tmp"
849 remote_file build delete "objcopy.tmp"
850
851 if { [lindex $cmdret 0] != 0 \
852 || ![string match "" $comp_output] } {
853 send_log "$comp_output\n"
854 verbose "$comp_output" 3
855
856 set exitstat "succeeded"
857 if { $cmdret != 0 } { set exitstat "failed" }
858 verbose -log "$exitstat with: <$comp_output>"
859 fail $testname
860 return
861 }
862 }
863 }
864
865 if { (($opts(warning) != "") && ($opts(error) != "")) \
866 || (($opts(warning) != "") && ($opts(error_output) != "")) \
867 || (($opts(warning) != "") && ($opts(warning_output) != "")) \
868 || (($opts(error) != "") && ($opts(warning_output) != "")) \
869 || (($opts(error) != "") && ($opts(error_output) != "")) \
870 || (($opts(warning_output) != "") && ($opts(error_output) != "")) } {
871 perror "$testname: bad mix of warning, error, warning_output, and error_output test-directives"
872 unresolved $testname
873 return
874 }
875
876 set check_ld(source) ""
877 if { $opts(error) != "" \
878 || $opts(warning) != "" \
879 || $opts(error_output) != "" \
880 || $opts(warning_output) != "" } {
881
882 if { $opts(error) != "" || $opts(error_output) != "" } {
883 set check_ld(terminal) 1
884 } else {
885 set check_ld(terminal) 0
886 }
887
888 if { $opts(error) != "" || $opts(warning) != "" } {
889 set check_ld(source) "regex"
890 if { $opts(error) != "" } {
891 set check_ld(regex) $opts(error)
892 } else {
893 set check_ld(regex) $opts(warning)
894 }
895 } else {
896 set check_ld(source) "file"
897 if { $opts(error_output) != "" } {
898 set check_ld(file) $opts(error_output)
899 } else {
900 set check_ld(file) $opts(warning_output)
901 }
902 }
903 }
904
905 # Perhaps link the file(s).
906 if { $run_ld } {
907 set objfile "tmpdir/dump"
908 catch "exec rm -f $objfile" exec_output
909
910 # Add -L$srcdir/$subdir so that the linker command can use
911 # linker scripts in the source directory.
912 set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
913 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
914
915 # If needed then check for, or add a -Map option.
916 set mapfile ""
917 if { $opts(map) != "" } then {
918 if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then {
919 # Found existing mapfile option
920 verbose -log "Existing mapfile '$mapfile' found"
921 } else {
922 # No mapfile option.
923 set mapfile "tmpdir/dump.map"
924 verbose -log "Adding mapfile '$mapfile'"
925 set cmd "$cmd -Map=$mapfile"
926 }
927 }
928
929 send_log "$cmd\n"
930 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
931 remote_upload host "ld.tmp"
932 set comp_output [file_contents "ld.tmp"]
933 remote_file host delete "ld.tmp"
934 remote_file build delete "ld.tmp"
935 set cmdret [lindex $cmdret 0]
936
937 if { $cmdret == 0 && $run_objcopy } {
938 set infile $objfile
939 set objfile "tmpdir/dump1"
940 remote_file host delete $objfile
941
942 # Note that we don't use OBJCOPYFLAGS here; any flags must be
943 # explicitly specified.
944 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
945
946 send_log "$cmd\n"
947 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
948 remote_upload host "ld.tmp"
949 append comp_output [file_contents "ld.tmp"]
950 remote_file host delete "ld.tmp"
951 remote_file build delete "ld.tmp"
952 set cmdret [lindex $cmdret 0]
953 }
954
955 regsub "\n$" $comp_output "" comp_output
956 if { $cmdret != 0 || $comp_output != "" || $check_ld(source) != "" } then {
957 set exitstat "succeeded"
958 if { $cmdret != 0 } { set exitstat "failed" }
959
960 if { $check_ld(source) == "regexp" } {
961 verbose -log "$exitstat with: <$comp_output>, expected: <$check_ld(regex)>"
962 } elseif { $check_ld(source) == "file" } {
963 verbose -log "$exitstat with: <$comp_output>, expected in file $check_ld(file)"
964 set_file_contents "tmpdir/ld.messages" "$comp_output"
965 } else {
966 verbose -log "$exitstat with: <$comp_output>, no expected output"
967 }
968 send_log "$comp_output\n"
969 verbose "$comp_output" 3
970
971 if { (($check_ld(source) == "") == ($comp_output == "")) \
972 && (($cmdret == 0) == ($check_ld(terminal) == 0)) \
973 && ((($check_ld(source) == "regex") \
974 && ($check_ld(regex) == "") == ($comp_output == "") \
975 && [regexp $check_ld(regex) $comp_output]) \
976 || (($check_ld(source) == "file") \
977 && ([regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$check_ld(file)"]))) } {
978 # We have the expected output from ld.
979 if { $check_ld(terminal) || $program == "" } {
980 pass $testname
981 return
982 }
983 } else {
984 fail $testname
985 return
986 }
987 }
988
989 if { $opts(map) != "" } then {
990 # Check the map file matches.
991 set map_pattern_file $srcdir/$subdir/$opts(map)
992 verbose -log "Compare '$mapfile' against '$map_pattern_file'"
993 if { [regexp_diff $mapfile $map_pattern_file] } then {
994 fail "$testname (map file check)"
995 } else {
996 pass "$testname (map file check)"
997 }
998 }
999 } else {
1000 set objfile "tmpdir/dump0.o"
1001 }
1002
1003 # We must not have expected failure if we get here.
1004 if { $opts(error) != "" } {
1005 fail $testname
1006 return
1007 }
1008
1009 set progopts1 $opts($program)
1010 eval set progopts \$[string toupper $program]FLAGS
1011 eval set binary \$[string toupper $program]
1012
1013 if { ![is_remote host] && [which $binary] == 0 } {
1014 untested $testname
1015 return
1016 }
1017
1018 if { $progopts1 == "" } { set $progopts1 "-r" }
1019 verbose "running $binary $progopts $progopts1" 3
1020
1021 # Objcopy, unlike the other two, won't send its output to stdout,
1022 # so we have to run it specially.
1023 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
1024 if { $program == "objcopy" } {
1025 set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
1026 }
1027
1028 # Ensure consistent sorting of symbols
1029 if {[info exists env(LC_ALL)]} {
1030 set old_lc_all $env(LC_ALL)
1031 }
1032 set env(LC_ALL) "C"
1033 send_log "$cmd\n"
1034 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
1035 set cmdret [lindex $cmdret 0]
1036 remote_upload host "ld.tmp"
1037 set comp_output [prune_warnings [file_contents "ld.tmp"]]
1038 remote_file host delete "ld.tmp"
1039 remote_file build delete "ld.tmp"
1040 if {[info exists old_lc_all]} {
1041 set env(LC_ALL) $old_lc_all
1042 } else {
1043 unset env(LC_ALL)
1044 }
1045 if { $cmdret != 0 || $comp_output != "" } {
1046 send_log "exited abnormally with $cmdret, output:$comp_output\n"
1047 fail $testname
1048 return
1049 }
1050
1051 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
1052 if { [regexp_diff $dumpfile "${dfile}"] } then {
1053 fail $testname
1054 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
1055 return
1056 }
1057
1058 pass $testname
1059 }
1060
1061 proc slurp_options { file } {
1062 # If options_regsub(foo) is set to {a b}, then the contents of a
1063 # "#foo:" line will have regsub -all applied to replace a with b.
1064 global options_regsub
1065
1066 if [catch { set f [open $file r] } x] {
1067 #perror "couldn't open `$file': $x"
1068 perror "$x"
1069 return -1
1070 }
1071 set opt_array {}
1072 # whitespace expression
1073 set ws {[ ]*}
1074 set nws {[^ ]*}
1075 # whitespace is ignored anywhere except within the options list;
1076 # option names are alphabetic plus underscore only.
1077 set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
1078 while { [gets $f line] != -1 } {
1079 set line [string trim $line]
1080 # Whitespace here is space-tab.
1081 if [regexp $pat $line xxx opt_name opt_val] {
1082 # match!
1083 if [info exists options_regsub($opt_name)] {
1084 set subst $options_regsub($opt_name)
1085 regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \
1086 opt_val
1087 }
1088 lappend opt_array [list $opt_name $opt_val]
1089 } else {
1090 break
1091 }
1092 }
1093 close $f
1094 return $opt_array
1095 }
1096
1097 proc file_contents { filename } {
1098 set file [open $filename r]
1099 set contents [read $file]
1100 close $file
1101 return $contents
1102 }
1103
1104 proc set_file_contents { filename contents } {
1105 set file [open $filename w]
1106 puts $file "$contents"
1107 close $file
1108 }
1109
1110 # Create an archive using ar
1111 #
1112 proc ar_simple_create { ar aropts target objects } {
1113 remote_file host delete $target
1114
1115 set exec_output [run_host_cmd "$ar" "-rc $aropts $target $objects"]
1116 set exec_output [prune_warnings $exec_output]
1117
1118 if [string match "" $exec_output] then {
1119 send_log "$exec_output\n"
1120 return 1
1121 } else {
1122 return 0
1123 }
1124 }
1125
1126 # List contains test-items with 3 items followed by 2 lists, one item and
1127 # one optional item:
1128 # 0:name
1129 # 1:ld/ar leading options, placed before object files
1130 # 2:ld/ar trailing options, placed after object files
1131 # 3:assembler options
1132 # 4:filenames of assembler files
1133 # 5:list of actions, options and expected outputs.
1134 # 6:name of output file
1135 # 7:compiler flags (optional)
1136 #
1137 # Actions: { command command-line-options file-containg-expected-output-regexps }
1138 # Commands:
1139 # objdump: Apply objdump options on result.
1140 # nm: Apply nm options on result.
1141 # readelf: Apply readelf options on result.
1142 # ld: Don't apply anything on result. Compare output during linking with
1143 # the file containing regexps (which is the second arg, not the third).
1144 # Note that this *must* be the first action if it is to be used at all;
1145 # in all other cases, any output from the linker during linking is
1146 # treated as a sign of an error and FAILs the test.
1147 #
1148 proc run_ld_link_tests { ldtests } {
1149 global ld
1150 global as
1151 global nm
1152 global ar
1153 global objdump
1154 global READELF
1155 global srcdir
1156 global subdir
1157 global env
1158 global CC
1159 global CFLAGS
1160 global runtests
1161 global exec_output
1162
1163 foreach testitem $ldtests {
1164 set testname [lindex $testitem 0]
1165
1166 if ![runtest_file_p $runtests $testname] then {
1167 continue
1168 }
1169
1170 set ld_options [lindex $testitem 1]
1171 set ld_after [lindex $testitem 2]
1172 set as_options [lindex $testitem 3]
1173 set src_files [lindex $testitem 4]
1174 set actions [lindex $testitem 5]
1175 set binfile tmpdir/[lindex $testitem 6]
1176 set cflags [lindex $testitem 7]
1177 set objfiles {}
1178 set is_unresolved 0
1179 set failed 0
1180 set maybe_failed 0
1181 set ld_output ""
1182
1183 # verbose -log "Testname is $testname"
1184 # verbose -log "ld_options is $ld_options"
1185 # verbose -log "ld_after is $ld_after"
1186 # verbose -log "as_options is $as_options"
1187 # verbose -log "src_files is $src_files"
1188 # verbose -log "actions is $actions"
1189 # verbose -log "binfile is $binfile"
1190
1191 # Assemble each file in the test.
1192 foreach src_file $src_files {
1193 set fileroot "[file rootname [file tail $src_file]]"
1194 set objfile "tmpdir/$fileroot.o"
1195 lappend objfiles $objfile
1196
1197 if { [file extension $src_file] == ".c" } {
1198 set as_file "tmpdir/$fileroot.s"
1199 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1200 set is_unresolved 1
1201 break
1202 }
1203 } else {
1204 set as_file "$srcdir/$subdir/$src_file"
1205 }
1206 if ![ld_assemble $as "$as_options $as_file" $objfile] {
1207 set is_unresolved 1
1208 break
1209 }
1210 }
1211
1212 # Catch assembler errors.
1213 if { $is_unresolved } {
1214 unresolved $testname
1215 continue
1216 }
1217
1218 if { $binfile eq "tmpdir/" } {
1219 # compile only
1220 } elseif { [regexp ".*\\.a$" $binfile] } {
1221 if { ![ar_simple_create $ar $ld_options $binfile "$objfiles $ld_after"] } {
1222 set failed 1
1223 }
1224 } elseif { ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles $ld_after"] } {
1225 set maybe_failed 1
1226 set ld_output "$exec_output"
1227 }
1228
1229 if { !$failed } {
1230 foreach actionlist $actions {
1231 set action [lindex $actionlist 0]
1232 set progopts [lindex $actionlist 1]
1233
1234 # There are actions where we run regexp_diff on the
1235 # output, and there are other actions (presumably).
1236 # Handling of the former look the same.
1237 set dump_prog ""
1238 switch -- $action {
1239 objdump
1240 { set dump_prog $objdump }
1241 nm
1242 { set dump_prog $nm }
1243 readelf
1244 { set dump_prog $READELF }
1245 ld
1246 { set dump_prog "ld" }
1247 default
1248 {
1249 perror "Unrecognized action $action"
1250 set is_unresolved 1
1251 break
1252 }
1253 }
1254
1255 if { $action == "ld" } {
1256 set regexpfile $progopts
1257 verbose "regexpfile is $srcdir/$subdir/$regexpfile"
1258 set_file_contents "tmpdir/ld.messages" "$ld_output"
1259 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
1260 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$regexpfile"] } then {
1261 verbose "output is $ld_output" 2
1262 set failed 1
1263 break
1264 }
1265 set maybe_failed 0
1266 } elseif { !$maybe_failed && $dump_prog != "" } {
1267 set dumpfile [lindex $actionlist 2]
1268 set binary $dump_prog
1269
1270 # Ensure consistent sorting of symbols
1271 if {[info exists env(LC_ALL)]} {
1272 set old_lc_all $env(LC_ALL)
1273 }
1274 set env(LC_ALL) "C"
1275 set cmd "$binary $progopts $binfile"
1276 set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
1277 send_log "$cmd\n"
1278 remote_upload host "ld.stderr"
1279 set comp_output [prune_warnings [file_contents "ld.stderr"]]
1280 remote_file host delete "ld.stderr"
1281 remote_file build delete "ld.stderr"
1282
1283 if {[info exists old_lc_all]} {
1284 set env(LC_ALL) $old_lc_all
1285 } else {
1286 unset env(LC_ALL)
1287 }
1288
1289 if ![string match "" $comp_output] then {
1290 send_log "$comp_output\n"
1291 set failed 1
1292 break
1293 }
1294
1295 remote_upload host "dump.out"
1296
1297 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1298 verbose "output is [file_contents "dump.out"]" 2
1299 set failed 1
1300 remote_file build delete "dump.out"
1301 remote_file host delete "dump.out"
1302 break
1303 }
1304 remote_file build delete "dump.out"
1305 remote_file host delete "dump.out"
1306 }
1307 }
1308 }
1309
1310 if { $is_unresolved } {
1311 unresolved $testname
1312 } elseif { $maybe_failed || $failed } {
1313 fail $testname
1314 } else {
1315 pass $testname
1316 }
1317 }
1318 }
1319
1320 # This definition is taken from an unreleased version of DejaGnu. Once
1321 # that version gets released, and has been out in the world for a few
1322 # months at least, it may be safe to delete this copy.
1323 if ![string length [info proc prune_warnings]] {
1324 #
1325 # prune_warnings -- delete various system verbosities from TEXT
1326 #
1327 # An example is:
1328 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1329 #
1330 # Sites with particular verbose os's may wish to override this in site.exp.
1331 #
1332 proc prune_warnings { text } {
1333 # This is from sun4's. Do it for all machines for now.
1334 # The "\\1" is to try to preserve a "\n" but only if necessary.
1335 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1336
1337 # It might be tempting to get carried away and delete blank lines, etc.
1338 # Just delete *exactly* what we're ask to, and that's it.
1339 return $text
1340 }
1341 }
1342
1343 # targets_to_xfail is a list of target triplets to be xfailed.
1344 # ldtests contains test-items with 3 items followed by 1 lists, 2 items
1345 # and 3 optional items:
1346 # 0:name
1347 # 1:ld options
1348 # 2:assembler options
1349 # 3:filenames of source files
1350 # 4:name of output file
1351 # 5:expected output
1352 # 6:compiler flags (optional)
1353 # 7:language (optional)
1354 # 8:linker warning (optional)
1355
1356 proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
1357 global ld
1358 global as
1359 global srcdir
1360 global subdir
1361 global env
1362 global CC
1363 global CXX
1364 global CFLAGS
1365 global CXXFLAGS
1366 global errcnt
1367 global exec_output
1368
1369 foreach testitem $ldtests {
1370 foreach target $targets_to_xfail {
1371 setup_xfail $target
1372 }
1373 set testname [lindex $testitem 0]
1374 set ld_options [lindex $testitem 1]
1375 set as_options [lindex $testitem 2]
1376 set src_files [lindex $testitem 3]
1377 set binfile tmpdir/[lindex $testitem 4]
1378 set expfile [lindex $testitem 5]
1379 set cflags [lindex $testitem 6]
1380 set lang [lindex $testitem 7]
1381 set warning [lindex $testitem 8]
1382 set objfiles {}
1383 set failed 0
1384
1385 # verbose -log "Testname is $testname"
1386 # verbose -log "ld_options is $ld_options"
1387 # verbose -log "as_options is $as_options"
1388 # verbose -log "src_files is $src_files"
1389 # verbose -log "binfile is $binfile"
1390
1391 # Assemble each file in the test.
1392 foreach src_file $src_files {
1393 set fileroot "[file rootname [file tail $src_file]]"
1394 set objfile "tmpdir/$fileroot.o"
1395 lappend objfiles $objfile
1396
1397 # We ignore warnings since some compilers may generate
1398 # incorrect section attributes and the assembler will warn
1399 # them.
1400 if { [ string match "c++" $lang ] } {
1401 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1402 } else {
1403 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1404 }
1405 }
1406
1407 # We have to use $CC to build PIE and shared library.
1408 if { [ string match "c" $lang ] } {
1409 set link_proc ld_simple_link
1410 set link_cmd $CC
1411 } elseif { [ string match "c++" $lang ] } {
1412 set link_proc ld_simple_link
1413 set link_cmd $CXX
1414 } elseif { [ string match "-shared" $ld_options ] \
1415 || [ string match "-pie" $ld_options ] } {
1416 set link_proc ld_simple_link
1417 set link_cmd $CC
1418 } else {
1419 set link_proc ld_link
1420 set link_cmd $ld
1421 }
1422
1423 if { $binfile eq "tmpdir/" } {
1424 # compile only
1425 pass $testname
1426 continue;
1427 } elseif ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1428 set failed 1
1429 }
1430
1431 # Check if exec_output is expected.
1432 if { $warning != "" } then {
1433 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1434 if { [regexp $warning $exec_output] } then {
1435 set failed 0
1436 } else {
1437 set failed 1
1438 }
1439 }
1440
1441 if { $failed == 0 } {
1442 send_log "Running: $binfile > $binfile.out\n"
1443 verbose "Running: $binfile > $binfile.out"
1444 catch "exec $binfile > $binfile.out" exec_output
1445
1446 if ![string match "" $exec_output] then {
1447 send_log "$exec_output\n"
1448 verbose "$exec_output" 1
1449 set failed 1
1450 } else {
1451 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1452 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1453 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1454 set exec_output [prune_warnings $exec_output]
1455
1456 if ![string match "" $exec_output] then {
1457 send_log "$exec_output\n"
1458 verbose "$exec_output" 1
1459 set failed 1
1460 }
1461 }
1462 }
1463
1464 if { $failed != 0 } {
1465 fail $testname
1466 } else {
1467 set errcnt 0
1468 pass $testname
1469 }
1470 }
1471 }
1472
1473 # List contains test-items with 3 items followed by 2 lists, one item and
1474 # one optional item:
1475 # 0:name
1476 # 1:ld or ar options
1477 # 2:compile options
1478 # 3:filenames of source files
1479 # 4:action and options.
1480 # 5:name of output file
1481 # 6:language (optional)
1482 # 7:linker warnings (optional)
1483 #
1484 # Actions:
1485 # objdump: Apply objdump options on result. Compare with regex (last arg).
1486 # nm: Apply nm options on result. Compare with regex (last arg).
1487 # readelf: Apply readelf options on result. Compare with regex (last arg).
1488 #
1489 proc run_cc_link_tests { ldtests } {
1490 global nm
1491 global objdump
1492 global READELF
1493 global srcdir
1494 global subdir
1495 global env
1496 global CC
1497 global CXX
1498 global CFLAGS
1499 global CXXFLAGS
1500 global ar
1501 global exec_output
1502 global board_cflags
1503
1504 if [board_info [target_info name] exists cflags] {
1505 set board_cflags " [board_info [target_info name] cflags]"
1506 } else {
1507 set board_cflags ""
1508 }
1509
1510 foreach testitem $ldtests {
1511 set testname [lindex $testitem 0]
1512 set ldflags [lindex $testitem 1]
1513 set cflags [lindex $testitem 2]
1514 set src_files [lindex $testitem 3]
1515 set actions [lindex $testitem 4]
1516 set binfile tmpdir/[lindex $testitem 5]
1517 set lang [lindex $testitem 6]
1518 set warnings [lindex $testitem 7]
1519 set objfiles {}
1520 set is_unresolved 0
1521 set failed 0
1522
1523 #verbose -log "testname is $testname"
1524 #verbose -log "ldflags is $ldflags"
1525 #verbose -log "cflags is $cflags"
1526 #verbose -log "src_files is $src_files"
1527 #verbose -log "actions is $actions"
1528 #verbose -log "binfile is $binfile"
1529 #verbose -log "lang is $lang"
1530 #verbose -log "warnings is $warnings"
1531
1532 # Compile each file in the test.
1533 foreach src_file $src_files {
1534 set fileroot "[file rootname [file tail $src_file]]"
1535 set objfile "tmpdir/$fileroot.o"
1536 lappend objfiles $objfile
1537
1538 # We ignore warnings since some compilers may generate
1539 # incorrect section attributes and the assembler will warn
1540 # them.
1541 if { [ string match "c++" $lang ] } {
1542 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1543 } else {
1544 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1545 }
1546 }
1547
1548 # Clear error and warning counts.
1549 reset_vars
1550
1551 if { [ string match "c++" $lang ] } {
1552 set cc_cmd $CXX
1553 } else {
1554 set cc_cmd $CC
1555 }
1556
1557 if { $binfile eq "tmpdir/" } {
1558 # compile only
1559 } elseif { [regexp ".*\\.a$" $binfile] } {
1560 if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
1561 fail $testname
1562 set failed 1
1563 }
1564 } else {
1565 if { ![ld_simple_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"] } {
1566 set failed 1
1567 }
1568
1569 # Check if exec_output is expected.
1570 if { $warnings != "" } then {
1571 verbose -log "returned with: <$exec_output>, expected: <$warnings>"
1572 if { [regexp $warnings $exec_output] } then {
1573 set failed 0
1574 } else {
1575 set failed 1
1576 }
1577 }
1578
1579 if { $failed == 1 } {
1580 fail $testname
1581 }
1582 }
1583
1584 if { $failed == 0 } {
1585 foreach actionlist $actions {
1586 set action [lindex $actionlist 0]
1587 set progopts [lindex $actionlist 1]
1588
1589 # There are actions where we run regexp_diff on the
1590 # output, and there are other actions (presumably).
1591 # Handling of the former look the same.
1592 set dump_prog ""
1593 switch -- $action {
1594 objdump
1595 { set dump_prog $objdump }
1596 nm
1597 { set dump_prog $nm }
1598 readelf
1599 { set dump_prog $READELF }
1600 default
1601 {
1602 perror "Unrecognized action $action"
1603 set is_unresolved 1
1604 break
1605 }
1606 }
1607
1608 if { $dump_prog != "" } {
1609 set dumpfile [lindex $actionlist 2]
1610 set binary $dump_prog
1611
1612 # Ensure consistent sorting of symbols
1613 if {[info exists env(LC_ALL)]} {
1614 set old_lc_all $env(LC_ALL)
1615 }
1616 set env(LC_ALL) "C"
1617 set cmd "$binary $progopts $binfile > dump.out"
1618 send_log "$cmd\n"
1619 catch "exec $cmd" comp_output
1620 if {[info exists old_lc_all]} {
1621 set env(LC_ALL) $old_lc_all
1622 } else {
1623 unset env(LC_ALL)
1624 }
1625 set comp_output [prune_warnings $comp_output]
1626
1627 if ![string match "" $comp_output] then {
1628 send_log "$comp_output\n"
1629 set failed 1
1630 break
1631 }
1632
1633 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1634 verbose "output is [file_contents "dump.out"]" 2
1635 set failed 1
1636 break
1637 }
1638 }
1639 }
1640 }
1641
1642 if { $failed != 0 } {
1643 fail $testname
1644 } elseif { $is_unresolved == 0 } {
1645 pass $testname
1646 } else {
1647 unresolved $testname
1648 continue
1649 }
1650 }
1651 }
1652
1653 # Returns true if --gc-sections is supported on the target.
1654
1655 proc check_gc_sections_available { } {
1656 global gc_sections_available_saved
1657 global ld
1658
1659 if {![info exists gc_sections_available_saved]} {
1660 # Some targets don't support gc-sections despite whatever's
1661 # advertised by ld's options.
1662 if { [istarget arc-*-*]
1663 || [istarget d30v-*-*]
1664 || [istarget dlx-*-*]
1665 || [istarget i960-*-*]
1666 || [istarget pj*-*-*]
1667 || [istarget alpha-*-*]
1668 || [istarget hppa*64-*-*]
1669 || [istarget i370-*-*]
1670 || [istarget i860-*-*]
1671 || [istarget ia64-*-*]
1672 || [istarget mep-*-*]
1673 || [istarget mn10200-*-*] } {
1674 set gc_sections_available_saved 0
1675 return 0
1676 }
1677
1678 # elf2flt uses -q (--emit-relocs), which is incompatible with
1679 # --gc-sections.
1680 if { [board_info target exists ldflags]
1681 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1682 set gc_sections_available_saved 0
1683 return 0
1684 }
1685
1686 # Check if the ld used by gcc supports --gc-sections.
1687 # FIXME: this test is useless since ld --help always says
1688 # --gc-sections is available
1689 set ld_output [remote_exec host $ld "--help"]
1690 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1691 set gc_sections_available_saved 1
1692 } else {
1693 set gc_sections_available_saved 0
1694 }
1695 }
1696 return $gc_sections_available_saved
1697 }
1698
1699 # Returns true if -shared is supported on the target
1700 # Only used and accurate for ELF targets at the moment
1701
1702 proc check_shared_lib_support { } {
1703 if {![istarget aarch64*-*-elf]
1704 && ![istarget arc-*-*]
1705 && ![istarget arm*-*-elf]
1706 && ![istarget avr-*-*]
1707 && ![istarget cr16-*-*]
1708 && ![istarget cris*-*-elf]
1709 && ![istarget crx-*-*]
1710 && ![istarget d10v-*-*]
1711 && ![istarget d30v-*-*]
1712 && ![istarget dlx-*-*]
1713 && ![istarget epiphany-*-*]
1714 && ![istarget fr30-*-*]
1715 && ![istarget frv-*-*]
1716 && ![istarget h8300-*-*]
1717 && ![istarget i860-*-*]
1718 && ![istarget i960-*-*]
1719 && ![istarget ip2k-*-*]
1720 && ![istarget iq2000-*-*]
1721 && ![istarget lm32-*-*]
1722 && ![istarget m32c-*-*]
1723 && ![istarget m32r-*-*]
1724 && ![istarget m6811-*-*]
1725 && ![istarget m6812-*-*]
1726 && ![istarget m68hc1*-*-*]
1727 && ![istarget mcore*-*-*]
1728 && ![istarget mep-*-*]
1729 && ![istarget microblaze-*-*]
1730 && ![istarget mips*-*-elf]
1731 && ![istarget mn10200-*-*]
1732 && ![istarget moxie-*-*]
1733 && ![istarget msp430-*-*]
1734 && ![istarget mt-*-*]
1735 && ![istarget nds32*-*-*]
1736 && ![istarget or1k*-*-*]
1737 && ![istarget pj-*-*]
1738 && ![istarget rl78-*-*]
1739 && ![istarget rx-*-*]
1740 && ![istarget spu-*-*]
1741 && ![istarget v850*-*-*]
1742 && ![istarget visium-*-*]
1743 && ![istarget xstormy16-*-*]
1744 && ![istarget *-*-irix*]
1745 && ![istarget *-*-rtems] } {
1746 return 1
1747 }
1748 return 0
1749 }
1750
1751 # Returns true if the target ld supports the plugin API.
1752 proc check_plugin_api_available { } {
1753 global plugin_api_available_saved
1754 global ld
1755 if {![info exists plugin_api_available_saved]} {
1756 # Check if the ld used by gcc supports --plugin.
1757 set ld_output [remote_exec host $ld "--help"]
1758 if { [ string first "-plugin PLUGIN" $ld_output ] >= 0 } {
1759 set plugin_api_available_saved 1
1760 } else {
1761 set plugin_api_available_saved 0
1762 }
1763 }
1764 return $plugin_api_available_saved
1765 }
1766
1767 # Sets ld_sysroot to the current sysroot (empty if not supported) and
1768 # returns true if the target ld supports sysroot.
1769 proc check_sysroot_available { } {
1770 global ld_sysroot_available_saved ld ld_sysroot
1771 if {![info exists ld_sysroot_available_saved]} {
1772 # Check if ld supports --sysroot *other* than empty.
1773 set ld_sysroot [string trimright [lindex [remote_exec host $ld "--print-sysroot"] 1]]
1774 if { $ld_sysroot == "" } {
1775 set ld_sysroot_available_saved 0
1776 } else {
1777 set ld_sysroot_available_saved 1
1778 }
1779 }
1780 return $ld_sysroot_available_saved
1781 }
1782
1783 # Returns true if the target compiler supports LTO
1784 proc check_lto_available { } {
1785 global lto_available_saved
1786 global CC
1787
1788 if {![info exists lto_available_saved]} {
1789 if { [which $CC] == 0 } {
1790 set lto_available_saved 0
1791 return 0
1792 }
1793 # Check if gcc supports -flto -fuse-linker-plugin
1794 set flags ""
1795 if [board_info [target_info name] exists cflags] {
1796 append flags " [board_info [target_info name] cflags]"
1797 }
1798 if [board_info [target_info name] exists ldflags] {
1799 append flags " [board_info [target_info name] ldflags]"
1800 }
1801
1802 set basename "tmpdir/lto[pid]"
1803 set src ${basename}.c
1804 set output ${basename}.out
1805 set f [open $src "w"]
1806 puts $f "int main() { return 0; }"
1807 close $f
1808 remote_download host $src
1809 set lto_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -fuse-linker-plugin $src -o $output"]
1810 remote_file host delete $src
1811 remote_file host delete $output
1812 file delete $src
1813 }
1814 return $lto_available_saved
1815 }
1816
1817 # Returns true if the target compiler supports LTO -ffat-lto-objects
1818 proc check_lto_fat_available { } {
1819 global lto_fat_available_saved
1820 global CC
1821
1822 if {![info exists lto_fat_available_saved]} {
1823 if { [which $CC] == 0 } {
1824 set lto_fat_available_saved 0
1825 return 0
1826 }
1827 # Check if gcc supports -flto -fuse-linker-plugin
1828 set flags ""
1829 if [board_info [target_info name] exists cflags] {
1830 append flags " [board_info [target_info name] cflags]"
1831 }
1832 if [board_info [target_info name] exists ldflags] {
1833 append flags " [board_info [target_info name] ldflags]"
1834 }
1835
1836 set basename "tmpdir/lto[pid]"
1837 set src ${basename}.c
1838 set output ${basename}.out
1839 set f [open $src "w"]
1840 puts $f "int main() { return 0; }"
1841 close $f
1842 remote_download host $src
1843 set lto_fat_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -ffat-lto-objects -fuse-linker-plugin $src -o $output"]
1844 remote_file host delete $src
1845 remote_file host delete $output
1846 file delete $src
1847 }
1848 return $lto_fat_available_saved
1849 }
1850
1851 # Returns true if the target compiler supports LTO and -shared
1852 proc check_lto_shared_available { } {
1853 global lto_shared_available_saved
1854 global CC
1855
1856 if {![info exists lto_shared_available_saved]} {
1857 if { [which $CC] == 0 } {
1858 set lto_shared_available_saved 0
1859 return 0
1860 }
1861 # Check if gcc supports -flto -fuse-linker-plugin -shared
1862 set flags ""
1863 if [board_info [target_info name] exists cflags] {
1864 append flags " [board_info [target_info name] cflags]"
1865 }
1866 if [board_info [target_info name] exists ldflags] {
1867 append flags " [board_info [target_info name] ldflags]"
1868 }
1869
1870 set basename "tmpdir/lto_shared[pid]"
1871 set src ${basename}.c
1872 set output ${basename}.so
1873 set f [open $src "w"]
1874 puts $f ""
1875 close $f
1876 remote_download host $src
1877 set lto_shared_available_saved [run_host_cmd_yesno "$CC" "$flags -shared -fPIC -flto -fuse-linker-plugin $src -o $output"]
1878 remote_file host delete $src
1879 remote_file host delete $output
1880 file delete $src
1881 }
1882 return $lto_shared_available_saved
1883 }
1884
1885 # Check if the assembler supports CFI statements.
1886
1887 proc check_as_cfi { } {
1888 global check_as_cfi_result
1889 global as
1890 if [info exists check_as_cfi_result] {
1891 return $check_as_cfi_result
1892 }
1893 set as_file "tmpdir/check_as_cfi.s"
1894 set as_fh [open $as_file w 0666]
1895 puts $as_fh "# Generated file. DO NOT EDIT"
1896 puts $as_fh "\t.cfi_startproc"
1897 puts $as_fh "\t.cfi_endproc"
1898 close $as_fh
1899 remote_download host $as_file
1900 verbose -log "Checking CFI support:"
1901 rename "perror" "check_as_cfi_perror"
1902 proc perror { args } { }
1903 set success [ld_assemble $as $as_file "/dev/null"]
1904 rename "perror" ""
1905 rename "check_as_cfi_perror" "perror"
1906 #remote_file host delete $as_file
1907 set check_as_cfi_result $success
1908 return $success
1909 }
1910
1911 # Returns true if IFUNC works.
1912
1913 proc check_ifunc_available { } {
1914 global ifunc_available_saved
1915 global CC
1916
1917 if {![info exists ifunc_available_saved]} {
1918 if { [which $CC] == 0 } {
1919 set ifunc_available_saved 0
1920 return 0
1921 }
1922 # Check if gcc supports -flto -fuse-linker-plugin
1923 set flags ""
1924 if [board_info [target_info name] exists cflags] {
1925 append flags " [board_info [target_info name] cflags]"
1926 }
1927 if [board_info [target_info name] exists ldflags] {
1928 append flags " [board_info [target_info name] ldflags]"
1929 }
1930
1931 set basename "tmpdir/ifunc[pid]"
1932 set src ${basename}.c
1933 set output ${basename}.out
1934 set f [open $src "w"]
1935 puts $f "extern int library_func2 (void);"
1936 puts $f "int main (void)"
1937 puts $f "{"
1938 puts $f " if (library_func2 () != 2) __builtin_abort ();"
1939 puts $f " return 0; "
1940 puts $f "}"
1941 puts $f "static int library_func1 (void) {return 2; }"
1942 puts $f "void *foo (void) __asm__ (\"library_func2\");"
1943 puts $f "void *foo (void) { return library_func1; }"
1944 puts $f "__asm__(\".type library_func2, %gnu_indirect_function\");"
1945 close $f
1946 remote_download host $src
1947 set ifunc_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
1948 if { $ifunc_available_saved == 1 } {
1949 set ifunc_available_saved [run_host_cmd_yesno "$output" ""]
1950 }
1951 remote_file host delete $src
1952 remote_file host delete $output
1953 file delete $src
1954 }
1955 return $ifunc_available_saved
1956 }
1957
1958 # Provide virtual target "cfi" for targets supporting CFI.
1959
1960 rename "istarget" "istarget_ld"
1961 proc istarget { target } {
1962 if {$target == "cfi"} {
1963 return [check_as_cfi]
1964 }
1965 return [istarget_ld $target]
1966 }
This page took 0.069459 seconds and 5 git commands to generate.