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