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