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