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