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