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