Automatic date update in version.in
[deliverable/binutils-gdb.git] / ld / testsuite / lib / ld-lib.exp
CommitLineData
a2b64bed 1# Support routines for LD testsuite.
2571583a 2# Copyright (C) 1994-2017 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 } {
68bce020 32 global CC
5a68afcf 33
fb35d3d8
DD
34 if {![info exists CC]} {
35 set CC [find_gcc]
36 }
37 if { $CC == "" } {
8be1e369 38 return 0
fb35d3d8
DD
39 }
40 set state [remote_exec host $CC --version]
8be1e369
AM
41 if { [lindex $state 0] != 0 } {
42 return 0;
43 }
fb35d3d8
DD
44 set tmp "[lindex $state 1]\n"
45 # Look for (eg) 4.6.1 in the version output.
8b5b2228
MR
46 set ver_re "\[^\\.0-9\]+(\[1-9\]\[0-9\]*)\\.(\[0-9\]+)(?:\\.\[0-9\]+)?"
47 regexp $ver_re $tmp fred maj min
fb35d3d8 48 verbose "gcc version: $tmp"
8b5b2228
MR
49 if { ![info exists maj] || ![info exists min] } then {
50 perror "can't decipher gcc version number, fix the framework!"
51 return 0
52 }
fb35d3d8
DD
53 verbose "major gcc version is $maj, want at least $major"
54 if { $maj == $major } then {
55 verbose "minor gcc version is $min, want at least $minor"
8b5b2228 56 return [expr $min >= $minor]
fb35d3d8 57 } else {
8b5b2228 58 return [expr $maj > $major]
fb35d3d8
DD
59 }
60}
61
3b6fe0cc 62# Extract and print the version number of ld.
252b5132
RH
63#
64proc default_ld_version { ld } {
65 global host_triplet
66
7f6a71ff 67 if { ![is_remote host] && [which $ld] == 0 } then {
252b5132
RH
68 perror "$ld does not exist"
69 exit 1
70 }
3e8cba19 71
7f6a71ff
JM
72 remote_exec host "$ld --version" "" "/dev/null" "ld.version"
73 remote_upload host "ld.version"
74 set tmp [prune_warnings [file_contents "ld.version"]]
75 remote_file build delete "ld.version"
76 remote_file host delete "ld.version"
77
252b5132
RH
78 regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number
79 if [info exists number] then {
80 clone_output "$ld $number\n"
81 }
82}
83
7f6a71ff
JM
84proc run_host_cmd { prog command } {
85 global link_output
f1d7f4a6
AM
86 global gcc_B_opt
87 global ld_L_opt
3e8cba19 88
7f6a71ff
JM
89 if { ![is_remote host] && [which "$prog"] == 0 } then {
90 perror "$prog does not exist"
252b5132
RH
91 return 0
92 }
3e8cba19 93
f1d7f4a6
AM
94 # If we are compiling with gcc, we want to add gcc_B_opt and
95 # ld_L_opt to flags. However, if $prog already has -B options,
96 # which might be the case when running gcc out of a build
97 # directory, we want our -B options to come first.
98 set gccexe $prog
99 set gccparm [string first " " $gccexe]
100 set gccflags ""
101 if { $gccparm > 0 } then {
102 set gccflags [string range $gccexe $gccparm end]
103 set gccexe [string range $gccexe 0 $gccparm]
104 set prog $gccexe
105 }
106 set gccexe [string replace $gccexe 0 [string last "/" $gccexe] ""]
107 if {[string match "*cc*" $gccexe] || [string match "*++*" $gccexe]} then {
108 set gccflags "$gcc_B_opt $gccflags $ld_L_opt"
109 }
110
111 verbose -log "$prog $gccflags $command"
112 set status [remote_exec host [concat sh -c [list "$prog $gccflags $command 2>&1"]] "" "/dev/null" "ld.tmp"]
7f6a71ff
JM
113 remote_upload host "ld.tmp"
114 set link_output [file_contents "ld.tmp"]
115 regsub "\n$" $link_output "" link_output
116 if { [lindex $status 0] != 0 && [string match "" $link_output] } then {
117 append link_output "child process exited abnormally"
118 }
119 remote_file build delete ld.tmp
120 remote_file host delete ld.tmp
fab4a87f 121
7f6a71ff
JM
122 if [string match "" $link_output] then {
123 return ""
124 }
3e8cba19 125
7f6a71ff
JM
126 verbose -log "$link_output"
127 return "$link_output"
128}
129
130proc run_host_cmd_yesno { prog command } {
131 global exec_output
d76b6207 132 global errcnt warncnt
7f6a71ff
JM
133
134 set exec_output [prune_warnings [run_host_cmd "$prog" "$command"]]
d76b6207
L
135 # Ignore error and warning.
136 set errcnt 0
137 set warncnt 0
252b5132 138 if [string match "" $exec_output] then {
7f6a71ff 139 return 1;
252b5132 140 }
7f6a71ff
JM
141 return 0;
142}
143
144# Link an object using relocation.
145#
146proc default_ld_relocate { ld target objects } {
147 global HOSTING_EMU
148
149 remote_file host delete $target
150 return [run_host_cmd_yesno "$ld" "$HOSTING_EMU -o $target -r $objects"]
252b5132
RH
151}
152
1688b748 153# Check to see if ld is being invoked with a non-endian output format
3b6fe0cc 154#
1688b748
MH
155proc is_endian_output_format { object_flags } {
156
157 if {[string match "*-oformat binary*" $object_flags] || \
158 [string match "*-oformat ieee*" $object_flags] || \
159 [string match "*-oformat ihex*" $object_flags] || \
160 [string match "*-oformat netbsd-core*" $object_flags] || \
161 [string match "*-oformat srec*" $object_flags] || \
162 [string match "*-oformat tekhex*" $object_flags] || \
163 [string match "*-oformat trad-core*" $object_flags] } then {
164 return 0
165 } else {
166 return 1
167 }
168}
169
38e31547
NC
170# Look for big-endian or little-endian switches in the multlib
171# options and translate these into a -EB or -EL switch. Note
172# we cannot rely upon proc process_multilib_options to do this
173# for us because for some targets the compiler does not support
174# -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
175# the site.exp file will include the switch "-mbig-endian"
176# (rather than "big-endian") which is not detected by proc
177# process_multilib_options.
3b6fe0cc 178#
38e31547 179proc big_or_little_endian {} {
3e8cba19 180
38e31547 181 if [board_info [target_info name] exists multilib_flags] {
b24f926d 182 set tmp_flags " [board_info [target_info name] multilib_flags]"
38e31547
NC
183
184 foreach x $tmp_flags {
185 case $x in {
906156c4 186 {*big*endian eb EB -eb -EB -mb -meb} {
38e31547
NC
187 set flags " -EB"
188 return $flags
189 }
906156c4 190 {*little*endian el EL -el -EL -ml -mel} {
38e31547
NC
191 set flags " -EL"
192 return $flags
193 }
194 }
195 }
196 }
197
198 set flags ""
199 return $flags
200}
252b5132 201
d9816402 202# Link a program using ld
252b5132
RH
203#
204proc default_ld_link { ld target objects } {
252b5132 205 global host_triplet
fab4a87f 206 global exec_output
7cda33a1 207
f1d7f4a6 208 set flags ""
1688b748
MH
209 if [is_endian_output_format $objects] then {
210 set flags [big_or_little_endian]
b765d4e3
L
211 }
212
7f6a71ff 213 remote_file host delete $target
f1d7f4a6 214 set exec_output [run_host_cmd "$ld" "$flags -o $target $objects"]
7f6a71ff 215 set exec_output [prune_warnings $exec_output]
252b5132
RH
216
217 # We don't care if we get a warning about a non-existent start
218 # symbol, since the default linker script might use ENTRY.
219 regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
220
f1d7f4a6 221 return [string match "" $exec_output]
252b5132
RH
222}
223
3b6fe0cc 224# Compile an object using cc.
252b5132
RH
225#
226proc default_ld_compile { cc source object } {
227 global CFLAGS
58ffc3bd 228 global CXXFLAGS
252b5132
RH
229 global srcdir
230 global subdir
231 global host_triplet
f1d7f4a6 232 global gcc_B_opt
252b5132
RH
233
234 set cc_prog $cc
235 if {[llength $cc_prog] > 1} then {
236 set cc_prog [lindex $cc_prog 0]
237 }
7f6a71ff 238 if {![is_remote host] && [which $cc_prog] == 0} then {
252b5132
RH
239 perror "$cc_prog does not exist"
240 return 0
241 }
242
7f6a71ff
JM
243 remote_file build delete "$object"
244 remote_file host delete "$object"
252b5132 245
f1d7f4a6 246 set flags "$gcc_B_opt -I$srcdir/$subdir"
252b5132 247
f1d7f4a6
AM
248 # If we are compiling with gcc, we want to add gcc_B_opt to flags.
249 # However, if $prog already has -B options, which might be the
250 # case when running gcc out of a build directory, we want our -B
251 # options to come first.
b0fe1bf3
AM
252 set ccexe $cc
253 set ccparm [string first " " $cc]
dec20c9e 254 set ccflags ""
b0fe1bf3 255 if { $ccparm > 0 } then {
dec20c9e 256 set ccflags [string range $cc $ccparm end]
b0fe1bf3 257 set ccexe [string range $cc 0 $ccparm]
dec20c9e 258 set cc $ccexe
b0fe1bf3 259 }
252b5132 260
f1d7f4a6 261 set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""]
58ffc3bd 262 if {[string match "*++*" $ccexe]} {
f1d7f4a6 263 append flags " $CXXFLAGS"
58ffc3bd 264 } else {
f1d7f4a6 265 append flags " $CFLAGS"
58ffc3bd
MF
266 }
267
3046b3d3
VP
268 if [board_info [target_info name] exists cflags] {
269 append flags " [board_info [target_info name] cflags]"
270 }
271
38e31547 272 if [board_info [target_info name] exists multilib_flags] {
b24f926d 273 append flags " [board_info [target_info name] multilib_flags]"
38e31547
NC
274 }
275
f1d7f4a6
AM
276 set cmd "$cc $flags $ccflags -c $source -o $object"
277 verbose -log "$cmd"
252b5132 278
f1d7f4a6 279 set status [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
7f6a71ff
JM
280 remote_upload host "ld.tmp"
281 set exec_output [file_contents "ld.tmp"]
282 remote_file build delete "ld.tmp"
283 remote_file host delete "ld.tmp"
252b5132 284 set exec_output [prune_warnings $exec_output]
6f9dbcd4
AM
285 # Versions of gcc up to and including pre-release gcc-7, at least on
286 # some targets, generate .section directives with incorrect type.
287 # Ignore warnings from the assembler about this.
288 regsub -all "(^|\n)\[^\n\]*: ignoring incorrect section type \[^\n\]*" $exec_output "" exec_output
289 regsub -all "^\[^\n\]*: Assembler messages:\n" $exec_output "" exec_output
252b5132
RH
290 if [string match "" $exec_output] then {
291 if {![file exists $object]} then {
292 regexp ".*/(\[^/\]*)$" $source all dobj
293 regsub "\\.c" $dobj ".o" realobj
294 verbose "looking for $realobj"
7f6a71ff 295 if {[remote_file host exists $realobj]} then {
252b5132 296 verbose -log "mv $realobj $object"
7f6a71ff 297 remote_upload "$realobj" "$object"
252b5132
RH
298 } else {
299 perror "$object not found after compilation"
300 return 0
301 }
302 }
303 return 1
304 } else {
305 verbose -log "$exec_output"
306 perror "$source: compilation failed"
307 return 0
308 }
309}
310
3b6fe0cc 311# Assemble a file.
252b5132 312#
de1491f0 313proc default_ld_assemble { as in_flags source object } {
252b5132
RH
314 global ASFLAGS
315 global host_triplet
690f47bf
RS
316 global srcdir
317 global subdir
3e8cba19 318
252b5132
RH
319 if ![info exists ASFLAGS] { set ASFLAGS "" }
320
690f47bf 321 set flags "[big_or_little_endian] -I$srcdir/$subdir"
de1491f0 322 set exec_output [run_host_cmd "$as" "$flags $in_flags $ASFLAGS -o $object $source"]
252b5132
RH
323 set exec_output [prune_warnings $exec_output]
324 if [string match "" $exec_output] then {
325 return 1
326 } else {
252b5132
RH
327 perror "$source: assembly failed"
328 return 0
329 }
330}
331
3b6fe0cc 332# Run nm on a file, putting the result in the array nm_output.
252b5132 333#
992c450d 334proc default_ld_nm { nm nmflags object } {
252b5132
RH
335 global NMFLAGS
336 global nm_output
337 global host_triplet
338
77e0b0ef
ILT
339 if {[info exists nm_output]} {
340 unset nm_output
341 }
342
252b5132
RH
343 if ![info exists NMFLAGS] { set NMFLAGS "" }
344
3e8cba19
AM
345 # Ensure consistent sorting of symbols
346 if {[info exists env(LC_ALL)]} {
347 set old_lc_all $env(LC_ALL)
348 }
349 set env(LC_ALL) "C"
7f6a71ff 350
992c450d 351 verbose -log "$nm $NMFLAGS $nmflags $object >tmpdir/nm.out"
252b5132 352
7f6a71ff 353 set status [remote_exec host [concat sh -c [list "$nm $NMFLAGS $nmflags $object 2>ld.stderr"]] "" "/dev/null" "tmpdir/nm.out"]
3e8cba19
AM
354 if {[info exists old_lc_all]} {
355 set env(LC_ALL) $old_lc_all
356 } else {
357 unset env(LC_ALL)
358 }
7f6a71ff
JM
359 remote_upload host "ld.stderr"
360 remote_upload host "tmpdir/nm.out" "tmpdir/nm.out"
361 set exec_output [prune_warnings [file_contents "ld.stderr"]]
362 remote_file host delete "ld.stderr"
363 remote_file build delete "ld.stderr"
252b5132
RH
364 if [string match "" $exec_output] then {
365 set file [open tmpdir/nm.out r]
366 while { [gets $file line] != -1 } {
367 verbose "$line" 2
dbc37f89 368 if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] \\.*(.+)$" $line whole value name] {
252b5132
RH
369 set name [string trimleft $name "_"]
370 verbose "Setting nm_output($name) to 0x$value" 2
371 set nm_output($name) 0x$value
372 }
373 }
374 close $file
375 return 1
376 } else {
377 verbose -log "$exec_output"
378 perror "$object: nm failed"
379 return 0
380 }
381}
382
1b662205
AM
383# Define various symbols needed when not linking against all
384# target libs.
d9816402 385proc ld_link_defsyms {} {
1b662205
AM
386
387 set flags "--defsym __stack_chk_fail=0"
388
389 # ARM targets call __gccmain
8c5fc800 390 if {[istarget arm*-*-*]} {
1b662205
AM
391 append flags " --defsym __gccmain=0"
392 }
393
5a1431e6 394 # Windows targets need __main, some prefixed with underscore.
36fe835f 395 if {[istarget *-*-cygwin* ] || [istarget *-*-mingw*]} {
5a1431e6 396 append flags " --defsym __main=0 --defsym ___main=0"
36fe835f
DK
397 }
398
1b662205
AM
399 # PowerPC EABI code calls __eabi.
400 if {[istarget powerpc*-*-eabi*] || [istarget powerpc*-*-rtems*]} {
401 append flags " --defsym __eabi=0"
402 }
403
404 # mn10200 code calls __truncsipsi2_d0_d2.
405 if {[istarget mn10200*-*-*]} then {
406 append flags " --defsym __truncsipsi2_d0_d2=0"
407 }
408
409 # m6811/m6812 code has references to soft registers.
32d79e68 410 if {[istarget m6811-*-*] || [istarget m6812-*-*] || [istarget m68hc1*-*-*]} {
1b662205
AM
411 append flags " --defsym _.frame=0 --defsym _.d1=0 --defsym _.d2=0"
412 append flags " --defsym _.d3=0 --defsym _.d4=0"
413 append flags " --defsym _.tmp=0 --defsym _.xy=0 --defsym _.z=0"
414 }
415
416 # Some OpenBSD targets have ProPolice and reference __guard and
417 # __stack_smash_handler.
418 if [istarget *-*-openbsd*] {
419 append flags " --defsym __guard=0"
420 append flags " --defsym __stack_smash_handler=0"
421 }
422
423 return $flags
424}
425
ef2b5578 426# run_dump_test FILE (optional:) EXTRA_OPTIONS
261def70
HPN
427# Copied from gas testsuite, tweaked and further extended.
428#
429# Assemble a .s file, then run some utility on it and check the output.
3e8cba19 430#
261def70
HPN
431# There should be an assembly language file named FILE.s in the test
432# suite directory, and a pattern file called FILE.d. `run_dump_test'
433# will assemble FILE.s, run some tool like `objdump', `objcopy', or
434# `nm' on the .o file to produce textual output, and then analyze that
435# with regexps. The FILE.d file specifies what program to run, and
436# what to expect in its output.
437#
438# The FILE.d file begins with zero or more option lines, which specify
439# flags to pass to the assembler, the program to run to dump the
440# assembler's output, and the options it wants. The option lines have
441# the syntax:
3e8cba19 442#
261def70 443# # OPTION: VALUE
3e8cba19 444#
261def70
HPN
445# OPTION is the name of some option, like "name" or "objdump", and
446# VALUE is OPTION's value. The valid options are described below.
447# Whitespace is ignored everywhere, except within VALUE. The option
448# list ends with the first line that doesn't match the above syntax
449# (hmm, not great for error detection).
450#
ef2b5578
MR
451# The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of
452# two-element lists. The first element of each is an option name, and
453# the second additional arguments to be added on to the end of the
454# option list as given in FILE.d. (If omitted, no additional options
455# are added.)
456#
261def70 457# The interesting options are:
3e8cba19 458#
261def70
HPN
459# name: TEST-NAME
460# The name of this test, passed to DejaGNU's `pass' and `fail'
461# commands. If omitted, this defaults to FILE, the root of the
462# .s and .d files' names.
3e8cba19 463#
261def70
HPN
464# as: FLAGS
465# When assembling, pass FLAGS to the assembler.
466# If assembling several files, you can pass different assembler
467# options in the "source" directives. See below.
468#
469# ld: FLAGS
470# Link assembled files using FLAGS, in the order of the "source"
471# directives, when using multiple files.
472#
d6e0b160
HPN
473# ld_after_inputfiles: FLAGS
474# Similar to "ld", but put after all input files.
475#
9854d43d 476# objcopy_objects: FLAGS
477# Run objcopy with the specified flags after assembling any source
478# that has the special marker RUN_OBJCOPY in the source specific
479# flags.
480#
cfe5266f
HPN
481# objcopy_linked_file: FLAGS
482# Run objcopy on the linked file with the specified flags.
483# This lets you transform the linked file using objcopy, before the
484# result is analyzed by an analyzer program specified below (which
485# may in turn *also* be objcopy).
486#
261def70
HPN
487# PROG: PROGRAM-NAME
488# The name of the program to run to analyze the .o file produced
489# by the assembler or the linker output. This can be omitted;
490# run_dump_test will guess which program to run by seeing which of
491# the flags options below is present.
492#
8d983e36 493# readelf: FLAGS
261def70
HPN
494# objdump: FLAGS
495# nm: FLAGS
496# objcopy: FLAGS
497# Use the specified program to analyze the assembler or linker
498# output file, and pass it FLAGS, in addition to the output name.
3e8cba19
AM
499# Note that they are run with LC_ALL=C in the environment to give
500# consistent sorting of symbols.
261def70
HPN
501#
502# source: SOURCE [FLAGS]
503# Assemble the file SOURCE.s using the flags in the "as" directive
504# and the (optional) FLAGS. If omitted, the source defaults to
505# FILE.s.
506# This is useful if several .d files want to share a .s file.
507# More than one "source" directive can be given, which is useful
508# when testing linking.
509#
ef2b5578
MR
510# dump: DUMP
511# Match against DUMP.d. If omitted, this defaults to FILE.d. This
512# is useful if several .d files differ by options only. Options are
513# always read from FILE.d.
514#
261def70
HPN
515# xfail: TARGET
516# The test is expected to fail on TARGET. This may occur more than
517# once.
518#
519# target: TARGET
520# Only run the test for TARGET. This may occur more than once; the
33aa234e
JK
521# target being tested must match at least one. You may provide target
522# name "cfi" for any target supporting the CFI statements.
261def70
HPN
523#
524# notarget: TARGET
525# Do not run the test for TARGET. This may occur more than once;
526# the target being tested must not match any of them.
527#
528# error: REGEX
529# An error with message matching REGEX must be emitted for the test
8d983e36
AB
530# to pass. The PROG, readelf, objdump, nm and objcopy options have
531# no meaning and need not be supplied if this is present. Multiple
532# "error" directives append to the expected linker error message.
261def70 533#
bb57e4c7
AB
534# error_output: FILE
535# Means the same as 'error', except the regular expression lines
536# are contains in FILE.
537#
bb00e284
HPN
538# warning: REGEX
539# Expect a linker warning matching REGEX. It is an error to issue
164de317
HPN
540# both "error" and "warning". Multiple "warning" directives
541# append to the expected linker warning message.
bb00e284 542#
bb57e4c7
AB
543# warning_output: FILE
544# Means the same as 'warning', except the regular expression
545# lines are contains in FILE.
546#
43d66c95
AB
547# map: FILE
548# Adding this option will cause the linker to generate a linker
549# map file, using the -Map=MAPFILE command line option. If
550# there is no -Map=MAPFILE in the 'ld: FLAGS' then one will be
551# added to the linker command line. The contents of the
552# generated MAPFILE are then compared against the regexp lines
553# in FILE using `regexp_diff' (see below for details).
554#
261def70
HPN
555# Each option may occur at most once unless otherwise mentioned.
556#
557# After the option lines come regexp lines. `run_dump_test' calls
558# `regexp_diff' to compare the output of the dumping tool against the
eb22018c
RS
559# regexps in FILE.d. `regexp_diff' is defined in binutils-common.exp;
560# see further comments there.
3b6fe0cc 561#
ef2b5578 562proc run_dump_test { name {extra_options {}} } {
261def70
HPN
563 global subdir srcdir
564 global OBJDUMP NM AS OBJCOPY READELF LD
565 global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
566 global host_triplet runtests
9a2ee7fc 567 global env verbose
647e4d46
L
568 global ld_elf_shared_opt
569
570 if { [is_elf_format] && [check_shared_lib_support] } {
571 set ld_extra_opt "$ld_elf_shared_opt"
572 } else {
573 set ld_extra_opt ""
574 }
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
88bd1539 596 set objfile_names {}
261def70
HPN
597 set opts(as) {}
598 set opts(ld) {}
d6e0b160 599 set opts(ld_after_inputfiles) {}
261def70
HPN
600 set opts(xfail) {}
601 set opts(target) {}
602 set opts(notarget) {}
603 set opts(objdump) {}
604 set opts(nm) {}
605 set opts(objcopy) {}
606 set opts(readelf) {}
607 set opts(name) {}
608 set opts(PROG) {}
609 set opts(source) {}
ef2b5578 610 set opts(dump) {}
261def70 611 set opts(error) {}
bb00e284 612 set opts(warning) {}
bb57e4c7
AB
613 set opts(error_output) {}
614 set opts(warning_output) {}
cfe5266f 615 set opts(objcopy_linked_file) {}
9854d43d 616 set opts(objcopy_objects) {}
43d66c95 617 set opts(map) {}
261def70
HPN
618
619 foreach i $opt_array {
620 set opt_name [lindex $i 0]
621 set opt_val [lindex $i 1]
622 if ![info exists opts($opt_name)] {
623 perror "unknown option $opt_name in file $file.d"
624 unresolved $subdir/$name
625 return
626 }
627
628 switch -- $opt_name {
629 xfail {}
630 target {}
631 notarget {}
164de317
HPN
632 warning {}
633 error {}
261def70 634 source {
df58fc94 635 # Move any source-specific as-flags to a separate list to
261def70
HPN
636 # simplify processing.
637 if { [llength $opt_val] > 1 } {
df58fc94 638 lappend asflags [lrange $opt_val 1 end]
261def70
HPN
639 set opt_val [lindex $opt_val 0]
640 } else {
df58fc94 641 lappend asflags {}
261def70 642 }
88bd1539
AB
643
644 # Create the object file name based on nothing but the source
645 # file name.
646 set new_objfile \
647 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]].o]
648 # But, sometimes, we have the exact same source filename in
649 # different directories (foo/src.s bar/src.s) which would lead
650 # us to try and create two src.o files. We detect this
651 # conflict here, and instead create src.o and src1.o.
652 set j 0
653 while { [lsearch $objfile_names $new_objfile] != -1 } {
654 incr j
655 set new_objfile \
656 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]]${j}.o]
657 }
658 lappend objfile_names $new_objfile
261def70
HPN
659 }
660 default {
661 if [string length $opts($opt_name)] {
662 perror "option $opt_name multiply set in $file.d"
663 unresolved $subdir/$name
664 return
665 }
666
667 # A single "# ld:" with no options should do the right thing.
668 if { $opt_name == "ld" } {
669 set run_ld 1
670 }
cfe5266f
HPN
671 # Likewise objcopy_linked_file.
672 if { $opt_name == "objcopy_linked_file" } {
673 set run_objcopy 1
674 }
261def70
HPN
675 }
676 }
7f6a71ff
JM
677 if { $opt_name == "as" || $opt_name == "ld" } {
678 set opt_val [subst $opt_val]
679 }
134fa82e
HPN
680
681 # Append differently whether it's a message (without space) or
682 # an option or list (with space).
683 switch -- $opt_name {
684 warning -
685 error {
686 append opts($opt_name) $opt_val
687 }
688 default {
689 set opts($opt_name) [concat $opts($opt_name) $opt_val]
690 }
691 }
261def70 692 }
ef2b5578
MR
693
694 foreach i $extra_options {
695 set opt_name [lindex $i 0]
696 set opt_val [lindex $i 1]
697 if ![info exists opts($opt_name)] {
698 perror "unknown option $opt_name given in extra_opts"
699 unresolved $subdir/$name
700 return
701 }
702 # Add extra option to end of existing option, adding space
703 # if necessary.
704 if { ![regexp "warning|error" $opt_name]
705 && [string length $opts($opt_name)] } {
706 append opts($opt_name) " "
707 }
708 append opts($opt_name) $opt_val
709 }
710
3935e1af
RS
711 foreach opt { as ld } {
712 regsub {\[big_or_little_endian\]} $opts($opt) \
713 [big_or_little_endian] opts($opt)
714 }
261def70
HPN
715
716 # Decide early whether we should run the test for this target.
717 if { [llength $opts(target)] > 0 } {
718 set targmatch 0
719 foreach targ $opts(target) {
720 if [istarget $targ] {
721 set targmatch 1
722 break
723 }
724 }
725 if { $targmatch == 0 } {
726 return
727 }
728 }
729 foreach targ $opts(notarget) {
730 if [istarget $targ] {
731 return
732 }
733 }
734
f364d1ca
AM
735 set program ""
736 # It's meaningless to require an output-testing method when we
737 # expect an error.
bb57e4c7 738 if { $opts(error) == "" && $opts(error_output) == "" } {
f364d1ca
AM
739 if {$opts(PROG) != ""} {
740 switch -- $opts(PROG) {
741 objdump { set program objdump }
742 nm { set program nm }
743 objcopy { set program objcopy }
744 readelf { set program readelf }
745 default
261def70
HPN
746 { perror "unrecognized program option $opts(PROG) in $file.d"
747 unresolved $subdir/$name
748 return }
f364d1ca
AM
749 }
750 } else {
261def70 751 # Guess which program to run, by seeing which option was specified.
f364d1ca
AM
752 foreach p {objdump objcopy nm readelf} {
753 if {$opts($p) != ""} {
754 if {$program != ""} {
755 perror "ambiguous dump program in $file.d"
756 unresolved $subdir/$name
757 return
758 } else {
759 set program $p
760 }
261def70
HPN
761 }
762 }
763 }
bb57e4c7 764 if { $program == "" \
9c98104c 765 && $opts(map) == "" \
bb57e4c7
AB
766 && $opts(warning) == "" \
767 && $opts(warning_output) == "" \
768 && $opts(error) == "" \
769 && $opts(error_output) == "" } {
261def70
HPN
770 perror "dump program unspecified in $file.d"
771 unresolved $subdir/$name
772 return
773 }
774 }
775
261def70
HPN
776 if { $opts(name) == "" } {
777 set testname "$subdir/$name"
778 } else {
779 set testname $opts(name)
780 }
781
782 if { $opts(source) == "" } {
783 set sourcefiles [list ${file}.s]
df58fc94 784 set asflags [list ""]
88bd1539 785 set objfile_names [list tmpdir/[file tail ${file}].o]
261def70
HPN
786 } else {
787 set sourcefiles {}
788 foreach sf $opts(source) {
b7b0b729
HPN
789 if { [string match "/*" $sf] } {
790 lappend sourcefiles "$sf"
f364d1ca 791 } else {
b7b0b729
HPN
792 lappend sourcefiles "$srcdir/$subdir/$sf"
793 }
261def70
HPN
794 }
795 }
796
ef2b5578
MR
797 if { $opts(dump) == "" } {
798 set dfile ${file}.d
799 } else {
800 set dfile $srcdir/$subdir/$opts(dump)
801 }
802
261def70
HPN
803 # Time to setup xfailures.
804 foreach targ $opts(xfail) {
805 setup_xfail $targ
806 }
807
808 # Assemble each file.
809 set objfiles {}
810 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
811 set sourcefile [lindex $sourcefiles $i]
df58fc94 812 set sourceasflags [lindex $asflags $i]
9854d43d 813 set run_objcopy_objects 0
814
815 if { [string match "*RUN_OBJCOPY*" $sourceasflags] } {
816 set run_objcopy_objects 1
817 }
818 regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
261def70 819
88bd1539 820 set objfile [lindex $objfile_names $i]
30dabe8a 821 catch "exec rm -f $objfile" exec_output
261def70 822 lappend objfiles $objfile
df58fc94 823 set cmd "$AS $ASFLAGS $opts(as) $sourceasflags -o $objfile $sourcefile"
261def70
HPN
824
825 send_log "$cmd\n"
7f6a71ff
JM
826 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
827 remote_upload host "ld.tmp"
828 set comp_output [prune_warnings [file_contents "ld.tmp"]]
829 remote_file host delete "ld.tmp"
830 remote_file build delete "ld.tmp"
261def70 831
7f6a71ff 832 if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
517c4166 833 send_log -- "$comp_output\n"
261def70 834 verbose "$comp_output" 3
f364d1ca
AM
835
836 set exitstat "succeeded"
837 if { $cmdret != 0 } { set exitstat "failed" }
838 verbose -log "$exitstat with: <$comp_output>"
261def70
HPN
839 fail $testname
840 return
841 }
9854d43d 842
843 if { $run_objcopy_objects } {
844 set cmd "$OBJCOPY $opts(objcopy_objects) $objfile"
845
846 send_log "$cmd\n"
847 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \
848 "" "/dev/null" "objcopy.tmp"]
849 remote_upload host "objcopy.tmp"
850 set comp_output [prune_warnings [file_contents "objcopy.tmp"]]
851 remote_file host delete "objcopy.tmp"
852 remote_file build delete "objcopy.tmp"
853
854 if { [lindex $cmdret 0] != 0 \
855 || ![string match "" $comp_output] } {
517c4166 856 send_log -- "$comp_output\n"
9854d43d 857 verbose "$comp_output" 3
858
859 set exitstat "succeeded"
860 if { $cmdret != 0 } { set exitstat "failed" }
861 verbose -log "$exitstat with: <$comp_output>"
862 fail $testname
863 return
864 }
865 }
261def70
HPN
866 }
867
bb57e4c7
AB
868 if { (($opts(warning) != "") && ($opts(error) != "")) \
869 || (($opts(warning) != "") && ($opts(error_output) != "")) \
870 || (($opts(warning) != "") && ($opts(warning_output) != "")) \
871 || (($opts(error) != "") && ($opts(warning_output) != "")) \
872 || (($opts(error) != "") && ($opts(error_output) != "")) \
873 || (($opts(warning_output) != "") && ($opts(error_output) != "")) } {
874 perror "$testname: bad mix of warning, error, warning_output, and error_output test-directives"
875 unresolved $testname
876 return
877 }
878
879 set check_ld(source) ""
758c5495 880 set check_ld(terminal) 0
bb57e4c7
AB
881 if { $opts(error) != "" \
882 || $opts(warning) != "" \
883 || $opts(error_output) != "" \
884 || $opts(warning_output) != "" } {
885
886 if { $opts(error) != "" || $opts(error_output) != "" } {
887 set check_ld(terminal) 1
888 } else {
889 set check_ld(terminal) 0
890 }
891
892 if { $opts(error) != "" || $opts(warning) != "" } {
893 set check_ld(source) "regex"
894 if { $opts(error) != "" } {
895 set check_ld(regex) $opts(error)
896 } else {
897 set check_ld(regex) $opts(warning)
898 }
899 } else {
900 set check_ld(source) "file"
901 if { $opts(error_output) != "" } {
902 set check_ld(file) $opts(error_output)
903 } else {
904 set check_ld(file) $opts(warning_output)
905 }
906 }
f364d1ca
AM
907 }
908
261def70
HPN
909 # Perhaps link the file(s).
910 if { $run_ld } {
911 set objfile "tmpdir/dump"
30dabe8a 912 catch "exec rm -f $objfile" exec_output
3e3f011f
RS
913
914 # Add -L$srcdir/$subdir so that the linker command can use
915 # linker scripts in the source directory.
647e4d46 916 set cmd "$LD $ld_extra_opt $LDFLAGS -L$srcdir/$subdir \
d6e0b160 917 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
261def70 918
43d66c95
AB
919 # If needed then check for, or add a -Map option.
920 set mapfile ""
921 if { $opts(map) != "" } then {
922 if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then {
923 # Found existing mapfile option
924 verbose -log "Existing mapfile '$mapfile' found"
925 } else {
926 # No mapfile option.
927 set mapfile "tmpdir/dump.map"
928 verbose -log "Adding mapfile '$mapfile'"
929 set cmd "$cmd -Map=$mapfile"
930 }
931 }
932
261def70 933 send_log "$cmd\n"
7f6a71ff
JM
934 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
935 remote_upload host "ld.tmp"
d3746675 936 set comp_output [file_contents "ld.tmp"]
7f6a71ff
JM
937 remote_file host delete "ld.tmp"
938 remote_file build delete "ld.tmp"
939 set cmdret [lindex $cmdret 0]
cfe5266f 940
f364d1ca 941 if { $cmdret == 0 && $run_objcopy } {
cfe5266f
HPN
942 set infile $objfile
943 set objfile "tmpdir/dump1"
7f6a71ff 944 remote_file host delete $objfile
cfe5266f
HPN
945
946 # Note that we don't use OBJCOPYFLAGS here; any flags must be
947 # explicitly specified.
948 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
949
950 send_log "$cmd\n"
7f6a71ff
JM
951 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
952 remote_upload host "ld.tmp"
d3746675 953 append comp_output [file_contents "ld.tmp"]
7f6a71ff
JM
954 remote_file host delete "ld.tmp"
955 remote_file build delete "ld.tmp"
956 set cmdret [lindex $cmdret 0]
f364d1ca
AM
957 }
958
7f6a71ff 959 regsub "\n$" $comp_output "" comp_output
bb57e4c7 960 if { $cmdret != 0 || $comp_output != "" || $check_ld(source) != "" } then {
f364d1ca
AM
961 set exitstat "succeeded"
962 if { $cmdret != 0 } { set exitstat "failed" }
bb57e4c7 963
2e9af2d0 964 if { $check_ld(source) == "regex" } {
bb57e4c7
AB
965 verbose -log "$exitstat with: <$comp_output>, expected: <$check_ld(regex)>"
966 } elseif { $check_ld(source) == "file" } {
967 verbose -log "$exitstat with: <$comp_output>, expected in file $check_ld(file)"
968 set_file_contents "tmpdir/ld.messages" "$comp_output"
969 } else {
970 verbose -log "$exitstat with: <$comp_output>, no expected output"
971 }
517c4166 972 send_log -- "$comp_output\n"
f364d1ca
AM
973 verbose "$comp_output" 3
974
bb57e4c7
AB
975 if { (($check_ld(source) == "") == ($comp_output == "")) \
976 && (($cmdret == 0) == ($check_ld(terminal) == 0)) \
977 && ((($check_ld(source) == "regex") \
978 && ($check_ld(regex) == "") == ($comp_output == "") \
979 && [regexp $check_ld(regex) $comp_output]) \
980 || (($check_ld(source) == "file") \
62bdf2d6 981 && (![regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$check_ld(file)"]))) } {
bb57e4c7
AB
982 # We have the expected output from ld.
983 if { $check_ld(terminal) || $program == "" } {
f364d1ca
AM
984 pass $testname
985 return
cfe5266f 986 }
f364d1ca 987 } else {
cfe5266f
HPN
988 fail $testname
989 return
990 }
991 }
43d66c95
AB
992
993 if { $opts(map) != "" } then {
994 # Check the map file matches.
995 set map_pattern_file $srcdir/$subdir/$opts(map)
996 verbose -log "Compare '$mapfile' against '$map_pattern_file'"
997 if { [regexp_diff $mapfile $map_pattern_file] } then {
998 fail "$testname (map file check)"
999 } else {
1000 pass "$testname (map file check)"
1001 }
9c98104c
AB
1002
1003 if { $program == "" } then {
1004 return
1005 }
43d66c95 1006 }
261def70 1007 } else {
88bd1539 1008 set objfile [lindex $objfiles 0]
261def70
HPN
1009 }
1010
1011 # We must not have expected failure if we get here.
1012 if { $opts(error) != "" } {
1013 fail $testname
cfe5266f 1014 return
261def70
HPN
1015 }
1016
f364d1ca
AM
1017 set progopts1 $opts($program)
1018 eval set progopts \$[string toupper $program]FLAGS
1019 eval set binary \$[string toupper $program]
1020
7f6a71ff 1021 if { ![is_remote host] && [which $binary] == 0 } {
261def70
HPN
1022 untested $testname
1023 return
1024 }
1025
1026 if { $progopts1 == "" } { set $progopts1 "-r" }
1027 verbose "running $binary $progopts $progopts1" 3
1028
1029 # Objcopy, unlike the other two, won't send its output to stdout,
1030 # so we have to run it specially.
3e8cba19 1031 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
261def70
HPN
1032 if { $program == "objcopy" } {
1033 set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
3e8cba19
AM
1034 }
1035
1036 # Ensure consistent sorting of symbols
1037 if {[info exists env(LC_ALL)]} {
1038 set old_lc_all $env(LC_ALL)
1039 }
1040 set env(LC_ALL) "C"
1041 send_log "$cmd\n"
7f6a71ff 1042 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
164de317 1043 set cmdret [lindex $cmdret 0]
7f6a71ff
JM
1044 remote_upload host "ld.tmp"
1045 set comp_output [prune_warnings [file_contents "ld.tmp"]]
1046 remote_file host delete "ld.tmp"
1047 remote_file build delete "ld.tmp"
3e8cba19
AM
1048 if {[info exists old_lc_all]} {
1049 set env(LC_ALL) $old_lc_all
261def70 1050 } else {
3e8cba19
AM
1051 unset env(LC_ALL)
1052 }
164de317
HPN
1053 if { $cmdret != 0 || $comp_output != "" } {
1054 send_log "exited abnormally with $cmdret, output:$comp_output\n"
3e8cba19
AM
1055 fail $testname
1056 return
261def70
HPN
1057 }
1058
9a2ee7fc 1059 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
ef2b5578 1060 if { [regexp_diff $dumpfile "${dfile}"] } then {
261def70 1061 fail $testname
9a2ee7fc 1062 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
261def70
HPN
1063 return
1064 }
1065
1066 pass $testname
1067}
1068
1069proc slurp_options { file } {
5a68afcf
RM
1070 # If options_regsub(foo) is set to {a b}, then the contents of a
1071 # "#foo:" line will have regsub -all applied to replace a with b.
1072 global options_regsub
1073
261def70
HPN
1074 if [catch { set f [open $file r] } x] {
1075 #perror "couldn't open `$file': $x"
1076 perror "$x"
1077 return -1
1078 }
1079 set opt_array {}
1080 # whitespace expression
1081 set ws {[ ]*}
1082 set nws {[^ ]*}
1083 # whitespace is ignored anywhere except within the options list;
cfe5266f
HPN
1084 # option names are alphabetic plus underscore only.
1085 set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
261def70
HPN
1086 while { [gets $f line] != -1 } {
1087 set line [string trim $line]
1088 # Whitespace here is space-tab.
1089 if [regexp $pat $line xxx opt_name opt_val] {
1090 # match!
5a68afcf
RM
1091 if [info exists options_regsub($opt_name)] {
1092 set subst $options_regsub($opt_name)
1093 regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \
1094 opt_val
1095 }
261def70
HPN
1096 lappend opt_array [list $opt_name $opt_val]
1097 } else {
1098 break
1099 }
1100 }
1101 close $f
1102 return $opt_array
1103}
1104
261def70
HPN
1105proc file_contents { filename } {
1106 set file [open $filename r]
1107 set contents [read $file]
1108 close $file
1109 return $contents
1110}
bffbf940 1111
5d3236ee
DK
1112proc set_file_contents { filename contents } {
1113 set file [open $filename w]
1114 puts $file "$contents"
1115 close $file
1116}
1117
d8880531
L
1118# Create an archive using ar
1119#
fa0a16b1 1120proc ar_simple_create { ar aropts target objects } {
d8880531
L
1121 remote_file host delete $target
1122
1a215085 1123 set exec_output [run_host_cmd "$ar" "-rc $aropts $target $objects"]
d8880531
L
1124 set exec_output [prune_warnings $exec_output]
1125
1126 if [string match "" $exec_output] then {
1127 send_log "$exec_output\n"
1128 return 1
1129 } else {
1130 return 0
1131 }
1132}
1133
9147e853
JJ
1134# List contains test-items with 3 items followed by 2 lists, one item and
1135# one optional item:
894891db 1136# 0:name
897aea50
MR
1137# 1:ld/ar leading options, placed before object files
1138# 2:ld/ar trailing options, placed after object files
1139# 3:assembler options
1140# 4:filenames of assembler files
1141# 5:list of actions, options and expected outputs.
1142# 6:name of output file
1143# 7:compiler flags (optional)
3b6fe0cc 1144#
894891db
NC
1145# Actions: { command command-line-options file-containg-expected-output-regexps }
1146# Commands:
1147# objdump: Apply objdump options on result.
1148# nm: Apply nm options on result.
1149# readelf: Apply readelf options on result.
5a68afcf 1150# ld: Don't apply anything on result. Compare output during linking with
894891db
NC
1151# the file containing regexps (which is the second arg, not the third).
1152# Note that this *must* be the first action if it is to be used at all;
1153# in all other cases, any output from the linker during linking is
1154# treated as a sign of an error and FAILs the test.
3b6fe0cc 1155#
5df1bc57
AM
1156# args is an optional list of target triplets to be xfailed.
1157#
1158proc run_ld_link_tests { ldtests args } {
bffbf940
JJ
1159 global ld
1160 global as
1161 global nm
d8880531 1162 global ar
bffbf940
JJ
1163 global objdump
1164 global READELF
1165 global srcdir
1166 global subdir
1167 global env
9147e853
JJ
1168 global CC
1169 global CFLAGS
eca41774 1170 global runtests
5d3236ee 1171 global exec_output
647e4d46
L
1172 global ld_elf_shared_opt
1173
1174 if { [is_elf_format] && [check_shared_lib_support] } {
1175 set ld_extra_opt "$ld_elf_shared_opt"
1176 } else {
1177 set ld_extra_opt ""
1178 }
bffbf940
JJ
1179
1180 foreach testitem $ldtests {
1181 set testname [lindex $testitem 0]
eca41774
DK
1182
1183 if ![runtest_file_p $runtests $testname] then {
1184 continue
1185 }
1186
5df1bc57
AM
1187 foreach target $args {
1188 setup_xfail $target
1189 }
1190
bffbf940 1191 set ld_options [lindex $testitem 1]
897aea50
MR
1192 set ld_after [lindex $testitem 2]
1193 set as_options [lindex $testitem 3]
1194 set src_files [lindex $testitem 4]
1195 set actions [lindex $testitem 5]
1196 set binfile tmpdir/[lindex $testitem 6]
1197 set cflags [lindex $testitem 7]
bffbf940
JJ
1198 set objfiles {}
1199 set is_unresolved 0
1200 set failed 0
5d3236ee
DK
1201 set maybe_failed 0
1202 set ld_output ""
bffbf940
JJ
1203
1204# verbose -log "Testname is $testname"
1205# verbose -log "ld_options is $ld_options"
897aea50 1206# verbose -log "ld_after is $ld_after"
bffbf940 1207# verbose -log "as_options is $as_options"
9147e853 1208# verbose -log "src_files is $src_files"
bffbf940
JJ
1209# verbose -log "actions is $actions"
1210# verbose -log "binfile is $binfile"
1211
1212 # Assemble each file in the test.
9147e853 1213 foreach src_file $src_files {
74d44110
MR
1214 set fileroot "[file rootname [file tail $src_file]]"
1215 set objfile "tmpdir/$fileroot.o"
bffbf940
JJ
1216 lappend objfiles $objfile
1217
9147e853 1218 if { [file extension $src_file] == ".c" } {
74d44110 1219 set as_file "tmpdir/$fileroot.s"
9147e853
JJ
1220 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1221 set is_unresolved 1
1222 break
1223 }
1224 } else {
1225 set as_file "$srcdir/$subdir/$src_file"
1226 }
1227 if ![ld_assemble $as "$as_options $as_file" $objfile] {
bffbf940
JJ
1228 set is_unresolved 1
1229 break
1230 }
1231 }
1232
1233 # Catch assembler errors.
77c56f44 1234 if { $is_unresolved } {
bffbf940
JJ
1235 unresolved $testname
1236 continue
1237 }
1238
abc868c6
AM
1239 if { $binfile eq "tmpdir/" } {
1240 # compile only
1241 } elseif { [regexp ".*\\.a$" $binfile] } {
897aea50 1242 if { ![ar_simple_create $ar $ld_options $binfile "$objfiles $ld_after"] } {
d8880531 1243 set failed 1
d8880531 1244 }
d9816402 1245 } elseif { ![ld_link $ld $binfile "$ld_extra_opt -L$srcdir/$subdir $ld_options $objfiles $ld_after"] } {
5d3236ee
DK
1246 set maybe_failed 1
1247 set ld_output "$exec_output"
d8880531
L
1248 }
1249
77c56f44 1250 if { !$failed } {
bffbf940
JJ
1251 foreach actionlist $actions {
1252 set action [lindex $actionlist 0]
1253 set progopts [lindex $actionlist 1]
1254
1255 # There are actions where we run regexp_diff on the
1256 # output, and there are other actions (presumably).
1257 # Handling of the former look the same.
1258 set dump_prog ""
1259 switch -- $action {
1260 objdump
1261 { set dump_prog $objdump }
1262 nm
1263 { set dump_prog $nm }
1264 readelf
1265 { set dump_prog $READELF }
5d3236ee
DK
1266 ld
1267 { set dump_prog "ld" }
bffbf940
JJ
1268 default
1269 {
1270 perror "Unrecognized action $action"
1271 set is_unresolved 1
1272 break
1273 }
1274 }
1275
5d3236ee 1276 if { $action == "ld" } {
894891db
NC
1277 set regexpfile $progopts
1278 verbose "regexpfile is $srcdir/$subdir/$regexpfile"
5d3236ee
DK
1279 set_file_contents "tmpdir/ld.messages" "$ld_output"
1280 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
894891db 1281 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$regexpfile"] } then {
5d3236ee
DK
1282 verbose "output is $ld_output" 2
1283 set failed 1
1284 break
1285 }
1286 set maybe_failed 0
77c56f44 1287 } elseif { !$maybe_failed && $dump_prog != "" } {
bffbf940
JJ
1288 set dumpfile [lindex $actionlist 2]
1289 set binary $dump_prog
1290
1291 # Ensure consistent sorting of symbols
1292 if {[info exists env(LC_ALL)]} {
1293 set old_lc_all $env(LC_ALL)
1294 }
1295 set env(LC_ALL) "C"
7f6a71ff
JM
1296 set cmd "$binary $progopts $binfile"
1297 set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
bffbf940 1298 send_log "$cmd\n"
7f6a71ff
JM
1299 remote_upload host "ld.stderr"
1300 set comp_output [prune_warnings [file_contents "ld.stderr"]]
1301 remote_file host delete "ld.stderr"
1302 remote_file build delete "ld.stderr"
5a68afcf 1303
bffbf940
JJ
1304 if {[info exists old_lc_all]} {
1305 set env(LC_ALL) $old_lc_all
1306 } else {
1307 unset env(LC_ALL)
1308 }
bffbf940
JJ
1309
1310 if ![string match "" $comp_output] then {
1311 send_log "$comp_output\n"
1312 set failed 1
1313 break
1314 }
1315
7f6a71ff
JM
1316 remote_upload host "dump.out"
1317
bffbf940
JJ
1318 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1319 verbose "output is [file_contents "dump.out"]" 2
1320 set failed 1
7f6a71ff
JM
1321 remote_file build delete "dump.out"
1322 remote_file host delete "dump.out"
bffbf940
JJ
1323 break
1324 }
7f6a71ff
JM
1325 remote_file build delete "dump.out"
1326 remote_file host delete "dump.out"
bffbf940
JJ
1327 }
1328 }
bffbf940
JJ
1329 }
1330
77c56f44 1331 if { $is_unresolved } {
bffbf940 1332 unresolved $testname
77c56f44
RS
1333 } elseif { $maybe_failed || $failed } {
1334 fail $testname
1335 } else {
1336 pass $testname
bffbf940
JJ
1337 }
1338 }
1339}
1340
252b5132
RH
1341# This definition is taken from an unreleased version of DejaGnu. Once
1342# that version gets released, and has been out in the world for a few
1343# months at least, it may be safe to delete this copy.
1344if ![string length [info proc prune_warnings]] {
1345 #
1346 # prune_warnings -- delete various system verbosities from TEXT
1347 #
1348 # An example is:
1349 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1350 #
1351 # Sites with particular verbose os's may wish to override this in site.exp.
1352 #
1353 proc prune_warnings { text } {
1354 # This is from sun4's. Do it for all machines for now.
1355 # The "\\1" is to try to preserve a "\n" but only if necessary.
1356 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1357
1358 # It might be tempting to get carried away and delete blank lines, etc.
1359 # Just delete *exactly* what we're ask to, and that's it.
1360 return $text
1361 }
1362}
24edc24d 1363
c8c140d9 1364# ldtests contains test-items with 3 items followed by 1 lists, 2 items
fab4a87f 1365# and 3 optional items:
c8c140d9
BE
1366# 0:name
1367# 1:ld options
1368# 2:assembler options
55255dae 1369# 3:filenames of source files
c8c140d9
BE
1370# 4:name of output file
1371# 5:expected output
1372# 6:compiler flags (optional)
55255dae 1373# 7:language (optional)
fab4a87f 1374# 8:linker warning (optional)
982c6f26 1375# args is an optional list of target triplets to be xfailed.
c8c140d9 1376
982c6f26 1377proc run_ld_link_exec_tests { ldtests args } {
24edc24d
L
1378 global ld
1379 global as
1380 global srcdir
1381 global subdir
1382 global env
1383 global CC
55255dae 1384 global CXX
24edc24d 1385 global CFLAGS
58ffc3bd 1386 global CXXFLAGS
22ec3bd1 1387 global errcnt
fab4a87f 1388 global exec_output
9966f7ee
JW
1389 global board_cflags
1390
1391 # When using GCC as the linker driver, we need to specify board cflags when
1392 # linking because cflags may contain linker options. For example when
1393 # linker options are included in GCC spec files then we need the -specs
1394 # option.
1395 if [board_info [target_info name] exists cflags] {
1396 set board_cflags " [board_info [target_info name] cflags]"
1397 } else {
1398 set board_cflags ""
1399 }
24edc24d
L
1400
1401 foreach testitem $ldtests {
982c6f26 1402 foreach target $args {
c8c140d9
BE
1403 setup_xfail $target
1404 }
24edc24d
L
1405 set testname [lindex $testitem 0]
1406 set ld_options [lindex $testitem 1]
1407 set as_options [lindex $testitem 2]
1408 set src_files [lindex $testitem 3]
1409 set binfile tmpdir/[lindex $testitem 4]
1410 set expfile [lindex $testitem 5]
1411 set cflags [lindex $testitem 6]
55255dae 1412 set lang [lindex $testitem 7]
fab4a87f 1413 set warning [lindex $testitem 8]
24edc24d 1414 set objfiles {}
24edc24d
L
1415 set failed 0
1416
1417# verbose -log "Testname is $testname"
1418# verbose -log "ld_options is $ld_options"
1419# verbose -log "as_options is $as_options"
1420# verbose -log "src_files is $src_files"
24edc24d
L
1421# verbose -log "binfile is $binfile"
1422
1423 # Assemble each file in the test.
1424 foreach src_file $src_files {
74d44110
MR
1425 set fileroot "[file rootname [file tail $src_file]]"
1426 set objfile "tmpdir/$fileroot.o"
24edc24d
L
1427 lappend objfiles $objfile
1428
58ffc3bd 1429 if { [ string match "c++" $lang ] } {
a44d0bd7 1430 set cmd "$CXX -c $CXXFLAGS $cflags"
58ffc3bd 1431 } else {
a44d0bd7 1432 set cmd "$CC -c $CFLAGS $cflags"
58ffc3bd 1433 }
a44d0bd7
AM
1434 if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] {
1435 set failed 1
1436 break
1437 }
1438 }
1439 if { $failed != 0 } {
1440 unresolved $testname
1441 continue
cb5ab6c8 1442 }
a10e6b21 1443
d9816402
AM
1444 if { [ string match "c++" $lang ] } {
1445 set link_proc ld_link
cb5ab6c8 1446 set link_cmd $CXX
cb5ab6c8
L
1447 } else {
1448 set link_proc ld_link
d9816402 1449 set link_cmd $CC
cb5ab6c8 1450 }
24edc24d 1451
abc868c6
AM
1452 if { $binfile eq "tmpdir/" } {
1453 # compile only
1454 pass $testname
1455 continue;
9966f7ee 1456 } elseif ![$link_proc $link_cmd $binfile "$board_cflags -L$srcdir/$subdir $ld_options $objfiles"] {
cb5ab6c8 1457 set failed 1
cb5ab6c8
L
1458 }
1459
1460 # Check if exec_output is expected.
1461 if { $warning != "" } then {
1462 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1463 if { [regexp $warning $exec_output] } then {
a10e6b21 1464 set failed 0
cb5ab6c8
L
1465 } else {
1466 set failed 1
fab4a87f 1467 }
cb5ab6c8 1468 }
fab4a87f 1469
d9816402 1470 if { $failed == 0 && [isnative] } {
cb5ab6c8
L
1471 send_log "Running: $binfile > $binfile.out\n"
1472 verbose "Running: $binfile > $binfile.out"
1473 catch "exec $binfile > $binfile.out" exec_output
fab4a87f 1474
cb5ab6c8
L
1475 if ![string match "" $exec_output] then {
1476 send_log "$exec_output\n"
1477 verbose "$exec_output" 1
1478 set failed 1
1479 } else {
1480 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1481 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1482 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1483 set exec_output [prune_warnings $exec_output]
5a68afcf 1484
24edc24d
L
1485 if ![string match "" $exec_output] then {
1486 send_log "$exec_output\n"
1487 verbose "$exec_output" 1
1488 set failed 1
1489 }
1490 }
cb5ab6c8 1491 }
24edc24d 1492
cb5ab6c8
L
1493 if { $failed != 0 } {
1494 fail $testname
d9816402
AM
1495 } elseif ![isnative] {
1496 unsupported $testname
cb5ab6c8
L
1497 } else {
1498 set errcnt 0
1499 pass $testname
24edc24d 1500 }
24edc24d
L
1501 }
1502}
d2dee3b2
L
1503
1504# List contains test-items with 3 items followed by 2 lists, one item and
1505# one optional item:
55255dae 1506# 0:name
fa0a16b1 1507# 1:ld or ar options
55255dae
L
1508# 2:compile options
1509# 3:filenames of source files
1510# 4:action and options.
1511# 5:name of output file
1512# 6:language (optional)
d2dee3b2
L
1513#
1514# Actions:
1515# objdump: Apply objdump options on result. Compare with regex (last arg).
1516# nm: Apply nm options on result. Compare with regex (last arg).
1517# readelf: Apply readelf options on result. Compare with regex (last arg).
2bd7f877
AB
1518# warning: Check linker output against regex (last arg).
1519# error: Like 'warning' but checking output in error case.
1520# warning_output: Check linker output against regex in a file (last arg).
1521# error_output: Like 'warning_output' but checking output in error case.
d2dee3b2
L
1522#
1523proc run_cc_link_tests { ldtests } {
1524 global nm
1525 global objdump
1526 global READELF
1527 global srcdir
1528 global subdir
1529 global env
1530 global CC
55255dae 1531 global CXX
d2dee3b2 1532 global CFLAGS
58ffc3bd 1533 global CXXFLAGS
d8880531 1534 global ar
dd98f8d2 1535 global exec_output
603c4399
JW
1536 global board_cflags
1537
1538 if [board_info [target_info name] exists cflags] {
1539 set board_cflags " [board_info [target_info name] cflags]"
1540 } else {
1541 set board_cflags ""
1542 }
d2dee3b2
L
1543
1544 foreach testitem $ldtests {
1545 set testname [lindex $testitem 0]
1546 set ldflags [lindex $testitem 1]
1547 set cflags [lindex $testitem 2]
1548 set src_files [lindex $testitem 3]
1549 set actions [lindex $testitem 4]
1550 set binfile tmpdir/[lindex $testitem 5]
55255dae 1551 set lang [lindex $testitem 6]
d2dee3b2
L
1552 set objfiles {}
1553 set is_unresolved 0
1554 set failed 0
2bd7f877
AB
1555 set check_ld(terminal) 0
1556 set check_ld(source) ""
d2dee3b2 1557
c3e11cbe
AM
1558 #verbose -log "testname is $testname"
1559 #verbose -log "ldflags is $ldflags"
1560 #verbose -log "cflags is $cflags"
1561 #verbose -log "src_files is $src_files"
1562 #verbose -log "actions is $actions"
1563 #verbose -log "binfile is $binfile"
1564 #verbose -log "lang is $lang"
2bd7f877
AB
1565
1566 foreach actionlist $actions {
1567 set action [lindex $actionlist 0]
1568 set progopts [lindex $actionlist 1]
1569
1570 # Find actions related to error/warning processing.
1571 switch -- $action {
1572 error
1573 {
1574 set check_ld(source) "regexp"
1575 set check_ld(regexp) $progopts
1576 set check_ld(terminal) 1
1577 }
1578 warning
1579 {
1580 set check_ld(source) "regexp"
1581 set check_ld(regexp) $progopts
1582 }
1583 error_output
1584 {
1585 set check_ld(source) "file"
1586 set check_ld(file) $progopts
1587 set check_ld(terminal) 1
1588 }
1589 warning_output
1590 {
1591 set check_ld(source) "file"
1592 set check_ld(file) $progopts
1593 }
1594 }
1595 }
c3e11cbe 1596
d2dee3b2
L
1597 # Compile each file in the test.
1598 foreach src_file $src_files {
74d44110
MR
1599 set fileroot "[file rootname [file tail $src_file]]"
1600 set objfile "tmpdir/$fileroot.o"
d2dee3b2
L
1601 lappend objfiles $objfile
1602
58ffc3bd 1603 if { [ string match "c++" $lang ] } {
a44d0bd7 1604 set cmd "$CXX -c $CXXFLAGS $cflags"
58ffc3bd 1605 } else {
a44d0bd7 1606 set cmd "$CC -c $CFLAGS $cflags"
58ffc3bd 1607 }
a44d0bd7
AM
1608 if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] {
1609 set failed 1
1610 break
1611 }
1612 }
1613 if { $failed != 0 } {
1614 unresolved $testname
1615 continue
d2dee3b2
L
1616 }
1617
1618 # Clear error and warning counts.
1619 reset_vars
1620
55255dae
L
1621 if { [ string match "c++" $lang ] } {
1622 set cc_cmd $CXX
1623 } else {
1624 set cc_cmd $CC
1625 }
1626
abc868c6
AM
1627 if { $binfile eq "tmpdir/" } {
1628 # compile only
1629 } elseif { [regexp ".*\\.a$" $binfile] } {
fa0a16b1 1630 if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
d8880531 1631 set failed 1
d8880531 1632 }
741e0128 1633 } else {
2bd7f877
AB
1634 ld_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"
1635 set ld_output "$exec_output"
741e0128 1636
2bd7f877
AB
1637 if { $check_ld(source) == "regexp" } then {
1638 # Match output against regexp argument.
1639 verbose -log "returned with: <$ld_output>, expected: <$check_ld(regexp)>"
1640 if { ![regexp $check_ld(regexp) $ld_output] } then {
dd98f8d2
NC
1641 set failed 1
1642 }
2bd7f877
AB
1643 } elseif { $check_ld(source) == "file" } then {
1644 # Match output against patterns in a file.
1645 set_file_contents "tmpdir/ld.messages" "$ld_output"
1646 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
1647 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$check_ld(file)"] } then {
1648 verbose "output is $ld_output" 2
1649 set failed 1
1650 }
1651 }
1652
1653 if { $check_ld(source) != "" } then {
1654 if { $ld_output == "" } then {
1655 verbose -log "Linker was expected to give error or warning"
1656 set failed 1
1657 }
1658 } else {
1659 if { $ld_output != "" } then {
1660 verbose -log "Unexpected linker warning or error"
1661 set failed 1
1662 }
741e0128 1663 }
d8880531
L
1664 }
1665
1666 if { $failed == 0 } {
d2dee3b2
L
1667 foreach actionlist $actions {
1668 set action [lindex $actionlist 0]
1669 set progopts [lindex $actionlist 1]
1670
1671 # There are actions where we run regexp_diff on the
1672 # output, and there are other actions (presumably).
1673 # Handling of the former look the same.
1674 set dump_prog ""
1675 switch -- $action {
1676 objdump
1677 { set dump_prog $objdump }
1678 nm
1679 { set dump_prog $nm }
1680 readelf
1681 { set dump_prog $READELF }
2bd7f877
AB
1682 error {}
1683 warning {}
1684 error_output {}
1685 warning_output {}
d2dee3b2
L
1686 default
1687 {
1688 perror "Unrecognized action $action"
1689 set is_unresolved 1
1690 break
1691 }
1692 }
1693
1694 if { $dump_prog != "" } {
1695 set dumpfile [lindex $actionlist 2]
1696 set binary $dump_prog
1697
1698 # Ensure consistent sorting of symbols
1699 if {[info exists env(LC_ALL)]} {
1700 set old_lc_all $env(LC_ALL)
1701 }
1702 set env(LC_ALL) "C"
1703 set cmd "$binary $progopts $binfile > dump.out"
1704 send_log "$cmd\n"
1705 catch "exec $cmd" comp_output
1706 if {[info exists old_lc_all]} {
1707 set env(LC_ALL) $old_lc_all
1708 } else {
1709 unset env(LC_ALL)
1710 }
1711 set comp_output [prune_warnings $comp_output]
1712
1713 if ![string match "" $comp_output] then {
1714 send_log "$comp_output\n"
1715 set failed 1
1716 break
1717 }
1718
1719 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1720 verbose "output is [file_contents "dump.out"]" 2
1721 set failed 1
1722 break
1723 }
1724 }
1725 }
d2dee3b2
L
1726 }
1727
d44ea5d0 1728 if { $failed } {
abc868c6 1729 fail $testname
d44ea5d0 1730 } elseif { $is_unresolved } {
d2dee3b2 1731 unresolved $testname
d44ea5d0
AM
1732 } else {
1733 pass $testname
d2dee3b2
L
1734 }
1735 }
1736}
430a16a5
NC
1737
1738# Returns true if --gc-sections is supported on the target.
1739
1740proc check_gc_sections_available { } {
1741 global gc_sections_available_saved
1742 global ld
5a68afcf 1743
430a16a5
NC
1744 if {![info exists gc_sections_available_saved]} {
1745 # Some targets don't support gc-sections despite whatever's
1746 # advertised by ld's options.
fc3eec7e 1747 if { [istarget d30v-*-*]
59c108f7
NC
1748 || [istarget dlx-*-*]
1749 || [istarget i960-*-*]
59c108f7 1750 || [istarget pj*-*-*]
0220170b 1751 || [istarget pru*-*-*]
59c108f7
NC
1752 || [istarget alpha-*-*]
1753 || [istarget hppa*64-*-*]
1754 || [istarget i370-*-*]
1755 || [istarget i860-*-*]
1756 || [istarget ia64-*-*]
1757 || [istarget mep-*-*]
0f088b2a 1758 || [istarget mn10200-*-*] } {
430a16a5
NC
1759 set gc_sections_available_saved 0
1760 return 0
1761 }
1762
1763 # elf2flt uses -q (--emit-relocs), which is incompatible with
1764 # --gc-sections.
1765 if { [board_info target exists ldflags]
1766 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1767 set gc_sections_available_saved 0
1768 return 0
1769 }
1770
430a16a5 1771 # Check if the ld used by gcc supports --gc-sections.
1d5316ab
AM
1772 # FIXME: this test is useless since ld --help always says
1773 # --gc-sections is available
430a16a5
NC
1774 set ld_output [remote_exec host $ld "--help"]
1775 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1776 set gc_sections_available_saved 1
1777 } else {
1778 set gc_sections_available_saved 0
1779 }
1780 }
1781 return $gc_sections_available_saved
1782}
33aa234e 1783
1d5316ab
AM
1784# Returns true if -shared is supported on the target
1785# Only used and accurate for ELF targets at the moment
1786
1787proc check_shared_lib_support { } {
83a23418 1788 if {![istarget aarch64*-*-elf]
fc3eec7e 1789 && ![istarget arc*-*-elf*]
83a23418 1790 && ![istarget arm*-*-elf]
1d5316ab
AM
1791 && ![istarget avr-*-*]
1792 && ![istarget cr16-*-*]
5220199d 1793 && ![istarget cris*-*-elf]
1d5316ab
AM
1794 && ![istarget crx-*-*]
1795 && ![istarget d10v-*-*]
1796 && ![istarget d30v-*-*]
1797 && ![istarget dlx-*-*]
cfb8c092 1798 && ![istarget epiphany-*-*]
1d5316ab
AM
1799 && ![istarget fr30-*-*]
1800 && ![istarget frv-*-*]
c4107a7d 1801 && ![istarget ft32-*-*]
1d5316ab
AM
1802 && ![istarget h8300-*-*]
1803 && ![istarget i860-*-*]
1804 && ![istarget i960-*-*]
1805 && ![istarget ip2k-*-*]
1806 && ![istarget iq2000-*-*]
1807 && ![istarget lm32-*-*]
1808 && ![istarget m32c-*-*]
1809 && ![istarget m32r-*-*]
32d79e68
AM
1810 && ![istarget m6811-*-*]
1811 && ![istarget m6812-*-*]
1d5316ab
AM
1812 && ![istarget m68hc1*-*-*]
1813 && ![istarget mcore*-*-*]
1814 && ![istarget mep-*-*]
1815 && ![istarget microblaze-*-*]
23c80bf4 1816 && ![istarget mips*-*-elf]
1d5316ab
AM
1817 && ![istarget mn10200-*-*]
1818 && ![istarget moxie-*-*]
1819 && ![istarget msp430-*-*]
1820 && ![istarget mt-*-*]
35c08157 1821 && ![istarget nds32*-*-*]
4c8798c9 1822 && ![istarget nios2-*-elf]
73589c9d 1823 && ![istarget or1k*-*-*]
1d5316ab 1824 && ![istarget pj-*-*]
0220170b 1825 && ![istarget pru-*-*]
4046d87a 1826 && ![istarget rl78-*-*]
1d5316ab
AM
1827 && ![istarget rx-*-*]
1828 && ![istarget spu-*-*]
1829 && ![istarget v850*-*-*]
c18392d8 1830 && ![istarget visium-*-*]
b709ef7c 1831 && ![istarget xc16x-*-elf]
b3066ae8 1832 && ![istarget xgate-*-*]
1d5316ab
AM
1833 && ![istarget xstormy16-*-*]
1834 && ![istarget *-*-irix*]
1835 && ![istarget *-*-rtems] } {
1836 return 1
1837 }
1838 return 0
1839}
1840
b62b1f71
AM
1841# Return true if target uses genelf.em (assuming it is ELF).
1842proc is_generic_elf { } {
1843 if { [istarget "d30v-*-*"]
1844 || [istarget "dlx-*-*"]
1845 || [istarget "fr30-*-*"]
1846 || ([istarget "frv-*-*"] && ![istarget "frv-*-linux*"])
1847 || [istarget "ft32-*-*"]
1848 || [istarget "i860-*-*"]
1849 || [istarget "i960-*-*"]
1850 || [istarget "iq2000-*-*"]
1851 || [istarget "mn10200-*-*"]
1852 || [istarget "moxie-*-*"]
1853 || [istarget "msp430-*-*"]
1854 || [istarget "mt-*-*"]
1855 || [istarget "pj*-*-*"] } {
1856 return 1;
1857 }
1858 return 0;
1859}
1860
5d3236ee
DK
1861# Returns true if the target ld supports the plugin API.
1862proc check_plugin_api_available { } {
1863 global plugin_api_available_saved
1864 global ld
1865 if {![info exists plugin_api_available_saved]} {
1866 # Check if the ld used by gcc supports --plugin.
1867 set ld_output [remote_exec host $ld "--help"]
2d03dd2f 1868 if { [ string first "-plugin PLUGIN" $ld_output ] >= 0 } {
5d3236ee
DK
1869 set plugin_api_available_saved 1
1870 } else {
1871 set plugin_api_available_saved 0
1872 }
1873 }
1874 return $plugin_api_available_saved
1875}
1876
3f730821
HPN
1877# Sets ld_sysroot to the current sysroot (empty if not supported) and
1878# returns true if the target ld supports sysroot.
bdd65db9 1879proc check_sysroot_available { } {
3f730821 1880 global ld_sysroot_available_saved ld ld_sysroot
bdd65db9 1881 if {![info exists ld_sysroot_available_saved]} {
3f730821
HPN
1882 # Check if ld supports --sysroot *other* than empty.
1883 set ld_sysroot [string trimright [lindex [remote_exec host $ld "--print-sysroot"] 1]]
1884 if { $ld_sysroot == "" } {
bdd65db9
HPN
1885 set ld_sysroot_available_saved 0
1886 } else {
1887 set ld_sysroot_available_saved 1
1888 }
1889 }
1890 return $ld_sysroot_available_saved
1891}
1892
5ff55910
L
1893# Returns 1 if plugin is enabled in gcc. Returns 0 otherwise.
1894proc check_gcc_plugin_enabled { } {
1895 global CC
1896
1897 if {![info exists CC]} {
1898 set CC [find_gcc]
1899 }
7f6bf02d 1900 if { $CC == ""} {
8be1e369 1901 return 0
5ff55910
L
1902 }
1903 set state [remote_exec host $CC -v]
8be1e369
AM
1904 if { [lindex $state 0] != 0 } {
1905 return 0;
1906 }
1907 for { set i 1 } { $i < [llength $state] } { incr i } {
5ff55910
L
1908 set v [lindex $state $i]
1909 if { [ string match "*--disable-plugin*" $v ] } {
1910 verbose "plugin is disabled by $v"
1911 return 0;
1912 }
1913 }
1914
1915 return 1;
1916}
1917
3bd58fbe
L
1918# Returns true if the target compiler supports LTO
1919proc check_lto_available { } {
1920 global lto_available_saved
1921 global CC
7174e19f 1922
3bd58fbe 1923 if {![info exists lto_available_saved]} {
5ff55910 1924 if { ![check_gcc_plugin_enabled] } {
19aef622
NC
1925 set lto_available_saved 0
1926 return 0
1927 }
00f4a602
L
1928 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1929 # -ffat-lto-objects, we always run LTO tests on Linux with
1930 # GCC 4.9 or newer.
1931 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1932 set lto_available_saved 1
1933 return 1
1934 }
3bd58fbe 1935 # Check if gcc supports -flto -fuse-linker-plugin
f1d7f4a6
AM
1936 set flags ""
1937 if [board_info [target_info name] exists cflags] {
1938 append flags " [board_info [target_info name] cflags]"
1939 }
1940 if [board_info [target_info name] exists ldflags] {
1941 append flags " [board_info [target_info name] ldflags]"
3bd58fbe 1942 }
f1d7f4a6
AM
1943
1944 set basename "tmpdir/lto[pid]"
1945 set src ${basename}.c
1946 set output ${basename}.out
3bd58fbe 1947 set f [open $src "w"]
7174e19f 1948 puts $f "int main() { return 0; }"
3bd58fbe 1949 close $f
010f98a5
L
1950 if [is_remote host] {
1951 set src [remote_download host $src]
1952 }
c3e11cbe 1953 set lto_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -fuse-linker-plugin $src -o $output"]
f1d7f4a6
AM
1954 remote_file host delete $src
1955 remote_file host delete $output
3bd58fbe 1956 file delete $src
3bd58fbe
L
1957 }
1958 return $lto_available_saved
1959}
1960
c3e11cbe
AM
1961# Returns true if the target compiler supports LTO -ffat-lto-objects
1962proc check_lto_fat_available { } {
1963 global lto_fat_available_saved
1964 global CC
1965
1966 if {![info exists lto_fat_available_saved]} {
5ff55910 1967 if { ![check_gcc_plugin_enabled] } {
c3e11cbe
AM
1968 set lto_fat_available_saved 0
1969 return 0
1970 }
00f4a602
L
1971 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1972 # -ffat-lto-objects, we always run LTO tests on Linux with
1973 # GCC 4.9 or newer.
1974 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1975 set lto_fat_available_saved 1
1976 return 1
1977 }
c3e11cbe
AM
1978 # Check if gcc supports -flto -fuse-linker-plugin
1979 set flags ""
1980 if [board_info [target_info name] exists cflags] {
1981 append flags " [board_info [target_info name] cflags]"
1982 }
1983 if [board_info [target_info name] exists ldflags] {
1984 append flags " [board_info [target_info name] ldflags]"
1985 }
1986
1987 set basename "tmpdir/lto[pid]"
1988 set src ${basename}.c
1989 set output ${basename}.out
1990 set f [open $src "w"]
1991 puts $f "int main() { return 0; }"
1992 close $f
010f98a5
L
1993 if [is_remote host] {
1994 set src [remote_download host $src]
1995 }
c3e11cbe
AM
1996 set lto_fat_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -ffat-lto-objects -fuse-linker-plugin $src -o $output"]
1997 remote_file host delete $src
1998 remote_file host delete $output
1999 file delete $src
2000 }
2001 return $lto_fat_available_saved
2002}
2003
92c09111
L
2004# Returns true if the target compiler supports LTO and -shared
2005proc check_lto_shared_available { } {
2006 global lto_shared_available_saved
2007 global CC
2008
92c09111 2009 if {![info exists lto_shared_available_saved]} {
5ff55910 2010 if { ![check_gcc_plugin_enabled] } {
3bb9e7b4
AM
2011 set lto_shared_available_saved 0
2012 return 0
2013 }
00f4a602
L
2014 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
2015 # -ffat-lto-objects, we always run LTO tests on Linux with
2016 # GCC 4.9 or newer.
2017 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
2018 set lto_shared_available_saved 1
2019 return 1
2020 }
92c09111 2021 # Check if gcc supports -flto -fuse-linker-plugin -shared
f1d7f4a6
AM
2022 set flags ""
2023 if [board_info [target_info name] exists cflags] {
2024 append flags " [board_info [target_info name] cflags]"
2025 }
2026 if [board_info [target_info name] exists ldflags] {
2027 append flags " [board_info [target_info name] ldflags]"
92c09111 2028 }
f1d7f4a6
AM
2029
2030 set basename "tmpdir/lto_shared[pid]"
2031 set src ${basename}.c
2032 set output ${basename}.so
92c09111
L
2033 set f [open $src "w"]
2034 puts $f ""
2035 close $f
010f98a5
L
2036 if [is_remote host] {
2037 set src [remote_download host $src]
2038 }
f1d7f4a6
AM
2039 set lto_shared_available_saved [run_host_cmd_yesno "$CC" "$flags -shared -fPIC -flto -fuse-linker-plugin $src -o $output"]
2040 remote_file host delete $src
2041 remote_file host delete $output
92c09111 2042 file delete $src
92c09111
L
2043 }
2044 return $lto_shared_available_saved
2045}
2046
33aa234e
JK
2047# Check if the assembler supports CFI statements.
2048
2049proc check_as_cfi { } {
2050 global check_as_cfi_result
2051 global as
2052 if [info exists check_as_cfi_result] {
2053 return $check_as_cfi_result
2054 }
2055 set as_file "tmpdir/check_as_cfi.s"
2056 set as_fh [open $as_file w 0666]
2057 puts $as_fh "# Generated file. DO NOT EDIT"
2058 puts $as_fh "\t.cfi_startproc"
2059 puts $as_fh "\t.cfi_endproc"
2060 close $as_fh
2061 remote_download host $as_file
2062 verbose -log "Checking CFI support:"
2063 rename "perror" "check_as_cfi_perror"
2064 proc perror { args } { }
2065 set success [ld_assemble $as $as_file "/dev/null"]
2066 rename "perror" ""
2067 rename "check_as_cfi_perror" "perror"
2068 #remote_file host delete $as_file
2069 set check_as_cfi_result $success
2070 return $success
2071}
2072
c22ee0ad
L
2073# Returns true if IFUNC works.
2074
2075proc check_ifunc_available { } {
2076 global ifunc_available_saved
2077 global CC
2078
2079 if {![info exists ifunc_available_saved]} {
2080 if { [which $CC] == 0 } {
2081 set ifunc_available_saved 0
2082 return 0
2083 }
2084 # Check if gcc supports -flto -fuse-linker-plugin
2085 set flags ""
2086 if [board_info [target_info name] exists cflags] {
2087 append flags " [board_info [target_info name] cflags]"
2088 }
2089 if [board_info [target_info name] exists ldflags] {
2090 append flags " [board_info [target_info name] ldflags]"
2091 }
2092
2093 set basename "tmpdir/ifunc[pid]"
2094 set src ${basename}.c
2095 set output ${basename}.out
2096 set f [open $src "w"]
2097 puts $f "extern int library_func2 (void);"
2098 puts $f "int main (void)"
2099 puts $f "{"
2100 puts $f " if (library_func2 () != 2) __builtin_abort ();"
2101 puts $f " return 0; "
2102 puts $f "}"
2103 puts $f "static int library_func1 (void) {return 2; }"
2104 puts $f "void *foo (void) __asm__ (\"library_func2\");"
2105 puts $f "void *foo (void) { return library_func1; }"
2106 puts $f "__asm__(\".type library_func2, %gnu_indirect_function\");"
2107 close $f
010f98a5
L
2108 if [is_remote host] {
2109 set src [remote_download host $src]
2110 }
c22ee0ad
L
2111 set ifunc_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
2112 if { $ifunc_available_saved == 1 } {
2113 set ifunc_available_saved [run_host_cmd_yesno "$output" ""]
2114 }
2115 remote_file host delete $src
2116 remote_file host delete $output
2117 file delete $src
2118 }
2119 return $ifunc_available_saved
2120}
2121
97dc35c8
L
2122# Returns true if ifunc attribute works.
2123
2124proc check_ifunc_attribute_available { } {
2125 global ifunc_attribute_available_saved
2126 global CC
2127
2128 if {![info exists ifunc_attribute_available_saved]} {
2129 if { [which $CC] == 0 } {
2130 set ifunc_attribute_available_saved 0
2131 return 0
2132 }
2133 # Check if gcc supports -flto -fuse-linker-plugin
2134 set flags ""
2135 if [board_info [target_info name] exists cflags] {
2136 append flags " [board_info [target_info name] cflags]"
2137 }
2138 if [board_info [target_info name] exists ldflags] {
2139 append flags " [board_info [target_info name] ldflags]"
2140 }
2141
2142 set basename "tmpdir/ifunc[pid]"
2143 set src ${basename}.c
2144 set output ${basename}.out
2145 set f [open $src "w"]
2146 puts $f "extern int library_func2 (void) __attribute__ ((ifunc (\"foo\")));"
2147 puts $f "int main (void)"
2148 puts $f "{"
2149 puts $f " if (library_func2 () != 2) __builtin_abort ();"
2150 puts $f " return 0; "
2151 puts $f "}"
2152 puts $f "static int library_func1 (void) {return 2; }"
2153 puts $f "void *foo (void) { return library_func1; }"
2154 close $f
010f98a5
L
2155 if [is_remote host] {
2156 set src [remote_download host $src]
2157 }
97dc35c8
L
2158 set ifunc_attribute_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
2159 if { $ifunc_attribute_available_saved == 1 } {
2160 set ifunc_attribute_available_saved [run_host_cmd_yesno "$output" ""]
2161 }
2162 remote_file host delete $src
2163 remote_file host delete $output
2164 file delete $src
2165 }
2166 return $ifunc_attribute_available_saved
2167}
2168
33aa234e
JK
2169# Provide virtual target "cfi" for targets supporting CFI.
2170
2171rename "istarget" "istarget_ld"
2172proc istarget { target } {
2173 if {$target == "cfi"} {
2174 return [check_as_cfi]
2175 }
2176 return [istarget_ld $target]
2177}
fd121c5c
JW
2178
2179# Return true if libdl is supported.
2180
2181proc check_libdl_available { } {
2182 global libdl_available_saved
2183 global CC
2184
2185 if {![info exists libdl_available_saved]} {
2186 if { [which $CC] == 0 } {
2187 set libdl_available_saved 0
2188 return 0
2189 }
2190
2191 set basename "tmpdir/dl_avail_test[pid]"
2192 set src ${basename}.c
2193 set output ${basename}.out
2194 set f [open $src "w"]
2195 # Sample test file.
2196 puts $f "#include <dlfcn.h>"
2197 puts $f "int main (void)"
2198 puts $f "{"
2199 puts $f " dlopen (\"dummy.so\", RTLD_NOW);"
2200 puts $f " return 0; "
2201 puts $f "}"
2202 close $f
2203 if [is_remote host] {
2204 set src [remote_download host $src]
2205 }
2206 set libdl_available_saved [run_host_cmd_yesno "$CC" "$src -o $output -ldl"]
2207 remote_file host delete $src
2208 remote_file host delete $output
2209 file delete $src
2210 }
2211 return $libdl_available_saved
2212}
0aae7e72
L
2213
2214# Returns true if GNU2 TLS works.
2215
2216proc check_gnu2_tls_available { } {
2217 global gnu2_tls_available_saved
2218 global CC
2219 global GNU2_CFLAGS
2220
2221 if {![info exists gnu2_tls_available_saved]} {
2222 if { [which $CC] == 0 || "$GNU2_CFLAGS" == "" } {
2223 set gnu2_tls_available_saved 0
2224 return 0
2225 }
2226 # Check if GNU2 TLS works.
2227 set flags "$GNU2_CFLAGS"
2228 if [board_info [target_info name] exists cflags] {
2229 append flags " [board_info [target_info name] cflags]"
2230 }
2231 if [board_info [target_info name] exists ldflags] {
2232 append flags " [board_info [target_info name] ldflags]"
2233 }
2234
2235 set basename "tmpdir/gnu2_tls[pid]"
2236 set src1 ${basename}1.c
2237 set output1 ${basename}.so
2238 set f [open $src1 "w"]
2239 puts $f "extern __thread int zzz;"
2240 puts $f "int foo (void)"
2241 puts $f "{"
2242 puts $f " return zzz;"
2243 puts $f "}"
2244 close $f
2245 if [is_remote host] {
2246 set src1 [remote_download host $src1]
2247 }
2248 set src2 ${basename}2.c
2249 set output2 ${basename}.exe
2250 set f [open $src2 "w"]
2251 puts $f "__thread int zzz = 20;"
2252 puts $f "extern int foo (void);"
2253 puts $f "int main (void)"
2254 puts $f "{"
2255 puts $f " if (foo () != 20) __builtin_abort ();"
2256 puts $f " return 0; "
2257 puts $f "}"
2258 close $f
2259 if [is_remote host] {
2260 set src2 [remote_download host $src2]
2261 }
2262 set gnu2_tls_available_saved [run_host_cmd_yesno "$CC" "-fPIC -shared $flags $src1 -o $output1"]
2263 if { $gnu2_tls_available_saved == 1 } {
2264 set gnu2_tls_available_saved [run_host_cmd_yesno "$CC" "$flags $src2 $output1 -o $output2"]
2265 if { $gnu2_tls_available_saved == 1 } {
2266 set gnu2_tls_available_saved [run_host_cmd_yesno "$output2" ""]
2267 }
2268 }
2269 remote_file host delete $src1
2270 remote_file host delete $output1
2271 remote_file host delete $src2
2272 remote_file host delete $output2
2273 file delete $src1 $src2
2274 }
2275 return $gnu2_tls_available_saved
2276}
This page took 0.991511 seconds and 4 git commands to generate.