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