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