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