1 # Copyright (C) 1993-2021 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 # Check for support of the .noinit section, used for data that is not
349 # initialized at load, or during the application's initialization sequence.
350 proc supports_noinit_section {} {
351 # .noinit is only supported by ELF targets.
352 if { ![is_elf_format] } {
356 # Targets that set HAVE_NOINIT=yes in their emulparams script utilizing
357 # elf.sc, or explicitly define a .noinit section in their linker script.
359 # arc-*-* is not included here, since it only supports .noinit with the
360 # non-default arcv2elf emulation.
361 if {[istarget "arm-*-*"]
362 || [istarget "avr-*-*"]
363 || [istarget "msp430-*-*"]
364 || [istarget "pru-*-*"] } {
370 # Check for support of the .persistent section, used for data that is
371 # initialized at load, but not during the application's initialization sequence.
372 proc supports_persistent_section {} {
373 # .persistent is only supported by ELF targets.
374 if { ![is_elf_format] } {
378 # Targets that set HAVE_PERSISTENT=yes in their emulparams script utilizing
379 # elf.sc, or explicitly define a .persistent section in their linker script.
380 if { [istarget "arm-*-*"]
381 || [istarget "msp430-*-*"] } {
387 # Compare two files line-by-line. FILE_1 is the actual output and FILE_2
388 # is the expected output. Ignore blank lines in either file.
390 # FILE_2 is a series of regexps, comments and # directives. The directives
394 # Treat the test as a PASS if everything up till this point has
395 # matched. Ignore any remaining lines in either FILE_1 or FILE_2.
398 # Reverse the sense of the test: expect differences to exist.
402 # Skip all lines in FILE_1 until the first that matches REGEXP.
405 # Optionally match REGEXP against line from FILE_1. If the REGEXP
406 # does not match then the next line from FILE_2 is tried.
408 # Other # lines are comments. Regexp lines starting with the `!' character
409 # specify inverse matching (use `\!' for literal matching against a leading
410 # `!'). Skip empty lines in both files.
412 # The first optional argument is a list of regexp substitutions of the form:
414 # EXP1 SUBSPEC1 EXP2 SUBSPEC2 ...
416 # This tells the function to apply each regexp substitution EXPi->SUBSPECi
417 # in order to every line of FILE_2.
419 # Return nonzero if differences exist.
420 proc regexp_diff { file_1 file_2 args } {
428 if { [llength $args] > 0 } {
429 set ref_subst [lindex $args 0]
431 if { [llength $args] > 1 } {
432 perror "Too many arguments to regexp_diff"
436 if [file exists $file_1] then {
437 set file_a [open $file_1 r]
439 perror "$file_1 doesn't exist"
443 if [file exists $file_2] then {
444 set file_b [open $file_2 r]
446 perror "$file_2 doesn't exist"
451 verbose " Regexp-diff'ing: $file_1 $file_2" 2
456 while { [string length $line_a] == 0 } {
457 # Ignore blank line in FILE_1.
458 if { [gets $file_a line_a] == $eof } {
463 while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
464 if { [string match "#pass" $line_b] } {
468 } elseif { [string match "#failif" $line_b] } {
469 send_log "fail if no difference\n"
470 verbose "fail if no difference" 3
472 } elseif { [string match "#..." $line_b] } {
473 if { [gets $file_b line_b] == $eof } {
478 set negated [expr { [string index $line_b 0] == "!" }]
479 set line_bx [string range $line_b $negated end]
480 set n [expr { $negated ? "! " : "" }]
481 # Substitute on the reference.
482 foreach {name value} $ref_subst {
483 regsub -- $name $line_bx $value line_bx
485 verbose "looking for $n\"^$line_bx$\"" 3
486 while { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
487 verbose "skipping \"$line_a\"" 3
488 if { [gets $file_a line_a] == $eof } {
494 } elseif { [string match "#\\?*" $line_b] } {
496 set line_b [string replace $line_b 0 1]
497 set negated [expr { [string index $line_b 0] == "!" }]
498 set line_bx [string range $line_b $negated end]
499 set n [expr { $negated ? "! " : "" }]
500 # Substitute on the reference.
501 foreach {name value} $ref_subst {
502 regsub -- $name $line_bx $value line_bx
504 verbose "optional match for $n\"^$line_bx$\"" 3
505 if { [expr [regexp "^$line_bx$" "$line_a"] != $negated] } {
510 if { [gets $file_b line_b] == $eof } {
518 } elseif { $end_1 && $end_2 } {
520 } elseif { $end_1 } {
521 send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
522 verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
525 } elseif { $end_2 } {
526 send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
527 verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
531 set negated [expr { [string index $line_b 0] == "!" }]
532 set line_bx [string range $line_b $negated end]
533 set n [expr { $negated ? "! " : "" }]
534 set s [expr { $negated ? " " : "" }]
535 # Substitute on the reference.
536 foreach {name value} $ref_subst {
537 regsub -- $name $line_bx $value line_bx
539 verbose "regexp $n\"^$line_bx$\"\nline \"$line_a\"" 3
540 if { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
541 send_log "regexp_diff match failure\n"
542 send_log "regexp $n\"^$line_bx$\"\nline $s\"$line_a\"\n"
543 verbose "regexp_diff match failure\n" 3
549 if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
550 send_log "$file_1 and $file_2 are different lengths\n"
551 verbose "$file_1 and $file_2 are different lengths" 3
555 if { $fail_if_match } {
556 if { $differences == 0 } {
569 # prune_warnings_extra -- delete extra warnings from TEXT.
572 # ld: warning: /lib64/ld-linux-x86-64.so.2: unsupported GNU_PROPERTY_TYPE (5) type : 0xc0010001
573 proc prune_warnings_extra { text } {
575 # Warnings are only pruned from non-experimental code (ie code not
576 # on a release branch). For experimental code we want the warnings
577 # as they indicate that the sources need to be updated to recognise
578 # the new properties.
579 if { "$experimental" == "false" } {
580 # The "\\1" is to try to preserve a "\n" but only if necessary.
581 regsub -all "(^|\n)(\[^\n\]*: warning:\[^\n\]*unsupported GNU_PROPERTY_TYPE\[^\n\]*\n?)+" $text "\\1" text
583 # PR binutils/23898: It is OK to have gaps in build notes.
584 regsub -all "(^|\n)(\[^\n\]*: Warning: Gap in build notes detected from\[^\n\]*\n?)+" $text "\\1" text
588 # This definition is taken from an unreleased version of DejaGnu. Once
589 # that version gets released, and has been out in the world for a few
590 # months at least, it may be safe to delete this copy.
591 if ![string length [info proc prune_warnings]] {
593 # prune_warnings -- delete various system verbosities from TEXT
596 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
598 # Sites with particular verbose os's may wish to override this in site.exp.
600 proc prune_warnings { text } {
601 # This is from sun4's. Do it for all machines for now.
602 # The "\\1" is to try to preserve a "\n" but only if necessary.
603 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
604 # It might be tempting to get carried away and delete blank lines, etc.
605 # Just delete *exactly* what we're ask to, and that's it.
606 set text [prune_warnings_extra $text]
609 } elseif { [info procs saved-prune_warnings] == [list] } {
610 rename prune_warnings saved-prune_warnings
611 proc prune_warnings { text } {
612 set text [saved-prune_warnings $text]
613 set text [prune_warnings_extra $text]
618 # run_dump_test FILE (optional:) EXTRA_OPTIONS
620 # Assemble a .s file, then run some utility on it and check the output.
621 # Optionally generate the .s file first by running the compiler.
623 # There should be an assembly language file named FILE.s in the test
624 # suite directory, and a pattern file called FILE.d. run_dump_test
625 # will assemble FILE.s, optionally run objcopy on the object file,
626 # optionally run ld, optionally run another objcopy, optionally run
627 # another tool under test specified by PROG, then run a dump tool like
628 # addr2line, nm, objdump, readelf or size on the object file to produce
629 # textual output, and then analyze that with regexps.
630 # The FILE.d file specifies what program to run, and what to expect in
633 # The FILE.d file begins with zero or more option lines, which specify
634 # flags to pass to the assembler, the program to run to dump the
635 # assembler's output, and the options it wants. The option lines have
640 # OPTION is the name of some option, like "name" or "objdump", and
641 # VALUE is OPTION's value. The valid options are described below.
642 # Whitespace is ignored everywhere, except within VALUE. The option
643 # list ends with the first line that doesn't match the above syntax.
644 # However, a line within the options that begins with a #, but doesn't
645 # have a recognizable option name followed by a colon, is considered a
646 # comment and entirely ignored.
648 # The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of
649 # two-element lists. The first element of each is an option name, and
650 # the second additional arguments to be added on to the end of the
651 # option list as given in FILE.d. (If omitted, no additional options
654 # The interesting options are:
657 # The name of this test, passed to DejaGNU's `pass' and `fail'
658 # commands. If omitted, this defaults to FILE, the root of the
659 # .s and .d files' names.
662 # When assembling, pass FLAGS to the assembler.
663 # If assembling several files, you can pass different assembler
664 # options in the "source" directives. See below.
665 # Multiple instances of this directive tells run_dump_test to run the test
666 # multiple times -- one time with each set of flags provided.
667 # Each instance will run exactly as a file with a single "as" line, it is
668 # not possible to condition any behaviour on which set of "as" flags is
669 # used. That means that the "source" specific options are appended to
670 # the "as" flags for their corresponding files, and any extra processing
671 # (e.g. with "ld" and "objcopy") is repeated for each test.
674 # Link assembled files using FLAGS, in the order of the "source"
675 # directives, when using multiple files.
677 # ld_after_inputfiles: FLAGS
678 # Similar to "ld", but put FLAGS after all input files.
681 # Run the compiler with FLAGS (to which -S is added) to generate assembler
682 # source first. source: must be provided and should consist of .c files.
683 # Source-specific CC flags are not supported.
685 # objcopy_objects: FLAGS
686 # Run objcopy with the specified flags after assembling any source
687 # that has the special marker RUN_OBJCOPY in the source specific
690 # objcopy_linked_file: FLAGS
691 # Run objcopy on the linked file with the specified flags.
692 # This lets you transform the linked file using objcopy, before the
693 # result is analyzed by an analyzer program specified below.
696 # The name of a program under test, to run to modify or analyze the
697 # .o file produced by the assembler. Recognised names are: ar,
698 # elfedit, nm, objcopy, ranlib, strings, and strip.
700 # DUMPPROG: PROGRAM-NAME
701 # The name of the program to run to analyze the file produced
702 # by the assembler or the linker. This can be omitted;
703 # run_dump_test will guess which program to run from which of
704 # the flags options below is present.
711 # Use the specified program to analyze the output file, and pass it
712 # FLAGS, in addition to the output name. Note that they are run
713 # with LC_ALL=C in the environment to give consistent sorting of
714 # symbols. If no FLAGS are needed then you can use:
715 # DUMPPROG: [nm objdump readelf addr2line]
716 # instead, or just pass a flag that happens to be the default.
717 # If objdump is the dump tool and we're not dumping binary, nor
718 # have run ld, then the standard section names (.text, .data and
719 # .bss) are replaced by target ones if any (eg. rx-elf uses "P"
720 # instead of .text). The substition is done for both the
721 # objdump options (eg: "-j .text" is replaced by "-j P") and the
724 # source: SOURCE [FLAGS]
725 # Assemble the file SOURCE.s using the flags in the "as" directive
726 # and the (optional) FLAGS. If omitted, the source defaults to
728 # This is useful if several .d files want to share a .s file.
729 # More than one "source" directive can be given, which is useful
730 # when testing linking.
733 # Match against DUMP.d. If omitted, this defaults to FILE.d. This
734 # is useful if several .d files differ by options only. Options are
735 # always read from FILE.d.
737 # target: GLOB|PROC ...
738 # Run this test only on a specified list of targets. More precisely,
739 # in the space-separated list each glob is passed to "istarget" and
740 # each proc is called as a TCL procedure. List items are interpreted
741 # such that procs are denoted by surrounding square brackets, and any
742 # other items are consired globs. If the call evaluates true for any
743 # of them, the test will be run, otherwise it will be marked
746 # notarget: GLOB|PROC ...
747 # Do not run this test on a specified list of targets. Again, each
748 # glob in the space-separated list is passed to "istarget" and each
749 # proc is called as a TCL procedure, and the test is run if it
750 # evaluates *false* for *all* of them. Otherwise it will be marked
753 # alltargets: GLOB|PROC ...
754 # Run this test on a specified list of targets. Again, each
755 # glob in the space-separated list is passed to "istarget" and each
756 # proc is called as a TCL procedure, and the test is run if it
757 # evaluates *true* for *all* of them. Otherwise it will be marked
760 # skip: GLOB|PROC ...
761 # anyskip: GLOB|PROC ...
762 # noskip: GLOB|PROC ...
763 # These are exactly the same as "notarget", "alltargets" and
764 # "target" respectively, except that they do nothing at all if the
765 # check fails. They should only be used in groups, to construct a
766 # single test which is run on all targets but with variant options
767 # or expected output on some targets. (For example, see
768 # gas/arm/inst.d and gas/arm/wince_inst.d.)
770 # xfail: GLOB|PROC ...
771 # Run this test and it is is expected to fail on a specified list
775 # An error with message matching REGEX must be emitted for the test
776 # to pass. The DUMPPROG, addr2line, nm, objdump, readelf and size
777 # options have no meaning and need not supplied if this is present.
778 # Multiple "error" directives append to the expected error message.
781 # Means the same as 'error', except the regular expression lines
782 # are contains in FILE.
785 # Expect a warning matching REGEX. It is an error to issue
786 # both "error" and "warning". Multiple "warning" directives
787 # append to the expected warning message.
789 # warning_output: FILE
790 # Means the same as 'warning', except the regular expression
791 # lines are contains in FILE.
794 # Adding this option will cause the linker to generate a linker
795 # map file, using the -Map=MAPFILE command line option. If
796 # there is no -Map=MAPFILE in the 'ld: FLAGS' then one will be
797 # added to the linker command line. The contents of the
798 # generated MAPFILE are then compared against the regexp lines
799 # in FILE using `regexp_diff' (see below for details).
802 # Means that the section substitution for objdump is disabled.
804 # Each option may occur at most once unless otherwise mentioned.
806 # After the option lines come regexp lines. run_dump_test calls
807 # regexp_diff to compare the output of the dumping tool against the
810 proc run_dump_test { name {extra_options {}} } {
811 global ADDR2LINE ADDR2LINEFLAGS AS ASFLAGS CC CFLAGS ELFEDIT ELFEDITFLAGS
812 global LD LDFLAGS NM NMFLAGS OBJCOPY OBJCOPYFLAGS OBJDUMP OBJDUMPFLAGS
813 global READELF READELFFLAGS STRIP STRIPFLAGS
814 global copyfile env runtests srcdir subdir verbose
816 if [string match "*/*" $name] {
818 set name [file tail $name]
820 set file "$srcdir/$subdir/$name"
823 if ![runtest_file_p $runtests $name] then {
827 set opt_array [slurp_options "${file}.d"]
828 if { $opt_array == -1 } {
829 perror "error reading options from $file.d"
830 unresolved $subdir/$name
833 set dumpfile tmpdir/dump.out
838 set opts(DUMPPROG) {}
839 set opts(addr2line) {}
840 set opts(alltargets) {}
844 set as_final_flags {}
845 set as_additional_flags {}
850 set opts(error_output) {}
852 set opts(ld_after_inputfiles) {}
857 set opts(notarget) {}
859 set opts(objcopy_linked_file) {}
860 set opts(objcopy_objects) {}
864 set opts(section_subst) {}
873 set opts(warning_output) {}
877 foreach i [concat $opt_array {{} {}} $extra_options] {
878 set opt_name [lindex $i 0]
879 set opt_val [lindex $i 1]
880 if { $opt_name == "" } {
884 if ![info exists opts($opt_name)] {
885 perror "unknown option $opt_name in file $file.d"
886 unresolved $subdir/$name
890 # Allow more substitutions, including tcl functions, for as, ld,
891 # and cc. Not done in general because extra quoting is needed for glob
892 # args used for example in binutils-all/remove-relocs-04.d.
893 if { $opt_name == "as" || $opt_name == "ld" || $opt_name == "cc" } {
894 set opt_val [subst $opt_val]
896 # Just substitute $srcdir and $subdir
897 regsub -all {\$srcdir} "$opt_val" "$srcdir" opt_val
898 regsub -all {\$subdir} "$opt_val" "$subdir" opt_val
901 switch -- $opt_name {
912 # Move any source-specific as-flags to a separate list to
913 # simplify processing.
914 if { [llength $opt_val] > 1 } {
915 lappend asflags [lrange $opt_val 1 end]
916 set opt_val [lindex $opt_val 0]
921 # Create the object file name based on nothing but the source
924 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]].o]
925 # But, sometimes, we have the exact same source filename in
926 # different directories (foo/src.s bar/src.s) which would lead
927 # us to try and create two src.o files. We detect this
928 # conflict here, and instead create src.o and src1.o.
930 while { [lsearch $objfile_names $new_objfile] != -1 } {
933 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]]${j}.o]
935 lappend objfile_names $new_objfile
939 && [string length $opts($opt_name)]
940 && $opt_name != "as" } {
941 perror "option $opt_name multiply set in $file.d"
942 unresolved $subdir/$name
946 # A single "#ld:" with no options should do the right thing.
947 if { $opt_name == "ld" } {
950 # Likewise objcopy_linked_file.
951 if { $opt_name == "objcopy_linked_file" } {
957 # Append differently whether it's a message (without space) or
958 # an option or list (with space).
959 switch -- $opt_name {
962 append opts($opt_name) $opt_val
966 set as_additional_flags [concat $as_additional_flags $opt_val]
968 lappend opts(as) $opt_val
972 set opts($opt_name) [concat $opts($opt_name) $opt_val]
977 # Ensure there is something in $opts(as) for the foreach loop below.
978 if { [llength $opts(as)] == 0 } {
979 set opts(as) [list " "]
981 foreach x $opts(as) {
982 if { [string length $x] && [string length $as_additional_flags] } {
985 append x $as_additional_flags
986 regsub {\[big_or_little_endian\]} $x \
987 [big_or_little_endian] x
988 lappend as_final_flags $x
991 regsub {\[big_or_little_endian\]} $opts(ld) \
992 [big_or_little_endian] opts(ld)
994 if { $opts(name) == "" } {
995 set testname "$subdir/$name"
997 set testname $opts(name)
1001 foreach opt { warning error warning_output error_output } {
1002 if { $opts($opt) != "" } {
1004 perror "$testname: bad mix of warning and error test directives"
1005 unresolved $testname
1012 # Decide early whether we should run the test for this target.
1013 if { [llength $opts(noskip)] > 0 } {
1015 foreach targ $opts(noskip) {
1016 if [match_target $targ] {
1021 if { $targmatch == 0 } {
1025 foreach targ $opts(anyskip) {
1026 if ![match_target $targ] {
1030 foreach targ $opts(skip) {
1031 if [match_target $targ] {
1035 if { [llength $opts(target)] > 0 } {
1037 foreach targ $opts(target) {
1038 if [match_target $targ] {
1043 if { $targmatch == 0 } {
1044 unsupported $testname
1048 foreach targ $opts(alltargets) {
1049 if ![match_target $targ] {
1050 unsupported $testname
1054 foreach targ $opts(notarget) {
1055 if [match_target $targ] {
1056 unsupported $testname
1062 # It's meaningless to require an output-testing method when we
1064 if { $opts(error) == "" && $opts(error_output) == "" } {
1065 if { $opts(DUMPPROG) != "" } {
1066 switch -- $opts(DUMPPROG) {
1067 addr2line { set dumpprogram addr2line }
1068 nm { set dumpprogram nm }
1069 objdump { set dumpprogram objdump }
1070 readelf { set dumpprogram readelf }
1071 size { set dumpprogram size }
1073 perror "unrecognized DUMPPROG option $opts(DUMPPROG) in $file.d"
1074 unresolved $testname
1079 # Guess which program to run, by seeing which option was specified.
1080 foreach p {addr2line nm objdump readelf size} {
1081 if {$opts($p) != ""} {
1082 if {$dumpprogram != ""} {
1083 perror "ambiguous dump program in $file.d"
1084 unresolved $testname
1092 if { $dumpprogram == "" && $opts(map) == "" && !$err_warn } {
1093 perror "dump program unspecified in $file.d"
1094 unresolved $testname
1099 # Possibly compile some of the inputs, and build up a replacement
1100 # for opts(source) with the output .s names substituted in as we go.
1101 # Set the .s names from the objfile_names to take advantage of the
1102 # uniquification that happened earlier.
1103 if { $opts(cc) != ""} {
1107 foreach cfile $opts(source) ofile $objfile_names {
1108 if { [file extension $cfile] != ".c" } {
1109 lappend new_source "$cfile"
1113 if { ! [string match "./*" $cfile] } {
1114 set cfile "$srcdir/$subdir/$cfile"
1116 # ofile is never absolute, so this always works to protect sfile
1117 # from later absolutization.
1118 set sfile "./[file rootname $ofile].s"
1119 set cmd "$CC $CFLAGS -S $opts(cc) -o $sfile $cfile"
1121 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1122 remote_upload host "dump.tmp"
1123 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1124 remote_file host delete "dump.tmp"
1125 remote_file build delete "dump.tmp"
1126 lappend new_source "$sfile"
1127 set cmdret [lindex $cmdret 0]
1129 regsub "\n$" $comp_output "" comp_output
1130 if { $cmdret != 0} {
1131 send_log "compilation of $cfile failed, exit status $cmdret with <$comp_output>"
1132 # Should this be 'unresolved', or is that too silent?
1137 set opts(source) $new_source
1140 if { $opts(source) == "" } {
1141 set sourcefiles [list ${file}.s]
1142 set asflags [list ""]
1143 set objfile_names [list tmpdir/[file tail ${file}].o]
1146 foreach sf $opts(source) {
1147 if { [string match "./*" $sf] } {
1148 lappend sourcefiles "$sf"
1150 lappend sourcefiles "$srcdir/$subdir/$sf"
1155 if { $opts(dump) == "" } {
1158 set dfile $srcdir/$subdir/$opts(dump)
1161 # Time to setup xfailures.
1162 foreach targ $opts(xfail) {
1163 if [match_target $targ] {
1169 foreach as_flags $as_final_flags {
1170 # Assemble each file.
1172 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
1173 set sourcefile [lindex $sourcefiles $i]
1174 set sourceasflags [lindex $asflags $i]
1175 set run_objcopy_objects 0
1177 if { [string match "*RUN_OBJCOPY*" $sourceasflags] } {
1178 set run_objcopy_objects 1
1180 regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
1182 set objfile [lindex $objfile_names $i]
1183 catch "exec rm -f $objfile" exec_output
1184 lappend objfiles $objfile
1186 if { $as_flags == "binary" } {
1187 while {[file type $sourcefile] eq "link"} {
1188 set newfile [file readlink $sourcefile]
1189 if {[string index $newfile 0] ne "/"} {
1190 set newfile [file dirname $sourcefile]/$newfile
1192 set sourcefile $newfile
1194 set newfile [remote_download host $sourcefile $objfile]
1196 if { $newfile == "" } {
1200 if { [istarget "hppa*-*-*"] \
1201 && ![istarget "*-*-linux*"] \
1202 && ![istarget "*-*-netbsd*" ] } {
1203 set cmd "sed -e 's/^\[ \]*\.comm \\(\[^,\]*\\),\\(.*\\)/\\1 .comm \\2/' < $sourcefile > tmpdir/asm.s"
1205 set cmdret [remote_exec host [concat sh -c [list "$cmd"]]]
1206 set cmdret [lindex $cmdret 0]
1207 if { $cmdret != 0 } {
1208 perror "sed failure"
1209 unresolved $testname
1212 set sourcefile tmpdir/asm.s
1214 set cmd "$AS $ASFLAGS $as_flags $sourceasflags -o $objfile $sourcefile"
1217 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1218 remote_upload host "dump.tmp"
1219 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1220 remote_file host delete "dump.tmp"
1221 remote_file build delete "dump.tmp"
1222 set cmdret [lindex $cmdret 0]
1224 if { $cmdret == 0 && $run_objcopy_objects } {
1225 set cmd "$OBJCOPY $opts(objcopy_objects) $objfile"
1228 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \
1229 "" "/dev/null" "dump.tmp"]
1230 remote_upload host "dump.tmp"
1231 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1232 remote_file host delete "dump.tmp"
1233 remote_file build delete "dump.tmp"
1234 set cmdret [lindex $cmdret 0]
1238 # Perhaps link the file(s).
1239 if { $cmdret == 0 && $run_ld } {
1240 set objfile "tmpdir/dump"
1241 catch "exec rm -f $objfile" exec_output
1246 if [check_relro_support] {
1247 set ld_extra_opt "-z norelro"
1250 # Add -L$srcdir/$subdir so that the linker command can use
1251 # linker scripts in the source directory.
1252 set cmd "$LD $ld_extra_opt $LDFLAGS -L$srcdir/$subdir \
1253 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
1255 # If needed then check for, or add a -Map option.
1257 if { $opts(map) != "" } then {
1258 if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then {
1259 # Found existing mapfile option
1260 verbose -log "Existing mapfile '$mapfile' found"
1262 # No mapfile option.
1263 set mapfile "tmpdir/dump.map"
1264 verbose -log "Adding mapfile '$mapfile'"
1265 set cmd "$cmd -Map=$mapfile"
1270 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1271 remote_upload host "dump.tmp"
1272 append comp_output [file_contents "dump.tmp"]
1273 remote_file host delete "dump.tmp"
1274 remote_file build delete "dump.tmp"
1275 set cmdret [lindex $cmdret 0]
1277 if { $cmdret == 0 && $run_objcopy } {
1279 set objfile "tmpdir/dump1"
1280 remote_file host delete $objfile
1282 # Note that we don't use OBJCOPYFLAGS here; any flags must be
1283 # explicitly specified.
1284 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
1287 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1288 remote_upload host "dump.tmp"
1289 append comp_output [file_contents "dump.tmp"]
1290 remote_file host delete "dump.tmp"
1291 remote_file build delete "dump.tmp"
1292 set cmdret [lindex $cmdret 0]
1295 set objfile [lindex $objfiles 0]
1298 if { $cmdret == 0 && $opts(PROG) != "" } {
1299 set destopt ${copyfile}.o
1300 switch -- $opts(PROG) {
1301 ar { set program ar }
1306 nm { set program nm }
1307 objcopy { set program objcopy }
1308 ranlib { set program ranlib }
1309 strings { set program strings }
1312 set destopt "-o $destopt"
1315 perror "unrecognized PROG option $opts(PROG) in $file.d"
1316 unresolved $testname
1321 set progopts1 $opts($program)
1322 eval set progopts \$[string toupper $program]FLAGS
1323 eval set binary \$[string toupper $program]
1325 if { ![is_remote host] && [which $binary] == 0 } {
1330 verbose "running $binary $progopts $progopts1" 3
1331 set cmd "$binary $progopts $progopts1 $objfile $destopt"
1333 # Ensure consistent sorting of symbols
1334 if {[info exists env(LC_ALL)]} {
1335 set old_lc_all $env(LC_ALL)
1339 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"]
1340 set cmdret [lindex $cmdret 0]
1341 remote_upload host "dump.tmp"
1342 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1343 remote_file host delete "dump.tmp"
1344 remote_file build delete "dump.tmp"
1345 if {[info exists old_lc_all]} {
1346 set env(LC_ALL) $old_lc_all
1350 if { $destopt != "" } {
1351 set objfile ${copyfile}.o
1355 set want_out(source) ""
1356 set want_out(terminal) 0
1358 if { $opts(error) != "" || $opts(error_output) != "" } {
1359 set want_out(terminal) 1
1362 if { $opts(error) != "" || $opts(warning) != "" } {
1363 set want_out(source) "regex"
1364 if { $opts(error) != "" } {
1365 set want_out(regex) $opts(error)
1367 set want_out(regex) $opts(warning)
1370 set want_out(source) "file"
1371 if { $opts(error_output) != "" } {
1372 set want_out(file) $opts(error_output)
1374 set want_out(file) $opts(warning_output)
1379 regsub "\n$" $comp_output "" comp_output
1380 if { $cmdret != 0 || $comp_output != "" || $want_out(source) != "" } {
1381 set exitstat "succeeded"
1382 if { $cmdret != 0 } { set exitstat "failed" }
1384 if { $want_out(source) == "regex" } {
1385 verbose -log "$exitstat with: <$comp_output>, expected: <$want_out(regex)>"
1386 } elseif { $want_out(source) == "file" } {
1387 verbose -log "$exitstat with: <$comp_output>, expected in file $want_out(file)"
1388 set_file_contents "tmpdir/ld.messages" "$comp_output"
1390 verbose -log "$exitstat with: <$comp_output>, no expected output"
1393 if { (($want_out(source) == "") == ($comp_output == "")) \
1394 && (($cmdret == 0) == ($want_out(terminal) == 0)) \
1395 && ((($want_out(source) == "regex") \
1396 && [regexp -- $want_out(regex) $comp_output]) \
1397 || (($want_out(source) == "file") \
1398 && (![regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$want_out(file)"]))) } {
1399 # We have the expected output.
1400 if { $want_out(terminal) || $dumpprogram == "" } {
1410 # We must not have expected failure if we get here.
1411 if { $opts(error) != "" } {
1416 if { $opts(map) != "" } then {
1417 # Check the map file matches.
1418 set map_pattern_file $srcdir/$subdir/$opts(map)
1419 verbose -log "Compare '$mapfile' against '$map_pattern_file'"
1420 if { [regexp_diff $mapfile $map_pattern_file] } then {
1421 fail "$testname (map file check)"
1423 pass "$testname (map file check)"
1426 if { $dumpprogram == "" } then {
1431 set progopts1 $opts($dumpprogram)
1432 eval set progopts \$[string toupper $dumpprogram]FLAGS
1433 eval set binary \$[string toupper $dumpprogram]
1435 if { ![is_remote host] && [which $binary] == 0 } {
1440 # For objdump of gas output, automatically translate standard section names
1442 if { !$run_ld && $dumpprogram == "objdump" \
1443 && $opts(section_subst) != "no" \
1444 && ![string match "*-b binary*" $progopts1] } {
1445 set sect_names [get_standard_section_names]
1446 if { $sect_names != ""} {
1447 regsub -- "\\.text" $progopts1 "[lindex $sect_names 0]" progopts1
1448 regsub -- "\\.data" $progopts1 "[lindex $sect_names 1]" progopts1
1449 regsub -- "\\.bss" $progopts1 "[lindex $sect_names 2]" progopts1
1453 if { $progopts1 == "" } { set $progopts1 "-r" }
1454 verbose "running $binary $progopts $progopts1" 3
1456 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
1458 # Ensure consistent sorting of symbols
1459 if {[info exists env(LC_ALL)]} {
1460 set old_lc_all $env(LC_ALL)
1464 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"]
1465 set cmdret [lindex $cmdret 0]
1466 remote_upload host "dump.tmp"
1467 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1468 remote_file host delete "dump.tmp"
1469 remote_file build delete "dump.tmp"
1470 if {[info exists old_lc_all]} {
1471 set env(LC_ALL) $old_lc_all
1475 if { $cmdret != 0 || $comp_output != "" } {
1476 send_log "exited abnormally with $cmdret, output:$comp_output\n"
1481 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
1483 # Create the substition list for objdump output.
1485 if { $sect_names != "" } {
1486 set regexp_subst [list "\\\\?\\.text" [lindex $sect_names 0] \
1487 "\\\\?\\.data" [lindex $sect_names 1] \
1488 "\\\\?\\.bss" [lindex $sect_names 2] ]
1491 if { [regexp_diff $dumpfile "${dfile}" $regexp_subst] } then {
1493 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
1501 proc slurp_options { file } {
1502 # If options_regsub(foo) is set to {a b}, then the contents of a
1503 # "#foo:" line will have regsub -all applied to replace a with b.
1504 global options_regsub
1506 if [catch { set f [open $file r] } x] {
1507 #perror "couldn't open `$file': $x"
1512 # whitespace expression
1515 # whitespace is ignored anywhere except within the options list;
1516 # option names are alphanumeric plus underscore.
1517 set pat "^#${ws}(\[a-zA-Z0-9_\]*)$ws:${ws}(.*)$ws\$"
1518 while { [gets $f line] != -1 } {
1519 set line [string trim $line]
1520 # Whitespace here is space-tab.
1521 if [regexp $pat $line xxx opt_name opt_val] {
1523 if [info exists options_regsub($opt_name)] {
1524 set subst $options_regsub($opt_name)
1525 regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \
1528 lappend opt_array [list $opt_name $opt_val]
1529 } elseif {![regexp "^#" $line ]} {
1537 proc file_contents { filename } {
1538 set file [open $filename r]
1539 set contents [read $file]
1544 proc set_file_contents { filename contents } {
1545 set file [open $filename w]
1546 puts $file "$contents"
1550 # Look for big-endian or little-endian switches in the multlib
1551 # options and translate these into a -EB or -EL switch. Note
1552 # we cannot rely upon proc process_multilib_options to do this
1553 # for us because for some targets the compiler does not support
1554 # -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
1555 # the site.exp file will include the switch "-mbig-endian"
1556 # (rather than "big-endian") which is not detected by proc
1557 # process_multilib_options.
1559 proc big_or_little_endian {} {
1561 if [board_info [target_info name] exists multilib_flags] {
1562 set tmp_flags " [board_info [target_info name] multilib_flags]"
1564 foreach x $tmp_flags {
1594 # Internal procedure: return the names of the standard sections
1596 proc get_standard_section_names {} {
1597 if [istarget "rx-*-elf"] {
1598 return { "P" "D_1" "B_1" }
1600 if { [istarget "alpha*-*-*vms*"] || [is_som_format] } {
1601 return { {\$CODE\$} {\$DATA\$} {\$BSS\$} }