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