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