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