Fix PRU GAS for 32-bit hosts
[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
24edc24d
L
1384
1385 foreach testitem $ldtests {
982c6f26 1386 foreach target $args {
c8c140d9
BE
1387 setup_xfail $target
1388 }
24edc24d
L
1389 set testname [lindex $testitem 0]
1390 set ld_options [lindex $testitem 1]
1391 set as_options [lindex $testitem 2]
1392 set src_files [lindex $testitem 3]
1393 set binfile tmpdir/[lindex $testitem 4]
1394 set expfile [lindex $testitem 5]
1395 set cflags [lindex $testitem 6]
55255dae 1396 set lang [lindex $testitem 7]
fab4a87f 1397 set warning [lindex $testitem 8]
24edc24d 1398 set objfiles {}
24edc24d
L
1399 set failed 0
1400
1401# verbose -log "Testname is $testname"
1402# verbose -log "ld_options is $ld_options"
1403# verbose -log "as_options is $as_options"
1404# verbose -log "src_files is $src_files"
24edc24d
L
1405# verbose -log "binfile is $binfile"
1406
1407 # Assemble each file in the test.
1408 foreach src_file $src_files {
74d44110
MR
1409 set fileroot "[file rootname [file tail $src_file]]"
1410 set objfile "tmpdir/$fileroot.o"
24edc24d
L
1411 lappend objfiles $objfile
1412
a10e6b21
L
1413 # We ignore warnings since some compilers may generate
1414 # incorrect section attributes and the assembler will warn
1415 # them.
58ffc3bd
MF
1416 if { [ string match "c++" $lang ] } {
1417 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1418 } else {
1419 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1420 }
cb5ab6c8 1421 }
a10e6b21 1422
d9816402
AM
1423 if { [ string match "c++" $lang ] } {
1424 set link_proc ld_link
cb5ab6c8 1425 set link_cmd $CXX
cb5ab6c8
L
1426 } else {
1427 set link_proc ld_link
d9816402 1428 set link_cmd $CC
cb5ab6c8 1429 }
24edc24d 1430
abc868c6
AM
1431 if { $binfile eq "tmpdir/" } {
1432 # compile only
1433 pass $testname
1434 continue;
1435 } elseif ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
cb5ab6c8 1436 set failed 1
cb5ab6c8
L
1437 }
1438
1439 # Check if exec_output is expected.
1440 if { $warning != "" } then {
1441 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1442 if { [regexp $warning $exec_output] } then {
a10e6b21 1443 set failed 0
cb5ab6c8
L
1444 } else {
1445 set failed 1
fab4a87f 1446 }
cb5ab6c8 1447 }
fab4a87f 1448
d9816402 1449 if { $failed == 0 && [isnative] } {
cb5ab6c8
L
1450 send_log "Running: $binfile > $binfile.out\n"
1451 verbose "Running: $binfile > $binfile.out"
1452 catch "exec $binfile > $binfile.out" exec_output
fab4a87f 1453
cb5ab6c8
L
1454 if ![string match "" $exec_output] then {
1455 send_log "$exec_output\n"
1456 verbose "$exec_output" 1
1457 set failed 1
1458 } else {
1459 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1460 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1461 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1462 set exec_output [prune_warnings $exec_output]
5a68afcf 1463
24edc24d
L
1464 if ![string match "" $exec_output] then {
1465 send_log "$exec_output\n"
1466 verbose "$exec_output" 1
1467 set failed 1
1468 }
1469 }
cb5ab6c8 1470 }
24edc24d 1471
cb5ab6c8
L
1472 if { $failed != 0 } {
1473 fail $testname
d9816402
AM
1474 } elseif ![isnative] {
1475 unsupported $testname
cb5ab6c8
L
1476 } else {
1477 set errcnt 0
1478 pass $testname
24edc24d 1479 }
24edc24d
L
1480 }
1481}
d2dee3b2
L
1482
1483# List contains test-items with 3 items followed by 2 lists, one item and
1484# one optional item:
55255dae 1485# 0:name
fa0a16b1 1486# 1:ld or ar options
55255dae
L
1487# 2:compile options
1488# 3:filenames of source files
1489# 4:action and options.
1490# 5:name of output file
1491# 6:language (optional)
dd98f8d2 1492# 7:linker warnings (optional)
d2dee3b2
L
1493#
1494# Actions:
1495# objdump: Apply objdump options on result. Compare with regex (last arg).
1496# nm: Apply nm options on result. Compare with regex (last arg).
1497# readelf: Apply readelf options on result. Compare with regex (last arg).
1498#
1499proc run_cc_link_tests { ldtests } {
1500 global nm
1501 global objdump
1502 global READELF
1503 global srcdir
1504 global subdir
1505 global env
1506 global CC
55255dae 1507 global CXX
d2dee3b2 1508 global CFLAGS
58ffc3bd 1509 global CXXFLAGS
d8880531 1510 global ar
dd98f8d2 1511 global exec_output
603c4399
JW
1512 global board_cflags
1513
1514 if [board_info [target_info name] exists cflags] {
1515 set board_cflags " [board_info [target_info name] cflags]"
1516 } else {
1517 set board_cflags ""
1518 }
d2dee3b2
L
1519
1520 foreach testitem $ldtests {
1521 set testname [lindex $testitem 0]
1522 set ldflags [lindex $testitem 1]
1523 set cflags [lindex $testitem 2]
1524 set src_files [lindex $testitem 3]
1525 set actions [lindex $testitem 4]
1526 set binfile tmpdir/[lindex $testitem 5]
55255dae 1527 set lang [lindex $testitem 6]
dd98f8d2 1528 set warnings [lindex $testitem 7]
d2dee3b2
L
1529 set objfiles {}
1530 set is_unresolved 0
1531 set failed 0
1532
c3e11cbe
AM
1533 #verbose -log "testname is $testname"
1534 #verbose -log "ldflags is $ldflags"
1535 #verbose -log "cflags is $cflags"
1536 #verbose -log "src_files is $src_files"
1537 #verbose -log "actions is $actions"
1538 #verbose -log "binfile is $binfile"
1539 #verbose -log "lang is $lang"
1540 #verbose -log "warnings is $warnings"
1541
d2dee3b2
L
1542 # Compile each file in the test.
1543 foreach src_file $src_files {
74d44110
MR
1544 set fileroot "[file rootname [file tail $src_file]]"
1545 set objfile "tmpdir/$fileroot.o"
d2dee3b2
L
1546 lappend objfiles $objfile
1547
1548 # We ignore warnings since some compilers may generate
1549 # incorrect section attributes and the assembler will warn
1550 # them.
58ffc3bd
MF
1551 if { [ string match "c++" $lang ] } {
1552 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1553 } else {
1554 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1555 }
d2dee3b2
L
1556 }
1557
1558 # Clear error and warning counts.
1559 reset_vars
1560
55255dae
L
1561 if { [ string match "c++" $lang ] } {
1562 set cc_cmd $CXX
1563 } else {
1564 set cc_cmd $CC
1565 }
1566
abc868c6
AM
1567 if { $binfile eq "tmpdir/" } {
1568 # compile only
1569 } elseif { [regexp ".*\\.a$" $binfile] } {
fa0a16b1 1570 if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
d8880531 1571 set failed 1
d8880531 1572 }
741e0128 1573 } else {
d9816402 1574 if { ![ld_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"] } {
741e0128 1575 set failed 1
741e0128
L
1576 }
1577
dd98f8d2
NC
1578 # Check if exec_output is expected.
1579 if { $warnings != "" } then {
1580 verbose -log "returned with: <$exec_output>, expected: <$warnings>"
1581 if { [regexp $warnings $exec_output] } then {
df71cb5c 1582 set failed 0
dd98f8d2
NC
1583 } else {
1584 set failed 1
1585 }
741e0128 1586 }
d8880531
L
1587 }
1588
1589 if { $failed == 0 } {
d2dee3b2
L
1590 foreach actionlist $actions {
1591 set action [lindex $actionlist 0]
1592 set progopts [lindex $actionlist 1]
1593
1594 # There are actions where we run regexp_diff on the
1595 # output, and there are other actions (presumably).
1596 # Handling of the former look the same.
1597 set dump_prog ""
1598 switch -- $action {
1599 objdump
1600 { set dump_prog $objdump }
1601 nm
1602 { set dump_prog $nm }
1603 readelf
1604 { set dump_prog $READELF }
1605 default
1606 {
1607 perror "Unrecognized action $action"
1608 set is_unresolved 1
1609 break
1610 }
1611 }
1612
1613 if { $dump_prog != "" } {
1614 set dumpfile [lindex $actionlist 2]
1615 set binary $dump_prog
1616
1617 # Ensure consistent sorting of symbols
1618 if {[info exists env(LC_ALL)]} {
1619 set old_lc_all $env(LC_ALL)
1620 }
1621 set env(LC_ALL) "C"
1622 set cmd "$binary $progopts $binfile > dump.out"
1623 send_log "$cmd\n"
1624 catch "exec $cmd" comp_output
1625 if {[info exists old_lc_all]} {
1626 set env(LC_ALL) $old_lc_all
1627 } else {
1628 unset env(LC_ALL)
1629 }
1630 set comp_output [prune_warnings $comp_output]
1631
1632 if ![string match "" $comp_output] then {
1633 send_log "$comp_output\n"
1634 set failed 1
1635 break
1636 }
1637
1638 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1639 verbose "output is [file_contents "dump.out"]" 2
1640 set failed 1
1641 break
1642 }
1643 }
1644 }
d2dee3b2
L
1645 }
1646
d44ea5d0 1647 if { $failed } {
abc868c6 1648 fail $testname
d44ea5d0 1649 } elseif { $is_unresolved } {
d2dee3b2 1650 unresolved $testname
d44ea5d0
AM
1651 } else {
1652 pass $testname
d2dee3b2
L
1653 }
1654 }
1655}
430a16a5
NC
1656
1657# Returns true if --gc-sections is supported on the target.
1658
1659proc check_gc_sections_available { } {
1660 global gc_sections_available_saved
1661 global ld
5a68afcf 1662
430a16a5
NC
1663 if {![info exists gc_sections_available_saved]} {
1664 # Some targets don't support gc-sections despite whatever's
1665 # advertised by ld's options.
fc3eec7e 1666 if { [istarget d30v-*-*]
59c108f7
NC
1667 || [istarget dlx-*-*]
1668 || [istarget i960-*-*]
59c108f7 1669 || [istarget pj*-*-*]
0220170b 1670 || [istarget pru*-*-*]
59c108f7
NC
1671 || [istarget alpha-*-*]
1672 || [istarget hppa*64-*-*]
1673 || [istarget i370-*-*]
1674 || [istarget i860-*-*]
1675 || [istarget ia64-*-*]
1676 || [istarget mep-*-*]
0f088b2a 1677 || [istarget mn10200-*-*] } {
430a16a5
NC
1678 set gc_sections_available_saved 0
1679 return 0
1680 }
1681
1682 # elf2flt uses -q (--emit-relocs), which is incompatible with
1683 # --gc-sections.
1684 if { [board_info target exists ldflags]
1685 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1686 set gc_sections_available_saved 0
1687 return 0
1688 }
1689
430a16a5 1690 # Check if the ld used by gcc supports --gc-sections.
1d5316ab
AM
1691 # FIXME: this test is useless since ld --help always says
1692 # --gc-sections is available
430a16a5
NC
1693 set ld_output [remote_exec host $ld "--help"]
1694 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1695 set gc_sections_available_saved 1
1696 } else {
1697 set gc_sections_available_saved 0
1698 }
1699 }
1700 return $gc_sections_available_saved
1701}
33aa234e 1702
1d5316ab
AM
1703# Returns true if -shared is supported on the target
1704# Only used and accurate for ELF targets at the moment
1705
1706proc check_shared_lib_support { } {
83a23418 1707 if {![istarget aarch64*-*-elf]
fc3eec7e 1708 && ![istarget arc*-*-elf*]
83a23418 1709 && ![istarget arm*-*-elf]
1d5316ab
AM
1710 && ![istarget avr-*-*]
1711 && ![istarget cr16-*-*]
5220199d 1712 && ![istarget cris*-*-elf]
1d5316ab
AM
1713 && ![istarget crx-*-*]
1714 && ![istarget d10v-*-*]
1715 && ![istarget d30v-*-*]
1716 && ![istarget dlx-*-*]
cfb8c092 1717 && ![istarget epiphany-*-*]
1d5316ab
AM
1718 && ![istarget fr30-*-*]
1719 && ![istarget frv-*-*]
c4107a7d 1720 && ![istarget ft32-*-*]
1d5316ab
AM
1721 && ![istarget h8300-*-*]
1722 && ![istarget i860-*-*]
1723 && ![istarget i960-*-*]
1724 && ![istarget ip2k-*-*]
1725 && ![istarget iq2000-*-*]
1726 && ![istarget lm32-*-*]
1727 && ![istarget m32c-*-*]
1728 && ![istarget m32r-*-*]
32d79e68
AM
1729 && ![istarget m6811-*-*]
1730 && ![istarget m6812-*-*]
1d5316ab
AM
1731 && ![istarget m68hc1*-*-*]
1732 && ![istarget mcore*-*-*]
1733 && ![istarget mep-*-*]
1734 && ![istarget microblaze-*-*]
23c80bf4 1735 && ![istarget mips*-*-elf]
1d5316ab
AM
1736 && ![istarget mn10200-*-*]
1737 && ![istarget moxie-*-*]
1738 && ![istarget msp430-*-*]
1739 && ![istarget mt-*-*]
35c08157 1740 && ![istarget nds32*-*-*]
73589c9d 1741 && ![istarget or1k*-*-*]
1d5316ab 1742 && ![istarget pj-*-*]
0220170b 1743 && ![istarget pru-*-*]
4046d87a 1744 && ![istarget rl78-*-*]
1d5316ab
AM
1745 && ![istarget rx-*-*]
1746 && ![istarget spu-*-*]
1747 && ![istarget v850*-*-*]
c18392d8 1748 && ![istarget visium-*-*]
b709ef7c 1749 && ![istarget xc16x-*-elf]
b3066ae8 1750 && ![istarget xgate-*-*]
1d5316ab
AM
1751 && ![istarget xstormy16-*-*]
1752 && ![istarget *-*-irix*]
1753 && ![istarget *-*-rtems] } {
1754 return 1
1755 }
1756 return 0
1757}
1758
b62b1f71
AM
1759# Return true if target uses genelf.em (assuming it is ELF).
1760proc is_generic_elf { } {
1761 if { [istarget "d30v-*-*"]
1762 || [istarget "dlx-*-*"]
1763 || [istarget "fr30-*-*"]
1764 || ([istarget "frv-*-*"] && ![istarget "frv-*-linux*"])
1765 || [istarget "ft32-*-*"]
1766 || [istarget "i860-*-*"]
1767 || [istarget "i960-*-*"]
1768 || [istarget "iq2000-*-*"]
1769 || [istarget "mn10200-*-*"]
1770 || [istarget "moxie-*-*"]
1771 || [istarget "msp430-*-*"]
1772 || [istarget "mt-*-*"]
1773 || [istarget "pj*-*-*"] } {
1774 return 1;
1775 }
1776 return 0;
1777}
1778
5d3236ee
DK
1779# Returns true if the target ld supports the plugin API.
1780proc check_plugin_api_available { } {
1781 global plugin_api_available_saved
1782 global ld
1783 if {![info exists plugin_api_available_saved]} {
1784 # Check if the ld used by gcc supports --plugin.
1785 set ld_output [remote_exec host $ld "--help"]
2d03dd2f 1786 if { [ string first "-plugin PLUGIN" $ld_output ] >= 0 } {
5d3236ee
DK
1787 set plugin_api_available_saved 1
1788 } else {
1789 set plugin_api_available_saved 0
1790 }
1791 }
1792 return $plugin_api_available_saved
1793}
1794
3f730821
HPN
1795# Sets ld_sysroot to the current sysroot (empty if not supported) and
1796# returns true if the target ld supports sysroot.
bdd65db9 1797proc check_sysroot_available { } {
3f730821 1798 global ld_sysroot_available_saved ld ld_sysroot
bdd65db9 1799 if {![info exists ld_sysroot_available_saved]} {
3f730821
HPN
1800 # Check if ld supports --sysroot *other* than empty.
1801 set ld_sysroot [string trimright [lindex [remote_exec host $ld "--print-sysroot"] 1]]
1802 if { $ld_sysroot == "" } {
bdd65db9
HPN
1803 set ld_sysroot_available_saved 0
1804 } else {
1805 set ld_sysroot_available_saved 1
1806 }
1807 }
1808 return $ld_sysroot_available_saved
1809}
1810
5ff55910
L
1811# Returns 1 if plugin is enabled in gcc. Returns 0 otherwise.
1812proc check_gcc_plugin_enabled { } {
1813 global CC
1814
1815 if {![info exists CC]} {
1816 set CC [find_gcc]
1817 }
7f6bf02d 1818 if { $CC == ""} {
8be1e369 1819 return 0
5ff55910
L
1820 }
1821 set state [remote_exec host $CC -v]
8be1e369
AM
1822 if { [lindex $state 0] != 0 } {
1823 return 0;
1824 }
1825 for { set i 1 } { $i < [llength $state] } { incr i } {
5ff55910
L
1826 set v [lindex $state $i]
1827 if { [ string match "*--disable-plugin*" $v ] } {
1828 verbose "plugin is disabled by $v"
1829 return 0;
1830 }
1831 }
1832
1833 return 1;
1834}
1835
3bd58fbe
L
1836# Returns true if the target compiler supports LTO
1837proc check_lto_available { } {
1838 global lto_available_saved
1839 global CC
7174e19f 1840
3bd58fbe 1841 if {![info exists lto_available_saved]} {
5ff55910 1842 if { ![check_gcc_plugin_enabled] } {
19aef622
NC
1843 set lto_available_saved 0
1844 return 0
1845 }
00f4a602
L
1846 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1847 # -ffat-lto-objects, we always run LTO tests on Linux with
1848 # GCC 4.9 or newer.
1849 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1850 set lto_available_saved 1
1851 return 1
1852 }
3bd58fbe 1853 # Check if gcc supports -flto -fuse-linker-plugin
f1d7f4a6
AM
1854 set flags ""
1855 if [board_info [target_info name] exists cflags] {
1856 append flags " [board_info [target_info name] cflags]"
1857 }
1858 if [board_info [target_info name] exists ldflags] {
1859 append flags " [board_info [target_info name] ldflags]"
3bd58fbe 1860 }
f1d7f4a6
AM
1861
1862 set basename "tmpdir/lto[pid]"
1863 set src ${basename}.c
1864 set output ${basename}.out
3bd58fbe 1865 set f [open $src "w"]
7174e19f 1866 puts $f "int main() { return 0; }"
3bd58fbe 1867 close $f
010f98a5
L
1868 if [is_remote host] {
1869 set src [remote_download host $src]
1870 }
c3e11cbe 1871 set lto_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -fuse-linker-plugin $src -o $output"]
f1d7f4a6
AM
1872 remote_file host delete $src
1873 remote_file host delete $output
3bd58fbe 1874 file delete $src
3bd58fbe
L
1875 }
1876 return $lto_available_saved
1877}
1878
c3e11cbe
AM
1879# Returns true if the target compiler supports LTO -ffat-lto-objects
1880proc check_lto_fat_available { } {
1881 global lto_fat_available_saved
1882 global CC
1883
1884 if {![info exists lto_fat_available_saved]} {
5ff55910 1885 if { ![check_gcc_plugin_enabled] } {
c3e11cbe
AM
1886 set lto_fat_available_saved 0
1887 return 0
1888 }
00f4a602
L
1889 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1890 # -ffat-lto-objects, we always run LTO tests on Linux with
1891 # GCC 4.9 or newer.
1892 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1893 set lto_fat_available_saved 1
1894 return 1
1895 }
c3e11cbe
AM
1896 # Check if gcc supports -flto -fuse-linker-plugin
1897 set flags ""
1898 if [board_info [target_info name] exists cflags] {
1899 append flags " [board_info [target_info name] cflags]"
1900 }
1901 if [board_info [target_info name] exists ldflags] {
1902 append flags " [board_info [target_info name] ldflags]"
1903 }
1904
1905 set basename "tmpdir/lto[pid]"
1906 set src ${basename}.c
1907 set output ${basename}.out
1908 set f [open $src "w"]
1909 puts $f "int main() { return 0; }"
1910 close $f
010f98a5
L
1911 if [is_remote host] {
1912 set src [remote_download host $src]
1913 }
c3e11cbe
AM
1914 set lto_fat_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -ffat-lto-objects -fuse-linker-plugin $src -o $output"]
1915 remote_file host delete $src
1916 remote_file host delete $output
1917 file delete $src
1918 }
1919 return $lto_fat_available_saved
1920}
1921
92c09111
L
1922# Returns true if the target compiler supports LTO and -shared
1923proc check_lto_shared_available { } {
1924 global lto_shared_available_saved
1925 global CC
1926
92c09111 1927 if {![info exists lto_shared_available_saved]} {
5ff55910 1928 if { ![check_gcc_plugin_enabled] } {
3bb9e7b4
AM
1929 set lto_shared_available_saved 0
1930 return 0
1931 }
00f4a602
L
1932 # This test will hide LTO bugs in ld. Since GCC 4.9 adds
1933 # -ffat-lto-objects, we always run LTO tests on Linux with
1934 # GCC 4.9 or newer.
1935 if { [istarget "*-*-linux*"] && [at_least_gcc_version 4 9] } {
1936 set lto_shared_available_saved 1
1937 return 1
1938 }
92c09111 1939 # Check if gcc supports -flto -fuse-linker-plugin -shared
f1d7f4a6
AM
1940 set flags ""
1941 if [board_info [target_info name] exists cflags] {
1942 append flags " [board_info [target_info name] cflags]"
1943 }
1944 if [board_info [target_info name] exists ldflags] {
1945 append flags " [board_info [target_info name] ldflags]"
92c09111 1946 }
f1d7f4a6
AM
1947
1948 set basename "tmpdir/lto_shared[pid]"
1949 set src ${basename}.c
1950 set output ${basename}.so
92c09111
L
1951 set f [open $src "w"]
1952 puts $f ""
1953 close $f
010f98a5
L
1954 if [is_remote host] {
1955 set src [remote_download host $src]
1956 }
f1d7f4a6
AM
1957 set lto_shared_available_saved [run_host_cmd_yesno "$CC" "$flags -shared -fPIC -flto -fuse-linker-plugin $src -o $output"]
1958 remote_file host delete $src
1959 remote_file host delete $output
92c09111 1960 file delete $src
92c09111
L
1961 }
1962 return $lto_shared_available_saved
1963}
1964
33aa234e
JK
1965# Check if the assembler supports CFI statements.
1966
1967proc check_as_cfi { } {
1968 global check_as_cfi_result
1969 global as
1970 if [info exists check_as_cfi_result] {
1971 return $check_as_cfi_result
1972 }
1973 set as_file "tmpdir/check_as_cfi.s"
1974 set as_fh [open $as_file w 0666]
1975 puts $as_fh "# Generated file. DO NOT EDIT"
1976 puts $as_fh "\t.cfi_startproc"
1977 puts $as_fh "\t.cfi_endproc"
1978 close $as_fh
1979 remote_download host $as_file
1980 verbose -log "Checking CFI support:"
1981 rename "perror" "check_as_cfi_perror"
1982 proc perror { args } { }
1983 set success [ld_assemble $as $as_file "/dev/null"]
1984 rename "perror" ""
1985 rename "check_as_cfi_perror" "perror"
1986 #remote_file host delete $as_file
1987 set check_as_cfi_result $success
1988 return $success
1989}
1990
c22ee0ad
L
1991# Returns true if IFUNC works.
1992
1993proc check_ifunc_available { } {
1994 global ifunc_available_saved
1995 global CC
1996
1997 if {![info exists ifunc_available_saved]} {
1998 if { [which $CC] == 0 } {
1999 set ifunc_available_saved 0
2000 return 0
2001 }
2002 # Check if gcc supports -flto -fuse-linker-plugin
2003 set flags ""
2004 if [board_info [target_info name] exists cflags] {
2005 append flags " [board_info [target_info name] cflags]"
2006 }
2007 if [board_info [target_info name] exists ldflags] {
2008 append flags " [board_info [target_info name] ldflags]"
2009 }
2010
2011 set basename "tmpdir/ifunc[pid]"
2012 set src ${basename}.c
2013 set output ${basename}.out
2014 set f [open $src "w"]
2015 puts $f "extern int library_func2 (void);"
2016 puts $f "int main (void)"
2017 puts $f "{"
2018 puts $f " if (library_func2 () != 2) __builtin_abort ();"
2019 puts $f " return 0; "
2020 puts $f "}"
2021 puts $f "static int library_func1 (void) {return 2; }"
2022 puts $f "void *foo (void) __asm__ (\"library_func2\");"
2023 puts $f "void *foo (void) { return library_func1; }"
2024 puts $f "__asm__(\".type library_func2, %gnu_indirect_function\");"
2025 close $f
010f98a5
L
2026 if [is_remote host] {
2027 set src [remote_download host $src]
2028 }
c22ee0ad
L
2029 set ifunc_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
2030 if { $ifunc_available_saved == 1 } {
2031 set ifunc_available_saved [run_host_cmd_yesno "$output" ""]
2032 }
2033 remote_file host delete $src
2034 remote_file host delete $output
2035 file delete $src
2036 }
2037 return $ifunc_available_saved
2038}
2039
97dc35c8
L
2040# Returns true if ifunc attribute works.
2041
2042proc check_ifunc_attribute_available { } {
2043 global ifunc_attribute_available_saved
2044 global CC
2045
2046 if {![info exists ifunc_attribute_available_saved]} {
2047 if { [which $CC] == 0 } {
2048 set ifunc_attribute_available_saved 0
2049 return 0
2050 }
2051 # Check if gcc supports -flto -fuse-linker-plugin
2052 set flags ""
2053 if [board_info [target_info name] exists cflags] {
2054 append flags " [board_info [target_info name] cflags]"
2055 }
2056 if [board_info [target_info name] exists ldflags] {
2057 append flags " [board_info [target_info name] ldflags]"
2058 }
2059
2060 set basename "tmpdir/ifunc[pid]"
2061 set src ${basename}.c
2062 set output ${basename}.out
2063 set f [open $src "w"]
2064 puts $f "extern int library_func2 (void) __attribute__ ((ifunc (\"foo\")));"
2065 puts $f "int main (void)"
2066 puts $f "{"
2067 puts $f " if (library_func2 () != 2) __builtin_abort ();"
2068 puts $f " return 0; "
2069 puts $f "}"
2070 puts $f "static int library_func1 (void) {return 2; }"
2071 puts $f "void *foo (void) { return library_func1; }"
2072 close $f
010f98a5
L
2073 if [is_remote host] {
2074 set src [remote_download host $src]
2075 }
97dc35c8
L
2076 set ifunc_attribute_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
2077 if { $ifunc_attribute_available_saved == 1 } {
2078 set ifunc_attribute_available_saved [run_host_cmd_yesno "$output" ""]
2079 }
2080 remote_file host delete $src
2081 remote_file host delete $output
2082 file delete $src
2083 }
2084 return $ifunc_attribute_available_saved
2085}
2086
33aa234e
JK
2087# Provide virtual target "cfi" for targets supporting CFI.
2088
2089rename "istarget" "istarget_ld"
2090proc istarget { target } {
2091 if {$target == "cfi"} {
2092 return [check_as_cfi]
2093 }
2094 return [istarget_ld $target]
2095}
This page took 0.905868 seconds and 4 git commands to generate.