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