Automatic date update in version.in
[deliverable/binutils-gdb.git] / ld / testsuite / lib / ld-lib.exp
CommitLineData
a2b64bed 1# Support routines for LD testsuite.
219d1afa 2# Copyright (C) 1994-2018 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 521# target being tested must match at least one. You may provide target
74ccf6db
JW
522# name "cfi" for any target supporting the CFI statements. You may
523# provide target name "shared" for any target supporting shared
524# libraries.
525#
526# alltargets: TARGET
527# Only run the test for TARGET. This may occur more than once; the
528# target being tested must match all of them.
261def70
HPN
529#
530# notarget: TARGET
531# Do not run the test for TARGET. This may occur more than once;
532# the target being tested must not match any of them.
533#
534# error: REGEX
535# An error with message matching REGEX must be emitted for the test
8d983e36
AB
536# to pass. The PROG, readelf, objdump, nm and objcopy options have
537# no meaning and need not be supplied if this is present. Multiple
538# "error" directives append to the expected linker error message.
261def70 539#
bb57e4c7
AB
540# error_output: FILE
541# Means the same as 'error', except the regular expression lines
542# are contains in FILE.
543#
bb00e284
HPN
544# warning: REGEX
545# Expect a linker warning matching REGEX. It is an error to issue
164de317
HPN
546# both "error" and "warning". Multiple "warning" directives
547# append to the expected linker warning message.
bb00e284 548#
bb57e4c7
AB
549# warning_output: FILE
550# Means the same as 'warning', except the regular expression
551# lines are contains in FILE.
552#
43d66c95
AB
553# map: FILE
554# Adding this option will cause the linker to generate a linker
555# map file, using the -Map=MAPFILE command line option. If
556# there is no -Map=MAPFILE in the 'ld: FLAGS' then one will be
557# added to the linker command line. The contents of the
558# generated MAPFILE are then compared against the regexp lines
559# in FILE using `regexp_diff' (see below for details).
560#
261def70
HPN
561# Each option may occur at most once unless otherwise mentioned.
562#
563# After the option lines come regexp lines. `run_dump_test' calls
564# `regexp_diff' to compare the output of the dumping tool against the
eb22018c
RS
565# regexps in FILE.d. `regexp_diff' is defined in binutils-common.exp;
566# see further comments there.
3b6fe0cc 567#
ef2b5578 568proc run_dump_test { name {extra_options {}} } {
261def70
HPN
569 global subdir srcdir
570 global OBJDUMP NM AS OBJCOPY READELF LD
571 global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
572 global host_triplet runtests
9a2ee7fc 573 global env verbose
647e4d46
L
574 global ld_elf_shared_opt
575
576 if { [is_elf_format] && [check_shared_lib_support] } {
577 set ld_extra_opt "$ld_elf_shared_opt"
578 } else {
579 set ld_extra_opt ""
580 }
261def70
HPN
581
582 if [string match "*/*" $name] {
583 set file $name
584 set name [file tail $name]
585 } else {
586 set file "$srcdir/$subdir/$name"
587 }
588
589 if ![runtest_file_p $runtests $name] then {
590 return
591 }
592
593 set opt_array [slurp_options "${file}.d"]
594 if { $opt_array == -1 } {
595 perror "error reading options from $file.d"
596 unresolved $subdir/$name
597 return
598 }
599 set dumpfile tmpdir/dump.out
600 set run_ld 0
cfe5266f 601 set run_objcopy 0
88bd1539 602 set objfile_names {}
261def70
HPN
603 set opts(as) {}
604 set opts(ld) {}
d6e0b160 605 set opts(ld_after_inputfiles) {}
261def70
HPN
606 set opts(xfail) {}
607 set opts(target) {}
74ccf6db 608 set opts(alltargets) {}
261def70
HPN
609 set opts(notarget) {}
610 set opts(objdump) {}
611 set opts(nm) {}
612 set opts(objcopy) {}
613 set opts(readelf) {}
614 set opts(name) {}
615 set opts(PROG) {}
616 set opts(source) {}
ef2b5578 617 set opts(dump) {}
261def70 618 set opts(error) {}
bb00e284 619 set opts(warning) {}
bb57e4c7
AB
620 set opts(error_output) {}
621 set opts(warning_output) {}
cfe5266f 622 set opts(objcopy_linked_file) {}
9854d43d 623 set opts(objcopy_objects) {}
43d66c95 624 set opts(map) {}
261def70
HPN
625
626 foreach i $opt_array {
627 set opt_name [lindex $i 0]
628 set opt_val [lindex $i 1]
629 if ![info exists opts($opt_name)] {
630 perror "unknown option $opt_name in file $file.d"
631 unresolved $subdir/$name
632 return
633 }
634
635 switch -- $opt_name {
636 xfail {}
637 target {}
74ccf6db 638 alltargets {}
261def70 639 notarget {}
164de317
HPN
640 warning {}
641 error {}
261def70 642 source {
df58fc94 643 # Move any source-specific as-flags to a separate list to
261def70
HPN
644 # simplify processing.
645 if { [llength $opt_val] > 1 } {
df58fc94 646 lappend asflags [lrange $opt_val 1 end]
261def70
HPN
647 set opt_val [lindex $opt_val 0]
648 } else {
df58fc94 649 lappend asflags {}
261def70 650 }
88bd1539
AB
651
652 # Create the object file name based on nothing but the source
653 # file name.
654 set new_objfile \
655 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]].o]
656 # But, sometimes, we have the exact same source filename in
657 # different directories (foo/src.s bar/src.s) which would lead
658 # us to try and create two src.o files. We detect this
659 # conflict here, and instead create src.o and src1.o.
660 set j 0
661 while { [lsearch $objfile_names $new_objfile] != -1 } {
662 incr j
663 set new_objfile \
664 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]]${j}.o]
665 }
666 lappend objfile_names $new_objfile
261def70
HPN
667 }
668 default {
669 if [string length $opts($opt_name)] {
670 perror "option $opt_name multiply set in $file.d"
671 unresolved $subdir/$name
672 return
673 }
674
675 # A single "# ld:" with no options should do the right thing.
676 if { $opt_name == "ld" } {
677 set run_ld 1
678 }
cfe5266f
HPN
679 # Likewise objcopy_linked_file.
680 if { $opt_name == "objcopy_linked_file" } {
681 set run_objcopy 1
682 }
261def70
HPN
683 }
684 }
7f6a71ff
JM
685 if { $opt_name == "as" || $opt_name == "ld" } {
686 set opt_val [subst $opt_val]
687 }
134fa82e
HPN
688
689 # Append differently whether it's a message (without space) or
690 # an option or list (with space).
691 switch -- $opt_name {
692 warning -
693 error {
694 append opts($opt_name) $opt_val
695 }
696 default {
697 set opts($opt_name) [concat $opts($opt_name) $opt_val]
698 }
699 }
261def70 700 }
ef2b5578
MR
701
702 foreach i $extra_options {
703 set opt_name [lindex $i 0]
704 set opt_val [lindex $i 1]
705 if ![info exists opts($opt_name)] {
706 perror "unknown option $opt_name given in extra_opts"
707 unresolved $subdir/$name
708 return
709 }
710 # Add extra option to end of existing option, adding space
711 # if necessary.
712 if { ![regexp "warning|error" $opt_name]
713 && [string length $opts($opt_name)] } {
714 append opts($opt_name) " "
715 }
716 append opts($opt_name) $opt_val
717 }
718
3935e1af
RS
719 foreach opt { as ld } {
720 regsub {\[big_or_little_endian\]} $opts($opt) \
721 [big_or_little_endian] opts($opt)
722 }
261def70
HPN
723
724 # Decide early whether we should run the test for this target.
725 if { [llength $opts(target)] > 0 } {
726 set targmatch 0
727 foreach targ $opts(target) {
728 if [istarget $targ] {
729 set targmatch 1
730 break
731 }
732 }
733 if { $targmatch == 0 } {
734 return
735 }
736 }
74ccf6db
JW
737 foreach targ $opts(alltargets) {
738 if ![istarget $targ] {
739 return
740 }
741 }
261def70
HPN
742 foreach targ $opts(notarget) {
743 if [istarget $targ] {
744 return
745 }
746 }
747
f364d1ca
AM
748 set program ""
749 # It's meaningless to require an output-testing method when we
750 # expect an error.
bb57e4c7 751 if { $opts(error) == "" && $opts(error_output) == "" } {
f364d1ca
AM
752 if {$opts(PROG) != ""} {
753 switch -- $opts(PROG) {
754 objdump { set program objdump }
755 nm { set program nm }
756 objcopy { set program objcopy }
757 readelf { set program readelf }
758 default
261def70
HPN
759 { perror "unrecognized program option $opts(PROG) in $file.d"
760 unresolved $subdir/$name
761 return }
f364d1ca
AM
762 }
763 } else {
261def70 764 # Guess which program to run, by seeing which option was specified.
f364d1ca
AM
765 foreach p {objdump objcopy nm readelf} {
766 if {$opts($p) != ""} {
767 if {$program != ""} {
768 perror "ambiguous dump program in $file.d"
769 unresolved $subdir/$name
770 return
771 } else {
772 set program $p
773 }
261def70
HPN
774 }
775 }
776 }
bb57e4c7 777 if { $program == "" \
9c98104c 778 && $opts(map) == "" \
bb57e4c7
AB
779 && $opts(warning) == "" \
780 && $opts(warning_output) == "" \
781 && $opts(error) == "" \
782 && $opts(error_output) == "" } {
261def70
HPN
783 perror "dump program unspecified in $file.d"
784 unresolved $subdir/$name
785 return
786 }
787 }
788
261def70
HPN
789 if { $opts(name) == "" } {
790 set testname "$subdir/$name"
791 } else {
792 set testname $opts(name)
793 }
794
795 if { $opts(source) == "" } {
796 set sourcefiles [list ${file}.s]
df58fc94 797 set asflags [list ""]
88bd1539 798 set objfile_names [list tmpdir/[file tail ${file}].o]
261def70
HPN
799 } else {
800 set sourcefiles {}
801 foreach sf $opts(source) {
b7b0b729
HPN
802 if { [string match "/*" $sf] } {
803 lappend sourcefiles "$sf"
f364d1ca 804 } else {
b7b0b729
HPN
805 lappend sourcefiles "$srcdir/$subdir/$sf"
806 }
261def70
HPN
807 }
808 }
809
ef2b5578
MR
810 if { $opts(dump) == "" } {
811 set dfile ${file}.d
812 } else {
813 set dfile $srcdir/$subdir/$opts(dump)
814 }
815
261def70
HPN
816 # Time to setup xfailures.
817 foreach targ $opts(xfail) {
818 setup_xfail $targ
819 }
820
821 # Assemble each file.
822 set objfiles {}
823 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
824 set sourcefile [lindex $sourcefiles $i]
df58fc94 825 set sourceasflags [lindex $asflags $i]
9854d43d 826 set run_objcopy_objects 0
827
828 if { [string match "*RUN_OBJCOPY*" $sourceasflags] } {
829 set run_objcopy_objects 1
830 }
831 regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
261def70 832
88bd1539 833 set objfile [lindex $objfile_names $i]
30dabe8a 834 catch "exec rm -f $objfile" exec_output
261def70 835 lappend objfiles $objfile
df58fc94 836 set cmd "$AS $ASFLAGS $opts(as) $sourceasflags -o $objfile $sourcefile"
261def70
HPN
837
838 send_log "$cmd\n"
7f6a71ff
JM
839 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
840 remote_upload host "ld.tmp"
841 set comp_output [prune_warnings [file_contents "ld.tmp"]]
842 remote_file host delete "ld.tmp"
843 remote_file build delete "ld.tmp"
261def70 844
7f6a71ff 845 if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
517c4166 846 send_log -- "$comp_output\n"
261def70 847 verbose "$comp_output" 3
f364d1ca
AM
848
849 set exitstat "succeeded"
850 if { $cmdret != 0 } { set exitstat "failed" }
851 verbose -log "$exitstat with: <$comp_output>"
261def70
HPN
852 fail $testname
853 return
854 }
9854d43d 855
856 if { $run_objcopy_objects } {
857 set cmd "$OBJCOPY $opts(objcopy_objects) $objfile"
858
859 send_log "$cmd\n"
860 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \
861 "" "/dev/null" "objcopy.tmp"]
862 remote_upload host "objcopy.tmp"
863 set comp_output [prune_warnings [file_contents "objcopy.tmp"]]
864 remote_file host delete "objcopy.tmp"
865 remote_file build delete "objcopy.tmp"
866
867 if { [lindex $cmdret 0] != 0 \
868 || ![string match "" $comp_output] } {
517c4166 869 send_log -- "$comp_output\n"
9854d43d 870 verbose "$comp_output" 3
871
872 set exitstat "succeeded"
873 if { $cmdret != 0 } { set exitstat "failed" }
874 verbose -log "$exitstat with: <$comp_output>"
875 fail $testname
876 return
877 }
878 }
261def70
HPN
879 }
880
bb57e4c7
AB
881 if { (($opts(warning) != "") && ($opts(error) != "")) \
882 || (($opts(warning) != "") && ($opts(error_output) != "")) \
883 || (($opts(warning) != "") && ($opts(warning_output) != "")) \
884 || (($opts(error) != "") && ($opts(warning_output) != "")) \
885 || (($opts(error) != "") && ($opts(error_output) != "")) \
886 || (($opts(warning_output) != "") && ($opts(error_output) != "")) } {
887 perror "$testname: bad mix of warning, error, warning_output, and error_output test-directives"
888 unresolved $testname
889 return
890 }
891
892 set check_ld(source) ""
758c5495 893 set check_ld(terminal) 0
bb57e4c7
AB
894 if { $opts(error) != "" \
895 || $opts(warning) != "" \
896 || $opts(error_output) != "" \
897 || $opts(warning_output) != "" } {
898
899 if { $opts(error) != "" || $opts(error_output) != "" } {
900 set check_ld(terminal) 1
901 } else {
902 set check_ld(terminal) 0
903 }
904
905 if { $opts(error) != "" || $opts(warning) != "" } {
906 set check_ld(source) "regex"
907 if { $opts(error) != "" } {
908 set check_ld(regex) $opts(error)
909 } else {
910 set check_ld(regex) $opts(warning)
911 }
912 } else {
913 set check_ld(source) "file"
914 if { $opts(error_output) != "" } {
915 set check_ld(file) $opts(error_output)
916 } else {
917 set check_ld(file) $opts(warning_output)
918 }
919 }
f364d1ca
AM
920 }
921
261def70
HPN
922 # Perhaps link the file(s).
923 if { $run_ld } {
924 set objfile "tmpdir/dump"
30dabe8a 925 catch "exec rm -f $objfile" exec_output
3e3f011f
RS
926
927 # Add -L$srcdir/$subdir so that the linker command can use
928 # linker scripts in the source directory.
647e4d46 929 set cmd "$LD $ld_extra_opt $LDFLAGS -L$srcdir/$subdir \
d6e0b160 930 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
261def70 931
43d66c95
AB
932 # If needed then check for, or add a -Map option.
933 set mapfile ""
934 if { $opts(map) != "" } then {
935 if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then {
936 # Found existing mapfile option
937 verbose -log "Existing mapfile '$mapfile' found"
938 } else {
939 # No mapfile option.
940 set mapfile "tmpdir/dump.map"
941 verbose -log "Adding mapfile '$mapfile'"
942 set cmd "$cmd -Map=$mapfile"
943 }
944 }
945
261def70 946 send_log "$cmd\n"
7f6a71ff
JM
947 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
948 remote_upload host "ld.tmp"
d3746675 949 set comp_output [file_contents "ld.tmp"]
7f6a71ff
JM
950 remote_file host delete "ld.tmp"
951 remote_file build delete "ld.tmp"
952 set cmdret [lindex $cmdret 0]
cfe5266f 953
f364d1ca 954 if { $cmdret == 0 && $run_objcopy } {
cfe5266f
HPN
955 set infile $objfile
956 set objfile "tmpdir/dump1"
7f6a71ff 957 remote_file host delete $objfile
cfe5266f
HPN
958
959 # Note that we don't use OBJCOPYFLAGS here; any flags must be
960 # explicitly specified.
961 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
962
963 send_log "$cmd\n"
7f6a71ff
JM
964 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
965 remote_upload host "ld.tmp"
d3746675 966 append comp_output [file_contents "ld.tmp"]
7f6a71ff
JM
967 remote_file host delete "ld.tmp"
968 remote_file build delete "ld.tmp"
969 set cmdret [lindex $cmdret 0]
f364d1ca
AM
970 }
971
7f6a71ff 972 regsub "\n$" $comp_output "" comp_output
bb57e4c7 973 if { $cmdret != 0 || $comp_output != "" || $check_ld(source) != "" } then {
f364d1ca
AM
974 set exitstat "succeeded"
975 if { $cmdret != 0 } { set exitstat "failed" }
bb57e4c7 976
2e9af2d0 977 if { $check_ld(source) == "regex" } {
bb57e4c7
AB
978 verbose -log "$exitstat with: <$comp_output>, expected: <$check_ld(regex)>"
979 } elseif { $check_ld(source) == "file" } {
980 verbose -log "$exitstat with: <$comp_output>, expected in file $check_ld(file)"
981 set_file_contents "tmpdir/ld.messages" "$comp_output"
982 } else {
983 verbose -log "$exitstat with: <$comp_output>, no expected output"
984 }
517c4166 985 send_log -- "$comp_output\n"
f364d1ca
AM
986 verbose "$comp_output" 3
987
bb57e4c7
AB
988 if { (($check_ld(source) == "") == ($comp_output == "")) \
989 && (($cmdret == 0) == ($check_ld(terminal) == 0)) \
990 && ((($check_ld(source) == "regex") \
991 && ($check_ld(regex) == "") == ($comp_output == "") \
176047c9 992 && [regexp -- $check_ld(regex) $comp_output]) \
bb57e4c7 993 || (($check_ld(source) == "file") \
62bdf2d6 994 && (![regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$check_ld(file)"]))) } {
bb57e4c7
AB
995 # We have the expected output from ld.
996 if { $check_ld(terminal) || $program == "" } {
f364d1ca
AM
997 pass $testname
998 return
cfe5266f 999 }
f364d1ca 1000 } else {
cfe5266f
HPN
1001 fail $testname
1002 return
1003 }
1004 }
43d66c95
AB
1005
1006 if { $opts(map) != "" } then {
1007 # Check the map file matches.
1008 set map_pattern_file $srcdir/$subdir/$opts(map)
1009 verbose -log "Compare '$mapfile' against '$map_pattern_file'"
1010 if { [regexp_diff $mapfile $map_pattern_file] } then {
1011 fail "$testname (map file check)"
1012 } else {
1013 pass "$testname (map file check)"
1014 }
9c98104c
AB
1015
1016 if { $program == "" } then {
1017 return
1018 }
43d66c95 1019 }
261def70 1020 } else {
88bd1539 1021 set objfile [lindex $objfiles 0]
261def70
HPN
1022 }
1023
1024 # We must not have expected failure if we get here.
1025 if { $opts(error) != "" } {
1026 fail $testname
cfe5266f 1027 return
261def70
HPN
1028 }
1029
f364d1ca
AM
1030 set progopts1 $opts($program)
1031 eval set progopts \$[string toupper $program]FLAGS
1032 eval set binary \$[string toupper $program]
1033
7f6a71ff 1034 if { ![is_remote host] && [which $binary] == 0 } {
261def70
HPN
1035 untested $testname
1036 return
1037 }
1038
1039 if { $progopts1 == "" } { set $progopts1 "-r" }
1040 verbose "running $binary $progopts $progopts1" 3
1041
1042 # Objcopy, unlike the other two, won't send its output to stdout,
1043 # so we have to run it specially.
3e8cba19 1044 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
261def70
HPN
1045 if { $program == "objcopy" } {
1046 set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
3e8cba19
AM
1047 }
1048
1049 # Ensure consistent sorting of symbols
1050 if {[info exists env(LC_ALL)]} {
1051 set old_lc_all $env(LC_ALL)
1052 }
1053 set env(LC_ALL) "C"
1054 send_log "$cmd\n"
7f6a71ff 1055 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
164de317 1056 set cmdret [lindex $cmdret 0]
7f6a71ff
JM
1057 remote_upload host "ld.tmp"
1058 set comp_output [prune_warnings [file_contents "ld.tmp"]]
1059 remote_file host delete "ld.tmp"
1060 remote_file build delete "ld.tmp"
3e8cba19
AM
1061 if {[info exists old_lc_all]} {
1062 set env(LC_ALL) $old_lc_all
261def70 1063 } else {
3e8cba19
AM
1064 unset env(LC_ALL)
1065 }
164de317
HPN
1066 if { $cmdret != 0 || $comp_output != "" } {
1067 send_log "exited abnormally with $cmdret, output:$comp_output\n"
3e8cba19
AM
1068 fail $testname
1069 return
261def70
HPN
1070 }
1071
9a2ee7fc 1072 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
ef2b5578 1073 if { [regexp_diff $dumpfile "${dfile}"] } then {
261def70 1074 fail $testname
9a2ee7fc 1075 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
261def70
HPN
1076 return
1077 }
1078
1079 pass $testname
1080}
1081
1082proc slurp_options { file } {
5a68afcf
RM
1083 # If options_regsub(foo) is set to {a b}, then the contents of a
1084 # "#foo:" line will have regsub -all applied to replace a with b.
1085 global options_regsub
1086
261def70
HPN
1087 if [catch { set f [open $file r] } x] {
1088 #perror "couldn't open `$file': $x"
1089 perror "$x"
1090 return -1
1091 }
1092 set opt_array {}
1093 # whitespace expression
1094 set ws {[ ]*}
1095 set nws {[^ ]*}
1096 # whitespace is ignored anywhere except within the options list;
cfe5266f
HPN
1097 # option names are alphabetic plus underscore only.
1098 set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
261def70
HPN
1099 while { [gets $f line] != -1 } {
1100 set line [string trim $line]
1101 # Whitespace here is space-tab.
1102 if [regexp $pat $line xxx opt_name opt_val] {
1103 # match!
5a68afcf
RM
1104 if [info exists options_regsub($opt_name)] {
1105 set subst $options_regsub($opt_name)
1106 regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \
1107 opt_val
1108 }
261def70
HPN
1109 lappend opt_array [list $opt_name $opt_val]
1110 } else {
1111 break
1112 }
1113 }
1114 close $f
1115 return $opt_array
1116}
1117
261def70
HPN
1118proc file_contents { filename } {
1119 set file [open $filename r]
1120 set contents [read $file]
1121 close $file
1122 return $contents
1123}
bffbf940 1124
5d3236ee
DK
1125proc set_file_contents { filename contents } {
1126 set file [open $filename w]
1127 puts $file "$contents"
1128 close $file
1129}
1130
d8880531
L
1131# Create an archive using ar
1132#
fa0a16b1 1133proc ar_simple_create { ar aropts target objects } {
d8880531
L
1134 remote_file host delete $target
1135
1a215085 1136 set exec_output [run_host_cmd "$ar" "-rc $aropts $target $objects"]
d8880531
L
1137 set exec_output [prune_warnings $exec_output]
1138
1139 if [string match "" $exec_output] then {
1140 send_log "$exec_output\n"
1141 return 1
1142 } else {
1143 return 0
1144 }
1145}
1146
9147e853
JJ
1147# List contains test-items with 3 items followed by 2 lists, one item and
1148# one optional item:
894891db 1149# 0:name
897aea50
MR
1150# 1:ld/ar leading options, placed before object files
1151# 2:ld/ar trailing options, placed after object files
1152# 3:assembler options
1153# 4:filenames of assembler files
1154# 5:list of actions, options and expected outputs.
1155# 6:name of output file
1156# 7:compiler flags (optional)
3b6fe0cc 1157#
894891db
NC
1158# Actions: { command command-line-options file-containg-expected-output-regexps }
1159# Commands:
1160# objdump: Apply objdump options on result.
1161# nm: Apply nm options on result.
1162# readelf: Apply readelf options on result.
5a68afcf 1163# ld: Don't apply anything on result. Compare output during linking with
894891db
NC
1164# the file containing regexps (which is the second arg, not the third).
1165# Note that this *must* be the first action if it is to be used at all;
1166# in all other cases, any output from the linker during linking is
1167# treated as a sign of an error and FAILs the test.
3b6fe0cc 1168#
5df1bc57
AM
1169# args is an optional list of target triplets to be xfailed.
1170#
1171proc run_ld_link_tests { ldtests args } {
bffbf940
JJ
1172 global ld
1173 global as
1174 global nm
d8880531 1175 global ar
bffbf940
JJ
1176 global objdump
1177 global READELF
1178 global srcdir
1179 global subdir
1180 global env
9147e853
JJ
1181 global CC
1182 global CFLAGS
eca41774 1183 global runtests
5d3236ee 1184 global exec_output
647e4d46
L
1185 global ld_elf_shared_opt
1186
1187 if { [is_elf_format] && [check_shared_lib_support] } {
1188 set ld_extra_opt "$ld_elf_shared_opt"
1189 } else {
1190 set ld_extra_opt ""
1191 }
bffbf940
JJ
1192
1193 foreach testitem $ldtests {
1194 set testname [lindex $testitem 0]
eca41774
DK
1195
1196 if ![runtest_file_p $runtests $testname] then {
1197 continue
1198 }
1199
5df1bc57
AM
1200 foreach target $args {
1201 setup_xfail $target
1202 }
1203
bffbf940 1204 set ld_options [lindex $testitem 1]
897aea50
MR
1205 set ld_after [lindex $testitem 2]
1206 set as_options [lindex $testitem 3]
1207 set src_files [lindex $testitem 4]
1208 set actions [lindex $testitem 5]
1209 set binfile tmpdir/[lindex $testitem 6]
1210 set cflags [lindex $testitem 7]
bffbf940
JJ
1211 set objfiles {}
1212 set is_unresolved 0
1213 set failed 0
5d3236ee
DK
1214 set maybe_failed 0
1215 set ld_output ""
bffbf940
JJ
1216
1217# verbose -log "Testname is $testname"
1218# verbose -log "ld_options is $ld_options"
897aea50 1219# verbose -log "ld_after is $ld_after"
bffbf940 1220# verbose -log "as_options is $as_options"
9147e853 1221# verbose -log "src_files is $src_files"
bffbf940
JJ
1222# verbose -log "actions is $actions"
1223# verbose -log "binfile is $binfile"
1224
1225 # Assemble each file in the test.
9147e853 1226 foreach src_file $src_files {
74d44110
MR
1227 set fileroot "[file rootname [file tail $src_file]]"
1228 set objfile "tmpdir/$fileroot.o"
bffbf940
JJ
1229 lappend objfiles $objfile
1230
9147e853 1231 if { [file extension $src_file] == ".c" } {
74d44110 1232 set as_file "tmpdir/$fileroot.s"
9147e853
JJ
1233 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1234 set is_unresolved 1
1235 break
1236 }
1237 } else {
1238 set as_file "$srcdir/$subdir/$src_file"
1239 }
1240 if ![ld_assemble $as "$as_options $as_file" $objfile] {
bffbf940
JJ
1241 set is_unresolved 1
1242 break
1243 }
1244 }
1245
1246 # Catch assembler errors.
77c56f44 1247 if { $is_unresolved } {
bffbf940
JJ
1248 unresolved $testname
1249 continue
1250 }
1251
abc868c6
AM
1252 if { $binfile eq "tmpdir/" } {
1253 # compile only
1254 } elseif { [regexp ".*\\.a$" $binfile] } {
897aea50 1255 if { ![ar_simple_create $ar $ld_options $binfile "$objfiles $ld_after"] } {
d8880531 1256 set failed 1
d8880531 1257 }
d9816402 1258 } elseif { ![ld_link $ld $binfile "$ld_extra_opt -L$srcdir/$subdir $ld_options $objfiles $ld_after"] } {
5d3236ee
DK
1259 set maybe_failed 1
1260 set ld_output "$exec_output"
d8880531
L
1261 }
1262
77c56f44 1263 if { !$failed } {
bffbf940
JJ
1264 foreach actionlist $actions {
1265 set action [lindex $actionlist 0]
1266 set progopts [lindex $actionlist 1]
1267
1268 # There are actions where we run regexp_diff on the
1269 # output, and there are other actions (presumably).
1270 # Handling of the former look the same.
1271 set dump_prog ""
1272 switch -- $action {
1273 objdump
1274 { set dump_prog $objdump }
1275 nm
1276 { set dump_prog $nm }
1277 readelf
1278 { set dump_prog $READELF }
5d3236ee
DK
1279 ld
1280 { set dump_prog "ld" }
bffbf940
JJ
1281 default
1282 {
1283 perror "Unrecognized action $action"
1284 set is_unresolved 1
1285 break
1286 }
1287 }
1288
5d3236ee 1289 if { $action == "ld" } {
894891db
NC
1290 set regexpfile $progopts
1291 verbose "regexpfile is $srcdir/$subdir/$regexpfile"
5d3236ee
DK
1292 set_file_contents "tmpdir/ld.messages" "$ld_output"
1293 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
894891db 1294 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$regexpfile"] } then {
5d3236ee
DK
1295 verbose "output is $ld_output" 2
1296 set failed 1
1297 break
1298 }
1299 set maybe_failed 0
77c56f44 1300 } elseif { !$maybe_failed && $dump_prog != "" } {
bffbf940
JJ
1301 set dumpfile [lindex $actionlist 2]
1302 set binary $dump_prog
1303
1304 # Ensure consistent sorting of symbols
1305 if {[info exists env(LC_ALL)]} {
1306 set old_lc_all $env(LC_ALL)
1307 }
1308 set env(LC_ALL) "C"
7f6a71ff
JM
1309 set cmd "$binary $progopts $binfile"
1310 set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
bffbf940 1311 send_log "$cmd\n"
7f6a71ff
JM
1312 remote_upload host "ld.stderr"
1313 set comp_output [prune_warnings [file_contents "ld.stderr"]]
1314 remote_file host delete "ld.stderr"
1315 remote_file build delete "ld.stderr"
5a68afcf 1316
bffbf940
JJ
1317 if {[info exists old_lc_all]} {
1318 set env(LC_ALL) $old_lc_all
1319 } else {
1320 unset env(LC_ALL)
1321 }
bffbf940
JJ
1322
1323 if ![string match "" $comp_output] then {
1324 send_log "$comp_output\n"
1325 set failed 1
1326 break
1327 }
1328
7f6a71ff
JM
1329 remote_upload host "dump.out"
1330
bffbf940
JJ
1331 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1332 verbose "output is [file_contents "dump.out"]" 2
1333 set failed 1
7f6a71ff
JM
1334 remote_file build delete "dump.out"
1335 remote_file host delete "dump.out"
bffbf940
JJ
1336 break
1337 }
7f6a71ff
JM
1338 remote_file build delete "dump.out"
1339 remote_file host delete "dump.out"
bffbf940
JJ
1340 }
1341 }
bffbf940
JJ
1342 }
1343
77c56f44 1344 if { $is_unresolved } {
bffbf940 1345 unresolved $testname
77c56f44
RS
1346 } elseif { $maybe_failed || $failed } {
1347 fail $testname
1348 } else {
1349 pass $testname
bffbf940
JJ
1350 }
1351 }
1352}
1353
252b5132
RH
1354# This definition is taken from an unreleased version of DejaGnu. Once
1355# that version gets released, and has been out in the world for a few
1356# months at least, it may be safe to delete this copy.
1357if ![string length [info proc prune_warnings]] {
1358 #
1359 # prune_warnings -- delete various system verbosities from TEXT
1360 #
1361 # An example is:
1362 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1363 #
1364 # Sites with particular verbose os's may wish to override this in site.exp.
1365 #
1366 proc prune_warnings { text } {
1367 # This is from sun4's. Do it for all machines for now.
1368 # The "\\1" is to try to preserve a "\n" but only if necessary.
1369 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1370
1371 # It might be tempting to get carried away and delete blank lines, etc.
1372 # Just delete *exactly* what we're ask to, and that's it.
1373 return $text
1374 }
1375}
24edc24d 1376
c8c140d9 1377# ldtests contains test-items with 3 items followed by 1 lists, 2 items
fab4a87f 1378# and 3 optional items:
c8c140d9 1379# 0:name
fef75122 1380# 1:ld leading options, placed before object files
c8c140d9 1381# 2:assembler options
55255dae 1382# 3:filenames of source files
c8c140d9
BE
1383# 4:name of output file
1384# 5:expected output
1385# 6:compiler flags (optional)
55255dae 1386# 7:language (optional)
fab4a87f 1387# 8:linker warning (optional)
fef75122 1388# 9:ld trailing options, placed after object files (optional)
982c6f26 1389# args is an optional list of target triplets to be xfailed.
c8c140d9 1390
982c6f26 1391proc run_ld_link_exec_tests { ldtests args } {
24edc24d
L
1392 global ld
1393 global as
1394 global srcdir
1395 global subdir
1396 global env
1397 global CC
55255dae 1398 global CXX
24edc24d 1399 global CFLAGS
58ffc3bd 1400 global CXXFLAGS
22ec3bd1 1401 global errcnt
fab4a87f 1402 global exec_output
9966f7ee 1403 global board_cflags
98d72909 1404 global STATIC_LDFLAGS
9966f7ee
JW
1405
1406 # When using GCC as the linker driver, we need to specify board cflags when
1407 # linking because cflags may contain linker options. For example when
1408 # linker options are included in GCC spec files then we need the -specs
1409 # option.
1410 if [board_info [target_info name] exists cflags] {
1411 set board_cflags " [board_info [target_info name] cflags]"
1412 } else {
1413 set board_cflags ""
1414 }
24edc24d
L
1415
1416 foreach testitem $ldtests {
982c6f26 1417 foreach target $args {
c8c140d9
BE
1418 setup_xfail $target
1419 }
24edc24d
L
1420 set testname [lindex $testitem 0]
1421 set ld_options [lindex $testitem 1]
1422 set as_options [lindex $testitem 2]
1423 set src_files [lindex $testitem 3]
1424 set binfile tmpdir/[lindex $testitem 4]
1425 set expfile [lindex $testitem 5]
1426 set cflags [lindex $testitem 6]
55255dae 1427 set lang [lindex $testitem 7]
fab4a87f 1428 set warning [lindex $testitem 8]
fef75122 1429 set ld_after [lindex $testitem 9]
24edc24d 1430 set objfiles {}
24edc24d
L
1431 set failed 0
1432
1433# verbose -log "Testname is $testname"
1434# verbose -log "ld_options is $ld_options"
1435# verbose -log "as_options is $as_options"
1436# verbose -log "src_files is $src_files"
24edc24d
L
1437# verbose -log "binfile is $binfile"
1438
1439 # Assemble each file in the test.
1440 foreach src_file $src_files {
74d44110
MR
1441 set fileroot "[file rootname [file tail $src_file]]"
1442 set objfile "tmpdir/$fileroot.o"
24edc24d
L
1443 lappend objfiles $objfile
1444
58ffc3bd 1445 if { [ string match "c++" $lang ] } {
a44d0bd7 1446 set cmd "$CXX -c $CXXFLAGS $cflags"
58ffc3bd 1447 } else {
a44d0bd7 1448 set cmd "$CC -c $CFLAGS $cflags"
58ffc3bd 1449 }
a44d0bd7
AM
1450 if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] {
1451 set failed 1
1452 break
1453 }
1454 }
1455 if { $failed != 0 } {
1456 unresolved $testname
1457 continue
cb5ab6c8 1458 }
a10e6b21 1459
d9816402
AM
1460 if { [ string match "c++" $lang ] } {
1461 set link_proc ld_link
cb5ab6c8 1462 set link_cmd $CXX
cb5ab6c8
L
1463 } else {
1464 set link_proc ld_link
d9816402 1465 set link_cmd $CC
cb5ab6c8 1466 }
24edc24d 1467
abc868c6
AM
1468 if { $binfile eq "tmpdir/" } {
1469 # compile only
1470 pass $testname
1471 continue;
98d72909
L
1472 } else {
1473 if { [string match "" $STATIC_LDFLAGS] \
1474 && [regexp -- ".* \[-\]+static .*" " $board_cflags $ld_options $objfiles $ld_after "] } {
1475 untested $testname
1476 continue
1477 }
1478 if ![$link_proc $link_cmd $binfile "$board_cflags -L$srcdir/$subdir $ld_options $objfiles $ld_after"] {
1479 set failed 1
1480 }
cb5ab6c8
L
1481 }
1482
1483 # Check if exec_output is expected.
1484 if { $warning != "" } then {
1485 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1486 if { [regexp $warning $exec_output] } then {
a10e6b21 1487 set failed 0
cb5ab6c8
L
1488 } else {
1489 set failed 1
fab4a87f 1490 }
cb5ab6c8 1491 }
fab4a87f 1492
d9816402 1493 if { $failed == 0 && [isnative] } {
cb5ab6c8
L
1494 send_log "Running: $binfile > $binfile.out\n"
1495 verbose "Running: $binfile > $binfile.out"
1496 catch "exec $binfile > $binfile.out" exec_output
fab4a87f 1497
cb5ab6c8
L
1498 if ![string match "" $exec_output] then {
1499 send_log "$exec_output\n"
1500 verbose "$exec_output" 1
1501 set failed 1
1502 } else {
1503 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1504 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1505 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1506 set exec_output [prune_warnings $exec_output]
5a68afcf 1507
24edc24d
L
1508 if ![string match "" $exec_output] then {
1509 send_log "$exec_output\n"
1510 verbose "$exec_output" 1
1511 set failed 1
1512 }
1513 }
cb5ab6c8 1514 }
24edc24d 1515
cb5ab6c8
L
1516 if { $failed != 0 } {
1517 fail $testname
d9816402
AM
1518 } elseif ![isnative] {
1519 unsupported $testname
cb5ab6c8
L
1520 } else {
1521 set errcnt 0
1522 pass $testname
24edc24d 1523 }
24edc24d
L
1524 }
1525}
d2dee3b2
L
1526
1527# List contains test-items with 3 items followed by 2 lists, one item and
1528# one optional item:
55255dae 1529# 0:name
fa0a16b1 1530# 1:ld or ar options
55255dae
L
1531# 2:compile options
1532# 3:filenames of source files
1533# 4:action and options.
1534# 5:name of output file
1535# 6:language (optional)
d2dee3b2
L
1536#
1537# Actions:
1538# objdump: Apply objdump options on result. Compare with regex (last arg).
1539# nm: Apply nm options on result. Compare with regex (last arg).
1540# readelf: Apply readelf options on result. Compare with regex (last arg).
2bd7f877
AB
1541# warning: Check linker output against regex (last arg).
1542# error: Like 'warning' but checking output in error case.
1543# warning_output: Check linker output against regex in a file (last arg).
1544# error_output: Like 'warning_output' but checking output in error case.
d2dee3b2
L
1545#
1546proc run_cc_link_tests { ldtests } {
1547 global nm
1548 global objdump
1549 global READELF
1550 global srcdir
1551 global subdir
1552 global env
1553 global CC
55255dae 1554 global CXX
d2dee3b2 1555 global CFLAGS
58ffc3bd 1556 global CXXFLAGS
d8880531 1557 global ar
dd98f8d2 1558 global exec_output
603c4399 1559 global board_cflags
98d72909 1560 global STATIC_LDFLAGS
603c4399
JW
1561
1562 if [board_info [target_info name] exists cflags] {
1563 set board_cflags " [board_info [target_info name] cflags]"
1564 } else {
1565 set board_cflags ""
1566 }
d2dee3b2
L
1567
1568 foreach testitem $ldtests {
1569 set testname [lindex $testitem 0]
1570 set ldflags [lindex $testitem 1]
1571 set cflags [lindex $testitem 2]
1572 set src_files [lindex $testitem 3]
1573 set actions [lindex $testitem 4]
1574 set binfile tmpdir/[lindex $testitem 5]
55255dae 1575 set lang [lindex $testitem 6]
d2dee3b2
L
1576 set objfiles {}
1577 set is_unresolved 0
1578 set failed 0
2bd7f877
AB
1579 set check_ld(terminal) 0
1580 set check_ld(source) ""
d2dee3b2 1581
c3e11cbe
AM
1582 #verbose -log "testname is $testname"
1583 #verbose -log "ldflags is $ldflags"
1584 #verbose -log "cflags is $cflags"
1585 #verbose -log "src_files is $src_files"
1586 #verbose -log "actions is $actions"
1587 #verbose -log "binfile is $binfile"
1588 #verbose -log "lang is $lang"
2bd7f877
AB
1589
1590 foreach actionlist $actions {
1591 set action [lindex $actionlist 0]
1592 set progopts [lindex $actionlist 1]
1593
1594 # Find actions related to error/warning processing.
1595 switch -- $action {
1596 error
1597 {
1598 set check_ld(source) "regexp"
1599 set check_ld(regexp) $progopts
1600 set check_ld(terminal) 1
1601 }
1602 warning
1603 {
1604 set check_ld(source) "regexp"
1605 set check_ld(regexp) $progopts
1606 }
1607 error_output
1608 {
1609 set check_ld(source) "file"
1610 set check_ld(file) $progopts
1611 set check_ld(terminal) 1
1612 }
1613 warning_output
1614 {
1615 set check_ld(source) "file"
1616 set check_ld(file) $progopts
1617 }
1618 }
1619 }
c3e11cbe 1620
d2dee3b2
L
1621 # Compile each file in the test.
1622 foreach src_file $src_files {
74d44110
MR
1623 set fileroot "[file rootname [file tail $src_file]]"
1624 set objfile "tmpdir/$fileroot.o"
d2dee3b2
L
1625 lappend objfiles $objfile
1626
58ffc3bd 1627 if { [ string match "c++" $lang ] } {
a44d0bd7 1628 set cmd "$CXX -c $CXXFLAGS $cflags"
58ffc3bd 1629 } else {
a44d0bd7 1630 set cmd "$CC -c $CFLAGS $cflags"
58ffc3bd 1631 }
a44d0bd7
AM
1632 if ![ld_compile $cmd $srcdir/$subdir/$src_file $objfile] {
1633 set failed 1
1634 break
1635 }
1636 }
1637 if { $failed != 0 } {
1638 unresolved $testname
1639 continue
d2dee3b2
L
1640 }
1641
1642 # Clear error and warning counts.
1643 reset_vars
1644
55255dae
L
1645 if { [ string match "c++" $lang ] } {
1646 set cc_cmd $CXX
1647 } else {
1648 set cc_cmd $CC
1649 }
1650
abc868c6
AM
1651 if { $binfile eq "tmpdir/" } {
1652 # compile only
1653 } elseif { [regexp ".*\\.a$" $binfile] } {
fa0a16b1 1654 if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
d8880531 1655 set failed 1
d8880531 1656 }
741e0128 1657 } else {
98d72909
L
1658 if { [string match "" $STATIC_LDFLAGS] \
1659 && [regexp -- ".* \[-\]+static .*" " $board_cflags $ldflags $objfiles "] } {
1660 untested $testname
1661 continue
1662 }
2bd7f877
AB
1663 ld_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"
1664 set ld_output "$exec_output"
741e0128 1665
2bd7f877
AB
1666 if { $check_ld(source) == "regexp" } then {
1667 # Match output against regexp argument.
1668 verbose -log "returned with: <$ld_output>, expected: <$check_ld(regexp)>"
1669 if { ![regexp $check_ld(regexp) $ld_output] } then {
dd98f8d2
NC
1670 set failed 1
1671 }
2bd7f877
AB
1672 } elseif { $check_ld(source) == "file" } then {
1673 # Match output against patterns in a file.
1674 set_file_contents "tmpdir/ld.messages" "$ld_output"
1675 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
1676 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$check_ld(file)"] } then {
1677 verbose "output is $ld_output" 2
1678 set failed 1
1679 }
1680 }
1681
1682 if { $check_ld(source) != "" } then {
1683 if { $ld_output == "" } then {
1684 verbose -log "Linker was expected to give error or warning"
1685 set failed 1
1686 }
1687 } else {
1688 if { $ld_output != "" } then {
1689 verbose -log "Unexpected linker warning or error"
1690 set failed 1
1691 }
741e0128 1692 }
d8880531
L
1693 }
1694
1695 if { $failed == 0 } {
d2dee3b2
L
1696 foreach actionlist $actions {
1697 set action [lindex $actionlist 0]
1698 set progopts [lindex $actionlist 1]
1699
1700 # There are actions where we run regexp_diff on the
1701 # output, and there are other actions (presumably).
1702 # Handling of the former look the same.
1703 set dump_prog ""
1704 switch -- $action {
1705 objdump
1706 { set dump_prog $objdump }
1707 nm
1708 { set dump_prog $nm }
1709 readelf
1710 { set dump_prog $READELF }
2bd7f877
AB
1711 error {}
1712 warning {}
1713 error_output {}
1714 warning_output {}
d2dee3b2
L
1715 default
1716 {
1717 perror "Unrecognized action $action"
1718 set is_unresolved 1
1719 break
1720 }
1721 }
1722
1723 if { $dump_prog != "" } {
1724 set dumpfile [lindex $actionlist 2]
1725 set binary $dump_prog
1726
1727 # Ensure consistent sorting of symbols
1728 if {[info exists env(LC_ALL)]} {
1729 set old_lc_all $env(LC_ALL)
1730 }
1731 set env(LC_ALL) "C"
1732 set cmd "$binary $progopts $binfile > dump.out"
1733 send_log "$cmd\n"
1734 catch "exec $cmd" comp_output
1735 if {[info exists old_lc_all]} {
1736 set env(LC_ALL) $old_lc_all
1737 } else {
1738 unset env(LC_ALL)
1739 }
1740 set comp_output [prune_warnings $comp_output]
1741
1742 if ![string match "" $comp_output] then {
1743 send_log "$comp_output\n"
1744 set failed 1
1745 break
1746 }
1747
1748 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1749 verbose "output is [file_contents "dump.out"]" 2
1750 set failed 1
1751 break
1752 }
1753 }
1754 }
d2dee3b2
L
1755 }
1756
d44ea5d0 1757 if { $failed } {
abc868c6 1758 fail $testname
d44ea5d0 1759 } elseif { $is_unresolved } {
d2dee3b2 1760 unresolved $testname
d44ea5d0
AM
1761 } else {
1762 pass $testname
d2dee3b2
L
1763 }
1764 }
1765}
430a16a5
NC
1766
1767# Returns true if --gc-sections is supported on the target.
1768
1769proc check_gc_sections_available { } {
1770 global gc_sections_available_saved
1771 global ld
5a68afcf 1772
430a16a5
NC
1773 if {![info exists gc_sections_available_saved]} {
1774 # Some targets don't support gc-sections despite whatever's
1775 # advertised by ld's options.
fc3eec7e 1776 if { [istarget d30v-*-*]
59c108f7 1777 || [istarget dlx-*-*]
59c108f7 1778 || [istarget pj*-*-*]
0220170b 1779 || [istarget pru*-*-*]
59c108f7
NC
1780 || [istarget alpha-*-*]
1781 || [istarget hppa*64-*-*]
59c108f7
NC
1782 || [istarget ia64-*-*]
1783 || [istarget mep-*-*]
0f088b2a 1784 || [istarget mn10200-*-*] } {
430a16a5
NC
1785 set gc_sections_available_saved 0
1786 return 0
1787 }
1788
1789 # elf2flt uses -q (--emit-relocs), which is incompatible with
1790 # --gc-sections.
1791 if { [board_info target exists ldflags]
1792 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1793 set gc_sections_available_saved 0
1794 return 0
1795 }
1796
430a16a5 1797 # Check if the ld used by gcc supports --gc-sections.
1d5316ab
AM
1798 # FIXME: this test is useless since ld --help always says
1799 # --gc-sections is available
430a16a5
NC
1800 set ld_output [remote_exec host $ld "--help"]
1801 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1802 set gc_sections_available_saved 1
1803 } else {
1804 set gc_sections_available_saved 0
1805 }
1806 }
1807 return $gc_sections_available_saved
1808}
33aa234e 1809
1d5316ab 1810# Returns true if -shared is supported on the target
1d5316ab
AM
1811
1812proc check_shared_lib_support { } {
05a5feaf
AM
1813 global shared_available_saved
1814 global ld
1815
1816 if {![info exists shared_available_saved]} {
1817 set ld_output [remote_exec host $ld "-shared"]
1818 if { [ string first "not supported" $ld_output ] >= 0 } {
1819 set shared_available_saved 0
1820 } else {
1821 set shared_available_saved 1
1822 }
1d5316ab 1823 }
05a5feaf 1824 return $shared_available_saved
1d5316ab
AM
1825}
1826
b62b1f71
AM
1827# Return true if target uses genelf.em (assuming it is ELF).
1828proc is_generic_elf { } {
1829 if { [istarget "d30v-*-*"]
1830 || [istarget "dlx-*-*"]
1831 || [istarget "fr30-*-*"]
1832 || ([istarget "frv-*-*"] && ![istarget "frv-*-linux*"])
1833 || [istarget "ft32-*-*"]
b62b1f71
AM
1834 || [istarget "iq2000-*-*"]
1835 || [istarget "mn10200-*-*"]
1836 || [istarget "moxie-*-*"]
1837 || [istarget "msp430-*-*"]
1838 || [istarget "mt-*-*"]
1839 || [istarget "pj*-*-*"] } {
1840 return 1;
1841 }
1842 return 0;
1843}
1844
bdd32e03
AM
1845proc is_underscore_target { } {
1846 global is_underscore_target_saved
1847 global target_triplet
1848 global srcdir
1849
1850 if { ![info exists is_underscore_target_saved] } {
1851 set cmd "targ=$target_triplet . $srcdir/../../bfd/config.bfd &&"
1852 append cmd { echo "$targ_underscore"}
1853 verbose -log "$cmd"
1854 set status [catch {exec sh -c $cmd} result]
1855 if { $status == 0 && [string match "yes" $result] } {
1856 set is_underscore_target_saved 1
1857 } else {
1858 set is_underscore_target_saved 0
1859 }
1860 }
1861 return $is_underscore_target_saved
1862}
1863
5d3236ee
DK
1864# Returns true if the target ld supports the plugin API.
1865proc check_plugin_api_available { } {
1866 global plugin_api_available_saved
1867 global ld
1868 if {![info exists plugin_api_available_saved]} {
1869 # Check if the ld used by gcc supports --plugin.
1870 set ld_output [remote_exec host $ld "--help"]
2d03dd2f 1871 if { [ string first "-plugin PLUGIN" $ld_output ] >= 0 } {
5d3236ee
DK
1872 set plugin_api_available_saved 1
1873 } else {
1874 set plugin_api_available_saved 0
1875 }
1876 }
1877 return $plugin_api_available_saved
1878}
1879
3f730821
HPN
1880# Sets ld_sysroot to the current sysroot (empty if not supported) and
1881# returns true if the target ld supports sysroot.
bdd65db9 1882proc check_sysroot_available { } {
3f730821 1883 global ld_sysroot_available_saved ld ld_sysroot
bdd65db9 1884 if {![info exists ld_sysroot_available_saved]} {
3f730821
HPN
1885 # Check if ld supports --sysroot *other* than empty.
1886 set ld_sysroot [string trimright [lindex [remote_exec host $ld "--print-sysroot"] 1]]
1887 if { $ld_sysroot == "" } {
bdd65db9
HPN
1888 set ld_sysroot_available_saved 0
1889 } else {
1890 set ld_sysroot_available_saved 1
1891 }
1892 }
1893 return $ld_sysroot_available_saved
1894}
1895
5ff55910
L
1896# Returns 1 if plugin is enabled in gcc. Returns 0 otherwise.
1897proc check_gcc_plugin_enabled { } {
1898 global CC
1899
1900 if {![info exists CC]} {
1901 set CC [find_gcc]
1902 }
7f6bf02d 1903 if { $CC == ""} {
8be1e369 1904 return 0
5ff55910
L
1905 }
1906 set state [remote_exec host $CC -v]
8be1e369
AM
1907 if { [lindex $state 0] != 0 } {
1908 return 0;
1909 }
1910 for { set i 1 } { $i < [llength $state] } { incr i } {
5ff55910
L
1911 set v [lindex $state $i]
1912 if { [ string match "*--disable-plugin*" $v ] } {
1913 verbose "plugin is disabled by $v"
1914 return 0;
1915 }
1916 }
1917
1918 return 1;
1919}
1920
3bd58fbe
L
1921# Returns true if the target compiler supports LTO
1922proc check_lto_available { } {
1923 global lto_available_saved
1924 global CC
7174e19f 1925
3bd58fbe 1926 if {![info exists lto_available_saved]} {
5ff55910 1927 if { ![check_gcc_plugin_enabled] } {
19aef622
NC
1928 set lto_available_saved 0
1929 return 0
1930 }
00f4a602
L
1931 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1932 # -ffat-lto-objects, we always run LTO tests on Linux with
1933 # GCC 4.9 or newer.
1934 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1935 set lto_available_saved 1
1936 return 1
1937 }
3bd58fbe 1938 # Check if gcc supports -flto -fuse-linker-plugin
f1d7f4a6
AM
1939 set flags ""
1940 if [board_info [target_info name] exists cflags] {
1941 append flags " [board_info [target_info name] cflags]"
1942 }
1943 if [board_info [target_info name] exists ldflags] {
1944 append flags " [board_info [target_info name] ldflags]"
3bd58fbe 1945 }
f1d7f4a6
AM
1946
1947 set basename "tmpdir/lto[pid]"
1948 set src ${basename}.c
1949 set output ${basename}.out
3bd58fbe 1950 set f [open $src "w"]
7174e19f 1951 puts $f "int main() { return 0; }"
3bd58fbe 1952 close $f
010f98a5
L
1953 if [is_remote host] {
1954 set src [remote_download host $src]
1955 }
c3e11cbe 1956 set lto_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -fuse-linker-plugin $src -o $output"]
f1d7f4a6
AM
1957 remote_file host delete $src
1958 remote_file host delete $output
3bd58fbe 1959 file delete $src
3bd58fbe
L
1960 }
1961 return $lto_available_saved
1962}
1963
c3e11cbe
AM
1964# Returns true if the target compiler supports LTO -ffat-lto-objects
1965proc check_lto_fat_available { } {
1966 global lto_fat_available_saved
1967 global CC
1968
1969 if {![info exists lto_fat_available_saved]} {
5ff55910 1970 if { ![check_gcc_plugin_enabled] } {
c3e11cbe
AM
1971 set lto_fat_available_saved 0
1972 return 0
1973 }
00f4a602
L
1974 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1975 # -ffat-lto-objects, we always run LTO tests on Linux with
1976 # GCC 4.9 or newer.
1977 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1978 set lto_fat_available_saved 1
1979 return 1
1980 }
c3e11cbe
AM
1981 # Check if gcc supports -flto -fuse-linker-plugin
1982 set flags ""
1983 if [board_info [target_info name] exists cflags] {
1984 append flags " [board_info [target_info name] cflags]"
1985 }
1986 if [board_info [target_info name] exists ldflags] {
1987 append flags " [board_info [target_info name] ldflags]"
1988 }
1989
1990 set basename "tmpdir/lto[pid]"
1991 set src ${basename}.c
1992 set output ${basename}.out
1993 set f [open $src "w"]
1994 puts $f "int main() { return 0; }"
1995 close $f
010f98a5
L
1996 if [is_remote host] {
1997 set src [remote_download host $src]
1998 }
c3e11cbe
AM
1999 set lto_fat_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -ffat-lto-objects -fuse-linker-plugin $src -o $output"]
2000 remote_file host delete $src
2001 remote_file host delete $output
2002 file delete $src
2003 }
2004 return $lto_fat_available_saved
2005}
2006
92c09111
L
2007# Returns true if the target compiler supports LTO and -shared
2008proc check_lto_shared_available { } {
2009 global lto_shared_available_saved
2010 global CC
2011
92c09111 2012 if {![info exists lto_shared_available_saved]} {
5ff55910 2013 if { ![check_gcc_plugin_enabled] } {
3bb9e7b4
AM
2014 set lto_shared_available_saved 0
2015 return 0
2016 }
00f4a602
L
2017 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
2018 # -ffat-lto-objects, we always run LTO tests on Linux with
2019 # GCC 4.9 or newer.
2020 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
2021 set lto_shared_available_saved 1
2022 return 1
2023 }
92c09111 2024 # Check if gcc supports -flto -fuse-linker-plugin -shared
f1d7f4a6
AM
2025 set flags ""
2026 if [board_info [target_info name] exists cflags] {
2027 append flags " [board_info [target_info name] cflags]"
2028 }
2029 if [board_info [target_info name] exists ldflags] {
2030 append flags " [board_info [target_info name] ldflags]"
92c09111 2031 }
f1d7f4a6
AM
2032
2033 set basename "tmpdir/lto_shared[pid]"
2034 set src ${basename}.c
2035 set output ${basename}.so
92c09111
L
2036 set f [open $src "w"]
2037 puts $f ""
2038 close $f
010f98a5
L
2039 if [is_remote host] {
2040 set src [remote_download host $src]
2041 }
f1d7f4a6
AM
2042 set lto_shared_available_saved [run_host_cmd_yesno "$CC" "$flags -shared -fPIC -flto -fuse-linker-plugin $src -o $output"]
2043 remote_file host delete $src
2044 remote_file host delete $output
92c09111 2045 file delete $src
92c09111
L
2046 }
2047 return $lto_shared_available_saved
2048}
2049
33aa234e
JK
2050# Check if the assembler supports CFI statements.
2051
2052proc check_as_cfi { } {
2053 global check_as_cfi_result
2054 global as
2055 if [info exists check_as_cfi_result] {
2056 return $check_as_cfi_result
2057 }
2058 set as_file "tmpdir/check_as_cfi.s"
2059 set as_fh [open $as_file w 0666]
2060 puts $as_fh "# Generated file. DO NOT EDIT"
2061 puts $as_fh "\t.cfi_startproc"
2062 puts $as_fh "\t.cfi_endproc"
2063 close $as_fh
2064 remote_download host $as_file
2065 verbose -log "Checking CFI support:"
2066 rename "perror" "check_as_cfi_perror"
2067 proc perror { args } { }
2068 set success [ld_assemble $as $as_file "/dev/null"]
2069 rename "perror" ""
2070 rename "check_as_cfi_perror" "perror"
2071 #remote_file host delete $as_file
2072 set check_as_cfi_result $success
2073 return $success
2074}
2075
c22ee0ad
L
2076# Returns true if IFUNC works.
2077
2078proc check_ifunc_available { } {
2079 global ifunc_available_saved
2080 global CC
2081
2082 if {![info exists ifunc_available_saved]} {
2083 if { [which $CC] == 0 } {
2084 set ifunc_available_saved 0
2085 return 0
2086 }
2087 # Check if gcc supports -flto -fuse-linker-plugin
2088 set flags ""
2089 if [board_info [target_info name] exists cflags] {
2090 append flags " [board_info [target_info name] cflags]"
2091 }
2092 if [board_info [target_info name] exists ldflags] {
2093 append flags " [board_info [target_info name] ldflags]"
2094 }
2095
2096 set basename "tmpdir/ifunc[pid]"
2097 set src ${basename}.c
2098 set output ${basename}.out
2099 set f [open $src "w"]
2100 puts $f "extern int library_func2 (void);"
2101 puts $f "int main (void)"
2102 puts $f "{"
2103 puts $f " if (library_func2 () != 2) __builtin_abort ();"
2104 puts $f " return 0; "
2105 puts $f "}"
2106 puts $f "static int library_func1 (void) {return 2; }"
2107 puts $f "void *foo (void) __asm__ (\"library_func2\");"
2108 puts $f "void *foo (void) { return library_func1; }"
2109 puts $f "__asm__(\".type library_func2, %gnu_indirect_function\");"
2110 close $f
010f98a5
L
2111 if [is_remote host] {
2112 set src [remote_download host $src]
2113 }
c22ee0ad
L
2114 set ifunc_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
2115 if { $ifunc_available_saved == 1 } {
2116 set ifunc_available_saved [run_host_cmd_yesno "$output" ""]
2117 }
2118 remote_file host delete $src
2119 remote_file host delete $output
2120 file delete $src
2121 }
2122 return $ifunc_available_saved
2123}
2124
97dc35c8
L
2125# Returns true if ifunc attribute works.
2126
2127proc check_ifunc_attribute_available { } {
2128 global ifunc_attribute_available_saved
2129 global CC
2130
2131 if {![info exists ifunc_attribute_available_saved]} {
2132 if { [which $CC] == 0 } {
2133 set ifunc_attribute_available_saved 0
2134 return 0
2135 }
2136 # Check if gcc supports -flto -fuse-linker-plugin
2137 set flags ""
2138 if [board_info [target_info name] exists cflags] {
2139 append flags " [board_info [target_info name] cflags]"
2140 }
2141 if [board_info [target_info name] exists ldflags] {
2142 append flags " [board_info [target_info name] ldflags]"
2143 }
2144
2145 set basename "tmpdir/ifunc[pid]"
2146 set src ${basename}.c
2147 set output ${basename}.out
2148 set f [open $src "w"]
2149 puts $f "extern int library_func2 (void) __attribute__ ((ifunc (\"foo\")));"
2150 puts $f "int main (void)"
2151 puts $f "{"
2152 puts $f " if (library_func2 () != 2) __builtin_abort ();"
2153 puts $f " return 0; "
2154 puts $f "}"
2155 puts $f "static int library_func1 (void) {return 2; }"
2156 puts $f "void *foo (void) { return library_func1; }"
2157 close $f
010f98a5
L
2158 if [is_remote host] {
2159 set src [remote_download host $src]
2160 }
97dc35c8
L
2161 set ifunc_attribute_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
2162 if { $ifunc_attribute_available_saved == 1 } {
2163 set ifunc_attribute_available_saved [run_host_cmd_yesno "$output" ""]
2164 }
2165 remote_file host delete $src
2166 remote_file host delete $output
2167 file delete $src
2168 }
2169 return $ifunc_attribute_available_saved
2170}
2171
33aa234e
JK
2172# Provide virtual target "cfi" for targets supporting CFI.
2173
2174rename "istarget" "istarget_ld"
2175proc istarget { target } {
2176 if {$target == "cfi"} {
2177 return [check_as_cfi]
2178 }
74ccf6db
JW
2179 if {$target == "shared"} {
2180 return [check_shared_lib_support]
2181 }
33aa234e
JK
2182 return [istarget_ld $target]
2183}
fd121c5c
JW
2184
2185# Return true if libdl is supported.
2186
2187proc check_libdl_available { } {
2188 global libdl_available_saved
2189 global CC
2190
2191 if {![info exists libdl_available_saved]} {
2192 if { [which $CC] == 0 } {
2193 set libdl_available_saved 0
2194 return 0
2195 }
2196
2197 set basename "tmpdir/dl_avail_test[pid]"
2198 set src ${basename}.c
2199 set output ${basename}.out
2200 set f [open $src "w"]
2201 # Sample test file.
2202 puts $f "#include <dlfcn.h>"
2203 puts $f "int main (void)"
2204 puts $f "{"
2205 puts $f " dlopen (\"dummy.so\", RTLD_NOW);"
2206 puts $f " return 0; "
2207 puts $f "}"
2208 close $f
2209 if [is_remote host] {
2210 set src [remote_download host $src]
2211 }
2212 set libdl_available_saved [run_host_cmd_yesno "$CC" "$src -o $output -ldl"]
2213 remote_file host delete $src
2214 remote_file host delete $output
2215 file delete $src
2216 }
2217 return $libdl_available_saved
2218}
0aae7e72
L
2219
2220# Returns true if GNU2 TLS works.
2221
2222proc check_gnu2_tls_available { } {
2223 global gnu2_tls_available_saved
2224 global CC
2225 global GNU2_CFLAGS
2226
2227 if {![info exists gnu2_tls_available_saved]} {
2228 if { [which $CC] == 0 || "$GNU2_CFLAGS" == "" } {
2229 set gnu2_tls_available_saved 0
2230 return 0
2231 }
2232 # Check if GNU2 TLS works.
2233 set flags "$GNU2_CFLAGS"
2234 if [board_info [target_info name] exists cflags] {
2235 append flags " [board_info [target_info name] cflags]"
2236 }
2237 if [board_info [target_info name] exists ldflags] {
2238 append flags " [board_info [target_info name] ldflags]"
2239 }
2240
2241 set basename "tmpdir/gnu2_tls[pid]"
2242 set src1 ${basename}1.c
2243 set output1 ${basename}.so
2244 set f [open $src1 "w"]
2245 puts $f "extern __thread int zzz;"
2246 puts $f "int foo (void)"
2247 puts $f "{"
2248 puts $f " return zzz;"
2249 puts $f "}"
2250 close $f
2251 if [is_remote host] {
2252 set src1 [remote_download host $src1]
2253 }
2254 set src2 ${basename}2.c
2255 set output2 ${basename}.exe
2256 set f [open $src2 "w"]
2257 puts $f "__thread int zzz = 20;"
2258 puts $f "extern int foo (void);"
2259 puts $f "int main (void)"
2260 puts $f "{"
2261 puts $f " if (foo () != 20) __builtin_abort ();"
2262 puts $f " return 0; "
2263 puts $f "}"
2264 close $f
2265 if [is_remote host] {
2266 set src2 [remote_download host $src2]
2267 }
2268 set gnu2_tls_available_saved [run_host_cmd_yesno "$CC" "-fPIC -shared $flags $src1 -o $output1"]
2269 if { $gnu2_tls_available_saved == 1 } {
2270 set gnu2_tls_available_saved [run_host_cmd_yesno "$CC" "$flags $src2 $output1 -o $output2"]
2271 if { $gnu2_tls_available_saved == 1 } {
2272 set gnu2_tls_available_saved [run_host_cmd_yesno "$output2" ""]
2273 }
2274 }
2275 remote_file host delete $src1
2276 remote_file host delete $output1
2277 remote_file host delete $src2
2278 remote_file host delete $output2
2279 file delete $src1 $src2
2280 }
2281 return $gnu2_tls_available_saved
2282}
This page took 1.047842 seconds and 4 git commands to generate.