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