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