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