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