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