* plugin.h (plugin_active_plugins_p): New prototype.
[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
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"] {
5d3236ee 1154 verbose "regexp_diff match failure\n" 3
261def70
HPN
1155 send_log "regexp_diff match failure\n"
1156 send_log "regexp \"^$line_b$\"\nline \"$line_a\"\n"
1157 set differences 1
1158 }
1159 }
1160 }
1161
1162 if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
1163 send_log "$file_1 and $file_2 are different lengths\n"
1164 verbose "$file_1 and $file_2 are different lengths" 3
1165 set differences 1
1166 }
1167
bb6be443
JZ
1168 if { $fail_if_match } {
1169 if { $differences == 0 } {
1170 set differences 1
1171 } else {
1172 set differences 0
1173 }
1174 }
1175
261def70
HPN
1176 close $file_a
1177 close $file_b
1178
1179 return $differences
1180}
1181
1182proc file_contents { filename } {
1183 set file [open $filename r]
1184 set contents [read $file]
1185 close $file
1186 return $contents
1187}
bffbf940 1188
5d3236ee
DK
1189proc set_file_contents { filename contents } {
1190 set file [open $filename w]
1191 puts $file "$contents"
1192 close $file
1193}
1194
d8880531
L
1195# Create an archive using ar
1196#
fa0a16b1 1197proc ar_simple_create { ar aropts target objects } {
d8880531
L
1198 remote_file host delete $target
1199
fa0a16b1 1200 set exec_output [run_host_cmd "$ar" "$aropts rc $target $objects"]
d8880531
L
1201 set exec_output [prune_warnings $exec_output]
1202
1203 if [string match "" $exec_output] then {
1204 send_log "$exec_output\n"
1205 return 1
1206 } else {
1207 return 0
1208 }
1209}
1210
9147e853
JJ
1211# List contains test-items with 3 items followed by 2 lists, one item and
1212# one optional item:
fa0a16b1 1213# 0:name 1:ld/ar options 2:assembler options
bffbf940 1214# 3:filenames of assembler files 4: action and options. 5: name of output file
9147e853 1215# 6:compiler flags (optional)
3b6fe0cc 1216#
bffbf940
JJ
1217# Actions:
1218# objdump: Apply objdump options on result. Compare with regex (last arg).
1219# nm: Apply nm options on result. Compare with regex (last arg).
1220# readelf: Apply readelf options on result. Compare with regex (last arg).
5d3236ee
DK
1221# ld: Don't apply anything on result. Compare output during linking with
1222# regex (second arg). Note that this *must* be the first action if it
1223# is to be used at all; in all other cases, any output from the linker
1224# during linking is treated as a sign of an error and FAILs the test.
3b6fe0cc 1225#
bffbf940
JJ
1226proc run_ld_link_tests { ldtests } {
1227 global ld
1228 global as
1229 global nm
d8880531 1230 global ar
bffbf940
JJ
1231 global objdump
1232 global READELF
1233 global srcdir
1234 global subdir
1235 global env
9147e853
JJ
1236 global CC
1237 global CFLAGS
eca41774 1238 global runtests
5d3236ee 1239 global exec_output
bffbf940
JJ
1240
1241 foreach testitem $ldtests {
1242 set testname [lindex $testitem 0]
eca41774
DK
1243
1244 if ![runtest_file_p $runtests $testname] then {
1245 continue
1246 }
1247
bffbf940
JJ
1248 set ld_options [lindex $testitem 1]
1249 set as_options [lindex $testitem 2]
9147e853 1250 set src_files [lindex $testitem 3]
bffbf940
JJ
1251 set actions [lindex $testitem 4]
1252 set binfile tmpdir/[lindex $testitem 5]
9147e853 1253 set cflags [lindex $testitem 6]
bffbf940
JJ
1254 set objfiles {}
1255 set is_unresolved 0
1256 set failed 0
5d3236ee
DK
1257 set maybe_failed 0
1258 set ld_output ""
bffbf940
JJ
1259
1260# verbose -log "Testname is $testname"
1261# verbose -log "ld_options is $ld_options"
1262# verbose -log "as_options is $as_options"
9147e853 1263# verbose -log "src_files is $src_files"
bffbf940
JJ
1264# verbose -log "actions is $actions"
1265# verbose -log "binfile is $binfile"
1266
1267 # Assemble each file in the test.
9147e853
JJ
1268 foreach src_file $src_files {
1269 set objfile "tmpdir/[file rootname $src_file].o"
bffbf940
JJ
1270 lappend objfiles $objfile
1271
9147e853
JJ
1272 if { [file extension $src_file] == ".c" } {
1273 set as_file "tmpdir/[file rootname $src_file].s"
1274 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1275 set is_unresolved 1
1276 break
1277 }
1278 } else {
1279 set as_file "$srcdir/$subdir/$src_file"
1280 }
1281 if ![ld_assemble $as "$as_options $as_file" $objfile] {
bffbf940
JJ
1282 set is_unresolved 1
1283 break
1284 }
1285 }
1286
1287 # Catch assembler errors.
1288 if { $is_unresolved != 0 } {
1289 unresolved $testname
1290 continue
1291 }
1292
a7470592 1293 if { [regexp ".*\\.a$" $binfile] } {
fa0a16b1 1294 if { ![ar_simple_create $ar $ld_options $binfile "$objfiles"] } {
d8880531
L
1295 fail $testname
1296 set failed 1
1297 } else {
1298 set failed 0
1299 }
fa0a16b1 1300 } elseif { ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] } {
5d3236ee
DK
1301 set maybe_failed 1
1302 set ld_output "$exec_output"
bffbf940
JJ
1303 } else {
1304 set failed 0
d8880531
L
1305 }
1306
1307 if { $failed == 0 } {
bffbf940
JJ
1308 foreach actionlist $actions {
1309 set action [lindex $actionlist 0]
1310 set progopts [lindex $actionlist 1]
1311
1312 # There are actions where we run regexp_diff on the
1313 # output, and there are other actions (presumably).
1314 # Handling of the former look the same.
1315 set dump_prog ""
1316 switch -- $action {
1317 objdump
1318 { set dump_prog $objdump }
1319 nm
1320 { set dump_prog $nm }
1321 readelf
1322 { set dump_prog $READELF }
5d3236ee
DK
1323 ld
1324 { set dump_prog "ld" }
bffbf940
JJ
1325 default
1326 {
1327 perror "Unrecognized action $action"
1328 set is_unresolved 1
1329 break
1330 }
1331 }
1332
5d3236ee
DK
1333 if { $action == "ld" } {
1334 set dumpfile [lindex $actionlist 1]
1335 verbose "dumpfile is $dumpfile"
1336 set_file_contents "tmpdir/ld.messages" "$ld_output"
1337 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
1338 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$dumpfile"] } then {
1339 verbose "output is $ld_output" 2
1340 set failed 1
1341 break
1342 }
1343 set maybe_failed 0
1344 } elseif { $maybe_failed != 0 } {
1345 set failed 1
1346 break
1347 } elseif { $dump_prog != "" } {
bffbf940
JJ
1348 set dumpfile [lindex $actionlist 2]
1349 set binary $dump_prog
1350
1351 # Ensure consistent sorting of symbols
1352 if {[info exists env(LC_ALL)]} {
1353 set old_lc_all $env(LC_ALL)
1354 }
1355 set env(LC_ALL) "C"
7f6a71ff
JM
1356 set cmd "$binary $progopts $binfile"
1357 set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
bffbf940 1358 send_log "$cmd\n"
7f6a71ff
JM
1359 remote_upload host "ld.stderr"
1360 set comp_output [prune_warnings [file_contents "ld.stderr"]]
1361 remote_file host delete "ld.stderr"
1362 remote_file build delete "ld.stderr"
1363
bffbf940
JJ
1364 if {[info exists old_lc_all]} {
1365 set env(LC_ALL) $old_lc_all
1366 } else {
1367 unset env(LC_ALL)
1368 }
bffbf940
JJ
1369
1370 if ![string match "" $comp_output] then {
1371 send_log "$comp_output\n"
1372 set failed 1
1373 break
1374 }
1375
7f6a71ff
JM
1376 remote_upload host "dump.out"
1377
bffbf940
JJ
1378 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1379 verbose "output is [file_contents "dump.out"]" 2
1380 set failed 1
7f6a71ff
JM
1381 remote_file build delete "dump.out"
1382 remote_file host delete "dump.out"
bffbf940
JJ
1383 break
1384 }
7f6a71ff
JM
1385 remote_file build delete "dump.out"
1386 remote_file host delete "dump.out"
bffbf940
JJ
1387 }
1388 }
1389
1390 if { $failed != 0 } {
1391 fail $testname
1392 } else { if { $is_unresolved == 0 } {
1393 pass $testname
1394 } }
1395 }
1396
1397 # Catch action errors.
1398 if { $is_unresolved != 0 } {
1399 unresolved $testname
1400 continue
1401 }
1402 }
1403}
1404
252b5132
RH
1405# This definition is taken from an unreleased version of DejaGnu. Once
1406# that version gets released, and has been out in the world for a few
1407# months at least, it may be safe to delete this copy.
1408if ![string length [info proc prune_warnings]] {
1409 #
1410 # prune_warnings -- delete various system verbosities from TEXT
1411 #
1412 # An example is:
1413 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1414 #
1415 # Sites with particular verbose os's may wish to override this in site.exp.
1416 #
1417 proc prune_warnings { text } {
1418 # This is from sun4's. Do it for all machines for now.
1419 # The "\\1" is to try to preserve a "\n" but only if necessary.
1420 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1421
1422 # It might be tempting to get carried away and delete blank lines, etc.
1423 # Just delete *exactly* what we're ask to, and that's it.
1424 return $text
1425 }
1426}
24edc24d 1427
c8c140d9
BE
1428# targets_to_xfail is a list of target triplets to be xfailed.
1429# ldtests contains test-items with 3 items followed by 1 lists, 2 items
fab4a87f 1430# and 3 optional items:
c8c140d9
BE
1431# 0:name
1432# 1:ld options
1433# 2:assembler options
55255dae 1434# 3:filenames of source files
c8c140d9
BE
1435# 4:name of output file
1436# 5:expected output
1437# 6:compiler flags (optional)
55255dae 1438# 7:language (optional)
fab4a87f 1439# 8:linker warning (optional)
c8c140d9
BE
1440
1441proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
24edc24d
L
1442 global ld
1443 global as
1444 global srcdir
1445 global subdir
1446 global env
1447 global CC
55255dae 1448 global CXX
24edc24d 1449 global CFLAGS
58ffc3bd 1450 global CXXFLAGS
22ec3bd1 1451 global errcnt
fab4a87f 1452 global exec_output
24edc24d
L
1453
1454 foreach testitem $ldtests {
c8c140d9
BE
1455 foreach target $targets_to_xfail {
1456 setup_xfail $target
1457 }
24edc24d
L
1458 set testname [lindex $testitem 0]
1459 set ld_options [lindex $testitem 1]
1460 set as_options [lindex $testitem 2]
1461 set src_files [lindex $testitem 3]
1462 set binfile tmpdir/[lindex $testitem 4]
1463 set expfile [lindex $testitem 5]
1464 set cflags [lindex $testitem 6]
55255dae 1465 set lang [lindex $testitem 7]
fab4a87f 1466 set warning [lindex $testitem 8]
24edc24d 1467 set objfiles {}
24edc24d
L
1468 set failed 0
1469
1470# verbose -log "Testname is $testname"
1471# verbose -log "ld_options is $ld_options"
1472# verbose -log "as_options is $as_options"
1473# verbose -log "src_files is $src_files"
1474# verbose -log "actions is $actions"
1475# verbose -log "binfile is $binfile"
1476
1477 # Assemble each file in the test.
1478 foreach src_file $src_files {
1479 set objfile "tmpdir/[file rootname $src_file].o"
1480 lappend objfiles $objfile
1481
a10e6b21
L
1482 # We ignore warnings since some compilers may generate
1483 # incorrect section attributes and the assembler will warn
1484 # them.
58ffc3bd
MF
1485 if { [ string match "c++" $lang ] } {
1486 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1487 } else {
1488 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1489 }
a10e6b21
L
1490
1491 # We have to use $CC to build PIE and shared library.
55255dae
L
1492 if { [ string match "c" $lang ] } {
1493 set link_proc ld_simple_link
1494 set link_cmd $CC
1495 } elseif { [ string match "c++" $lang ] } {
1496 set link_proc ld_simple_link
1497 set link_cmd $CXX
1498 } elseif { [ string match "-shared" $ld_options ] \
a10e6b21
L
1499 || [ string match "-pie" $ld_options ] } {
1500 set link_proc ld_simple_link
1501 set link_cmd $CC
1502 } else {
1503 set link_proc ld_link
1504 set link_cmd $ld
1505 }
24edc24d 1506
a10e6b21 1507 if ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
24edc24d
L
1508 set failed 1
1509 } else {
a10e6b21 1510 set failed 0
fab4a87f
L
1511 }
1512
1513 # Check if exec_output is expected.
1514 if { $warning != "" } then {
1515 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1516 if { [regexp $warning $exec_output] } then {
1517 set failed 0
1518 } else {
1519 set failed 1
1520 }
1521 }
1522
1523 if { $failed == 0 } {
a10e6b21
L
1524 send_log "Running: $binfile > $binfile.out\n"
1525 verbose "Running: $binfile > $binfile.out"
1526 catch "exec $binfile > $binfile.out" exec_output
1527
24edc24d
L
1528 if ![string match "" $exec_output] then {
1529 send_log "$exec_output\n"
1530 verbose "$exec_output" 1
1531 set failed 1
a10e6b21
L
1532 } else {
1533 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1534 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1535 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1536 set exec_output [prune_warnings $exec_output]
1537
1538 if ![string match "" $exec_output] then {
1539 send_log "$exec_output\n"
1540 verbose "$exec_output" 1
1541 set failed 1
1542 }
24edc24d
L
1543 }
1544 }
1545
1546 if { $failed != 0 } {
1547 fail $testname
22ec3bd1
L
1548 } else {
1549 set errcnt 0
24edc24d 1550 pass $testname
a10e6b21 1551 }
24edc24d 1552 }
24edc24d
L
1553 }
1554}
d2dee3b2
L
1555
1556# List contains test-items with 3 items followed by 2 lists, one item and
1557# one optional item:
55255dae 1558# 0:name
fa0a16b1 1559# 1:ld or ar options
55255dae
L
1560# 2:compile options
1561# 3:filenames of source files
1562# 4:action and options.
1563# 5:name of output file
1564# 6:language (optional)
d2dee3b2
L
1565#
1566# Actions:
1567# objdump: Apply objdump options on result. Compare with regex (last arg).
1568# nm: Apply nm options on result. Compare with regex (last arg).
1569# readelf: Apply readelf options on result. Compare with regex (last arg).
1570#
1571proc run_cc_link_tests { ldtests } {
1572 global nm
1573 global objdump
1574 global READELF
1575 global srcdir
1576 global subdir
1577 global env
1578 global CC
55255dae 1579 global CXX
d2dee3b2 1580 global CFLAGS
58ffc3bd 1581 global CXXFLAGS
d8880531 1582 global ar
d2dee3b2
L
1583
1584 foreach testitem $ldtests {
1585 set testname [lindex $testitem 0]
1586 set ldflags [lindex $testitem 1]
1587 set cflags [lindex $testitem 2]
1588 set src_files [lindex $testitem 3]
1589 set actions [lindex $testitem 4]
1590 set binfile tmpdir/[lindex $testitem 5]
55255dae 1591 set lang [lindex $testitem 6]
d2dee3b2
L
1592 set objfiles {}
1593 set is_unresolved 0
1594 set failed 0
1595
1596 # Compile each file in the test.
1597 foreach src_file $src_files {
1598 set objfile "tmpdir/[file rootname $src_file].o"
1599 lappend objfiles $objfile
1600
1601 # We ignore warnings since some compilers may generate
1602 # incorrect section attributes and the assembler will warn
1603 # them.
58ffc3bd
MF
1604 if { [ string match "c++" $lang ] } {
1605 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1606 } else {
1607 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1608 }
d2dee3b2
L
1609 }
1610
1611 # Clear error and warning counts.
1612 reset_vars
1613
55255dae
L
1614 if { [ string match "c++" $lang ] } {
1615 set cc_cmd $CXX
1616 } else {
1617 set cc_cmd $CC
1618 }
1619
a7470592 1620 if { [regexp ".*\\.a$" $binfile] } {
fa0a16b1 1621 if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
d8880531
L
1622 fail $testname
1623 set failed 1
1624 } else {
1625 set failed 0
1626 }
fa0a16b1 1627 } elseif { ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] } {
d2dee3b2 1628 fail $testname
d8880531 1629 set failed 1
d2dee3b2
L
1630 } else {
1631 set failed 0
d8880531
L
1632 }
1633
1634 if { $failed == 0 } {
d2dee3b2
L
1635 foreach actionlist $actions {
1636 set action [lindex $actionlist 0]
1637 set progopts [lindex $actionlist 1]
1638
1639 # There are actions where we run regexp_diff on the
1640 # output, and there are other actions (presumably).
1641 # Handling of the former look the same.
1642 set dump_prog ""
1643 switch -- $action {
1644 objdump
1645 { set dump_prog $objdump }
1646 nm
1647 { set dump_prog $nm }
1648 readelf
1649 { set dump_prog $READELF }
1650 default
1651 {
1652 perror "Unrecognized action $action"
1653 set is_unresolved 1
1654 break
1655 }
1656 }
1657
1658 if { $dump_prog != "" } {
1659 set dumpfile [lindex $actionlist 2]
1660 set binary $dump_prog
1661
1662 # Ensure consistent sorting of symbols
1663 if {[info exists env(LC_ALL)]} {
1664 set old_lc_all $env(LC_ALL)
1665 }
1666 set env(LC_ALL) "C"
1667 set cmd "$binary $progopts $binfile > dump.out"
1668 send_log "$cmd\n"
1669 catch "exec $cmd" comp_output
1670 if {[info exists old_lc_all]} {
1671 set env(LC_ALL) $old_lc_all
1672 } else {
1673 unset env(LC_ALL)
1674 }
1675 set comp_output [prune_warnings $comp_output]
1676
1677 if ![string match "" $comp_output] then {
1678 send_log "$comp_output\n"
1679 set failed 1
1680 break
1681 }
1682
1683 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1684 verbose "output is [file_contents "dump.out"]" 2
1685 set failed 1
1686 break
1687 }
1688 }
1689 }
1690
1691 if { $failed != 0 } {
1692 fail $testname
1693 } else { if { $is_unresolved == 0 } {
1694 pass $testname
1695 } }
1696 }
1697
1698 # Catch action errors.
1699 if { $is_unresolved != 0 } {
1700 unresolved $testname
1701 continue
1702 }
1703 }
1704}
430a16a5
NC
1705
1706# Returns true if --gc-sections is supported on the target.
1707
1708proc check_gc_sections_available { } {
1709 global gc_sections_available_saved
1710 global ld
1711
1712 if {![info exists gc_sections_available_saved]} {
1713 # Some targets don't support gc-sections despite whatever's
1714 # advertised by ld's options.
de5c4ae2
AM
1715 if {[istarget arc-*-*]
1716 || [istarget d30v-*-*]
1717 || [istarget dlx-*-*]
1718 || [istarget i960-*-*]
1719 || [istarget or32-*-*]
1720 || [istarget pj*-*-*]
1721 || [istarget alpha-*-*]
1722 || [istarget hppa64-*-*]
1723 || [istarget i370-*-*]
1724 || [istarget i860-*-*]
5a7c5e86 1725 || [istarget ia64-*-*]
de5c4ae2
AM
1726 || [istarget mep-*-*]
1727 || [istarget mn10200-*-*]
b1435da1 1728 || [istarget *-*-cygwin]
5a7c5e86 1729 || [istarget *-*-mingw*] } {
430a16a5
NC
1730 set gc_sections_available_saved 0
1731 return 0
1732 }
1733
1734 # elf2flt uses -q (--emit-relocs), which is incompatible with
1735 # --gc-sections.
1736 if { [board_info target exists ldflags]
1737 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1738 set gc_sections_available_saved 0
1739 return 0
1740 }
1741
430a16a5
NC
1742 # Check if the ld used by gcc supports --gc-sections.
1743 set ld_output [remote_exec host $ld "--help"]
1744 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1745 set gc_sections_available_saved 1
1746 } else {
1747 set gc_sections_available_saved 0
1748 }
1749 }
1750 return $gc_sections_available_saved
1751}
33aa234e 1752
5d3236ee
DK
1753# Returns true if the target ld supports the plugin API.
1754proc check_plugin_api_available { } {
1755 global plugin_api_available_saved
1756 global ld
1757 if {![info exists plugin_api_available_saved]} {
1758 # Check if the ld used by gcc supports --plugin.
1759 set ld_output [remote_exec host $ld "--help"]
1760 if { [ string first "-plugin" $ld_output ] >= 0 } {
1761 set plugin_api_available_saved 1
1762 } else {
1763 set plugin_api_available_saved 0
1764 }
1765 }
1766 return $plugin_api_available_saved
1767}
1768
33aa234e
JK
1769# Check if the assembler supports CFI statements.
1770
1771proc check_as_cfi { } {
1772 global check_as_cfi_result
1773 global as
1774 if [info exists check_as_cfi_result] {
1775 return $check_as_cfi_result
1776 }
1777 set as_file "tmpdir/check_as_cfi.s"
1778 set as_fh [open $as_file w 0666]
1779 puts $as_fh "# Generated file. DO NOT EDIT"
1780 puts $as_fh "\t.cfi_startproc"
1781 puts $as_fh "\t.cfi_endproc"
1782 close $as_fh
1783 remote_download host $as_file
1784 verbose -log "Checking CFI support:"
1785 rename "perror" "check_as_cfi_perror"
1786 proc perror { args } { }
1787 set success [ld_assemble $as $as_file "/dev/null"]
1788 rename "perror" ""
1789 rename "check_as_cfi_perror" "perror"
1790 #remote_file host delete $as_file
1791 set check_as_cfi_result $success
1792 return $success
1793}
1794
1795# Provide virtual target "cfi" for targets supporting CFI.
1796
1797rename "istarget" "istarget_ld"
1798proc istarget { target } {
1799 if {$target == "cfi"} {
1800 return [check_as_cfi]
1801 }
1802 return [istarget_ld $target]
1803}
This page took 0.878404 seconds and 4 git commands to generate.