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