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