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