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