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 *-*-lynxos]
217 || ( [istarget *-*-nto*] && ![istarget arm*-*-*] )
218 || [istarget *-*-irix*]
219 || [istarget *-*-*eabi*]
220 || [istarget *-*-rtems*] } {
223 if { [istarget "wasm32*-*-*"] } {
226 if { ![istarget "*-*-elf*"] } {
229 if { [istarget "arm*-*-*"]
230 || [istarget "msp430-*-*"]
231 || [istarget "hppa-unknown-elf"]
232 || [istarget "visium-*-*"] } {
238 # Return true if target uses the generic_link_hash_table linker.
239 proc is_generic { } {
240 if { [istarget "d30v-*-*"]
241 || [istarget "dlx-*-*"]
242 || [istarget "pj*-*-*"]
243 || [istarget "s12z-*-*"]
244 || [istarget "xgate-*-*"] } {
250 # True if the object format is ELF with unused section symbols.
251 proc is_elf_unused_section_symbols {} {
252 global AS ASFLAGS READELF
254 if {![info exists elf_unused_section_symbols_saved]} {
255 set elf_unused_section_symbols_saved 1
256 if { [is_elf_format] } {
257 set base "empty[pid]"
260 set f [open $src "w"]
262 set cmd "$AS $ASFLAGS -o $obj $src"
264 set cmdret [remote_exec host $cmd]
265 set cmdret [lindex $cmdret 0]
266 if { $cmdret == 0 } {
267 set cmd "$READELF -sW $obj"
269 set got [remote_exec host $cmd]
270 if { ![string match "*SECTION*" $got] } {
271 set elf_unused_section_symbols_saved 0
278 return $elf_unused_section_symbols_saved
281 # True if the ELF target supports STB_GNU_UNIQUE.
283 # This require ELFOSABI_GNU, and `bfd_elf_final_link'.
285 proc supports_gnu_unique {} {
286 if { [istarget *-*-freebsd*] } {
289 if { [supports_gnu_osabi] && ![is_generic] } {
295 # True for targets that do not sort .symtab as per the ELF standard.
296 # ie. any that have mips_elf32_be_vec, mips_elf32_le_vec,
297 # mips_elf32_n_be_vec or mips_elf32_n_le_vec as the primary bfd target
298 # vector in config.bfd. When syncing with config.bfd, don't forget that
299 # earlier case-matches trump later ones.
300 proc is_bad_symtab {} {
301 if { ![istarget "mips*-*-*"] } {
304 if { [istarget "*-*-chorus*"]
305 || [istarget "*-*-irix5*"]
306 || [istarget "*-*-irix6*"]
307 || [istarget "*-*-none"]
308 || [istarget "*-*-rtems*"]
309 || [istarget "*-*-windiss"] } {
312 if { [istarget "*-*-elf*"]
313 && ![istarget "*-sde-*"]
314 && ![istarget "*-mti-*"]
315 && ![istarget "*-img-*"] } {
318 if { [istarget "*-*-openbsd*"]
319 && ![istarget "mips64*-*-*"] } {
325 # Returns true if -shared is supported on the target
327 proc check_shared_lib_support { } {
328 global shared_available_saved
331 if {![info exists shared_available_saved]} {
332 set ld_output [remote_exec host $ld "-shared"]
333 if { [ string first "not supported" $ld_output ] >= 0 } {
334 set shared_available_saved 0
336 set shared_available_saved 1
339 return $shared_available_saved
342 # Returns true if -pie is supported on the target
344 proc check_pie_support { } {
345 global pie_available_saved
348 if {![info exists pie_available_saved]} {
349 set ld_output [remote_exec host $ld "-pie"]
350 if { [ string first "not supported" $ld_output ] >= 0 } {
351 set pie_available_saved 0
353 set pie_available_saved 1
356 return $pie_available_saved
359 proc check_relro_support { } {
360 global relro_available_saved
363 if {![info exists relro_available_saved]} {
364 remote_file host delete norelro
365 set ld_output [remote_exec host $ld "-z norelro"]
366 if { [string first "not supported" $ld_output] >= 0
367 || [string first "unrecognized option" $ld_output] >= 0
368 || [string first "-z norelro ignored" $ld_output] >= 0
369 || [string first "cannot find norelro" $ld_output] >= 0 } {
370 set relro_available_saved 0
372 set relro_available_saved 1
375 return $relro_available_saved
378 # Check for support of the .noinit section, used for data that is not
379 # initialized at load, or during the application's initialization sequence.
380 proc supports_noinit_section {} {
381 # .noinit is only supported by ELF targets.
382 if { ![is_elf_format] } {
386 # Targets that set HAVE_NOINIT=yes in their emulparams script utilizing
387 # elf.sc, or explicitly define a .noinit section in their linker script.
389 # arc-*-* is not included here, since it only supports .noinit with the
390 # non-default arcv2elf emulation.
391 if {[istarget "arm-*-*"]
392 || [istarget "avr-*-*"]
393 || [istarget "msp430-*-*"]
394 || [istarget "pru-*-*"] } {
400 # Check for support of the .persistent section, used for data that is
401 # initialized at load, but not during the application's initialization sequence.
402 proc supports_persistent_section {} {
403 # .persistent is only supported by ELF targets.
404 if { ![is_elf_format] } {
408 # Targets that set HAVE_PERSISTENT=yes in their emulparams script utilizing
409 # elf.sc, or explicitly define a .persistent section in their linker script.
410 if { [istarget "arm-*-*"]
411 || [istarget "msp430-*-*"] } {
417 # Compare two files line-by-line. FILE_1 is the actual output and FILE_2
418 # is the expected output. Ignore blank lines in either file.
420 # FILE_2 is a series of regexps, comments and # directives. The directives
424 # Treat the test as a PASS if everything up till this point has
425 # matched. Ignore any remaining lines in either FILE_1 or FILE_2.
428 # Reverse the sense of the test: expect differences to exist.
432 # Skip all lines in FILE_1 until the first that matches REGEXP.
435 # Optionally match REGEXP against line from FILE_1. If the REGEXP
436 # does not match then the next line from FILE_2 is tried.
438 # Other # lines are comments. Regexp lines starting with the `!' character
439 # specify inverse matching (use `\!' for literal matching against a leading
440 # `!'). Skip empty lines in both files.
442 # The first optional argument is a list of regexp substitutions of the form:
444 # EXP1 SUBSPEC1 EXP2 SUBSPEC2 ...
446 # This tells the function to apply each regexp substitution EXPi->SUBSPECi
447 # in order to every line of FILE_2.
449 # Return nonzero if differences exist.
450 proc regexp_diff { file_1 file_2 args } {
458 if { [llength $args] > 0 } {
459 set ref_subst [lindex $args 0]
461 if { [llength $args] > 1 } {
462 perror "Too many arguments to regexp_diff"
466 if [file exists $file_1] then {
467 set file_a [open $file_1 r]
469 perror "$file_1 doesn't exist"
473 if [file exists $file_2] then {
474 set file_b [open $file_2 r]
476 perror "$file_2 doesn't exist"
481 verbose " Regexp-diff'ing: $file_1 $file_2" 2
486 while { [string length $line_a] == 0 } {
487 # Ignore blank line in FILE_1.
488 if { [gets $file_a line_a] == $eof } {
493 while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
494 if { [string match "#pass" $line_b] } {
498 } elseif { [string match "#failif" $line_b] } {
499 send_log "fail if no difference\n"
500 verbose "fail if no difference" 3
502 } elseif { [string match "#..." $line_b] } {
503 if { [gets $file_b line_b] == $eof } {
508 set negated [expr { [string index $line_b 0] == "!" }]
509 set line_bx [string range $line_b $negated end]
510 set n [expr { $negated ? "! " : "" }]
511 # Substitute on the reference.
512 foreach {name value} $ref_subst {
513 regsub -- $name $line_bx $value line_bx
515 verbose "looking for $n\"^$line_bx$\"" 3
516 while { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
517 verbose "skipping \"$line_a\"" 3
518 if { [gets $file_a line_a] == $eof } {
524 } elseif { [string match "#\\?*" $line_b] } {
526 set line_b [string replace $line_b 0 1]
527 set negated [expr { [string index $line_b 0] == "!" }]
528 set line_bx [string range $line_b $negated end]
529 set n [expr { $negated ? "! " : "" }]
530 # Substitute on the reference.
531 foreach {name value} $ref_subst {
532 regsub -- $name $line_bx $value line_bx
534 verbose "optional match for $n\"^$line_bx$\"" 3
535 if { [expr [regexp "^$line_bx$" "$line_a"] != $negated] } {
540 if { [gets $file_b line_b] == $eof } {
548 } elseif { $end_1 && $end_2 } {
550 } elseif { $end_1 } {
551 send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
552 verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
555 } elseif { $end_2 } {
556 send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
557 verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
561 set negated [expr { [string index $line_b 0] == "!" }]
562 set line_bx [string range $line_b $negated end]
563 set n [expr { $negated ? "! " : "" }]
564 set s [expr { $negated ? " " : "" }]
565 # Substitute on the reference.
566 foreach {name value} $ref_subst {
567 regsub -- $name $line_bx $value line_bx
569 verbose "regexp $n\"^$line_bx$\"\nline \"$line_a\"" 3
570 if { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
571 send_log "regexp_diff match failure\n"
572 send_log "regexp $n\"^$line_bx$\"\nline $s\"$line_a\"\n"
573 verbose "regexp_diff match failure\n" 3
579 if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
580 send_log "$file_1 and $file_2 are different lengths\n"
581 verbose "$file_1 and $file_2 are different lengths" 3
585 if { $fail_if_match } {
586 if { $differences == 0 } {
599 # prune_warnings_extra -- delete extra warnings from TEXT.
602 # ld: warning: /lib64/ld-linux-x86-64.so.2: unsupported GNU_PROPERTY_TYPE (5) type : 0xc0010001
603 proc prune_warnings_extra { text } {
605 # Warnings are only pruned from non-experimental code (ie code not
606 # on a release branch). For experimental code we want the warnings
607 # as they indicate that the sources need to be updated to recognise
608 # the new properties.
609 if { "$experimental" == "false" } {
610 # The "\\1" is to try to preserve a "\n" but only if necessary.
611 regsub -all "(^|\n)(\[^\n\]*: warning:\[^\n\]*unsupported GNU_PROPERTY_TYPE\[^\n\]*\n?)+" $text "\\1" text
613 # PR binutils/23898: It is OK to have gaps in build notes.
614 regsub -all "(^|\n)(\[^\n\]*: Warning: Gap in build notes detected from\[^\n\]*\n?)+" $text "\\1" text
618 # This definition is taken from an unreleased version of DejaGnu. Once
619 # that version gets released, and has been out in the world for a few
620 # months at least, it may be safe to delete this copy.
621 if ![string length [info proc prune_warnings]] {
623 # prune_warnings -- delete various system verbosities from TEXT
626 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
628 # Sites with particular verbose os's may wish to override this in site.exp.
630 proc prune_warnings { text } {
631 # This is from sun4's. Do it for all machines for now.
632 # The "\\1" is to try to preserve a "\n" but only if necessary.
633 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
634 # It might be tempting to get carried away and delete blank lines, etc.
635 # Just delete *exactly* what we're ask to, and that's it.
636 set text [prune_warnings_extra $text]
639 } elseif { [info procs saved-prune_warnings] == [list] } {
640 rename prune_warnings saved-prune_warnings
641 proc prune_warnings { text } {
642 set text [saved-prune_warnings $text]
643 set text [prune_warnings_extra $text]
648 # run_dump_test FILE (optional:) EXTRA_OPTIONS
650 # Assemble a .s file, then run some utility on it and check the output.
651 # Optionally generate the .s file first by running the compiler.
653 # There should be an assembly language file named FILE.s in the test
654 # suite directory, and a pattern file called FILE.d. run_dump_test
655 # will assemble FILE.s, optionally run objcopy on the object file,
656 # optionally run ld, optionally run another objcopy, optionally run
657 # another tool under test specified by PROG, then run a dump tool like
658 # addr2line, nm, objdump, readelf or size on the object file to produce
659 # textual output, and then analyze that with regexps.
660 # The FILE.d file specifies what program to run, and what to expect in
663 # The FILE.d file begins with zero or more option lines, which specify
664 # flags to pass to the assembler, the program to run to dump the
665 # assembler's output, and the options it wants. The option lines have
670 # OPTION is the name of some option, like "name" or "objdump", and
671 # VALUE is OPTION's value. The valid options are described below.
672 # Whitespace is ignored everywhere, except within VALUE. The option
673 # list ends with the first line that doesn't match the above syntax.
674 # However, a line within the options that begins with a #, but doesn't
675 # have a recognizable option name followed by a colon, is considered a
676 # comment and entirely ignored.
678 # The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of
679 # two-element lists. The first element of each is an option name, and
680 # the second additional arguments to be added on to the end of the
681 # option list as given in FILE.d. (If omitted, no additional options
684 # The interesting options are:
687 # The name of this test, passed to DejaGNU's `pass' and `fail'
688 # commands. If omitted, this defaults to FILE, the root of the
689 # .s and .d files' names.
692 # When assembling, pass FLAGS to the assembler.
693 # If assembling several files, you can pass different assembler
694 # options in the "source" directives. See below.
695 # Multiple instances of this directive tells run_dump_test to run the test
696 # multiple times -- one time with each set of flags provided.
697 # Each instance will run exactly as a file with a single "as" line, it is
698 # not possible to condition any behaviour on which set of "as" flags is
699 # used. That means that the "source" specific options are appended to
700 # the "as" flags for their corresponding files, and any extra processing
701 # (e.g. with "ld" and "objcopy") is repeated for each test.
704 # Link assembled files using FLAGS, in the order of the "source"
705 # directives, when using multiple files.
707 # ld_after_inputfiles: FLAGS
708 # Similar to "ld", but put FLAGS after all input files.
711 # Run the compiler with FLAGS (to which -S is added) to generate assembler
712 # source first. source: must be provided and should consist of .c files.
713 # Source-specific CC flags are not supported.
715 # objcopy_objects: FLAGS
716 # Run objcopy with the specified flags after assembling any source
717 # that has the special marker RUN_OBJCOPY in the source specific
720 # objcopy_linked_file: FLAGS
721 # Run objcopy on the linked file with the specified flags.
722 # This lets you transform the linked file using objcopy, before the
723 # result is analyzed by an analyzer program specified below.
726 # The name of a program under test, to run to modify or analyze the
727 # .o file produced by the assembler. Recognised names are: ar,
728 # elfedit, nm, objcopy, ranlib, strings, and strip.
730 # DUMPPROG: PROGRAM-NAME
731 # The name of the program to run to analyze the file produced
732 # by the assembler or the linker. This can be omitted;
733 # run_dump_test will guess which program to run from which of
734 # the flags options below is present.
741 # Use the specified program to analyze the output file, and pass it
742 # FLAGS, in addition to the output name. Note that they are run
743 # with LC_ALL=C in the environment to give consistent sorting of
744 # symbols. If no FLAGS are needed then you can use:
745 # DUMPPROG: [nm objdump readelf addr2line]
746 # instead, or just pass a flag that happens to be the default.
747 # If objdump is the dump tool and we're not dumping binary, nor
748 # have run ld, then the standard section names (.text, .data and
749 # .bss) are replaced by target ones if any (eg. rx-elf uses "P"
750 # instead of .text). The substition is done for both the
751 # objdump options (eg: "-j .text" is replaced by "-j P") and the
754 # source: SOURCE [FLAGS]
755 # Assemble the file SOURCE.s using the flags in the "as" directive
756 # and the (optional) FLAGS. If omitted, the source defaults to
758 # This is useful if several .d files want to share a .s file.
759 # More than one "source" directive can be given, which is useful
760 # when testing linking.
763 # Match against DUMP.d. If omitted, this defaults to FILE.d. This
764 # is useful if several .d files differ by options only. Options are
765 # always read from FILE.d.
767 # target: GLOB|PROC ...
768 # Run this test only on a specified list of targets. More precisely,
769 # in the space-separated list each glob is passed to "istarget" and
770 # each proc is called as a TCL procedure. List items are interpreted
771 # such that procs are denoted by surrounding square brackets, and any
772 # other items are consired globs. If the call evaluates true for any
773 # of them, the test will be run, otherwise it will be marked
776 # notarget: GLOB|PROC ...
777 # Do not run this test on a specified list of targets. Again, each
778 # glob in the space-separated list is passed to "istarget" and each
779 # proc is called as a TCL procedure, and the test is run if it
780 # evaluates *false* for *all* of them. Otherwise it will be marked
783 # alltargets: GLOB|PROC ...
784 # Run this test on a specified list of targets. Again, each
785 # glob in the space-separated list is passed to "istarget" and each
786 # proc is called as a TCL procedure, and the test is run if it
787 # evaluates *true* for *all* of them. Otherwise it will be marked
790 # skip: GLOB|PROC ...
791 # anyskip: GLOB|PROC ...
792 # noskip: GLOB|PROC ...
793 # These are exactly the same as "notarget", "alltargets" and
794 # "target" respectively, except that they do nothing at all if the
795 # check fails. They should only be used in groups, to construct a
796 # single test which is run on all targets but with variant options
797 # or expected output on some targets. (For example, see
798 # gas/arm/inst.d and gas/arm/wince_inst.d.)
800 # xfail: GLOB|PROC ...
801 # Run this test and it is is expected to fail on a specified list
805 # An error with message matching REGEX must be emitted for the test
806 # to pass. The DUMPPROG, addr2line, nm, objdump, readelf and size
807 # options have no meaning and need not supplied if this is present.
808 # Multiple "error" directives append to the expected error message.
811 # Means the same as 'error', except the regular expression lines
812 # are contains in FILE.
815 # Expect a warning matching REGEX. It is an error to issue
816 # both "error" and "warning". Multiple "warning" directives
817 # append to the expected warning message.
819 # warning_output: FILE
820 # Means the same as 'warning', except the regular expression
821 # lines are contains in FILE.
824 # Adding this option will cause the linker to generate a linker
825 # map file, using the -Map=MAPFILE command line option. If
826 # there is no -Map=MAPFILE in the 'ld: FLAGS' then one will be
827 # added to the linker command line. The contents of the
828 # generated MAPFILE are then compared against the regexp lines
829 # in FILE using `regexp_diff' (see below for details).
832 # Means that the section substitution for objdump is disabled.
834 # Each option may occur at most once unless otherwise mentioned.
836 # After the option lines come regexp lines. run_dump_test calls
837 # regexp_diff to compare the output of the dumping tool against the
840 proc run_dump_test { name {extra_options {}} } {
841 global ADDR2LINE ADDR2LINEFLAGS AS ASFLAGS CC CFLAGS ELFEDIT ELFEDITFLAGS
842 global LD LDFLAGS NM NMFLAGS OBJCOPY OBJCOPYFLAGS OBJDUMP OBJDUMPFLAGS
843 global READELF READELFFLAGS STRIP STRIPFLAGS
844 global copyfile env runtests srcdir subdir verbose
846 if [string match "*/*" $name] {
848 set name [file tail $name]
850 set file "$srcdir/$subdir/$name"
853 if ![runtest_file_p $runtests $name] then {
857 set opt_array [slurp_options "${file}.d"]
858 if { $opt_array == -1 } {
859 perror "error reading options from $file.d"
860 unresolved $subdir/$name
863 set dumpfile tmpdir/dump.out
868 set opts(DUMPPROG) {}
869 set opts(addr2line) {}
870 set opts(alltargets) {}
874 set as_final_flags {}
875 set as_additional_flags {}
880 set opts(error_output) {}
882 set opts(ld_after_inputfiles) {}
887 set opts(notarget) {}
889 set opts(objcopy_linked_file) {}
890 set opts(objcopy_objects) {}
894 set opts(section_subst) {}
903 set opts(warning_output) {}
907 foreach i [concat $opt_array {{} {}} $extra_options] {
908 set opt_name [lindex $i 0]
909 set opt_val [lindex $i 1]
910 if { $opt_name == "" } {
914 if ![info exists opts($opt_name)] {
915 perror "unknown option $opt_name in file $file.d"
916 unresolved $subdir/$name
920 # Allow more substitutions, including tcl functions, for as, ld,
921 # and cc. Not done in general because extra quoting is needed for glob
922 # args used for example in binutils-all/remove-relocs-04.d.
923 if { $opt_name == "as" || $opt_name == "ld" || $opt_name == "cc" } {
924 set opt_val [subst $opt_val]
926 # Just substitute $srcdir and $subdir
927 regsub -all {\$srcdir} "$opt_val" "$srcdir" opt_val
928 regsub -all {\$subdir} "$opt_val" "$subdir" opt_val
931 switch -- $opt_name {
942 # Move any source-specific as-flags to a separate list to
943 # simplify processing.
944 if { [llength $opt_val] > 1 } {
945 lappend asflags [lrange $opt_val 1 end]
946 set opt_val [lindex $opt_val 0]
951 # Create the object file name based on nothing but the source
954 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]].o]
955 # But, sometimes, we have the exact same source filename in
956 # different directories (foo/src.s bar/src.s) which would lead
957 # us to try and create two src.o files. We detect this
958 # conflict here, and instead create src.o and src1.o.
960 while { [lsearch $objfile_names $new_objfile] != -1 } {
963 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]]${j}.o]
965 lappend objfile_names $new_objfile
969 && [string length $opts($opt_name)]
970 && $opt_name != "as" } {
971 perror "option $opt_name multiply set in $file.d"
972 unresolved $subdir/$name
976 # A single "#ld:" with no options should do the right thing.
977 if { $opt_name == "ld" } {
980 # Likewise objcopy_linked_file.
981 if { $opt_name == "objcopy_linked_file" } {
987 # Append differently whether it's a message (without space) or
988 # an option or list (with space).
989 switch -- $opt_name {
992 append opts($opt_name) $opt_val
996 set as_additional_flags [concat $as_additional_flags $opt_val]
998 lappend opts(as) $opt_val
1002 set opts($opt_name) [concat $opts($opt_name) $opt_val]
1007 # Ensure there is something in $opts(as) for the foreach loop below.
1008 if { [llength $opts(as)] == 0 } {
1009 set opts(as) [list " "]
1011 foreach x $opts(as) {
1012 if { [string length $x] && [string length $as_additional_flags] } {
1015 append x $as_additional_flags
1016 regsub {\[big_or_little_endian\]} $x \
1017 [big_or_little_endian] x
1018 lappend as_final_flags $x
1021 regsub {\[big_or_little_endian\]} $opts(ld) \
1022 [big_or_little_endian] opts(ld)
1024 if { $opts(name) == "" } {
1025 set testname "$subdir/$name"
1027 set testname $opts(name)
1031 foreach opt { warning error warning_output error_output } {
1032 if { $opts($opt) != "" } {
1034 perror "$testname: bad mix of warning and error test directives"
1035 unresolved $testname
1042 # Decide early whether we should run the test for this target.
1043 if { [llength $opts(noskip)] > 0 } {
1045 foreach targ $opts(noskip) {
1046 if [match_target $targ] {
1051 if { $targmatch == 0 } {
1055 foreach targ $opts(anyskip) {
1056 if ![match_target $targ] {
1060 foreach targ $opts(skip) {
1061 if [match_target $targ] {
1065 if { [llength $opts(target)] > 0 } {
1067 foreach targ $opts(target) {
1068 if [match_target $targ] {
1073 if { $targmatch == 0 } {
1074 unsupported $testname
1078 foreach targ $opts(alltargets) {
1079 if ![match_target $targ] {
1080 unsupported $testname
1084 foreach targ $opts(notarget) {
1085 if [match_target $targ] {
1086 unsupported $testname
1092 # It's meaningless to require an output-testing method when we
1094 if { $opts(error) == "" && $opts(error_output) == "" } {
1095 if { $opts(DUMPPROG) != "" } {
1096 switch -- $opts(DUMPPROG) {
1097 addr2line { set dumpprogram addr2line }
1098 nm { set dumpprogram nm }
1099 objdump { set dumpprogram objdump }
1100 readelf { set dumpprogram readelf }
1101 size { set dumpprogram size }
1103 perror "unrecognized DUMPPROG option $opts(DUMPPROG) in $file.d"
1104 unresolved $testname
1109 # Guess which program to run, by seeing which option was specified.
1110 foreach p {addr2line nm objdump readelf size} {
1111 if {$opts($p) != ""} {
1112 if {$dumpprogram != ""} {
1113 perror "ambiguous dump program in $file.d"
1114 unresolved $testname
1122 if { $dumpprogram == "" && $opts(map) == "" && !$err_warn } {
1123 perror "dump program unspecified in $file.d"
1124 unresolved $testname
1129 # Possibly compile some of the inputs, and build up a replacement
1130 # for opts(source) with the output .s names substituted in as we go.
1131 # Set the .s names from the objfile_names to take advantage of the
1132 # uniquification that happened earlier.
1133 if { $opts(cc) != ""} {
1137 foreach cfile $opts(source) ofile $objfile_names {
1138 if { [file extension $cfile] != ".c" } {
1139 lappend new_source "$cfile"
1143 if { ! [string match "./*" $cfile] } {
1144 set cfile "$srcdir/$subdir/$cfile"
1146 # ofile is never absolute, so this always works to protect sfile
1147 # from later absolutization.
1148 set sfile "./[file rootname $ofile].s"
1149 set cmd "$CC $CFLAGS -S $opts(cc) -o $sfile $cfile"
1151 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1152 remote_upload host "dump.tmp"
1153 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1154 remote_file host delete "dump.tmp"
1155 remote_file build delete "dump.tmp"
1156 lappend new_source "$sfile"
1157 set cmdret [lindex $cmdret 0]
1159 regsub "\n$" $comp_output "" comp_output
1160 if { $cmdret != 0} {
1161 send_log "compilation of $cfile failed, exit status $cmdret with <$comp_output>"
1162 # Should this be 'unresolved', or is that too silent?
1167 set opts(source) $new_source
1170 if { $opts(source) == "" } {
1171 set sourcefiles [list ${file}.s]
1172 set asflags [list ""]
1173 set objfile_names [list tmpdir/[file tail ${file}].o]
1176 foreach sf $opts(source) {
1177 if { [string match "./*" $sf] } {
1178 lappend sourcefiles "$sf"
1180 lappend sourcefiles "$srcdir/$subdir/$sf"
1185 if { $opts(dump) == "" } {
1188 set dfile $srcdir/$subdir/$opts(dump)
1191 # Time to setup xfailures.
1192 foreach targ $opts(xfail) {
1193 if [match_target $targ] {
1199 foreach as_flags $as_final_flags {
1200 # Assemble each file.
1202 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
1203 set sourcefile [lindex $sourcefiles $i]
1204 set sourceasflags [lindex $asflags $i]
1205 set run_objcopy_objects 0
1207 if { [string match "*RUN_OBJCOPY*" $sourceasflags] } {
1208 set run_objcopy_objects 1
1210 regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
1212 set objfile [lindex $objfile_names $i]
1213 catch "exec rm -f $objfile" exec_output
1214 lappend objfiles $objfile
1216 if { $as_flags == "binary" } {
1217 while {[file type $sourcefile] eq "link"} {
1218 set newfile [file readlink $sourcefile]
1219 if {[string index $newfile 0] ne "/"} {
1220 set newfile [file dirname $sourcefile]/$newfile
1222 set sourcefile $newfile
1224 set newfile [remote_download host $sourcefile $objfile]
1226 if { $newfile == "" } {
1230 if { [istarget "hppa*-*-*"] \
1231 && ![istarget "*-*-linux*"] \
1232 && ![istarget "*-*-netbsd*" ] } {
1233 set cmd "sed -e 's/^\[ \]*\.comm \\(\[^,\]*\\),\\(.*\\)/\\1 .comm \\2/' < $sourcefile > tmpdir/asm.s"
1235 set cmdret [remote_exec host [concat sh -c [list "$cmd"]]]
1236 set cmdret [lindex $cmdret 0]
1237 if { $cmdret != 0 } {
1238 perror "sed failure"
1239 unresolved $testname
1242 set sourcefile tmpdir/asm.s
1244 set cmd "$AS $ASFLAGS $as_flags $sourceasflags -o $objfile $sourcefile"
1247 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1248 remote_upload host "dump.tmp"
1249 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1250 remote_file host delete "dump.tmp"
1251 remote_file build delete "dump.tmp"
1252 set cmdret [lindex $cmdret 0]
1254 if { $cmdret == 0 && $run_objcopy_objects } {
1255 set cmd "$OBJCOPY $opts(objcopy_objects) $objfile"
1258 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \
1259 "" "/dev/null" "dump.tmp"]
1260 remote_upload host "dump.tmp"
1261 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1262 remote_file host delete "dump.tmp"
1263 remote_file build delete "dump.tmp"
1264 set cmdret [lindex $cmdret 0]
1268 # Perhaps link the file(s).
1269 if { $cmdret == 0 && $run_ld } {
1270 set objfile "tmpdir/dump"
1271 catch "exec rm -f $objfile" exec_output
1276 if [check_relro_support] {
1277 set ld_extra_opt "-z norelro"
1280 # Add -L$srcdir/$subdir so that the linker command can use
1281 # linker scripts in the source directory.
1282 set cmd "$LD $ld_extra_opt $LDFLAGS -L$srcdir/$subdir \
1283 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
1285 # If needed then check for, or add a -Map option.
1287 if { $opts(map) != "" } then {
1288 if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then {
1289 # Found existing mapfile option
1290 verbose -log "Existing mapfile '$mapfile' found"
1292 # No mapfile option.
1293 set mapfile "tmpdir/dump.map"
1294 verbose -log "Adding mapfile '$mapfile'"
1295 set cmd "$cmd -Map=$mapfile"
1300 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1301 remote_upload host "dump.tmp"
1302 append comp_output [file_contents "dump.tmp"]
1303 remote_file host delete "dump.tmp"
1304 remote_file build delete "dump.tmp"
1305 set cmdret [lindex $cmdret 0]
1307 if { $cmdret == 0 && $run_objcopy } {
1309 set objfile "tmpdir/dump1"
1310 remote_file host delete $objfile
1312 # Note that we don't use OBJCOPYFLAGS here; any flags must be
1313 # explicitly specified.
1314 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
1317 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1318 remote_upload host "dump.tmp"
1319 append comp_output [file_contents "dump.tmp"]
1320 remote_file host delete "dump.tmp"
1321 remote_file build delete "dump.tmp"
1322 set cmdret [lindex $cmdret 0]
1325 set objfile [lindex $objfiles 0]
1328 if { $cmdret == 0 && $opts(PROG) != "" } {
1329 set destopt ${copyfile}.o
1330 switch -- $opts(PROG) {
1331 ar { set program ar }
1336 nm { set program nm }
1337 objcopy { set program objcopy }
1338 ranlib { set program ranlib }
1339 strings { set program strings }
1342 set destopt "-o $destopt"
1345 perror "unrecognized PROG option $opts(PROG) in $file.d"
1346 unresolved $testname
1351 set progopts1 $opts($program)
1352 eval set progopts \$[string toupper $program]FLAGS
1353 eval set binary \$[string toupper $program]
1355 if { ![is_remote host] && [which $binary] == 0 } {
1360 verbose "running $binary $progopts $progopts1" 3
1361 set cmd "$binary $progopts $progopts1 $objfile $destopt"
1363 # Ensure consistent sorting of symbols
1364 if {[info exists env(LC_ALL)]} {
1365 set old_lc_all $env(LC_ALL)
1369 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"]
1370 set cmdret [lindex $cmdret 0]
1371 remote_upload host "dump.tmp"
1372 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1373 remote_file host delete "dump.tmp"
1374 remote_file build delete "dump.tmp"
1375 if {[info exists old_lc_all]} {
1376 set env(LC_ALL) $old_lc_all
1380 if { $destopt != "" } {
1381 set objfile ${copyfile}.o
1385 set want_out(source) ""
1386 set want_out(terminal) 0
1388 if { $opts(error) != "" || $opts(error_output) != "" } {
1389 set want_out(terminal) 1
1392 if { $opts(error) != "" || $opts(warning) != "" } {
1393 set want_out(source) "regex"
1394 if { $opts(error) != "" } {
1395 set want_out(regex) $opts(error)
1397 set want_out(regex) $opts(warning)
1400 set want_out(source) "file"
1401 if { $opts(error_output) != "" } {
1402 set want_out(file) $opts(error_output)
1404 set want_out(file) $opts(warning_output)
1409 regsub "\n$" $comp_output "" comp_output
1410 if { $cmdret != 0 || $comp_output != "" || $want_out(source) != "" } {
1411 set exitstat "succeeded"
1412 if { $cmdret != 0 } { set exitstat "failed" }
1414 if { $want_out(source) == "regex" } {
1415 verbose -log "$exitstat with: <$comp_output>, expected: <$want_out(regex)>"
1416 } elseif { $want_out(source) == "file" } {
1417 verbose -log "$exitstat with: <$comp_output>, expected in file $want_out(file)"
1418 set_file_contents "tmpdir/ld.messages" "$comp_output"
1420 verbose -log "$exitstat with: <$comp_output>, no expected output"
1423 if { (($want_out(source) == "") == ($comp_output == "")) \
1424 && (($cmdret == 0) == ($want_out(terminal) == 0)) \
1425 && ((($want_out(source) == "regex") \
1426 && [regexp -- $want_out(regex) $comp_output]) \
1427 || (($want_out(source) == "file") \
1428 && (![regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$want_out(file)"]))) } {
1429 # We have the expected output.
1430 if { $want_out(terminal) || $dumpprogram == "" } {
1440 # We must not have expected failure if we get here.
1441 if { $want_out(terminal) } {
1446 if { $opts(map) != "" } then {
1447 # Check the map file matches.
1448 set map_pattern_file $srcdir/$subdir/$opts(map)
1449 verbose -log "Compare '$mapfile' against '$map_pattern_file'"
1450 if { [regexp_diff $mapfile $map_pattern_file] } then {
1451 fail "$testname (map file check)"
1453 pass "$testname (map file check)"
1456 if { $dumpprogram == "" } then {
1461 set progopts1 $opts($dumpprogram)
1462 eval set progopts \$[string toupper $dumpprogram]FLAGS
1463 eval set binary \$[string toupper $dumpprogram]
1465 if { ![is_remote host] && [which $binary] == 0 } {
1470 # For objdump of gas output, automatically translate standard section names
1472 if { !$run_ld && $dumpprogram == "objdump" \
1473 && $opts(section_subst) != "no" \
1474 && ![string match "*-b binary*" $progopts1] } {
1475 set sect_names [get_standard_section_names]
1476 if { $sect_names != ""} {
1477 regsub -- "\\.text" $progopts1 "[lindex $sect_names 0]" progopts1
1478 regsub -- "\\.data" $progopts1 "[lindex $sect_names 1]" progopts1
1479 regsub -- "\\.bss" $progopts1 "[lindex $sect_names 2]" progopts1
1483 if { $progopts1 == "" } { set $progopts1 "-r" }
1484 verbose "running $binary $progopts $progopts1" 3
1486 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
1488 # Ensure consistent sorting of symbols
1489 if {[info exists env(LC_ALL)]} {
1490 set old_lc_all $env(LC_ALL)
1494 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"]
1495 set cmdret [lindex $cmdret 0]
1496 remote_upload host "dump.tmp"
1497 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1498 remote_file host delete "dump.tmp"
1499 remote_file build delete "dump.tmp"
1500 if {[info exists old_lc_all]} {
1501 set env(LC_ALL) $old_lc_all
1505 if { $cmdret != 0 || $comp_output != "" } {
1506 send_log "exited abnormally with $cmdret, output:$comp_output\n"
1511 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
1513 # Create the substition list for objdump output.
1515 if { $sect_names != "" } {
1516 set regexp_subst [list "\\\\?\\.text" [lindex $sect_names 0] \
1517 "\\\\?\\.data" [lindex $sect_names 1] \
1518 "\\\\?\\.bss" [lindex $sect_names 2] ]
1521 if { [regexp_diff $dumpfile "${dfile}" $regexp_subst] } then {
1523 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
1531 proc slurp_options { file } {
1532 # If options_regsub(foo) is set to {a b}, then the contents of a
1533 # "#foo:" line will have regsub -all applied to replace a with b.
1534 global options_regsub
1536 if [catch { set f [open $file r] } x] {
1537 #perror "couldn't open `$file': $x"
1542 # whitespace expression
1545 # whitespace is ignored anywhere except within the options list;
1546 # option names are alphanumeric plus underscore.
1547 set pat "^#${ws}(\[a-zA-Z0-9_\]*)$ws:${ws}(.*)$ws\$"
1548 while { [gets $f line] != -1 } {
1549 set line [string trim $line]
1550 # Whitespace here is space-tab.
1551 if [regexp $pat $line xxx opt_name opt_val] {
1553 if [info exists options_regsub($opt_name)] {
1554 set subst $options_regsub($opt_name)
1555 regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \
1558 lappend opt_array [list $opt_name $opt_val]
1559 } elseif {![regexp "^#" $line ]} {
1567 proc file_contents { filename } {
1568 set file [open $filename r]
1569 set contents [read $file]
1574 proc set_file_contents { filename contents } {
1575 set file [open $filename w]
1576 puts $file "$contents"
1580 # Look for big-endian or little-endian switches in the multlib
1581 # options and translate these into a -EB or -EL switch. Note
1582 # we cannot rely upon proc process_multilib_options to do this
1583 # for us because for some targets the compiler does not support
1584 # -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
1585 # the site.exp file will include the switch "-mbig-endian"
1586 # (rather than "big-endian") which is not detected by proc
1587 # process_multilib_options.
1589 proc big_or_little_endian {} {
1591 if [board_info [target_info name] exists multilib_flags] {
1592 set tmp_flags " [board_info [target_info name] multilib_flags]"
1594 foreach x $tmp_flags {
1624 # Internal procedure: return the names of the standard sections
1626 proc get_standard_section_names {} {
1627 if [istarget "rx-*-elf"] {
1628 return { "P" "D_1" "B_1" }
1630 if { [istarget "alpha*-*-*vms*"] || [is_som_format] } {
1631 return { {\$CODE\$} {\$DATA\$} {\$BSS\$} }