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