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