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 {} {
98 if { [istarget *-*-beospe*]
99 || [istarget *-*-cegcc*]
100 || [istarget *-*-cygwin*]
101 || [istarget *-*-interix*]
102 || [istarget *-*-mingw*]
103 || [istarget *-*-netbsdpe*]
104 || [istarget *-*-pe*]
105 || [istarget *-*-winnt*] } {
111 proc is_som_format {} {
112 if { ![istarget hppa*-*-*] || [istarget hppa*64*-*-*] } {
115 if { [istarget *-*-osf*] \
116 || [istarget {*-*-h[ip]ux*}] \
117 || [istarget *-*-mpeix*] \
118 || [istarget *-*-bsd*] } {
124 # True if the object format is known to be 64-bit ELF.
126 proc is_elf64 { binary_file } {
130 set tmpfile [file dirname $binary_file]/readelf.out
132 catch "exec $READELF $READELFFLAGS -h $binary_file > $tmpfile" got
134 if ![string match "" $got] then {
138 if { ![regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \
139 [file_contents $tmpfile] nil readelf_size] } {
143 if { $readelf_size == "64" } {
150 # True if the object format is known to use RELA relocations.
152 proc is_rela { binary_file } {
156 set tmpfile [file dirname $binary_file]/readelf.out
157 catch "exec $READELF $READELFFLAGS -S $binary_file > $tmpfile" got
159 if ![string match "" $got] then {
163 if { ![regexp "RELA" [file_contents $tmpfile]] } {
170 # True if the target matches TARGET, specified as a TCL procedure if
171 # in square brackets or as machine triplet otherwise.
173 proc match_target { target } {
174 if [regexp {^!?\[.*\]$} $target] {
177 return [istarget $target]
181 # True if the ELF target supports setting the ELF header OSABI field
182 # to ELFOSABI_GNU or ELFOSABI_FREEBSD, a requirement for STT_GNU_IFUNC
183 # symbol and SHF_GNU_MBIND section support.
185 # This generally depends on the target OS only, however there are a
186 # number of exceptions for bare metal targets as follows. The MSP430
187 # and Visium targets set OSABI to ELFOSABI_STANDALONE. Likewise
188 # non-EABI ARM targets set OSABI to ELFOSABI_ARM
190 # Note that some TI C6X targets use ELFOSABI_C6000_* but one doesn't,
191 # so we don't try to sort out tic6x here. (The effect is that linker
192 # testcases will generally need to exclude tic6x or use a -m option.)
194 proc supports_gnu_osabi {} {
195 if { [istarget *-*-gnu*]
196 || [istarget *-*-linux*]
197 || [istarget *-*-nacl*]
198 || ( [istarget *-*-*bsd*] && ![istarget arm*-*-netbsd*] )
199 || [istarget *-*-symbianelf]
200 || [istarget *-*-lynxos]
201 || ( [istarget *-*-nto*] && ![istarget arm*-*-*] )
202 || [istarget *-*-irix*]
203 || [istarget *-*-*eabi*]
204 || [istarget *-*-rtems*] } {
207 if { [istarget "wasm32*-*-*"] } {
210 if { ![istarget "*-*-elf*"] } {
213 if { [istarget "arm*-*-*"]
214 || [istarget "msp430-*-*"]
215 || [istarget "visium-*-*"] } {
221 # Return true if target uses the generic_link_hash_table linker.
222 proc is_generic { } {
223 if { [istarget "d30v-*-*"]
224 || [istarget "dlx-*-*"]
225 || [istarget "pj*-*-*"]
226 || [istarget "s12z-*-*"]
227 || [istarget "xgate-*-*"] } {
233 # True if the ELF target supports STB_GNU_UNIQUE.
235 # This require ELFOSABI_GNU, and `bfd_elf_final_link'.
237 proc supports_gnu_unique {} {
238 if { [istarget *-*-freebsd*] } {
241 if { [supports_gnu_osabi] && ![is_generic] } {
247 # True for targets that do not sort .symtab as per the ELF standard.
248 # ie. any that have mips_elf32_be_vec, mips_elf32_le_vec,
249 # mips_elf32_n_be_vec or mips_elf32_n_le_vec as the primary bfd target
250 # vector in config.bfd. When syncing with config.bfd, don't forget that
251 # earlier case-matches trump later ones.
252 proc is_bad_symtab {} {
253 if { ![istarget "mips*-*-*"] } {
256 if { [istarget "*-*-chorus*"]
257 || [istarget "*-*-irix5*"]
258 || [istarget "*-*-irix6*"]
259 || [istarget "*-*-none"]
260 || [istarget "*-*-rtems*"]
261 || [istarget "*-*-windiss"] } {
264 if { [istarget "*-*-elf*"]
265 && ![istarget "*-sde-*"]
266 && ![istarget "*-mti-*"]
267 && ![istarget "*-img-*"] } {
270 if { [istarget "*-*-openbsd*"]
271 && ![istarget "mips64*-*-*"] } {
277 # Returns true if -shared is supported on the target
279 proc check_shared_lib_support { } {
280 global shared_available_saved
283 if {![info exists shared_available_saved]} {
284 set ld_output [remote_exec host $ld "-shared"]
285 if { [ string first "not supported" $ld_output ] >= 0 } {
286 set shared_available_saved 0
288 set shared_available_saved 1
291 return $shared_available_saved
294 # Returns true if -pie is supported on the target
296 proc check_pie_support { } {
297 global pie_available_saved
300 if {![info exists pie_available_saved]} {
301 set ld_output [remote_exec host $ld "-pie"]
302 if { [ string first "not supported" $ld_output ] >= 0 } {
303 set pie_available_saved 0
305 set pie_available_saved 1
308 return $pie_available_saved
311 proc check_relro_support { } {
312 global relro_available_saved
315 if {![info exists relro_available_saved]} {
316 remote_file host delete norelro
317 set ld_output [remote_exec host $ld "-z norelro"]
318 if { [string first "not supported" $ld_output] >= 0
319 || [string first "unrecognized option" $ld_output] >= 0
320 || [string first "-z norelro ignored" $ld_output] >= 0
321 || [string first "cannot find norelro" $ld_output] >= 0 } {
322 set relro_available_saved 0
324 set relro_available_saved 1
327 return $relro_available_saved
330 # Compare two files line-by-line. FILE_1 is the actual output and FILE_2
331 # is the expected output. Ignore blank lines in either file.
333 # FILE_2 is a series of regexps, comments and # directives. The directives
337 # Treat the test as a PASS if everything up till this point has
338 # matched. Ignore any remaining lines in either FILE_1 or FILE_2.
341 # Reverse the sense of the test: expect differences to exist.
345 # Skip all lines in FILE_1 until the first that matches REGEXP.
348 # Optionally match REGEXP against line from FILE_1. If the REGEXP
349 # does not match then the next line from FILE_2 is tried.
351 # Other # lines are comments. Regexp lines starting with the `!' character
352 # specify inverse matching (use `\!' for literal matching against a leading
353 # `!'). Skip empty lines in both files.
355 # The first optional argument is a list of regexp substitutions of the form:
357 # EXP1 SUBSPEC1 EXP2 SUBSPEC2 ...
359 # This tells the function to apply each regexp substitution EXPi->SUBSPECi
360 # in order to every line of FILE_2.
362 # Return nonzero if differences exist.
363 proc regexp_diff { file_1 file_2 args } {
371 if { [llength $args] > 0 } {
372 set ref_subst [lindex $args 0]
374 if { [llength $args] > 1 } {
375 perror "Too many arguments to regexp_diff"
379 if [file exists $file_1] then {
380 set file_a [open $file_1 r]
382 perror "$file_1 doesn't exist"
386 if [file exists $file_2] then {
387 set file_b [open $file_2 r]
389 perror "$file_2 doesn't exist"
394 verbose " Regexp-diff'ing: $file_1 $file_2" 2
399 while { [string length $line_a] == 0 } {
400 # Ignore blank line in FILE_1.
401 if { [gets $file_a line_a] == $eof } {
406 while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
407 if { [string match "#pass" $line_b] } {
411 } elseif { [string match "#failif" $line_b] } {
412 send_log "fail if no difference\n"
413 verbose "fail if no difference" 3
415 } elseif { [string match "#..." $line_b] } {
416 if { [gets $file_b line_b] == $eof } {
421 set negated [expr { [string index $line_b 0] == "!" }]
422 set line_bx [string range $line_b $negated end]
423 set n [expr { $negated ? "! " : "" }]
424 # Substitute on the reference.
425 foreach {name value} $ref_subst {
426 regsub -- $name $line_bx $value line_bx
428 verbose "looking for $n\"^$line_bx$\"" 3
429 while { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
430 verbose "skipping \"$line_a\"" 3
431 if { [gets $file_a line_a] == $eof } {
437 } elseif { [string match "#\\?*" $line_b] } {
439 set line_b [string replace $line_b 0 1]
440 set negated [expr { [string index $line_b 0] == "!" }]
441 set line_bx [string range $line_b $negated end]
442 set n [expr { $negated ? "! " : "" }]
443 # Substitute on the reference.
444 foreach {name value} $ref_subst {
445 regsub -- $name $line_bx $value line_bx
447 verbose "optional match for $n\"^$line_bx$\"" 3
448 if { [expr [regexp "^$line_bx$" "$line_a"] != $negated] } {
453 if { [gets $file_b line_b] == $eof } {
461 } elseif { $end_1 && $end_2 } {
463 } elseif { $end_1 } {
464 send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
465 verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
468 } elseif { $end_2 } {
469 send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
470 verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
474 set negated [expr { [string index $line_b 0] == "!" }]
475 set line_bx [string range $line_b $negated end]
476 set n [expr { $negated ? "! " : "" }]
477 set s [expr { $negated ? " " : "" }]
478 # Substitute on the reference.
479 foreach {name value} $ref_subst {
480 regsub -- $name $line_bx $value line_bx
482 verbose "regexp $n\"^$line_bx$\"\nline \"$line_a\"" 3
483 if { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
484 send_log "regexp_diff match failure\n"
485 send_log "regexp $n\"^$line_bx$\"\nline $s\"$line_a\"\n"
486 verbose "regexp_diff match failure\n" 3
492 if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
493 send_log "$file_1 and $file_2 are different lengths\n"
494 verbose "$file_1 and $file_2 are different lengths" 3
498 if { $fail_if_match } {
499 if { $differences == 0 } {
512 # prune_warnings_extra -- delete extra warnings from TEXT.
515 # ld: warning: /lib64/ld-linux-x86-64.so.2: unsupported GNU_PROPERTY_TYPE (5) type : 0xc0010001
516 proc prune_warnings_extra { text } {
518 # Warnings are only pruned from non-experimental code (ie code not
519 # on a release branch). For experimental code we want the warnings
520 # as they indicate that the sources need to be updated to recognise
521 # the new properties.
522 if { "$experimental" == "false" } {
523 # The "\\1" is to try to preserve a "\n" but only if necessary.
524 regsub -all "(^|\n)(\[^\n\]*: warning:\[^\n\]*unsupported GNU_PROPERTY_TYPE\[^\n\]*\n?)+" $text "\\1" text
526 # PR binutils/23898: It is OK to have gaps in build notes.
527 regsub -all "(^|\n)(\[^\n\]*: Warning: Gap in build notes detected from\[^\n\]*\n?)+" $text "\\1" text
531 # This definition is taken from an unreleased version of DejaGnu. Once
532 # that version gets released, and has been out in the world for a few
533 # months at least, it may be safe to delete this copy.
534 if ![string length [info proc prune_warnings]] {
536 # prune_warnings -- delete various system verbosities from TEXT
539 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
541 # Sites with particular verbose os's may wish to override this in site.exp.
543 proc prune_warnings { text } {
544 # This is from sun4's. Do it for all machines for now.
545 # The "\\1" is to try to preserve a "\n" but only if necessary.
546 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
547 # It might be tempting to get carried away and delete blank lines, etc.
548 # Just delete *exactly* what we're ask to, and that's it.
549 set text [prune_warnings_extra $text]
552 } elseif { [info procs saved-prune_warnings] == [list] } {
553 rename prune_warnings saved-prune_warnings
554 proc prune_warnings { text } {
555 set text [saved-prune_warnings $text]
556 set text [prune_warnings_extra $text]
561 # run_dump_test FILE (optional:) EXTRA_OPTIONS
563 # Assemble a .s file, then run some utility on it and check the output.
565 # There should be an assembly language file named FILE.s in the test
566 # suite directory, and a pattern file called FILE.d. run_dump_test
567 # will assemble FILE.s, optionally run objcopy on the object file,
568 # optionally run ld, optionally run another objcopy, optionally run
569 # another tool under test specified by PROG, then run a dump tool like
570 # addr2line, nm, objdump, readelf or size on the object file to produce
571 # textual output, and then analyze that with regexps.
572 # The FILE.d file specifies what program to run, and what to expect in
575 # The FILE.d file begins with zero or more option lines, which specify
576 # flags to pass to the assembler, the program to run to dump the
577 # assembler's output, and the options it wants. The option lines have
582 # OPTION is the name of some option, like "name" or "objdump", and
583 # VALUE is OPTION's value. The valid options are described below.
584 # Whitespace is ignored everywhere, except within VALUE. The option
585 # list ends with the first line that doesn't match the above syntax.
586 # However, a line within the options that begins with a #, but doesn't
587 # have a recognizable option name followed by a colon, is considered a
588 # comment and entirely ignored.
590 # The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of
591 # two-element lists. The first element of each is an option name, and
592 # the second additional arguments to be added on to the end of the
593 # option list as given in FILE.d. (If omitted, no additional options
596 # The interesting options are:
599 # The name of this test, passed to DejaGNU's `pass' and `fail'
600 # commands. If omitted, this defaults to FILE, the root of the
601 # .s and .d files' names.
604 # When assembling, pass FLAGS to the assembler.
605 # If assembling several files, you can pass different assembler
606 # options in the "source" directives. See below.
607 # Multiple instances of this directive tells run_dump_test to run the test
608 # multiple times -- one time with each set of flags provided.
609 # Each instance will run exactly as a file with a single "as" line, it is
610 # not possible to condition any behaviour on which set of "as" flags is
611 # used. That means that the "source" specific options are appended to
612 # the "as" flags for their corresponding files, and any extra processing
613 # (e.g. with "ld" and "objcopy") is repeated for each test.
616 # Link assembled files using FLAGS, in the order of the "source"
617 # directives, when using multiple files.
619 # ld_after_inputfiles: FLAGS
620 # Similar to "ld", but put FLAGS after all input files.
622 # objcopy_objects: FLAGS
623 # Run objcopy with the specified flags after assembling any source
624 # that has the special marker RUN_OBJCOPY in the source specific
627 # objcopy_linked_file: FLAGS
628 # Run objcopy on the linked file with the specified flags.
629 # This lets you transform the linked file using objcopy, before the
630 # result is analyzed by an analyzer program specified below.
633 # The name of a program under test, to run to modify or analyze the
634 # .o file produced by the assembler. Recognised names are: ar,
635 # elfedit, nm, objcopy, ranlib, strings, and strip.
637 # DUMPPROG: PROGRAM-NAME
638 # The name of the program to run to analyze the file produced
639 # by the assembler or the linker. This can be omitted;
640 # run_dump_test will guess which program to run from which of
641 # the flags options below is present.
648 # Use the specified program to analyze the output file, and pass it
649 # FLAGS, in addition to the output name. Note that they are run
650 # with LC_ALL=C in the environment to give consistent sorting of
651 # symbols. If no FLAGS are needed then you can use:
652 # DUMPPROG: [nm objdump readelf addr2line]
653 # instead, or just pass a flag that happens to be the default.
654 # If objdump is the dump tool and we're not dumping binary, nor
655 # have run ld, then the standard section names (.text, .data and
656 # .bss) are replaced by target ones if any (eg. rx-elf uses "P"
657 # instead of .text). The substition is done for both the
658 # objdump options (eg: "-j .text" is replaced by "-j P") and the
661 # source: SOURCE [FLAGS]
662 # Assemble the file SOURCE.s using the flags in the "as" directive
663 # and the (optional) FLAGS. If omitted, the source defaults to
665 # This is useful if several .d files want to share a .s file.
666 # More than one "source" directive can be given, which is useful
667 # when testing linking.
670 # Match against DUMP.d. If omitted, this defaults to FILE.d. This
671 # is useful if several .d files differ by options only. Options are
672 # always read from FILE.d.
674 # target: GLOB|PROC ...
675 # Run this test only on a specified list of targets. More precisely,
676 # in the space-separated list each glob is passed to "istarget" and
677 # each proc is called as a TCL procedure. List items are interpreted
678 # such that procs are denoted by surrounding square brackets, and any
679 # other items are consired globs. If the call evaluates true for any
680 # of them, the test will be run, otherwise it will be marked
683 # notarget: GLOB|PROC ...
684 # Do not run this test on a specified list of targets. Again, each
685 # glob in the space-separated list is passed to "istarget" and each
686 # proc is called as a TCL procedure, and the test is run if it
687 # evaluates *false* for *all* of them. Otherwise it will be marked
690 # alltargets: GLOB|PROC ...
691 # Run this test on a specified list of targets. Again, each
692 # glob in the space-separated list is passed to "istarget" and each
693 # proc is called as a TCL procedure, and the test is run if it
694 # evaluates *true* for *all* of them. Otherwise it will be marked
697 # skip: GLOB|PROC ...
698 # anyskip: GLOB|PROC ...
699 # noskip: GLOB|PROC ...
700 # These are exactly the same as "notarget", "alltargets" and
701 # "target" respectively, except that they do nothing at all if the
702 # check fails. They should only be used in groups, to construct a
703 # single test which is run on all targets but with variant options
704 # or expected output on some targets. (For example, see
705 # gas/arm/inst.d and gas/arm/wince_inst.d.)
707 # xfail: GLOB|PROC ...
708 # Run this test and it is is expected to fail on a specified list
712 # An error with message matching REGEX must be emitted for the test
713 # to pass. The DUMPPROG, addr2line, nm, objdump, readelf and size
714 # options have no meaning and need not supplied if this is present.
715 # Multiple "error" directives append to the expected error message.
718 # Means the same as 'error', except the regular expression lines
719 # are contains in FILE.
722 # Expect a warning matching REGEX. It is an error to issue
723 # both "error" and "warning". Multiple "warning" directives
724 # append to the expected warning message.
726 # warning_output: FILE
727 # Means the same as 'warning', except the regular expression
728 # lines are contains in FILE.
731 # Adding this option will cause the linker to generate a linker
732 # map file, using the -Map=MAPFILE command line option. If
733 # there is no -Map=MAPFILE in the 'ld: FLAGS' then one will be
734 # added to the linker command line. The contents of the
735 # generated MAPFILE are then compared against the regexp lines
736 # in FILE using `regexp_diff' (see below for details).
739 # Means that the section substitution for objdump is disabled.
741 # Each option may occur at most once unless otherwise mentioned.
743 # After the option lines come regexp lines. run_dump_test calls
744 # regexp_diff to compare the output of the dumping tool against the
747 proc run_dump_test { name {extra_options {}} } {
748 global ADDR2LINE ADDR2LINEFLAGS AS ASFLAGS ELFEDIT ELFEDITFLAGS LD LDFLAGS
749 global NM NMFLAGS OBJCOPY OBJCOPYFLAGS OBJDUMP OBJDUMPFLAGS
750 global READELF READELFFLAGS STRIP STRIPFLAGS
751 global copyfile env runtests srcdir subdir verbose
753 if [string match "*/*" $name] {
755 set name [file tail $name]
757 set file "$srcdir/$subdir/$name"
760 if ![runtest_file_p $runtests $name] then {
764 set opt_array [slurp_options "${file}.d"]
765 if { $opt_array == -1 } {
766 perror "error reading options from $file.d"
767 unresolved $subdir/$name
770 set dumpfile tmpdir/dump.out
775 set opts(DUMPPROG) {}
776 set opts(addr2line) {}
777 set opts(alltargets) {}
781 set as_final_flags {}
782 set as_additional_flags {}
786 set opts(error_output) {}
788 set opts(ld_after_inputfiles) {}
793 set opts(notarget) {}
795 set opts(objcopy_linked_file) {}
796 set opts(objcopy_objects) {}
800 set opts(section_subst) {}
809 set opts(warning_output) {}
813 foreach i [concat $opt_array {{} {}} $extra_options] {
814 set opt_name [lindex $i 0]
815 set opt_val [lindex $i 1]
816 if { $opt_name == "" } {
820 if ![info exists opts($opt_name)] {
821 perror "unknown option $opt_name in file $file.d"
822 unresolved $subdir/$name
826 # Allow more substitutions, including tcl functions, for as and ld.
827 # Not done in general because extra quoting is needed for glob
828 # args used for example in binutils-all/remove-relocs-04.d.
829 if { $opt_name == "as" || $opt_name == "ld" } {
830 set opt_val [subst $opt_val]
832 # Just substitute $srcdir and $subdir
833 regsub -all {\$srcdir} "$opt_val" "$srcdir" opt_val
834 regsub -all {\$subdir} "$opt_val" "$subdir" opt_val
837 switch -- $opt_name {
848 # Move any source-specific as-flags to a separate list to
849 # simplify processing.
850 if { [llength $opt_val] > 1 } {
851 lappend asflags [lrange $opt_val 1 end]
852 set opt_val [lindex $opt_val 0]
857 # Create the object file name based on nothing but the source
860 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]].o]
861 # But, sometimes, we have the exact same source filename in
862 # different directories (foo/src.s bar/src.s) which would lead
863 # us to try and create two src.o files. We detect this
864 # conflict here, and instead create src.o and src1.o.
866 while { [lsearch $objfile_names $new_objfile] != -1 } {
869 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]]${j}.o]
871 lappend objfile_names $new_objfile
875 && [string length $opts($opt_name)]
876 && $opt_name != "as" } {
877 perror "option $opt_name multiply set in $file.d"
878 unresolved $subdir/$name
882 # A single "#ld:" with no options should do the right thing.
883 if { $opt_name == "ld" } {
886 # Likewise objcopy_linked_file.
887 if { $opt_name == "objcopy_linked_file" } {
893 # Append differently whether it's a message (without space) or
894 # an option or list (with space).
895 switch -- $opt_name {
898 append opts($opt_name) $opt_val
902 set as_additional_flags [concat $as_additional_flags $opt_val]
904 lappend opts(as) $opt_val
908 set opts($opt_name) [concat $opts($opt_name) $opt_val]
913 # Ensure there is something in $opts(as) for the foreach loop below.
914 if { [llength $opts(as)] == 0 } {
915 set opts(as) [list " "]
917 foreach x $opts(as) {
918 if { [string length $x] && [string length $as_additional_flags] } {
921 append x $as_additional_flags
922 regsub {\[big_or_little_endian\]} $x \
923 [big_or_little_endian] x
924 lappend as_final_flags $x
927 regsub {\[big_or_little_endian\]} $opts(ld) \
928 [big_or_little_endian] opts(ld)
930 if { $opts(name) == "" } {
931 set testname "$subdir/$name"
933 set testname $opts(name)
937 foreach opt { warning error warning_output error_output } {
938 if { $opts($opt) != "" } {
940 perror "$testname: bad mix of warning and error test directives"
948 # Decide early whether we should run the test for this target.
949 if { [llength $opts(noskip)] > 0 } {
951 foreach targ $opts(noskip) {
952 if [match_target $targ] {
957 if { $targmatch == 0 } {
961 foreach targ $opts(anyskip) {
962 if ![match_target $targ] {
966 foreach targ $opts(skip) {
967 if [match_target $targ] {
971 if { [llength $opts(target)] > 0 } {
973 foreach targ $opts(target) {
974 if [match_target $targ] {
979 if { $targmatch == 0 } {
980 unsupported $testname
984 foreach targ $opts(alltargets) {
985 if ![match_target $targ] {
986 unsupported $testname
990 foreach targ $opts(notarget) {
991 if [match_target $targ] {
992 unsupported $testname
998 # It's meaningless to require an output-testing method when we
1000 if { $opts(error) == "" && $opts(error_output) == "" } {
1001 if { $opts(DUMPPROG) != "" } {
1002 switch -- $opts(DUMPPROG) {
1003 addr2line { set dumpprogram addr2line }
1004 nm { set dumpprogram nm }
1005 objdump { set dumpprogram objdump }
1006 readelf { set dumpprogram readelf }
1007 size { set dumpprogram size }
1009 perror "unrecognized DUMPPROG option $opts(DUMPPROG) in $file.d"
1010 unresolved $testname
1015 # Guess which program to run, by seeing which option was specified.
1016 foreach p {addr2line nm objdump readelf size} {
1017 if {$opts($p) != ""} {
1018 if {$dumpprogram != ""} {
1019 perror "ambiguous dump program in $file.d"
1020 unresolved $testname
1028 if { $dumpprogram == "" && $opts(map) == "" && !$err_warn } {
1029 perror "dump program unspecified in $file.d"
1030 unresolved $testname
1035 if { $opts(source) == "" } {
1036 set sourcefiles [list ${file}.s]
1037 set asflags [list ""]
1038 set objfile_names [list tmpdir/[file tail ${file}].o]
1041 foreach sf $opts(source) {
1042 if { [string match "./*" $sf] } {
1043 lappend sourcefiles "$sf"
1045 lappend sourcefiles "$srcdir/$subdir/$sf"
1050 if { $opts(dump) == "" } {
1053 set dfile $srcdir/$subdir/$opts(dump)
1056 # Time to setup xfailures.
1057 foreach targ $opts(xfail) {
1058 if [match_target $targ] {
1064 foreach as_flags $as_final_flags {
1065 # Assemble each file.
1067 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
1068 set sourcefile [lindex $sourcefiles $i]
1069 set sourceasflags [lindex $asflags $i]
1070 set run_objcopy_objects 0
1072 if { [string match "*RUN_OBJCOPY*" $sourceasflags] } {
1073 set run_objcopy_objects 1
1075 regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
1077 set objfile [lindex $objfile_names $i]
1078 catch "exec rm -f $objfile" exec_output
1079 lappend objfiles $objfile
1081 if { $as_flags == "binary" } {
1082 while {[file type $sourcefile] eq "link"} {
1083 set newfile [file readlink $sourcefile]
1084 if {[string index $newfile 0] ne "/"} {
1085 set newfile [file dirname $sourcefile]/$newfile
1087 set sourcefile $newfile
1089 set newfile [remote_download host $sourcefile $objfile]
1091 if { $newfile == "" } {
1095 if { [istarget "hppa*-*-*"] \
1096 && ![istarget "*-*-linux*"] \
1097 && ![istarget "*-*-netbsd*" ] } {
1098 set cmd "sed -e 's/^\[ \]*\.comm \\(\[^,\]*\\),\\(.*\\)/\\1 .comm \\2/' < $sourcefile > tmpdir/asm.s"
1100 set cmdret [remote_exec host [concat sh -c [list "$cmd"]]]
1101 set cmdret [lindex $cmdret 0]
1102 if { $cmdret != 0 } {
1103 perror "sed failure"
1104 unresolved $testname
1107 set sourcefile tmpdir/asm.s
1109 set cmd "$AS $ASFLAGS $as_flags $sourceasflags -o $objfile $sourcefile"
1112 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1113 remote_upload host "dump.tmp"
1114 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1115 remote_file host delete "dump.tmp"
1116 remote_file build delete "dump.tmp"
1117 set cmdret [lindex $cmdret 0]
1119 if { $cmdret == 0 && $run_objcopy_objects } {
1120 set cmd "$OBJCOPY $opts(objcopy_objects) $objfile"
1123 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \
1124 "" "/dev/null" "dump.tmp"]
1125 remote_upload host "dump.tmp"
1126 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1127 remote_file host delete "dump.tmp"
1128 remote_file build delete "dump.tmp"
1129 set cmdret [lindex $cmdret 0]
1133 # Perhaps link the file(s).
1134 if { $cmdret == 0 && $run_ld } {
1135 set objfile "tmpdir/dump"
1136 catch "exec rm -f $objfile" exec_output
1141 if [check_relro_support] {
1142 set ld_extra_opt "-z norelro"
1145 # Add -L$srcdir/$subdir so that the linker command can use
1146 # linker scripts in the source directory.
1147 set cmd "$LD $ld_extra_opt $LDFLAGS -L$srcdir/$subdir \
1148 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
1150 # If needed then check for, or add a -Map option.
1152 if { $opts(map) != "" } then {
1153 if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then {
1154 # Found existing mapfile option
1155 verbose -log "Existing mapfile '$mapfile' found"
1157 # No mapfile option.
1158 set mapfile "tmpdir/dump.map"
1159 verbose -log "Adding mapfile '$mapfile'"
1160 set cmd "$cmd -Map=$mapfile"
1165 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1166 remote_upload host "dump.tmp"
1167 append comp_output [file_contents "dump.tmp"]
1168 remote_file host delete "dump.tmp"
1169 remote_file build delete "dump.tmp"
1170 set cmdret [lindex $cmdret 0]
1172 if { $cmdret == 0 && $run_objcopy } {
1174 set objfile "tmpdir/dump1"
1175 remote_file host delete $objfile
1177 # Note that we don't use OBJCOPYFLAGS here; any flags must be
1178 # explicitly specified.
1179 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
1182 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1183 remote_upload host "dump.tmp"
1184 append comp_output [file_contents "dump.tmp"]
1185 remote_file host delete "dump.tmp"
1186 remote_file build delete "dump.tmp"
1187 set cmdret [lindex $cmdret 0]
1190 set objfile [lindex $objfiles 0]
1193 if { $cmdret == 0 && $opts(PROG) != "" } {
1194 set destopt ${copyfile}.o
1195 switch -- $opts(PROG) {
1196 ar { set program ar }
1201 nm { set program nm }
1202 objcopy { set program objcopy }
1203 ranlib { set program ranlib }
1204 strings { set program strings }
1207 set destopt "-o $destopt"
1210 perror "unrecognized PROG option $opts(PROG) in $file.d"
1211 unresolved $testname
1216 set progopts1 $opts($program)
1217 eval set progopts \$[string toupper $program]FLAGS
1218 eval set binary \$[string toupper $program]
1220 if { ![is_remote host] && [which $binary] == 0 } {
1225 verbose "running $binary $progopts $progopts1" 3
1226 set cmd "$binary $progopts $progopts1 $objfile $destopt"
1228 # Ensure consistent sorting of symbols
1229 if {[info exists env(LC_ALL)]} {
1230 set old_lc_all $env(LC_ALL)
1234 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"]
1235 set cmdret [lindex $cmdret 0]
1236 remote_upload host "dump.tmp"
1237 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1238 remote_file host delete "dump.tmp"
1239 remote_file build delete "dump.tmp"
1240 if {[info exists old_lc_all]} {
1241 set env(LC_ALL) $old_lc_all
1245 if { $destopt != "" } {
1246 set objfile ${copyfile}.o
1250 set want_out(source) ""
1251 set want_out(terminal) 0
1253 if { $opts(error) != "" || $opts(error_output) != "" } {
1254 set want_out(terminal) 1
1257 if { $opts(error) != "" || $opts(warning) != "" } {
1258 set want_out(source) "regex"
1259 if { $opts(error) != "" } {
1260 set want_out(regex) $opts(error)
1262 set want_out(regex) $opts(warning)
1265 set want_out(source) "file"
1266 if { $opts(error_output) != "" } {
1267 set want_out(file) $opts(error_output)
1269 set want_out(file) $opts(warning_output)
1274 regsub "\n$" $comp_output "" comp_output
1275 if { $cmdret != 0 || $comp_output != "" || $want_out(source) != "" } {
1276 set exitstat "succeeded"
1277 if { $cmdret != 0 } { set exitstat "failed" }
1279 if { $want_out(source) == "regex" } {
1280 verbose -log "$exitstat with: <$comp_output>, expected: <$want_out(regex)>"
1281 } elseif { $want_out(source) == "file" } {
1282 verbose -log "$exitstat with: <$comp_output>, expected in file $want_out(file)"
1283 set_file_contents "tmpdir/ld.messages" "$comp_output"
1285 verbose -log "$exitstat with: <$comp_output>, no expected output"
1288 if { (($want_out(source) == "") == ($comp_output == "")) \
1289 && (($cmdret == 0) == ($want_out(terminal) == 0)) \
1290 && ((($want_out(source) == "regex") \
1291 && [regexp -- $want_out(regex) $comp_output]) \
1292 || (($want_out(source) == "file") \
1293 && (![regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$want_out(file)"]))) } {
1294 # We have the expected output.
1295 if { $want_out(terminal) || $dumpprogram == "" } {
1305 # We must not have expected failure if we get here.
1306 if { $opts(error) != "" } {
1311 if { $opts(map) != "" } then {
1312 # Check the map file matches.
1313 set map_pattern_file $srcdir/$subdir/$opts(map)
1314 verbose -log "Compare '$mapfile' against '$map_pattern_file'"
1315 if { [regexp_diff $mapfile $map_pattern_file] } then {
1316 fail "$testname (map file check)"
1318 pass "$testname (map file check)"
1321 if { $dumpprogram == "" } then {
1326 set progopts1 $opts($dumpprogram)
1327 eval set progopts \$[string toupper $dumpprogram]FLAGS
1328 eval set binary \$[string toupper $dumpprogram]
1330 if { ![is_remote host] && [which $binary] == 0 } {
1335 # For objdump of gas output, automatically translate standard section names
1337 if { !$run_ld && $dumpprogram == "objdump" \
1338 && $opts(section_subst) != "no" \
1339 && ![string match "*-b binary*" $progopts1] } {
1340 set sect_names [get_standard_section_names]
1341 if { $sect_names != ""} {
1342 regsub -- "\\.text" $progopts1 "[lindex $sect_names 0]" progopts1
1343 regsub -- "\\.data" $progopts1 "[lindex $sect_names 1]" progopts1
1344 regsub -- "\\.bss" $progopts1 "[lindex $sect_names 2]" progopts1
1348 if { $progopts1 == "" } { set $progopts1 "-r" }
1349 verbose "running $binary $progopts $progopts1" 3
1351 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
1353 # Ensure consistent sorting of symbols
1354 if {[info exists env(LC_ALL)]} {
1355 set old_lc_all $env(LC_ALL)
1359 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"]
1360 set cmdret [lindex $cmdret 0]
1361 remote_upload host "dump.tmp"
1362 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1363 remote_file host delete "dump.tmp"
1364 remote_file build delete "dump.tmp"
1365 if {[info exists old_lc_all]} {
1366 set env(LC_ALL) $old_lc_all
1370 if { $cmdret != 0 || $comp_output != "" } {
1371 send_log "exited abnormally with $cmdret, output:$comp_output\n"
1376 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
1378 # Create the substition list for objdump output.
1380 if { $sect_names != "" } {
1381 set regexp_subst [list "\\\\?\\.text" [lindex $sect_names 0] \
1382 "\\\\?\\.data" [lindex $sect_names 1] \
1383 "\\\\?\\.bss" [lindex $sect_names 2] ]
1386 if { [regexp_diff $dumpfile "${dfile}" $regexp_subst] } then {
1388 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
1396 proc slurp_options { file } {
1397 # If options_regsub(foo) is set to {a b}, then the contents of a
1398 # "#foo:" line will have regsub -all applied to replace a with b.
1399 global options_regsub
1401 if [catch { set f [open $file r] } x] {
1402 #perror "couldn't open `$file': $x"
1407 # whitespace expression
1410 # whitespace is ignored anywhere except within the options list;
1411 # option names are alphanumeric plus underscore.
1412 set pat "^#${ws}(\[a-zA-Z0-9_\]*)$ws:${ws}(.*)$ws\$"
1413 while { [gets $f line] != -1 } {
1414 set line [string trim $line]
1415 # Whitespace here is space-tab.
1416 if [regexp $pat $line xxx opt_name opt_val] {
1418 if [info exists options_regsub($opt_name)] {
1419 set subst $options_regsub($opt_name)
1420 regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \
1423 lappend opt_array [list $opt_name $opt_val]
1424 } elseif {![regexp "^#" $line ]} {
1432 proc file_contents { filename } {
1433 set file [open $filename r]
1434 set contents [read $file]
1439 proc set_file_contents { filename contents } {
1440 set file [open $filename w]
1441 puts $file "$contents"
1445 # Look for big-endian or little-endian switches in the multlib
1446 # options and translate these into a -EB or -EL switch. Note
1447 # we cannot rely upon proc process_multilib_options to do this
1448 # for us because for some targets the compiler does not support
1449 # -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
1450 # the site.exp file will include the switch "-mbig-endian"
1451 # (rather than "big-endian") which is not detected by proc
1452 # process_multilib_options.
1454 proc big_or_little_endian {} {
1456 if [board_info [target_info name] exists multilib_flags] {
1457 set tmp_flags " [board_info [target_info name] multilib_flags]"
1459 foreach x $tmp_flags {
1489 # Internal procedure: return the names of the standard sections
1491 proc get_standard_section_names {} {
1492 if [istarget "rx-*-elf"] {
1493 return { "P" "D_1" "B_1" }
1495 if { [istarget "alpha*-*-*vms*"] || [is_som_format] } {
1496 return { {\$CODE\$} {\$DATA\$} {\$BSS\$} }