ld: Add '--require-defined' command line option.
[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#
bb00e284
HPN
557# warning: REGEX
558# Expect a linker warning matching REGEX. It is an error to issue
164de317
HPN
559# both "error" and "warning". Multiple "warning" directives
560# append to the expected linker warning message.
bb00e284 561#
43d66c95
AB
562# map: FILE
563# Adding this option will cause the linker to generate a linker
564# map file, using the -Map=MAPFILE command line option. If
565# there is no -Map=MAPFILE in the 'ld: FLAGS' then one will be
566# added to the linker command line. The contents of the
567# generated MAPFILE are then compared against the regexp lines
568# in FILE using `regexp_diff' (see below for details).
569#
261def70
HPN
570# Each option may occur at most once unless otherwise mentioned.
571#
572# After the option lines come regexp lines. `run_dump_test' calls
573# `regexp_diff' to compare the output of the dumping tool against the
eb22018c
RS
574# regexps in FILE.d. `regexp_diff' is defined in binutils-common.exp;
575# see further comments there.
3b6fe0cc 576#
ef2b5578 577proc run_dump_test { name {extra_options {}} } {
261def70
HPN
578 global subdir srcdir
579 global OBJDUMP NM AS OBJCOPY READELF LD
580 global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
581 global host_triplet runtests
9a2ee7fc 582 global env verbose
261def70
HPN
583
584 if [string match "*/*" $name] {
585 set file $name
586 set name [file tail $name]
587 } else {
588 set file "$srcdir/$subdir/$name"
589 }
590
591 if ![runtest_file_p $runtests $name] then {
592 return
593 }
594
595 set opt_array [slurp_options "${file}.d"]
596 if { $opt_array == -1 } {
597 perror "error reading options from $file.d"
598 unresolved $subdir/$name
599 return
600 }
601 set dumpfile tmpdir/dump.out
602 set run_ld 0
cfe5266f 603 set run_objcopy 0
261def70
HPN
604 set opts(as) {}
605 set opts(ld) {}
d6e0b160 606 set opts(ld_after_inputfiles) {}
261def70
HPN
607 set opts(xfail) {}
608 set opts(target) {}
609 set opts(notarget) {}
610 set opts(objdump) {}
611 set opts(nm) {}
612 set opts(objcopy) {}
613 set opts(readelf) {}
614 set opts(name) {}
615 set opts(PROG) {}
616 set opts(source) {}
ef2b5578 617 set opts(dump) {}
261def70 618 set opts(error) {}
bb00e284 619 set opts(warning) {}
cfe5266f 620 set opts(objcopy_linked_file) {}
9854d43d 621 set opts(objcopy_objects) {}
43d66c95 622 set opts(map) {}
261def70
HPN
623
624 foreach i $opt_array {
625 set opt_name [lindex $i 0]
626 set opt_val [lindex $i 1]
627 if ![info exists opts($opt_name)] {
628 perror "unknown option $opt_name in file $file.d"
629 unresolved $subdir/$name
630 return
631 }
632
633 switch -- $opt_name {
634 xfail {}
635 target {}
636 notarget {}
164de317
HPN
637 warning {}
638 error {}
261def70 639 source {
df58fc94 640 # Move any source-specific as-flags to a separate list to
261def70
HPN
641 # simplify processing.
642 if { [llength $opt_val] > 1 } {
df58fc94 643 lappend asflags [lrange $opt_val 1 end]
261def70
HPN
644 set opt_val [lindex $opt_val 0]
645 } else {
df58fc94 646 lappend asflags {}
261def70
HPN
647 }
648 }
649 default {
650 if [string length $opts($opt_name)] {
651 perror "option $opt_name multiply set in $file.d"
652 unresolved $subdir/$name
653 return
654 }
655
656 # A single "# ld:" with no options should do the right thing.
657 if { $opt_name == "ld" } {
658 set run_ld 1
659 }
cfe5266f
HPN
660 # Likewise objcopy_linked_file.
661 if { $opt_name == "objcopy_linked_file" } {
662 set run_objcopy 1
663 }
261def70
HPN
664 }
665 }
7f6a71ff
JM
666 if { $opt_name == "as" || $opt_name == "ld" } {
667 set opt_val [subst $opt_val]
668 }
134fa82e
HPN
669
670 # Append differently whether it's a message (without space) or
671 # an option or list (with space).
672 switch -- $opt_name {
673 warning -
674 error {
675 append opts($opt_name) $opt_val
676 }
677 default {
678 set opts($opt_name) [concat $opts($opt_name) $opt_val]
679 }
680 }
261def70 681 }
ef2b5578
MR
682
683 foreach i $extra_options {
684 set opt_name [lindex $i 0]
685 set opt_val [lindex $i 1]
686 if ![info exists opts($opt_name)] {
687 perror "unknown option $opt_name given in extra_opts"
688 unresolved $subdir/$name
689 return
690 }
691 # Add extra option to end of existing option, adding space
692 # if necessary.
693 if { ![regexp "warning|error" $opt_name]
694 && [string length $opts($opt_name)] } {
695 append opts($opt_name) " "
696 }
697 append opts($opt_name) $opt_val
698 }
699
3935e1af
RS
700 foreach opt { as ld } {
701 regsub {\[big_or_little_endian\]} $opts($opt) \
702 [big_or_little_endian] opts($opt)
703 }
261def70
HPN
704
705 # Decide early whether we should run the test for this target.
706 if { [llength $opts(target)] > 0 } {
707 set targmatch 0
708 foreach targ $opts(target) {
709 if [istarget $targ] {
710 set targmatch 1
711 break
712 }
713 }
714 if { $targmatch == 0 } {
715 return
716 }
717 }
718 foreach targ $opts(notarget) {
719 if [istarget $targ] {
720 return
721 }
722 }
723
f364d1ca
AM
724 set program ""
725 # It's meaningless to require an output-testing method when we
726 # expect an error.
727 if { $opts(error) == "" } {
728 if {$opts(PROG) != ""} {
729 switch -- $opts(PROG) {
730 objdump { set program objdump }
731 nm { set program nm }
732 objcopy { set program objcopy }
733 readelf { set program readelf }
734 default
261def70
HPN
735 { perror "unrecognized program option $opts(PROG) in $file.d"
736 unresolved $subdir/$name
737 return }
f364d1ca
AM
738 }
739 } else {
261def70 740 # Guess which program to run, by seeing which option was specified.
f364d1ca
AM
741 foreach p {objdump objcopy nm readelf} {
742 if {$opts($p) != ""} {
743 if {$program != ""} {
744 perror "ambiguous dump program in $file.d"
745 unresolved $subdir/$name
746 return
747 } else {
748 set program $p
749 }
261def70
HPN
750 }
751 }
752 }
f364d1ca 753 if { $program == "" && $opts(warning) == "" } {
261def70
HPN
754 perror "dump program unspecified in $file.d"
755 unresolved $subdir/$name
756 return
757 }
758 }
759
261def70
HPN
760 if { $opts(name) == "" } {
761 set testname "$subdir/$name"
762 } else {
763 set testname $opts(name)
764 }
765
766 if { $opts(source) == "" } {
767 set sourcefiles [list ${file}.s]
df58fc94 768 set asflags [list ""]
261def70
HPN
769 } else {
770 set sourcefiles {}
771 foreach sf $opts(source) {
b7b0b729
HPN
772 if { [string match "/*" $sf] } {
773 lappend sourcefiles "$sf"
f364d1ca 774 } else {
b7b0b729
HPN
775 lappend sourcefiles "$srcdir/$subdir/$sf"
776 }
261def70
HPN
777 }
778 }
779
ef2b5578
MR
780 if { $opts(dump) == "" } {
781 set dfile ${file}.d
782 } else {
783 set dfile $srcdir/$subdir/$opts(dump)
784 }
785
261def70
HPN
786 # Time to setup xfailures.
787 foreach targ $opts(xfail) {
788 setup_xfail $targ
789 }
790
791 # Assemble each file.
792 set objfiles {}
793 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
794 set sourcefile [lindex $sourcefiles $i]
df58fc94 795 set sourceasflags [lindex $asflags $i]
9854d43d 796 set run_objcopy_objects 0
797
798 if { [string match "*RUN_OBJCOPY*" $sourceasflags] } {
799 set run_objcopy_objects 1
800 }
801 regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
261def70
HPN
802
803 set objfile "tmpdir/dump$i.o"
30dabe8a 804 catch "exec rm -f $objfile" exec_output
261def70 805 lappend objfiles $objfile
df58fc94 806 set cmd "$AS $ASFLAGS $opts(as) $sourceasflags -o $objfile $sourcefile"
261def70
HPN
807
808 send_log "$cmd\n"
7f6a71ff
JM
809 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
810 remote_upload host "ld.tmp"
811 set comp_output [prune_warnings [file_contents "ld.tmp"]]
812 remote_file host delete "ld.tmp"
813 remote_file build delete "ld.tmp"
261def70 814
7f6a71ff 815 if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
261def70
HPN
816 send_log "$comp_output\n"
817 verbose "$comp_output" 3
f364d1ca
AM
818
819 set exitstat "succeeded"
820 if { $cmdret != 0 } { set exitstat "failed" }
821 verbose -log "$exitstat with: <$comp_output>"
261def70
HPN
822 fail $testname
823 return
824 }
9854d43d 825
826 if { $run_objcopy_objects } {
827 set cmd "$OBJCOPY $opts(objcopy_objects) $objfile"
828
829 send_log "$cmd\n"
830 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \
831 "" "/dev/null" "objcopy.tmp"]
832 remote_upload host "objcopy.tmp"
833 set comp_output [prune_warnings [file_contents "objcopy.tmp"]]
834 remote_file host delete "objcopy.tmp"
835 remote_file build delete "objcopy.tmp"
836
837 if { [lindex $cmdret 0] != 0 \
838 || ![string match "" $comp_output] } {
839 send_log "$comp_output\n"
840 verbose "$comp_output" 3
841
842 set exitstat "succeeded"
843 if { $cmdret != 0 } { set exitstat "failed" }
844 verbose -log "$exitstat with: <$comp_output>"
845 fail $testname
846 return
847 }
848 }
261def70
HPN
849 }
850
f364d1ca
AM
851 set expmsg $opts(error)
852 if { $opts(warning) != "" } {
853 if { $expmsg != "" } {
854 perror "$testname: mixing error and warning test-directives"
855 return
856 }
857 set expmsg $opts(warning)
858 }
859
261def70
HPN
860 # Perhaps link the file(s).
861 if { $run_ld } {
862 set objfile "tmpdir/dump"
30dabe8a 863 catch "exec rm -f $objfile" exec_output
3e3f011f
RS
864
865 # Add -L$srcdir/$subdir so that the linker command can use
866 # linker scripts in the source directory.
867 set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
d6e0b160 868 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
261def70 869
43d66c95
AB
870 # If needed then check for, or add a -Map option.
871 set mapfile ""
872 if { $opts(map) != "" } then {
873 if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then {
874 # Found existing mapfile option
875 verbose -log "Existing mapfile '$mapfile' found"
876 } else {
877 # No mapfile option.
878 set mapfile "tmpdir/dump.map"
879 verbose -log "Adding mapfile '$mapfile'"
880 set cmd "$cmd -Map=$mapfile"
881 }
882 }
883
261def70 884 send_log "$cmd\n"
7f6a71ff
JM
885 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
886 remote_upload host "ld.tmp"
d3746675 887 set comp_output [file_contents "ld.tmp"]
7f6a71ff
JM
888 remote_file host delete "ld.tmp"
889 remote_file build delete "ld.tmp"
890 set cmdret [lindex $cmdret 0]
cfe5266f 891
f364d1ca 892 if { $cmdret == 0 && $run_objcopy } {
cfe5266f
HPN
893 set infile $objfile
894 set objfile "tmpdir/dump1"
7f6a71ff 895 remote_file host delete $objfile
cfe5266f
HPN
896
897 # Note that we don't use OBJCOPYFLAGS here; any flags must be
898 # explicitly specified.
899 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
900
901 send_log "$cmd\n"
7f6a71ff
JM
902 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
903 remote_upload host "ld.tmp"
d3746675 904 append comp_output [file_contents "ld.tmp"]
7f6a71ff
JM
905 remote_file host delete "ld.tmp"
906 remote_file build delete "ld.tmp"
907 set cmdret [lindex $cmdret 0]
f364d1ca
AM
908 }
909
7f6a71ff 910 regsub "\n$" $comp_output "" comp_output
f364d1ca
AM
911 if { $cmdret != 0 || $comp_output != "" || $expmsg != "" } then {
912 set exitstat "succeeded"
913 if { $cmdret != 0 } { set exitstat "failed" }
914 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
915 send_log "$comp_output\n"
916 verbose "$comp_output" 3
917
164de317
HPN
918 if { ($expmsg == "") == ($comp_output == "") \
919 && [regexp $expmsg $comp_output] \
920 && (($cmdret == 0) == ($opts(error) == "")) } {
f364d1ca
AM
921 # We have the expected output from ld.
922 if { $opts(error) != "" || $program == "" } {
923 pass $testname
924 return
cfe5266f 925 }
f364d1ca
AM
926 } else {
927 verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
cfe5266f
HPN
928 fail $testname
929 return
930 }
931 }
43d66c95
AB
932
933 if { $opts(map) != "" } then {
934 # Check the map file matches.
935 set map_pattern_file $srcdir/$subdir/$opts(map)
936 verbose -log "Compare '$mapfile' against '$map_pattern_file'"
937 if { [regexp_diff $mapfile $map_pattern_file] } then {
938 fail "$testname (map file check)"
939 } else {
940 pass "$testname (map file check)"
941 }
942 }
261def70
HPN
943 } else {
944 set objfile "tmpdir/dump0.o"
945 }
946
947 # We must not have expected failure if we get here.
948 if { $opts(error) != "" } {
949 fail $testname
cfe5266f 950 return
261def70
HPN
951 }
952
f364d1ca
AM
953 set progopts1 $opts($program)
954 eval set progopts \$[string toupper $program]FLAGS
955 eval set binary \$[string toupper $program]
956
7f6a71ff 957 if { ![is_remote host] && [which $binary] == 0 } {
261def70
HPN
958 untested $testname
959 return
960 }
961
962 if { $progopts1 == "" } { set $progopts1 "-r" }
963 verbose "running $binary $progopts $progopts1" 3
964
965 # Objcopy, unlike the other two, won't send its output to stdout,
966 # so we have to run it specially.
3e8cba19 967 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
261def70
HPN
968 if { $program == "objcopy" } {
969 set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
3e8cba19
AM
970 }
971
972 # Ensure consistent sorting of symbols
973 if {[info exists env(LC_ALL)]} {
974 set old_lc_all $env(LC_ALL)
975 }
976 set env(LC_ALL) "C"
977 send_log "$cmd\n"
7f6a71ff 978 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
164de317 979 set cmdret [lindex $cmdret 0]
7f6a71ff
JM
980 remote_upload host "ld.tmp"
981 set comp_output [prune_warnings [file_contents "ld.tmp"]]
982 remote_file host delete "ld.tmp"
983 remote_file build delete "ld.tmp"
3e8cba19
AM
984 if {[info exists old_lc_all]} {
985 set env(LC_ALL) $old_lc_all
261def70 986 } else {
3e8cba19
AM
987 unset env(LC_ALL)
988 }
164de317
HPN
989 if { $cmdret != 0 || $comp_output != "" } {
990 send_log "exited abnormally with $cmdret, output:$comp_output\n"
3e8cba19
AM
991 fail $testname
992 return
261def70
HPN
993 }
994
9a2ee7fc 995 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
ef2b5578 996 if { [regexp_diff $dumpfile "${dfile}"] } then {
261def70 997 fail $testname
9a2ee7fc 998 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
261def70
HPN
999 return
1000 }
1001
1002 pass $testname
1003}
1004
1005proc slurp_options { file } {
5a68afcf
RM
1006 # If options_regsub(foo) is set to {a b}, then the contents of a
1007 # "#foo:" line will have regsub -all applied to replace a with b.
1008 global options_regsub
1009
261def70
HPN
1010 if [catch { set f [open $file r] } x] {
1011 #perror "couldn't open `$file': $x"
1012 perror "$x"
1013 return -1
1014 }
1015 set opt_array {}
1016 # whitespace expression
1017 set ws {[ ]*}
1018 set nws {[^ ]*}
1019 # whitespace is ignored anywhere except within the options list;
cfe5266f
HPN
1020 # option names are alphabetic plus underscore only.
1021 set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
261def70
HPN
1022 while { [gets $f line] != -1 } {
1023 set line [string trim $line]
1024 # Whitespace here is space-tab.
1025 if [regexp $pat $line xxx opt_name opt_val] {
1026 # match!
5a68afcf
RM
1027 if [info exists options_regsub($opt_name)] {
1028 set subst $options_regsub($opt_name)
1029 regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \
1030 opt_val
1031 }
261def70
HPN
1032 lappend opt_array [list $opt_name $opt_val]
1033 } else {
1034 break
1035 }
1036 }
1037 close $f
1038 return $opt_array
1039}
1040
261def70
HPN
1041proc file_contents { filename } {
1042 set file [open $filename r]
1043 set contents [read $file]
1044 close $file
1045 return $contents
1046}
bffbf940 1047
5d3236ee
DK
1048proc set_file_contents { filename contents } {
1049 set file [open $filename w]
1050 puts $file "$contents"
1051 close $file
1052}
1053
d8880531
L
1054# Create an archive using ar
1055#
fa0a16b1 1056proc ar_simple_create { ar aropts target objects } {
d8880531
L
1057 remote_file host delete $target
1058
1a215085 1059 set exec_output [run_host_cmd "$ar" "-rc $aropts $target $objects"]
d8880531
L
1060 set exec_output [prune_warnings $exec_output]
1061
1062 if [string match "" $exec_output] then {
1063 send_log "$exec_output\n"
1064 return 1
1065 } else {
1066 return 0
1067 }
1068}
1069
9147e853
JJ
1070# List contains test-items with 3 items followed by 2 lists, one item and
1071# one optional item:
894891db 1072# 0:name
897aea50
MR
1073# 1:ld/ar leading options, placed before object files
1074# 2:ld/ar trailing options, placed after object files
1075# 3:assembler options
1076# 4:filenames of assembler files
1077# 5:list of actions, options and expected outputs.
1078# 6:name of output file
1079# 7:compiler flags (optional)
3b6fe0cc 1080#
894891db
NC
1081# Actions: { command command-line-options file-containg-expected-output-regexps }
1082# Commands:
1083# objdump: Apply objdump options on result.
1084# nm: Apply nm options on result.
1085# readelf: Apply readelf options on result.
5a68afcf 1086# ld: Don't apply anything on result. Compare output during linking with
894891db
NC
1087# the file containing regexps (which is the second arg, not the third).
1088# Note that this *must* be the first action if it is to be used at all;
1089# in all other cases, any output from the linker during linking is
1090# treated as a sign of an error and FAILs the test.
3b6fe0cc 1091#
bffbf940
JJ
1092proc run_ld_link_tests { ldtests } {
1093 global ld
1094 global as
1095 global nm
d8880531 1096 global ar
bffbf940
JJ
1097 global objdump
1098 global READELF
1099 global srcdir
1100 global subdir
1101 global env
9147e853
JJ
1102 global CC
1103 global CFLAGS
eca41774 1104 global runtests
5d3236ee 1105 global exec_output
bffbf940
JJ
1106
1107 foreach testitem $ldtests {
1108 set testname [lindex $testitem 0]
eca41774
DK
1109
1110 if ![runtest_file_p $runtests $testname] then {
1111 continue
1112 }
1113
bffbf940 1114 set ld_options [lindex $testitem 1]
897aea50
MR
1115 set ld_after [lindex $testitem 2]
1116 set as_options [lindex $testitem 3]
1117 set src_files [lindex $testitem 4]
1118 set actions [lindex $testitem 5]
1119 set binfile tmpdir/[lindex $testitem 6]
1120 set cflags [lindex $testitem 7]
bffbf940
JJ
1121 set objfiles {}
1122 set is_unresolved 0
1123 set failed 0
5d3236ee
DK
1124 set maybe_failed 0
1125 set ld_output ""
bffbf940
JJ
1126
1127# verbose -log "Testname is $testname"
1128# verbose -log "ld_options is $ld_options"
897aea50 1129# verbose -log "ld_after is $ld_after"
bffbf940 1130# verbose -log "as_options is $as_options"
9147e853 1131# verbose -log "src_files is $src_files"
bffbf940
JJ
1132# verbose -log "actions is $actions"
1133# verbose -log "binfile is $binfile"
1134
1135 # Assemble each file in the test.
9147e853 1136 foreach src_file $src_files {
74d44110
MR
1137 set fileroot "[file rootname [file tail $src_file]]"
1138 set objfile "tmpdir/$fileroot.o"
bffbf940
JJ
1139 lappend objfiles $objfile
1140
9147e853 1141 if { [file extension $src_file] == ".c" } {
74d44110 1142 set as_file "tmpdir/$fileroot.s"
9147e853
JJ
1143 if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1144 set is_unresolved 1
1145 break
1146 }
1147 } else {
1148 set as_file "$srcdir/$subdir/$src_file"
1149 }
1150 if ![ld_assemble $as "$as_options $as_file" $objfile] {
bffbf940
JJ
1151 set is_unresolved 1
1152 break
1153 }
1154 }
1155
1156 # Catch assembler errors.
77c56f44 1157 if { $is_unresolved } {
bffbf940
JJ
1158 unresolved $testname
1159 continue
1160 }
1161
abc868c6
AM
1162 if { $binfile eq "tmpdir/" } {
1163 # compile only
1164 } elseif { [regexp ".*\\.a$" $binfile] } {
897aea50 1165 if { ![ar_simple_create $ar $ld_options $binfile "$objfiles $ld_after"] } {
d8880531 1166 set failed 1
d8880531 1167 }
897aea50 1168 } elseif { ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles $ld_after"] } {
5d3236ee
DK
1169 set maybe_failed 1
1170 set ld_output "$exec_output"
d8880531
L
1171 }
1172
77c56f44 1173 if { !$failed } {
bffbf940
JJ
1174 foreach actionlist $actions {
1175 set action [lindex $actionlist 0]
1176 set progopts [lindex $actionlist 1]
1177
1178 # There are actions where we run regexp_diff on the
1179 # output, and there are other actions (presumably).
1180 # Handling of the former look the same.
1181 set dump_prog ""
1182 switch -- $action {
1183 objdump
1184 { set dump_prog $objdump }
1185 nm
1186 { set dump_prog $nm }
1187 readelf
1188 { set dump_prog $READELF }
5d3236ee
DK
1189 ld
1190 { set dump_prog "ld" }
bffbf940
JJ
1191 default
1192 {
1193 perror "Unrecognized action $action"
1194 set is_unresolved 1
1195 break
1196 }
1197 }
1198
5d3236ee 1199 if { $action == "ld" } {
894891db
NC
1200 set regexpfile $progopts
1201 verbose "regexpfile is $srcdir/$subdir/$regexpfile"
5d3236ee
DK
1202 set_file_contents "tmpdir/ld.messages" "$ld_output"
1203 verbose "ld.messages has '[file_contents tmpdir/ld.messages]'"
894891db 1204 if { [regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$regexpfile"] } then {
5d3236ee
DK
1205 verbose "output is $ld_output" 2
1206 set failed 1
1207 break
1208 }
1209 set maybe_failed 0
77c56f44 1210 } elseif { !$maybe_failed && $dump_prog != "" } {
bffbf940
JJ
1211 set dumpfile [lindex $actionlist 2]
1212 set binary $dump_prog
1213
1214 # Ensure consistent sorting of symbols
1215 if {[info exists env(LC_ALL)]} {
1216 set old_lc_all $env(LC_ALL)
1217 }
1218 set env(LC_ALL) "C"
7f6a71ff
JM
1219 set cmd "$binary $progopts $binfile"
1220 set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
bffbf940 1221 send_log "$cmd\n"
7f6a71ff
JM
1222 remote_upload host "ld.stderr"
1223 set comp_output [prune_warnings [file_contents "ld.stderr"]]
1224 remote_file host delete "ld.stderr"
1225 remote_file build delete "ld.stderr"
5a68afcf 1226
bffbf940
JJ
1227 if {[info exists old_lc_all]} {
1228 set env(LC_ALL) $old_lc_all
1229 } else {
1230 unset env(LC_ALL)
1231 }
bffbf940
JJ
1232
1233 if ![string match "" $comp_output] then {
1234 send_log "$comp_output\n"
1235 set failed 1
1236 break
1237 }
1238
7f6a71ff
JM
1239 remote_upload host "dump.out"
1240
bffbf940
JJ
1241 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1242 verbose "output is [file_contents "dump.out"]" 2
1243 set failed 1
7f6a71ff
JM
1244 remote_file build delete "dump.out"
1245 remote_file host delete "dump.out"
bffbf940
JJ
1246 break
1247 }
7f6a71ff
JM
1248 remote_file build delete "dump.out"
1249 remote_file host delete "dump.out"
bffbf940
JJ
1250 }
1251 }
bffbf940
JJ
1252 }
1253
77c56f44 1254 if { $is_unresolved } {
bffbf940 1255 unresolved $testname
77c56f44
RS
1256 } elseif { $maybe_failed || $failed } {
1257 fail $testname
1258 } else {
1259 pass $testname
bffbf940
JJ
1260 }
1261 }
1262}
1263
252b5132
RH
1264# This definition is taken from an unreleased version of DejaGnu. Once
1265# that version gets released, and has been out in the world for a few
1266# months at least, it may be safe to delete this copy.
1267if ![string length [info proc prune_warnings]] {
1268 #
1269 # prune_warnings -- delete various system verbosities from TEXT
1270 #
1271 # An example is:
1272 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1273 #
1274 # Sites with particular verbose os's may wish to override this in site.exp.
1275 #
1276 proc prune_warnings { text } {
1277 # This is from sun4's. Do it for all machines for now.
1278 # The "\\1" is to try to preserve a "\n" but only if necessary.
1279 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1280
1281 # It might be tempting to get carried away and delete blank lines, etc.
1282 # Just delete *exactly* what we're ask to, and that's it.
1283 return $text
1284 }
1285}
24edc24d 1286
c8c140d9
BE
1287# targets_to_xfail is a list of target triplets to be xfailed.
1288# ldtests contains test-items with 3 items followed by 1 lists, 2 items
fab4a87f 1289# and 3 optional items:
c8c140d9
BE
1290# 0:name
1291# 1:ld options
1292# 2:assembler options
55255dae 1293# 3:filenames of source files
c8c140d9
BE
1294# 4:name of output file
1295# 5:expected output
1296# 6:compiler flags (optional)
55255dae 1297# 7:language (optional)
fab4a87f 1298# 8:linker warning (optional)
c8c140d9
BE
1299
1300proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
24edc24d
L
1301 global ld
1302 global as
1303 global srcdir
1304 global subdir
1305 global env
1306 global CC
55255dae 1307 global CXX
24edc24d 1308 global CFLAGS
58ffc3bd 1309 global CXXFLAGS
22ec3bd1 1310 global errcnt
fab4a87f 1311 global exec_output
24edc24d
L
1312
1313 foreach testitem $ldtests {
c8c140d9
BE
1314 foreach target $targets_to_xfail {
1315 setup_xfail $target
1316 }
24edc24d
L
1317 set testname [lindex $testitem 0]
1318 set ld_options [lindex $testitem 1]
1319 set as_options [lindex $testitem 2]
1320 set src_files [lindex $testitem 3]
1321 set binfile tmpdir/[lindex $testitem 4]
1322 set expfile [lindex $testitem 5]
1323 set cflags [lindex $testitem 6]
55255dae 1324 set lang [lindex $testitem 7]
fab4a87f 1325 set warning [lindex $testitem 8]
24edc24d 1326 set objfiles {}
24edc24d
L
1327 set failed 0
1328
1329# verbose -log "Testname is $testname"
1330# verbose -log "ld_options is $ld_options"
1331# verbose -log "as_options is $as_options"
1332# verbose -log "src_files is $src_files"
24edc24d
L
1333# verbose -log "binfile is $binfile"
1334
1335 # Assemble each file in the test.
1336 foreach src_file $src_files {
74d44110
MR
1337 set fileroot "[file rootname [file tail $src_file]]"
1338 set objfile "tmpdir/$fileroot.o"
24edc24d
L
1339 lappend objfiles $objfile
1340
a10e6b21
L
1341 # We ignore warnings since some compilers may generate
1342 # incorrect section attributes and the assembler will warn
1343 # them.
58ffc3bd
MF
1344 if { [ string match "c++" $lang ] } {
1345 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1346 } else {
1347 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1348 }
cb5ab6c8 1349 }
a10e6b21 1350
cb5ab6c8
L
1351 # We have to use $CC to build PIE and shared library.
1352 if { [ string match "c" $lang ] } {
1353 set link_proc ld_simple_link
1354 set link_cmd $CC
1355 } elseif { [ string match "c++" $lang ] } {
1356 set link_proc ld_simple_link
1357 set link_cmd $CXX
1358 } elseif { [ string match "-shared" $ld_options ] \
1359 || [ string match "-pie" $ld_options ] } {
1360 set link_proc ld_simple_link
1361 set link_cmd $CC
1362 } else {
1363 set link_proc ld_link
1364 set link_cmd $ld
1365 }
24edc24d 1366
abc868c6
AM
1367 if { $binfile eq "tmpdir/" } {
1368 # compile only
1369 pass $testname
1370 continue;
1371 } elseif ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
cb5ab6c8 1372 set failed 1
cb5ab6c8
L
1373 }
1374
1375 # Check if exec_output is expected.
1376 if { $warning != "" } then {
1377 verbose -log "returned with: <$exec_output>, expected: <$warning>"
1378 if { [regexp $warning $exec_output] } then {
a10e6b21 1379 set failed 0
cb5ab6c8
L
1380 } else {
1381 set failed 1
fab4a87f 1382 }
cb5ab6c8 1383 }
fab4a87f 1384
cb5ab6c8
L
1385 if { $failed == 0 } {
1386 send_log "Running: $binfile > $binfile.out\n"
1387 verbose "Running: $binfile > $binfile.out"
1388 catch "exec $binfile > $binfile.out" exec_output
fab4a87f 1389
cb5ab6c8
L
1390 if ![string match "" $exec_output] then {
1391 send_log "$exec_output\n"
1392 verbose "$exec_output" 1
1393 set failed 1
1394 } else {
1395 send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1396 verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1397 catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1398 set exec_output [prune_warnings $exec_output]
5a68afcf 1399
24edc24d
L
1400 if ![string match "" $exec_output] then {
1401 send_log "$exec_output\n"
1402 verbose "$exec_output" 1
1403 set failed 1
1404 }
1405 }
cb5ab6c8 1406 }
24edc24d 1407
cb5ab6c8
L
1408 if { $failed != 0 } {
1409 fail $testname
1410 } else {
1411 set errcnt 0
1412 pass $testname
24edc24d 1413 }
24edc24d
L
1414 }
1415}
d2dee3b2
L
1416
1417# List contains test-items with 3 items followed by 2 lists, one item and
1418# one optional item:
55255dae 1419# 0:name
fa0a16b1 1420# 1:ld or ar options
55255dae
L
1421# 2:compile options
1422# 3:filenames of source files
1423# 4:action and options.
1424# 5:name of output file
1425# 6:language (optional)
dd98f8d2 1426# 7:linker warnings (optional)
d2dee3b2
L
1427#
1428# Actions:
1429# objdump: Apply objdump options on result. Compare with regex (last arg).
1430# nm: Apply nm options on result. Compare with regex (last arg).
1431# readelf: Apply readelf options on result. Compare with regex (last arg).
1432#
1433proc run_cc_link_tests { ldtests } {
1434 global nm
1435 global objdump
1436 global READELF
1437 global srcdir
1438 global subdir
1439 global env
1440 global CC
55255dae 1441 global CXX
d2dee3b2 1442 global CFLAGS
58ffc3bd 1443 global CXXFLAGS
d8880531 1444 global ar
dd98f8d2 1445 global exec_output
603c4399
JW
1446 global board_cflags
1447
1448 if [board_info [target_info name] exists cflags] {
1449 set board_cflags " [board_info [target_info name] cflags]"
1450 } else {
1451 set board_cflags ""
1452 }
d2dee3b2
L
1453
1454 foreach testitem $ldtests {
1455 set testname [lindex $testitem 0]
1456 set ldflags [lindex $testitem 1]
1457 set cflags [lindex $testitem 2]
1458 set src_files [lindex $testitem 3]
1459 set actions [lindex $testitem 4]
1460 set binfile tmpdir/[lindex $testitem 5]
55255dae 1461 set lang [lindex $testitem 6]
dd98f8d2 1462 set warnings [lindex $testitem 7]
d2dee3b2
L
1463 set objfiles {}
1464 set is_unresolved 0
1465 set failed 0
1466
c3e11cbe
AM
1467 #verbose -log "testname is $testname"
1468 #verbose -log "ldflags is $ldflags"
1469 #verbose -log "cflags is $cflags"
1470 #verbose -log "src_files is $src_files"
1471 #verbose -log "actions is $actions"
1472 #verbose -log "binfile is $binfile"
1473 #verbose -log "lang is $lang"
1474 #verbose -log "warnings is $warnings"
1475
d2dee3b2
L
1476 # Compile each file in the test.
1477 foreach src_file $src_files {
74d44110
MR
1478 set fileroot "[file rootname [file tail $src_file]]"
1479 set objfile "tmpdir/$fileroot.o"
d2dee3b2
L
1480 lappend objfiles $objfile
1481
1482 # We ignore warnings since some compilers may generate
1483 # incorrect section attributes and the assembler will warn
1484 # them.
58ffc3bd
MF
1485 if { [ string match "c++" $lang ] } {
1486 ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1487 } else {
1488 ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1489 }
d2dee3b2
L
1490 }
1491
1492 # Clear error and warning counts.
1493 reset_vars
1494
55255dae
L
1495 if { [ string match "c++" $lang ] } {
1496 set cc_cmd $CXX
1497 } else {
1498 set cc_cmd $CC
1499 }
1500
abc868c6
AM
1501 if { $binfile eq "tmpdir/" } {
1502 # compile only
1503 } elseif { [regexp ".*\\.a$" $binfile] } {
fa0a16b1 1504 if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
d8880531
L
1505 fail $testname
1506 set failed 1
d8880531 1507 }
741e0128 1508 } else {
603c4399 1509 if { ![ld_simple_link $cc_cmd $binfile "$board_cflags -L$srcdir/$subdir $ldflags $objfiles"] } {
741e0128 1510 set failed 1
741e0128
L
1511 }
1512
dd98f8d2
NC
1513 # Check if exec_output is expected.
1514 if { $warnings != "" } then {
1515 verbose -log "returned with: <$exec_output>, expected: <$warnings>"
1516 if { [regexp $warnings $exec_output] } then {
df71cb5c 1517 set failed 0
dd98f8d2
NC
1518 } else {
1519 set failed 1
1520 }
741e0128
L
1521 }
1522
1523 if { $failed == 1 } {
dd98f8d2 1524 fail $testname
dd98f8d2 1525 }
d8880531
L
1526 }
1527
1528 if { $failed == 0 } {
d2dee3b2
L
1529 foreach actionlist $actions {
1530 set action [lindex $actionlist 0]
1531 set progopts [lindex $actionlist 1]
1532
1533 # There are actions where we run regexp_diff on the
1534 # output, and there are other actions (presumably).
1535 # Handling of the former look the same.
1536 set dump_prog ""
1537 switch -- $action {
1538 objdump
1539 { set dump_prog $objdump }
1540 nm
1541 { set dump_prog $nm }
1542 readelf
1543 { set dump_prog $READELF }
1544 default
1545 {
1546 perror "Unrecognized action $action"
1547 set is_unresolved 1
1548 break
1549 }
1550 }
1551
1552 if { $dump_prog != "" } {
1553 set dumpfile [lindex $actionlist 2]
1554 set binary $dump_prog
1555
1556 # Ensure consistent sorting of symbols
1557 if {[info exists env(LC_ALL)]} {
1558 set old_lc_all $env(LC_ALL)
1559 }
1560 set env(LC_ALL) "C"
1561 set cmd "$binary $progopts $binfile > dump.out"
1562 send_log "$cmd\n"
1563 catch "exec $cmd" comp_output
1564 if {[info exists old_lc_all]} {
1565 set env(LC_ALL) $old_lc_all
1566 } else {
1567 unset env(LC_ALL)
1568 }
1569 set comp_output [prune_warnings $comp_output]
1570
1571 if ![string match "" $comp_output] then {
1572 send_log "$comp_output\n"
1573 set failed 1
1574 break
1575 }
1576
1577 if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1578 verbose "output is [file_contents "dump.out"]" 2
1579 set failed 1
1580 break
1581 }
1582 }
1583 }
d2dee3b2
L
1584 }
1585
abc868c6
AM
1586 if { $failed != 0 } {
1587 fail $testname
1588 } elseif { $is_unresolved == 0 } {
1589 pass $testname
1590 } else {
d2dee3b2
L
1591 unresolved $testname
1592 continue
1593 }
1594 }
1595}
430a16a5
NC
1596
1597# Returns true if --gc-sections is supported on the target.
1598
1599proc check_gc_sections_available { } {
1600 global gc_sections_available_saved
1601 global ld
5a68afcf 1602
430a16a5
NC
1603 if {![info exists gc_sections_available_saved]} {
1604 # Some targets don't support gc-sections despite whatever's
1605 # advertised by ld's options.
59c108f7
NC
1606 if { [istarget arc-*-*]
1607 || [istarget d30v-*-*]
1608 || [istarget dlx-*-*]
1609 || [istarget i960-*-*]
59c108f7
NC
1610 || [istarget pj*-*-*]
1611 || [istarget alpha-*-*]
1612 || [istarget hppa*64-*-*]
1613 || [istarget i370-*-*]
1614 || [istarget i860-*-*]
1615 || [istarget ia64-*-*]
1616 || [istarget mep-*-*]
0f088b2a 1617 || [istarget mn10200-*-*] } {
430a16a5
NC
1618 set gc_sections_available_saved 0
1619 return 0
1620 }
1621
1622 # elf2flt uses -q (--emit-relocs), which is incompatible with
1623 # --gc-sections.
1624 if { [board_info target exists ldflags]
1625 && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1626 set gc_sections_available_saved 0
1627 return 0
1628 }
1629
430a16a5 1630 # Check if the ld used by gcc supports --gc-sections.
1d5316ab
AM
1631 # FIXME: this test is useless since ld --help always says
1632 # --gc-sections is available
430a16a5
NC
1633 set ld_output [remote_exec host $ld "--help"]
1634 if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1635 set gc_sections_available_saved 1
1636 } else {
1637 set gc_sections_available_saved 0
1638 }
1639 }
1640 return $gc_sections_available_saved
1641}
33aa234e 1642
1d5316ab
AM
1643# Returns true if -shared is supported on the target
1644# Only used and accurate for ELF targets at the moment
1645
1646proc check_shared_lib_support { } {
83a23418
YZ
1647 if {![istarget aarch64*-*-elf]
1648 && ![istarget arc-*-*]
1649 && ![istarget arm*-*-elf]
1d5316ab
AM
1650 && ![istarget avr-*-*]
1651 && ![istarget cr16-*-*]
5220199d 1652 && ![istarget cris*-*-elf]
1d5316ab
AM
1653 && ![istarget crx-*-*]
1654 && ![istarget d10v-*-*]
1655 && ![istarget d30v-*-*]
1656 && ![istarget dlx-*-*]
cfb8c092 1657 && ![istarget epiphany-*-*]
1d5316ab
AM
1658 && ![istarget fr30-*-*]
1659 && ![istarget frv-*-*]
1660 && ![istarget h8300-*-*]
1661 && ![istarget i860-*-*]
1662 && ![istarget i960-*-*]
1663 && ![istarget ip2k-*-*]
1664 && ![istarget iq2000-*-*]
1665 && ![istarget lm32-*-*]
1666 && ![istarget m32c-*-*]
1667 && ![istarget m32r-*-*]
32d79e68
AM
1668 && ![istarget m6811-*-*]
1669 && ![istarget m6812-*-*]
1d5316ab
AM
1670 && ![istarget m68hc1*-*-*]
1671 && ![istarget mcore*-*-*]
1672 && ![istarget mep-*-*]
1673 && ![istarget microblaze-*-*]
23c80bf4 1674 && ![istarget mips*-*-elf]
1d5316ab
AM
1675 && ![istarget mn10200-*-*]
1676 && ![istarget moxie-*-*]
1677 && ![istarget msp430-*-*]
1678 && ![istarget mt-*-*]
35c08157 1679 && ![istarget nds32*-*-*]
73589c9d 1680 && ![istarget or1k*-*-*]
1d5316ab 1681 && ![istarget pj-*-*]
4046d87a 1682 && ![istarget rl78-*-*]
1d5316ab
AM
1683 && ![istarget rx-*-*]
1684 && ![istarget spu-*-*]
1685 && ![istarget v850*-*-*]
c18392d8 1686 && ![istarget visium-*-*]
1d5316ab
AM
1687 && ![istarget xstormy16-*-*]
1688 && ![istarget *-*-irix*]
1689 && ![istarget *-*-rtems] } {
1690 return 1
1691 }
1692 return 0
1693}
1694
5d3236ee
DK
1695# Returns true if the target ld supports the plugin API.
1696proc check_plugin_api_available { } {
1697 global plugin_api_available_saved
1698 global ld
1699 if {![info exists plugin_api_available_saved]} {
1700 # Check if the ld used by gcc supports --plugin.
1701 set ld_output [remote_exec host $ld "--help"]
2d03dd2f 1702 if { [ string first "-plugin PLUGIN" $ld_output ] >= 0 } {
5d3236ee
DK
1703 set plugin_api_available_saved 1
1704 } else {
1705 set plugin_api_available_saved 0
1706 }
1707 }
1708 return $plugin_api_available_saved
1709}
1710
3f730821
HPN
1711# Sets ld_sysroot to the current sysroot (empty if not supported) and
1712# returns true if the target ld supports sysroot.
bdd65db9 1713proc check_sysroot_available { } {
3f730821 1714 global ld_sysroot_available_saved ld ld_sysroot
bdd65db9 1715 if {![info exists ld_sysroot_available_saved]} {
3f730821
HPN
1716 # Check if ld supports --sysroot *other* than empty.
1717 set ld_sysroot [string trimright [lindex [remote_exec host $ld "--print-sysroot"] 1]]
1718 if { $ld_sysroot == "" } {
bdd65db9
HPN
1719 set ld_sysroot_available_saved 0
1720 } else {
1721 set ld_sysroot_available_saved 1
1722 }
1723 }
1724 return $ld_sysroot_available_saved
1725}
1726
3bd58fbe
L
1727# Returns true if the target compiler supports LTO
1728proc check_lto_available { } {
1729 global lto_available_saved
1730 global CC
7174e19f 1731
3bd58fbe 1732 if {![info exists lto_available_saved]} {
19aef622
NC
1733 if { [which $CC] == 0 } {
1734 set lto_available_saved 0
1735 return 0
1736 }
3bd58fbe 1737 # Check if gcc supports -flto -fuse-linker-plugin
f1d7f4a6
AM
1738 set flags ""
1739 if [board_info [target_info name] exists cflags] {
1740 append flags " [board_info [target_info name] cflags]"
1741 }
1742 if [board_info [target_info name] exists ldflags] {
1743 append flags " [board_info [target_info name] ldflags]"
3bd58fbe 1744 }
f1d7f4a6
AM
1745
1746 set basename "tmpdir/lto[pid]"
1747 set src ${basename}.c
1748 set output ${basename}.out
3bd58fbe 1749 set f [open $src "w"]
7174e19f 1750 puts $f "int main() { return 0; }"
3bd58fbe 1751 close $f
f1d7f4a6 1752 remote_download host $src
c3e11cbe 1753 set lto_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -fuse-linker-plugin $src -o $output"]
f1d7f4a6
AM
1754 remote_file host delete $src
1755 remote_file host delete $output
3bd58fbe 1756 file delete $src
3bd58fbe
L
1757 }
1758 return $lto_available_saved
1759}
1760
c3e11cbe
AM
1761# Returns true if the target compiler supports LTO -ffat-lto-objects
1762proc check_lto_fat_available { } {
1763 global lto_fat_available_saved
1764 global CC
1765
1766 if {![info exists lto_fat_available_saved]} {
1767 if { [which $CC] == 0 } {
1768 set lto_fat_available_saved 0
1769 return 0
1770 }
1771 # Check if gcc supports -flto -fuse-linker-plugin
1772 set flags ""
1773 if [board_info [target_info name] exists cflags] {
1774 append flags " [board_info [target_info name] cflags]"
1775 }
1776 if [board_info [target_info name] exists ldflags] {
1777 append flags " [board_info [target_info name] ldflags]"
1778 }
1779
1780 set basename "tmpdir/lto[pid]"
1781 set src ${basename}.c
1782 set output ${basename}.out
1783 set f [open $src "w"]
1784 puts $f "int main() { return 0; }"
1785 close $f
1786 remote_download host $src
1787 set lto_fat_available_saved [run_host_cmd_yesno "$CC" "$flags -flto -ffat-lto-objects -fuse-linker-plugin $src -o $output"]
1788 remote_file host delete $src
1789 remote_file host delete $output
1790 file delete $src
1791 }
1792 return $lto_fat_available_saved
1793}
1794
92c09111
L
1795# Returns true if the target compiler supports LTO and -shared
1796proc check_lto_shared_available { } {
1797 global lto_shared_available_saved
1798 global CC
1799
92c09111 1800 if {![info exists lto_shared_available_saved]} {
3bb9e7b4
AM
1801 if { [which $CC] == 0 } {
1802 set lto_shared_available_saved 0
1803 return 0
1804 }
92c09111 1805 # Check if gcc supports -flto -fuse-linker-plugin -shared
f1d7f4a6
AM
1806 set flags ""
1807 if [board_info [target_info name] exists cflags] {
1808 append flags " [board_info [target_info name] cflags]"
1809 }
1810 if [board_info [target_info name] exists ldflags] {
1811 append flags " [board_info [target_info name] ldflags]"
92c09111 1812 }
f1d7f4a6
AM
1813
1814 set basename "tmpdir/lto_shared[pid]"
1815 set src ${basename}.c
1816 set output ${basename}.so
92c09111
L
1817 set f [open $src "w"]
1818 puts $f ""
1819 close $f
f1d7f4a6
AM
1820 remote_download host $src
1821 set lto_shared_available_saved [run_host_cmd_yesno "$CC" "$flags -shared -fPIC -flto -fuse-linker-plugin $src -o $output"]
1822 remote_file host delete $src
1823 remote_file host delete $output
92c09111 1824 file delete $src
92c09111
L
1825 }
1826 return $lto_shared_available_saved
1827}
1828
33aa234e
JK
1829# Check if the assembler supports CFI statements.
1830
1831proc check_as_cfi { } {
1832 global check_as_cfi_result
1833 global as
1834 if [info exists check_as_cfi_result] {
1835 return $check_as_cfi_result
1836 }
1837 set as_file "tmpdir/check_as_cfi.s"
1838 set as_fh [open $as_file w 0666]
1839 puts $as_fh "# Generated file. DO NOT EDIT"
1840 puts $as_fh "\t.cfi_startproc"
1841 puts $as_fh "\t.cfi_endproc"
1842 close $as_fh
1843 remote_download host $as_file
1844 verbose -log "Checking CFI support:"
1845 rename "perror" "check_as_cfi_perror"
1846 proc perror { args } { }
1847 set success [ld_assemble $as $as_file "/dev/null"]
1848 rename "perror" ""
1849 rename "check_as_cfi_perror" "perror"
1850 #remote_file host delete $as_file
1851 set check_as_cfi_result $success
1852 return $success
1853}
1854
c22ee0ad
L
1855# Returns true if IFUNC works.
1856
1857proc check_ifunc_available { } {
1858 global ifunc_available_saved
1859 global CC
1860
1861 if {![info exists ifunc_available_saved]} {
1862 if { [which $CC] == 0 } {
1863 set ifunc_available_saved 0
1864 return 0
1865 }
1866 # Check if gcc supports -flto -fuse-linker-plugin
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]"
1873 }
1874
1875 set basename "tmpdir/ifunc[pid]"
1876 set src ${basename}.c
1877 set output ${basename}.out
1878 set f [open $src "w"]
1879 puts $f "extern int library_func2 (void);"
1880 puts $f "int main (void)"
1881 puts $f "{"
1882 puts $f " if (library_func2 () != 2) __builtin_abort ();"
1883 puts $f " return 0; "
1884 puts $f "}"
1885 puts $f "static int library_func1 (void) {return 2; }"
1886 puts $f "void *foo (void) __asm__ (\"library_func2\");"
1887 puts $f "void *foo (void) { return library_func1; }"
1888 puts $f "__asm__(\".type library_func2, %gnu_indirect_function\");"
1889 close $f
1890 remote_download host $src
1891 set ifunc_available_saved [run_host_cmd_yesno "$CC" "$flags $src -o $output"]
1892 if { $ifunc_available_saved == 1 } {
1893 set ifunc_available_saved [run_host_cmd_yesno "$output" ""]
1894 }
1895 remote_file host delete $src
1896 remote_file host delete $output
1897 file delete $src
1898 }
1899 return $ifunc_available_saved
1900}
1901
33aa234e
JK
1902# Provide virtual target "cfi" for targets supporting CFI.
1903
1904rename "istarget" "istarget_ld"
1905proc istarget { target } {
1906 if {$target == "cfi"} {
1907 return [check_as_cfi]
1908 }
1909 return [istarget_ld $target]
1910}
This page took 0.781082 seconds and 4 git commands to generate.