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