1 # Copyright (C) 1993-2020 Free Software Foundation, Inc.
3 # This file is part of the GNU Binutils.
5 # This file is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 # True if the object format is known to be ELF.
22 proc is_elf_format {} {
23 # config.sub for these targets curiously transforms a target doublet
24 # ending in -elf to -none. eg. m68hc12-elf to m68hc12-unknown-none
25 # They are always elf.
26 if { [istarget m68hc1*-*] || [istarget s12z*-*] || [istarget xgate-*] } {
29 # vxworks (and windiss) excluded due to number of ELF tests that need
30 # modifying to pass on those targets.
31 # && ![istarget *-*-vxworks*]
32 # && ![istarget *-*-windiss*]
34 if { ![istarget *-*-chorus*]
35 && ![istarget *-*-cloudabi*]
36 && ![istarget *-*-eabi*]
37 && ![istarget *-*-*elf*]
38 && ![istarget *-*-*freebsd*]
39 && ![istarget *-*-fuchsia*]
40 && ![istarget *-*-gnu*]
41 && ![istarget *-*-irix5*]
42 && ![istarget *-*-irix6*]
43 && ![istarget *-*-kaos*]
44 && ![istarget *-*-*linux*]
45 && ![istarget *-*-lynxos*]
46 && ![istarget *-*-nacl*]
47 && ![istarget *-*-netbsd*]
48 && ![istarget *-*-nto*]
49 && ![istarget *-*-openbsd*]
50 && ![istarget *-*-rtems*]
51 && ![istarget *-*-solaris2*]
52 && ![istarget *-*-sysv4*]
53 && ![istarget *-*-unixware*]
54 && ![istarget *-*-wasm32*]
55 && ![istarget avr-*-*]
56 && ![istarget hppa*64*-*-hpux*]
57 && ![istarget ia64-*-hpux*] } {
61 if { [istarget *-*-linux*ecoff*]
62 || [istarget *-*-rtemscoff*] } {
66 if { ![istarget *-*-netbsdelf*]
67 && ( [istarget vax-*-netbsd*]
68 || [istarget ns32k-*-netbsd*]) } {
72 if { [istarget arm-*-openbsd*]
73 || [istarget ns32k-*-openbsd*]
74 || [istarget vax-*-openbsd*] } {
81 # True if the object format is known to be a.out.
83 proc is_aout_format {} {
84 if { [istarget *-*-*aout*]
85 || [istarget *-*-bsd*]
86 || [istarget *-*-msdos*]
87 || [istarget ns32k-*-*]
88 || [istarget pdp11-*-*]
89 || [istarget vax-*-netbsd] } {
95 # True if the object format is known to be PE COFF.
97 proc is_pecoff_format args {
98 if { [llength $args] == 1 } {
99 set m_os [lindex $args 0]
103 if { [istarget $m_os-beospe*]
104 || [istarget $m_os-cegcc*]
105 || [istarget $m_os-cygwin*]
106 || [istarget $m_os-interix*]
107 || [istarget $m_os-mingw*]
108 || [istarget $m_os-netbsdpe*]
109 || [istarget $m_os-pe*]
110 || [istarget $m_os-winnt*] } {
116 proc is_som_format {} {
117 if { ![istarget hppa*-*-*] || [istarget hppa*64*-*-*] } {
120 if { [istarget *-*-osf*] \
121 || [istarget {*-*-h[ip]ux*}] \
122 || [istarget *-*-mpeix*] \
123 || [istarget *-*-bsd*] } {
129 proc is_xcoff_format {} {
130 if { [istarget rs6000-*-*]
131 || [istarget powerpc*-*-aix*]
132 || [istarget powerpc*-*-beos*]
133 || [istarget powerpc*-*-macos*] } {
139 # True if the object format is known to be 64-bit ELF.
141 proc is_elf64 { binary_file } {
145 set tmpfile [file dirname $binary_file]/readelf.out
147 catch "exec $READELF $READELFFLAGS -h $binary_file > $tmpfile" got
149 if ![string match "" $got] then {
153 if { ![regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \
154 [file_contents $tmpfile] nil readelf_size] } {
158 if { $readelf_size == "64" } {
165 # True if the object format is known to use RELA relocations.
167 proc is_rela { binary_file } {
171 set tmpfile [file dirname $binary_file]/readelf.out
172 catch "exec $READELF $READELFFLAGS -S $binary_file > $tmpfile" got
174 if ![string match "" $got] then {
178 if { ![regexp "RELA" [file_contents $tmpfile]] } {
185 # True if the target matches TARGET, specified as a TCL procedure if
186 # in square brackets or as machine triplet otherwise.
188 proc match_target { target } {
189 if [regexp {^!?\[.*\]$} $target] {
192 return [istarget $target]
196 # True if the ELF target supports setting the ELF header OSABI field
197 # to ELFOSABI_GNU or ELFOSABI_FREEBSD, a requirement for STT_GNU_IFUNC
198 # symbol and SHF_GNU_MBIND or SHF_GNU_RETAIN section support.
200 # This generally depends on the target OS only, however there are a
201 # number of exceptions for bare metal targets as follows. The MSP430
202 # and Visium targets set OSABI to ELFOSABI_STANDALONE. Likewise
203 # non-EABI ARM targets set OSABI to ELFOSABI_ARM
205 # Non-Linux HPPA defaults to ELFOSABI_HPUX.
207 # Note that some TI C6X targets use ELFOSABI_C6000_* but one doesn't,
208 # so we don't try to sort out tic6x here. (The effect is that linker
209 # testcases will generally need to exclude tic6x or use a -m option.)
211 proc supports_gnu_osabi {} {
212 if { [istarget *-*-gnu*]
213 || [istarget *-*-linux*]
214 || [istarget *-*-nacl*]
215 || ( [istarget *-*-*bsd*] && ![istarget arm*-*-netbsd*] )
216 || [istarget *-*-symbianelf]
217 || [istarget *-*-lynxos]
218 || ( [istarget *-*-nto*] && ![istarget arm*-*-*] )
219 || [istarget *-*-irix*]
220 || [istarget *-*-*eabi*]
221 || [istarget *-*-rtems*] } {
224 if { [istarget "wasm32*-*-*"] } {
227 if { ![istarget "*-*-elf*"] } {
230 if { [istarget "arm*-*-*"]
231 || [istarget "msp430-*-*"]
232 || [istarget "hppa-unknown-elf"]
233 || [istarget "visium-*-*"] } {
239 # Return true if target uses the generic_link_hash_table linker.
240 proc is_generic { } {
241 if { [istarget "d30v-*-*"]
242 || [istarget "dlx-*-*"]
243 || [istarget "pj*-*-*"]
244 || [istarget "s12z-*-*"]
245 || [istarget "xgate-*-*"] } {
251 # True if the ELF target supports STB_GNU_UNIQUE.
253 # This require ELFOSABI_GNU, and `bfd_elf_final_link'.
255 proc supports_gnu_unique {} {
256 if { [istarget *-*-freebsd*] } {
259 if { [supports_gnu_osabi] && ![is_generic] } {
265 # True for targets that do not sort .symtab as per the ELF standard.
266 # ie. any that have mips_elf32_be_vec, mips_elf32_le_vec,
267 # mips_elf32_n_be_vec or mips_elf32_n_le_vec as the primary bfd target
268 # vector in config.bfd. When syncing with config.bfd, don't forget that
269 # earlier case-matches trump later ones.
270 proc is_bad_symtab {} {
271 if { ![istarget "mips*-*-*"] } {
274 if { [istarget "*-*-chorus*"]
275 || [istarget "*-*-irix5*"]
276 || [istarget "*-*-irix6*"]
277 || [istarget "*-*-none"]
278 || [istarget "*-*-rtems*"]
279 || [istarget "*-*-windiss"] } {
282 if { [istarget "*-*-elf*"]
283 && ![istarget "*-sde-*"]
284 && ![istarget "*-mti-*"]
285 && ![istarget "*-img-*"] } {
288 if { [istarget "*-*-openbsd*"]
289 && ![istarget "mips64*-*-*"] } {
295 # Returns true if -shared is supported on the target
297 proc check_shared_lib_support { } {
298 global shared_available_saved
301 if {![info exists shared_available_saved]} {
302 set ld_output [remote_exec host $ld "-shared"]
303 if { [ string first "not supported" $ld_output ] >= 0 } {
304 set shared_available_saved 0
306 set shared_available_saved 1
309 return $shared_available_saved
312 # Returns true if -pie is supported on the target
314 proc check_pie_support { } {
315 global pie_available_saved
318 if {![info exists pie_available_saved]} {
319 set ld_output [remote_exec host $ld "-pie"]
320 if { [ string first "not supported" $ld_output ] >= 0 } {
321 set pie_available_saved 0
323 set pie_available_saved 1
326 return $pie_available_saved
329 proc check_relro_support { } {
330 global relro_available_saved
333 if {![info exists relro_available_saved]} {
334 remote_file host delete norelro
335 set ld_output [remote_exec host $ld "-z norelro"]
336 if { [string first "not supported" $ld_output] >= 0
337 || [string first "unrecognized option" $ld_output] >= 0
338 || [string first "-z norelro ignored" $ld_output] >= 0
339 || [string first "cannot find norelro" $ld_output] >= 0 } {
340 set relro_available_saved 0
342 set relro_available_saved 1
345 return $relro_available_saved
348 # Compare two files line-by-line. FILE_1 is the actual output and FILE_2
349 # is the expected output. Ignore blank lines in either file.
351 # FILE_2 is a series of regexps, comments and # directives. The directives
355 # Treat the test as a PASS if everything up till this point has
356 # matched. Ignore any remaining lines in either FILE_1 or FILE_2.
359 # Reverse the sense of the test: expect differences to exist.
363 # Skip all lines in FILE_1 until the first that matches REGEXP.
366 # Optionally match REGEXP against line from FILE_1. If the REGEXP
367 # does not match then the next line from FILE_2 is tried.
369 # Other # lines are comments. Regexp lines starting with the `!' character
370 # specify inverse matching (use `\!' for literal matching against a leading
371 # `!'). Skip empty lines in both files.
373 # The first optional argument is a list of regexp substitutions of the form:
375 # EXP1 SUBSPEC1 EXP2 SUBSPEC2 ...
377 # This tells the function to apply each regexp substitution EXPi->SUBSPECi
378 # in order to every line of FILE_2.
380 # Return nonzero if differences exist.
381 proc regexp_diff { file_1 file_2 args } {
389 if { [llength $args] > 0 } {
390 set ref_subst [lindex $args 0]
392 if { [llength $args] > 1 } {
393 perror "Too many arguments to regexp_diff"
397 if [file exists $file_1] then {
398 set file_a [open $file_1 r]
400 perror "$file_1 doesn't exist"
404 if [file exists $file_2] then {
405 set file_b [open $file_2 r]
407 perror "$file_2 doesn't exist"
412 verbose " Regexp-diff'ing: $file_1 $file_2" 2
417 while { [string length $line_a] == 0 } {
418 # Ignore blank line in FILE_1.
419 if { [gets $file_a line_a] == $eof } {
424 while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
425 if { [string match "#pass" $line_b] } {
429 } elseif { [string match "#failif" $line_b] } {
430 send_log "fail if no difference\n"
431 verbose "fail if no difference" 3
433 } elseif { [string match "#..." $line_b] } {
434 if { [gets $file_b line_b] == $eof } {
439 set negated [expr { [string index $line_b 0] == "!" }]
440 set line_bx [string range $line_b $negated end]
441 set n [expr { $negated ? "! " : "" }]
442 # Substitute on the reference.
443 foreach {name value} $ref_subst {
444 regsub -- $name $line_bx $value line_bx
446 verbose "looking for $n\"^$line_bx$\"" 3
447 while { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
448 verbose "skipping \"$line_a\"" 3
449 if { [gets $file_a line_a] == $eof } {
455 } elseif { [string match "#\\?*" $line_b] } {
457 set line_b [string replace $line_b 0 1]
458 set negated [expr { [string index $line_b 0] == "!" }]
459 set line_bx [string range $line_b $negated end]
460 set n [expr { $negated ? "! " : "" }]
461 # Substitute on the reference.
462 foreach {name value} $ref_subst {
463 regsub -- $name $line_bx $value line_bx
465 verbose "optional match for $n\"^$line_bx$\"" 3
466 if { [expr [regexp "^$line_bx$" "$line_a"] != $negated] } {
471 if { [gets $file_b line_b] == $eof } {
479 } elseif { $end_1 && $end_2 } {
481 } elseif { $end_1 } {
482 send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
483 verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
486 } elseif { $end_2 } {
487 send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
488 verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
492 set negated [expr { [string index $line_b 0] == "!" }]
493 set line_bx [string range $line_b $negated end]
494 set n [expr { $negated ? "! " : "" }]
495 set s [expr { $negated ? " " : "" }]
496 # Substitute on the reference.
497 foreach {name value} $ref_subst {
498 regsub -- $name $line_bx $value line_bx
500 verbose "regexp $n\"^$line_bx$\"\nline \"$line_a\"" 3
501 if { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
502 send_log "regexp_diff match failure\n"
503 send_log "regexp $n\"^$line_bx$\"\nline $s\"$line_a\"\n"
504 verbose "regexp_diff match failure\n" 3
510 if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
511 send_log "$file_1 and $file_2 are different lengths\n"
512 verbose "$file_1 and $file_2 are different lengths" 3
516 if { $fail_if_match } {
517 if { $differences == 0 } {
530 # prune_warnings_extra -- delete extra warnings from TEXT.
533 # ld: warning: /lib64/ld-linux-x86-64.so.2: unsupported GNU_PROPERTY_TYPE (5) type : 0xc0010001
534 proc prune_warnings_extra { text } {
536 # Warnings are only pruned from non-experimental code (ie code not
537 # on a release branch). For experimental code we want the warnings
538 # as they indicate that the sources need to be updated to recognise
539 # the new properties.
540 if { "$experimental" == "false" } {
541 # The "\\1" is to try to preserve a "\n" but only if necessary.
542 regsub -all "(^|\n)(\[^\n\]*: warning:\[^\n\]*unsupported GNU_PROPERTY_TYPE\[^\n\]*\n?)+" $text "\\1" text
544 # PR binutils/23898: It is OK to have gaps in build notes.
545 regsub -all "(^|\n)(\[^\n\]*: Warning: Gap in build notes detected from\[^\n\]*\n?)+" $text "\\1" text
549 # This definition is taken from an unreleased version of DejaGnu. Once
550 # that version gets released, and has been out in the world for a few
551 # months at least, it may be safe to delete this copy.
552 if ![string length [info proc prune_warnings]] {
554 # prune_warnings -- delete various system verbosities from TEXT
557 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
559 # Sites with particular verbose os's may wish to override this in site.exp.
561 proc prune_warnings { text } {
562 # This is from sun4's. Do it for all machines for now.
563 # The "\\1" is to try to preserve a "\n" but only if necessary.
564 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
565 # It might be tempting to get carried away and delete blank lines, etc.
566 # Just delete *exactly* what we're ask to, and that's it.
567 set text [prune_warnings_extra $text]
570 } elseif { [info procs saved-prune_warnings] == [list] } {
571 rename prune_warnings saved-prune_warnings
572 proc prune_warnings { text } {
573 set text [saved-prune_warnings $text]
574 set text [prune_warnings_extra $text]
579 # run_dump_test FILE (optional:) EXTRA_OPTIONS
581 # Assemble a .s file, then run some utility on it and check the output.
582 # Optionally generate the .s file first by running the compiler.
584 # There should be an assembly language file named FILE.s in the test
585 # suite directory, and a pattern file called FILE.d. run_dump_test
586 # will assemble FILE.s, optionally run objcopy on the object file,
587 # optionally run ld, optionally run another objcopy, optionally run
588 # another tool under test specified by PROG, then run a dump tool like
589 # addr2line, nm, objdump, readelf or size on the object file to produce
590 # textual output, and then analyze that with regexps.
591 # The FILE.d file specifies what program to run, and what to expect in
594 # The FILE.d file begins with zero or more option lines, which specify
595 # flags to pass to the assembler, the program to run to dump the
596 # assembler's output, and the options it wants. The option lines have
601 # OPTION is the name of some option, like "name" or "objdump", and
602 # VALUE is OPTION's value. The valid options are described below.
603 # Whitespace is ignored everywhere, except within VALUE. The option
604 # list ends with the first line that doesn't match the above syntax.
605 # However, a line within the options that begins with a #, but doesn't
606 # have a recognizable option name followed by a colon, is considered a
607 # comment and entirely ignored.
609 # The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of
610 # two-element lists. The first element of each is an option name, and
611 # the second additional arguments to be added on to the end of the
612 # option list as given in FILE.d. (If omitted, no additional options
615 # The interesting options are:
618 # The name of this test, passed to DejaGNU's `pass' and `fail'
619 # commands. If omitted, this defaults to FILE, the root of the
620 # .s and .d files' names.
623 # When assembling, pass FLAGS to the assembler.
624 # If assembling several files, you can pass different assembler
625 # options in the "source" directives. See below.
626 # Multiple instances of this directive tells run_dump_test to run the test
627 # multiple times -- one time with each set of flags provided.
628 # Each instance will run exactly as a file with a single "as" line, it is
629 # not possible to condition any behaviour on which set of "as" flags is
630 # used. That means that the "source" specific options are appended to
631 # the "as" flags for their corresponding files, and any extra processing
632 # (e.g. with "ld" and "objcopy") is repeated for each test.
635 # Link assembled files using FLAGS, in the order of the "source"
636 # directives, when using multiple files.
638 # ld_after_inputfiles: FLAGS
639 # Similar to "ld", but put FLAGS after all input files.
642 # Run the compiler with FLAGS (to which -S is added) to generate assembler
643 # source first. source: must be provided and should consist of .c files.
644 # Source-specific CC flags are not supported.
646 # objcopy_objects: FLAGS
647 # Run objcopy with the specified flags after assembling any source
648 # that has the special marker RUN_OBJCOPY in the source specific
651 # objcopy_linked_file: FLAGS
652 # Run objcopy on the linked file with the specified flags.
653 # This lets you transform the linked file using objcopy, before the
654 # result is analyzed by an analyzer program specified below.
657 # The name of a program under test, to run to modify or analyze the
658 # .o file produced by the assembler. Recognised names are: ar,
659 # elfedit, nm, objcopy, ranlib, strings, and strip.
661 # DUMPPROG: PROGRAM-NAME
662 # The name of the program to run to analyze the file produced
663 # by the assembler or the linker. This can be omitted;
664 # run_dump_test will guess which program to run from which of
665 # the flags options below is present.
672 # Use the specified program to analyze the output file, and pass it
673 # FLAGS, in addition to the output name. Note that they are run
674 # with LC_ALL=C in the environment to give consistent sorting of
675 # symbols. If no FLAGS are needed then you can use:
676 # DUMPPROG: [nm objdump readelf addr2line]
677 # instead, or just pass a flag that happens to be the default.
678 # If objdump is the dump tool and we're not dumping binary, nor
679 # have run ld, then the standard section names (.text, .data and
680 # .bss) are replaced by target ones if any (eg. rx-elf uses "P"
681 # instead of .text). The substition is done for both the
682 # objdump options (eg: "-j .text" is replaced by "-j P") and the
685 # source: SOURCE [FLAGS]
686 # Assemble the file SOURCE.s using the flags in the "as" directive
687 # and the (optional) FLAGS. If omitted, the source defaults to
689 # This is useful if several .d files want to share a .s file.
690 # More than one "source" directive can be given, which is useful
691 # when testing linking.
694 # Match against DUMP.d. If omitted, this defaults to FILE.d. This
695 # is useful if several .d files differ by options only. Options are
696 # always read from FILE.d.
698 # target: GLOB|PROC ...
699 # Run this test only on a specified list of targets. More precisely,
700 # in the space-separated list each glob is passed to "istarget" and
701 # each proc is called as a TCL procedure. List items are interpreted
702 # such that procs are denoted by surrounding square brackets, and any
703 # other items are consired globs. If the call evaluates true for any
704 # of them, the test will be run, otherwise it will be marked
707 # notarget: GLOB|PROC ...
708 # Do not run this test on a specified list of targets. Again, each
709 # glob in the space-separated list is passed to "istarget" and each
710 # proc is called as a TCL procedure, and the test is run if it
711 # evaluates *false* for *all* of them. Otherwise it will be marked
714 # alltargets: GLOB|PROC ...
715 # Run this test on a specified list of targets. Again, each
716 # glob in the space-separated list is passed to "istarget" and each
717 # proc is called as a TCL procedure, and the test is run if it
718 # evaluates *true* for *all* of them. Otherwise it will be marked
721 # skip: GLOB|PROC ...
722 # anyskip: GLOB|PROC ...
723 # noskip: GLOB|PROC ...
724 # These are exactly the same as "notarget", "alltargets" and
725 # "target" respectively, except that they do nothing at all if the
726 # check fails. They should only be used in groups, to construct a
727 # single test which is run on all targets but with variant options
728 # or expected output on some targets. (For example, see
729 # gas/arm/inst.d and gas/arm/wince_inst.d.)
731 # xfail: GLOB|PROC ...
732 # Run this test and it is is expected to fail on a specified list
736 # An error with message matching REGEX must be emitted for the test
737 # to pass. The DUMPPROG, addr2line, nm, objdump, readelf and size
738 # options have no meaning and need not supplied if this is present.
739 # Multiple "error" directives append to the expected error message.
742 # Means the same as 'error', except the regular expression lines
743 # are contains in FILE.
746 # Expect a warning matching REGEX. It is an error to issue
747 # both "error" and "warning". Multiple "warning" directives
748 # append to the expected warning message.
750 # warning_output: FILE
751 # Means the same as 'warning', except the regular expression
752 # lines are contains in FILE.
755 # Adding this option will cause the linker to generate a linker
756 # map file, using the -Map=MAPFILE command line option. If
757 # there is no -Map=MAPFILE in the 'ld: FLAGS' then one will be
758 # added to the linker command line. The contents of the
759 # generated MAPFILE are then compared against the regexp lines
760 # in FILE using `regexp_diff' (see below for details).
763 # Means that the section substitution for objdump is disabled.
765 # Each option may occur at most once unless otherwise mentioned.
767 # After the option lines come regexp lines. run_dump_test calls
768 # regexp_diff to compare the output of the dumping tool against the
771 proc run_dump_test { name {extra_options {}} } {
772 global ADDR2LINE ADDR2LINEFLAGS AS ASFLAGS CC CFLAGS ELFEDIT ELFEDITFLAGS
773 global LD LDFLAGS NM NMFLAGS OBJCOPY OBJCOPYFLAGS OBJDUMP OBJDUMPFLAGS
774 global READELF READELFFLAGS STRIP STRIPFLAGS
775 global copyfile env runtests srcdir subdir verbose
777 if [string match "*/*" $name] {
779 set name [file tail $name]
781 set file "$srcdir/$subdir/$name"
784 if ![runtest_file_p $runtests $name] then {
788 set opt_array [slurp_options "${file}.d"]
789 if { $opt_array == -1 } {
790 perror "error reading options from $file.d"
791 unresolved $subdir/$name
794 set dumpfile tmpdir/dump.out
799 set opts(DUMPPROG) {}
800 set opts(addr2line) {}
801 set opts(alltargets) {}
805 set as_final_flags {}
806 set as_additional_flags {}
811 set opts(error_output) {}
813 set opts(ld_after_inputfiles) {}
818 set opts(notarget) {}
820 set opts(objcopy_linked_file) {}
821 set opts(objcopy_objects) {}
825 set opts(section_subst) {}
834 set opts(warning_output) {}
838 foreach i [concat $opt_array {{} {}} $extra_options] {
839 set opt_name [lindex $i 0]
840 set opt_val [lindex $i 1]
841 if { $opt_name == "" } {
845 if ![info exists opts($opt_name)] {
846 perror "unknown option $opt_name in file $file.d"
847 unresolved $subdir/$name
851 # Allow more substitutions, including tcl functions, for as, ld,
852 # and cc. Not done in general because extra quoting is needed for glob
853 # args used for example in binutils-all/remove-relocs-04.d.
854 if { $opt_name == "as" || $opt_name == "ld" || $opt_name == "cc" } {
855 set opt_val [subst $opt_val]
857 # Just substitute $srcdir and $subdir
858 regsub -all {\$srcdir} "$opt_val" "$srcdir" opt_val
859 regsub -all {\$subdir} "$opt_val" "$subdir" opt_val
862 switch -- $opt_name {
873 # Move any source-specific as-flags to a separate list to
874 # simplify processing.
875 if { [llength $opt_val] > 1 } {
876 lappend asflags [lrange $opt_val 1 end]
877 set opt_val [lindex $opt_val 0]
882 # Create the object file name based on nothing but the source
885 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]].o]
886 # But, sometimes, we have the exact same source filename in
887 # different directories (foo/src.s bar/src.s) which would lead
888 # us to try and create two src.o files. We detect this
889 # conflict here, and instead create src.o and src1.o.
891 while { [lsearch $objfile_names $new_objfile] != -1 } {
894 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]]${j}.o]
896 lappend objfile_names $new_objfile
900 && [string length $opts($opt_name)]
901 && $opt_name != "as" } {
902 perror "option $opt_name multiply set in $file.d"
903 unresolved $subdir/$name
907 # A single "#ld:" with no options should do the right thing.
908 if { $opt_name == "ld" } {
911 # Likewise objcopy_linked_file.
912 if { $opt_name == "objcopy_linked_file" } {
918 # Append differently whether it's a message (without space) or
919 # an option or list (with space).
920 switch -- $opt_name {
923 append opts($opt_name) $opt_val
927 set as_additional_flags [concat $as_additional_flags $opt_val]
929 lappend opts(as) $opt_val
933 set opts($opt_name) [concat $opts($opt_name) $opt_val]
938 # Ensure there is something in $opts(as) for the foreach loop below.
939 if { [llength $opts(as)] == 0 } {
940 set opts(as) [list " "]
942 foreach x $opts(as) {
943 if { [string length $x] && [string length $as_additional_flags] } {
946 append x $as_additional_flags
947 regsub {\[big_or_little_endian\]} $x \
948 [big_or_little_endian] x
949 lappend as_final_flags $x
952 regsub {\[big_or_little_endian\]} $opts(ld) \
953 [big_or_little_endian] opts(ld)
955 if { $opts(name) == "" } {
956 set testname "$subdir/$name"
958 set testname $opts(name)
962 foreach opt { warning error warning_output error_output } {
963 if { $opts($opt) != "" } {
965 perror "$testname: bad mix of warning and error test directives"
973 # Decide early whether we should run the test for this target.
974 if { [llength $opts(noskip)] > 0 } {
976 foreach targ $opts(noskip) {
977 if [match_target $targ] {
982 if { $targmatch == 0 } {
986 foreach targ $opts(anyskip) {
987 if ![match_target $targ] {
991 foreach targ $opts(skip) {
992 if [match_target $targ] {
996 if { [llength $opts(target)] > 0 } {
998 foreach targ $opts(target) {
999 if [match_target $targ] {
1004 if { $targmatch == 0 } {
1005 unsupported $testname
1009 foreach targ $opts(alltargets) {
1010 if ![match_target $targ] {
1011 unsupported $testname
1015 foreach targ $opts(notarget) {
1016 if [match_target $targ] {
1017 unsupported $testname
1023 # It's meaningless to require an output-testing method when we
1025 if { $opts(error) == "" && $opts(error_output) == "" } {
1026 if { $opts(DUMPPROG) != "" } {
1027 switch -- $opts(DUMPPROG) {
1028 addr2line { set dumpprogram addr2line }
1029 nm { set dumpprogram nm }
1030 objdump { set dumpprogram objdump }
1031 readelf { set dumpprogram readelf }
1032 size { set dumpprogram size }
1034 perror "unrecognized DUMPPROG option $opts(DUMPPROG) in $file.d"
1035 unresolved $testname
1040 # Guess which program to run, by seeing which option was specified.
1041 foreach p {addr2line nm objdump readelf size} {
1042 if {$opts($p) != ""} {
1043 if {$dumpprogram != ""} {
1044 perror "ambiguous dump program in $file.d"
1045 unresolved $testname
1053 if { $dumpprogram == "" && $opts(map) == "" && !$err_warn } {
1054 perror "dump program unspecified in $file.d"
1055 unresolved $testname
1060 # Possibly compile some of the inputs, and build up a replacement
1061 # for opts(source) with the output .s names substituted in as we go.
1062 # Set the .s names from the objfile_names to take advantage of the
1063 # uniquification that happened earlier.
1064 if { $opts(cc) != ""} {
1068 foreach cfile $opts(source) ofile $objfile_names {
1069 if { [file extension $cfile] != ".c" } {
1070 lappend new_source "$cfile"
1074 if { ! [string match "./*" $cfile] } {
1075 set cfile "$srcdir/$subdir/$cfile"
1077 # ofile is never absolute, so this always works to protect sfile
1078 # from later absolutization.
1079 set sfile "./[file rootname $ofile].s"
1080 set cmd "$CC $CFLAGS -S $opts(cc) -o $sfile $cfile"
1082 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1083 remote_upload host "dump.tmp"
1084 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1085 remote_file host delete "dump.tmp"
1086 remote_file build delete "dump.tmp"
1087 lappend new_source "$sfile"
1088 set cmdret [lindex $cmdret 0]
1090 regsub "\n$" $comp_output "" comp_output
1091 if { $cmdret != 0} {
1092 send_log "compilation of $cfile failed, exit status $cmdret with <$comp_output>"
1093 # Should this be 'unresolved', or is that too silent?
1098 set opts(source) $new_source
1101 if { $opts(source) == "" } {
1102 set sourcefiles [list ${file}.s]
1103 set asflags [list ""]
1104 set objfile_names [list tmpdir/[file tail ${file}].o]
1107 foreach sf $opts(source) {
1108 if { [string match "./*" $sf] } {
1109 lappend sourcefiles "$sf"
1111 lappend sourcefiles "$srcdir/$subdir/$sf"
1116 if { $opts(dump) == "" } {
1119 set dfile $srcdir/$subdir/$opts(dump)
1122 # Time to setup xfailures.
1123 foreach targ $opts(xfail) {
1124 if [match_target $targ] {
1130 foreach as_flags $as_final_flags {
1131 # Assemble each file.
1133 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
1134 set sourcefile [lindex $sourcefiles $i]
1135 set sourceasflags [lindex $asflags $i]
1136 set run_objcopy_objects 0
1138 if { [string match "*RUN_OBJCOPY*" $sourceasflags] } {
1139 set run_objcopy_objects 1
1141 regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
1143 set objfile [lindex $objfile_names $i]
1144 catch "exec rm -f $objfile" exec_output
1145 lappend objfiles $objfile
1147 if { $as_flags == "binary" } {
1148 while {[file type $sourcefile] eq "link"} {
1149 set newfile [file readlink $sourcefile]
1150 if {[string index $newfile 0] ne "/"} {
1151 set newfile [file dirname $sourcefile]/$newfile
1153 set sourcefile $newfile
1155 set newfile [remote_download host $sourcefile $objfile]
1157 if { $newfile == "" } {
1161 if { [istarget "hppa*-*-*"] \
1162 && ![istarget "*-*-linux*"] \
1163 && ![istarget "*-*-netbsd*" ] } {
1164 set cmd "sed -e 's/^\[ \]*\.comm \\(\[^,\]*\\),\\(.*\\)/\\1 .comm \\2/' < $sourcefile > tmpdir/asm.s"
1166 set cmdret [remote_exec host [concat sh -c [list "$cmd"]]]
1167 set cmdret [lindex $cmdret 0]
1168 if { $cmdret != 0 } {
1169 perror "sed failure"
1170 unresolved $testname
1173 set sourcefile tmpdir/asm.s
1175 set cmd "$AS $ASFLAGS $as_flags $sourceasflags -o $objfile $sourcefile"
1178 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1179 remote_upload host "dump.tmp"
1180 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1181 remote_file host delete "dump.tmp"
1182 remote_file build delete "dump.tmp"
1183 set cmdret [lindex $cmdret 0]
1185 if { $cmdret == 0 && $run_objcopy_objects } {
1186 set cmd "$OBJCOPY $opts(objcopy_objects) $objfile"
1189 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \
1190 "" "/dev/null" "dump.tmp"]
1191 remote_upload host "dump.tmp"
1192 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1193 remote_file host delete "dump.tmp"
1194 remote_file build delete "dump.tmp"
1195 set cmdret [lindex $cmdret 0]
1199 # Perhaps link the file(s).
1200 if { $cmdret == 0 && $run_ld } {
1201 set objfile "tmpdir/dump"
1202 catch "exec rm -f $objfile" exec_output
1207 if [check_relro_support] {
1208 set ld_extra_opt "-z norelro"
1211 # Add -L$srcdir/$subdir so that the linker command can use
1212 # linker scripts in the source directory.
1213 set cmd "$LD $ld_extra_opt $LDFLAGS -L$srcdir/$subdir \
1214 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
1216 # If needed then check for, or add a -Map option.
1218 if { $opts(map) != "" } then {
1219 if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then {
1220 # Found existing mapfile option
1221 verbose -log "Existing mapfile '$mapfile' found"
1223 # No mapfile option.
1224 set mapfile "tmpdir/dump.map"
1225 verbose -log "Adding mapfile '$mapfile'"
1226 set cmd "$cmd -Map=$mapfile"
1231 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1232 remote_upload host "dump.tmp"
1233 append comp_output [file_contents "dump.tmp"]
1234 remote_file host delete "dump.tmp"
1235 remote_file build delete "dump.tmp"
1236 set cmdret [lindex $cmdret 0]
1238 if { $cmdret == 0 && $run_objcopy } {
1240 set objfile "tmpdir/dump1"
1241 remote_file host delete $objfile
1243 # Note that we don't use OBJCOPYFLAGS here; any flags must be
1244 # explicitly specified.
1245 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
1248 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1249 remote_upload host "dump.tmp"
1250 append comp_output [file_contents "dump.tmp"]
1251 remote_file host delete "dump.tmp"
1252 remote_file build delete "dump.tmp"
1253 set cmdret [lindex $cmdret 0]
1256 set objfile [lindex $objfiles 0]
1259 if { $cmdret == 0 && $opts(PROG) != "" } {
1260 set destopt ${copyfile}.o
1261 switch -- $opts(PROG) {
1262 ar { set program ar }
1267 nm { set program nm }
1268 objcopy { set program objcopy }
1269 ranlib { set program ranlib }
1270 strings { set program strings }
1273 set destopt "-o $destopt"
1276 perror "unrecognized PROG option $opts(PROG) in $file.d"
1277 unresolved $testname
1282 set progopts1 $opts($program)
1283 eval set progopts \$[string toupper $program]FLAGS
1284 eval set binary \$[string toupper $program]
1286 if { ![is_remote host] && [which $binary] == 0 } {
1291 verbose "running $binary $progopts $progopts1" 3
1292 set cmd "$binary $progopts $progopts1 $objfile $destopt"
1294 # Ensure consistent sorting of symbols
1295 if {[info exists env(LC_ALL)]} {
1296 set old_lc_all $env(LC_ALL)
1300 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"]
1301 set cmdret [lindex $cmdret 0]
1302 remote_upload host "dump.tmp"
1303 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1304 remote_file host delete "dump.tmp"
1305 remote_file build delete "dump.tmp"
1306 if {[info exists old_lc_all]} {
1307 set env(LC_ALL) $old_lc_all
1311 if { $destopt != "" } {
1312 set objfile ${copyfile}.o
1316 set want_out(source) ""
1317 set want_out(terminal) 0
1319 if { $opts(error) != "" || $opts(error_output) != "" } {
1320 set want_out(terminal) 1
1323 if { $opts(error) != "" || $opts(warning) != "" } {
1324 set want_out(source) "regex"
1325 if { $opts(error) != "" } {
1326 set want_out(regex) $opts(error)
1328 set want_out(regex) $opts(warning)
1331 set want_out(source) "file"
1332 if { $opts(error_output) != "" } {
1333 set want_out(file) $opts(error_output)
1335 set want_out(file) $opts(warning_output)
1340 regsub "\n$" $comp_output "" comp_output
1341 if { $cmdret != 0 || $comp_output != "" || $want_out(source) != "" } {
1342 set exitstat "succeeded"
1343 if { $cmdret != 0 } { set exitstat "failed" }
1345 if { $want_out(source) == "regex" } {
1346 verbose -log "$exitstat with: <$comp_output>, expected: <$want_out(regex)>"
1347 } elseif { $want_out(source) == "file" } {
1348 verbose -log "$exitstat with: <$comp_output>, expected in file $want_out(file)"
1349 set_file_contents "tmpdir/ld.messages" "$comp_output"
1351 verbose -log "$exitstat with: <$comp_output>, no expected output"
1354 if { (($want_out(source) == "") == ($comp_output == "")) \
1355 && (($cmdret == 0) == ($want_out(terminal) == 0)) \
1356 && ((($want_out(source) == "regex") \
1357 && [regexp -- $want_out(regex) $comp_output]) \
1358 || (($want_out(source) == "file") \
1359 && (![regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$want_out(file)"]))) } {
1360 # We have the expected output.
1361 if { $want_out(terminal) || $dumpprogram == "" } {
1371 # We must not have expected failure if we get here.
1372 if { $opts(error) != "" } {
1377 if { $opts(map) != "" } then {
1378 # Check the map file matches.
1379 set map_pattern_file $srcdir/$subdir/$opts(map)
1380 verbose -log "Compare '$mapfile' against '$map_pattern_file'"
1381 if { [regexp_diff $mapfile $map_pattern_file] } then {
1382 fail "$testname (map file check)"
1384 pass "$testname (map file check)"
1387 if { $dumpprogram == "" } then {
1392 set progopts1 $opts($dumpprogram)
1393 eval set progopts \$[string toupper $dumpprogram]FLAGS
1394 eval set binary \$[string toupper $dumpprogram]
1396 if { ![is_remote host] && [which $binary] == 0 } {
1401 # For objdump of gas output, automatically translate standard section names
1403 if { !$run_ld && $dumpprogram == "objdump" \
1404 && $opts(section_subst) != "no" \
1405 && ![string match "*-b binary*" $progopts1] } {
1406 set sect_names [get_standard_section_names]
1407 if { $sect_names != ""} {
1408 regsub -- "\\.text" $progopts1 "[lindex $sect_names 0]" progopts1
1409 regsub -- "\\.data" $progopts1 "[lindex $sect_names 1]" progopts1
1410 regsub -- "\\.bss" $progopts1 "[lindex $sect_names 2]" progopts1
1414 if { $progopts1 == "" } { set $progopts1 "-r" }
1415 verbose "running $binary $progopts $progopts1" 3
1417 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
1419 # Ensure consistent sorting of symbols
1420 if {[info exists env(LC_ALL)]} {
1421 set old_lc_all $env(LC_ALL)
1425 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"]
1426 set cmdret [lindex $cmdret 0]
1427 remote_upload host "dump.tmp"
1428 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1429 remote_file host delete "dump.tmp"
1430 remote_file build delete "dump.tmp"
1431 if {[info exists old_lc_all]} {
1432 set env(LC_ALL) $old_lc_all
1436 if { $cmdret != 0 || $comp_output != "" } {
1437 send_log "exited abnormally with $cmdret, output:$comp_output\n"
1442 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
1444 # Create the substition list for objdump output.
1446 if { $sect_names != "" } {
1447 set regexp_subst [list "\\\\?\\.text" [lindex $sect_names 0] \
1448 "\\\\?\\.data" [lindex $sect_names 1] \
1449 "\\\\?\\.bss" [lindex $sect_names 2] ]
1452 if { [regexp_diff $dumpfile "${dfile}" $regexp_subst] } then {
1454 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
1462 proc slurp_options { file } {
1463 # If options_regsub(foo) is set to {a b}, then the contents of a
1464 # "#foo:" line will have regsub -all applied to replace a with b.
1465 global options_regsub
1467 if [catch { set f [open $file r] } x] {
1468 #perror "couldn't open `$file': $x"
1473 # whitespace expression
1476 # whitespace is ignored anywhere except within the options list;
1477 # option names are alphanumeric plus underscore.
1478 set pat "^#${ws}(\[a-zA-Z0-9_\]*)$ws:${ws}(.*)$ws\$"
1479 while { [gets $f line] != -1 } {
1480 set line [string trim $line]
1481 # Whitespace here is space-tab.
1482 if [regexp $pat $line xxx opt_name opt_val] {
1484 if [info exists options_regsub($opt_name)] {
1485 set subst $options_regsub($opt_name)
1486 regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \
1489 lappend opt_array [list $opt_name $opt_val]
1490 } elseif {![regexp "^#" $line ]} {
1498 proc file_contents { filename } {
1499 set file [open $filename r]
1500 set contents [read $file]
1505 proc set_file_contents { filename contents } {
1506 set file [open $filename w]
1507 puts $file "$contents"
1511 # Look for big-endian or little-endian switches in the multlib
1512 # options and translate these into a -EB or -EL switch. Note
1513 # we cannot rely upon proc process_multilib_options to do this
1514 # for us because for some targets the compiler does not support
1515 # -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
1516 # the site.exp file will include the switch "-mbig-endian"
1517 # (rather than "big-endian") which is not detected by proc
1518 # process_multilib_options.
1520 proc big_or_little_endian {} {
1522 if [board_info [target_info name] exists multilib_flags] {
1523 set tmp_flags " [board_info [target_info name] multilib_flags]"
1525 foreach x $tmp_flags {
1555 # Internal procedure: return the names of the standard sections
1557 proc get_standard_section_names {} {
1558 if [istarget "rx-*-elf"] {
1559 return { "P" "D_1" "B_1" }
1561 if { [istarget "alpha*-*-*vms*"] || [is_som_format] } {
1562 return { {\$CODE\$} {\$DATA\$} {\$BSS\$} }