1 # Copyright (C) 1993-2022 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 i?86-*-beos*]
58 && ![istarget ia64-*-hpux*] } {
62 if { [istarget i?86-*-beospe*] } {
66 if { [istarget *-*-linux*ecoff*]
67 || [istarget *-*-rtemscoff*] } {
71 if { [istarget *-*-netbsdaout*] } {
75 if { [istarget arm-*-openbsd*]
76 || [istarget ns32k-*-openbsd*]
77 || [istarget vax-*-openbsd*] } {
84 # True if the object format is known to be a.out.
86 proc is_aout_format {} {
87 if { [istarget *-*-*aout*]
88 || [istarget *-*-bsd*]
89 || [istarget *-*-msdos*]
90 || [istarget ns32k-*-*]
91 || [istarget pdp11-*-*] } {
97 # True if the object format is known to be PE COFF.
99 proc is_pecoff_format args {
100 if { [llength $args] == 1 } {
101 set m_os [lindex $args 0]
105 if { [istarget $m_os-beospe*]
106 || [istarget $m_os-cegcc*]
107 || [istarget $m_os-cygwin*]
108 || [istarget $m_os-interix*]
109 || [istarget $m_os-mingw*]
110 || [istarget $m_os-pe*]
111 || [istarget $m_os-winnt*] } {
117 proc is_som_format {} {
118 if { ![istarget hppa*-*-*] || [istarget hppa*64*-*-*] } {
121 if { [istarget *-*-osf*] \
122 || [istarget {*-*-h[ip]ux*}] \
123 || [istarget *-*-mpeix*] \
124 || [istarget *-*-bsd*] } {
130 proc is_xcoff_format {} {
131 if { [istarget rs6000-*-*]
132 || [istarget powerpc*-*-aix*]
133 || [istarget powerpc*-*-beos*]
134 || [istarget powerpc*-*-macos*] } {
140 # True if the object format is known to be 64-bit ELF.
142 proc is_elf64 { binary_file } {
146 set tmpfile [file dirname $binary_file]/readelf.out
148 catch "exec $READELF $READELFFLAGS -h $binary_file > $tmpfile" got
150 if ![string match "" $got] then {
154 if { ![regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \
155 [file_contents $tmpfile] nil readelf_size] } {
159 if { $readelf_size == "64" } {
166 # True if the object format is known to use RELA relocations.
168 proc is_rela { binary_file } {
172 set tmpfile [file dirname $binary_file]/readelf.out
173 catch "exec $READELF $READELFFLAGS -S $binary_file > $tmpfile" got
175 if ![string match "" $got] then {
179 if { ![regexp "RELA" [file_contents $tmpfile]] } {
186 # Return the file name suffix required for executables, if any.
189 if { [istarget *-*-cygwin*]
190 || [istarget *-*-mingw*]
191 || [istarget *-*-msdos*]
192 || [istarget *-*-*vms*] } {
198 # True if the target matches TARGET, specified as a TCL procedure if
199 # in square brackets or as machine triplet otherwise.
201 proc match_target { target } {
202 if [regexp {^!?\[.*\]$} $target] {
205 return [istarget $target]
209 # True if the ELF target supports setting the ELF header OSABI field
210 # to ELFOSABI_GNU or ELFOSABI_FREEBSD, a requirement for STT_GNU_IFUNC
211 # symbol and SHF_GNU_MBIND or SHF_GNU_RETAIN section support.
213 # This generally depends on the target OS only, however there are a
214 # number of exceptions for bare metal targets as follows. The MSP430
215 # and Visium targets set OSABI to ELFOSABI_STANDALONE. Likewise
216 # non-EABI ARM targets set OSABI to ELFOSABI_ARM
218 # Non-Linux HPPA defaults to ELFOSABI_HPUX.
220 # Note that some TI C6X targets use ELFOSABI_C6000_* but one doesn't,
221 # so we don't try to sort out tic6x here. (The effect is that linker
222 # testcases will generally need to exclude tic6x or use a -m option.)
224 proc supports_gnu_osabi {} {
225 if { [istarget *-*-gnu*]
226 || [istarget *-*-linux*]
227 || [istarget *-*-nacl*]
228 || ( [istarget *-*-*bsd*] && ![istarget arm*-*-netbsd*] )
229 || [istarget *-*-lynxos]
230 || ( [istarget *-*-nto*] && ![istarget arm*-*-*] )
231 || [istarget *-*-irix*]
232 || [istarget *-*-*eabi*]
233 || [istarget *-*-rtems*] } {
236 if { [istarget "wasm32*-*-*"] } {
239 if { ![istarget "*-*-elf*"] } {
242 if { [istarget "arm*-*-*"]
243 || [istarget "msp430-*-*"]
244 || [istarget "hppa-unknown-elf"]
245 || [istarget "visium-*-*"] } {
251 # Return true if target uses the generic_link_hash_table linker.
252 proc is_generic { } {
253 if { [istarget "d30v-*-*"]
254 || [istarget "dlx-*-*"]
255 || [istarget "pj*-*-*"]
256 || [istarget "s12z-*-*"]
257 || [istarget "xgate-*-*"] } {
263 # True if the object format is ELF with unused section symbols.
264 proc is_elf_unused_section_symbols {} {
265 global AS ASFLAGS READELF
267 if {![info exists elf_unused_section_symbols_saved]} {
268 set elf_unused_section_symbols_saved 1
269 if { [is_elf_format] } {
270 set base "empty[pid]"
273 set f [open $src "w"]
275 set cmd "$AS $ASFLAGS -o $obj $src"
277 set cmdret [remote_exec host $cmd]
278 set cmdret [lindex $cmdret 0]
279 if { $cmdret == 0 } {
280 set cmd "$READELF -sW $obj"
282 set got [remote_exec host $cmd]
283 if { ![string match "*SECTION*" $got] } {
284 set elf_unused_section_symbols_saved 0
291 return $elf_unused_section_symbols_saved
294 # True if the ELF target supports STB_GNU_UNIQUE.
296 # This require ELFOSABI_GNU, and `bfd_elf_final_link'.
298 proc supports_gnu_unique {} {
299 if { [istarget *-*-freebsd*] } {
302 if { [supports_gnu_osabi] && ![is_generic] } {
308 # True for targets that do not sort .symtab as per the ELF standard.
309 # ie. any that have mips_elf32_be_vec, mips_elf32_le_vec,
310 # mips_elf32_n_be_vec or mips_elf32_n_le_vec as the primary bfd target
311 # vector in config.bfd. When syncing with config.bfd, don't forget that
312 # earlier case-matches trump later ones.
313 proc is_bad_symtab {} {
314 if { ![istarget "mips*-*-*"] } {
317 if { [istarget "*-*-chorus*"]
318 || [istarget "*-*-irix5*"]
319 || [istarget "*-*-irix6*"]
320 || [istarget "*-*-none"]
321 || [istarget "*-*-rtems*"]
322 || [istarget "*-*-windiss"] } {
325 if { [istarget "*-*-elf*"]
326 && ![istarget "*-sde-*"]
327 && ![istarget "*-mti-*"]
328 && ![istarget "*-img-*"] } {
331 if { [istarget "*-*-openbsd*"]
332 && ![istarget "mips64*-*-*"] } {
338 # Returns true if -shared is supported on the target
340 proc check_shared_lib_support { } {
341 global shared_available_saved
344 if {![info exists shared_available_saved]} {
345 set ld_output [remote_exec host $ld "-shared"]
346 if { [ string first "not supported" $ld_output ] >= 0 } {
347 set shared_available_saved 0
349 set shared_available_saved 1
352 return $shared_available_saved
355 # Returns true if -pie is supported on the target
357 proc check_pie_support { } {
358 global pie_available_saved
361 if {![info exists pie_available_saved]} {
362 set ld_output [remote_exec host $ld "-pie"]
363 if { [ string first "not supported" $ld_output ] >= 0 } {
364 set pie_available_saved 0
366 set pie_available_saved 1
369 return $pie_available_saved
372 proc check_relro_support { } {
373 global relro_available_saved
376 if {![info exists relro_available_saved]} {
377 remote_file host delete norelro
378 set ld_output [remote_exec host $ld "-z norelro"]
379 if { [string first "not supported" $ld_output] >= 0
380 || [string first "unrecognized option" $ld_output] >= 0
381 || [string first "-z norelro ignored" $ld_output] >= 0
382 || [string first "cannot find norelro" $ld_output] >= 0 } {
383 set relro_available_saved 0
385 set relro_available_saved 1
388 return $relro_available_saved
391 # Check for support of the .noinit section, used for data that is not
392 # initialized at load, or during the application's initialization sequence.
393 proc supports_noinit_section {} {
394 # .noinit is only supported by ELF targets.
395 if { ![is_elf_format] } {
399 # Targets that set HAVE_NOINIT=yes in their emulparams script utilizing
400 # elf.sc, or explicitly define a .noinit section in their linker script.
402 # arc-*-* is not included here, since it only supports .noinit with the
403 # non-default arcv2elf emulation.
404 if { ([istarget "arm-*-*"] && ![istarget "arm*-linux-*"])
405 || [istarget "avr-*-*"]
406 || [istarget "msp430-*-*"]
407 || [istarget "pru-*-*"] } {
413 # Check for support of the .persistent section, used for data that is
414 # initialized at load, but not during the application's initialization sequence.
415 proc supports_persistent_section {} {
416 # .persistent is only supported by ELF targets.
417 if { ![is_elf_format] } {
421 # Targets that set HAVE_PERSISTENT=yes in their emulparams script utilizing
422 # elf.sc, or explicitly define a .persistent section in their linker script.
423 if { ([istarget "arm-*-*"] && ![istarget "arm*-linux-*"])
424 || [istarget "msp430-*-*"] } {
430 # Whether a target support DT_RELR sections.
431 proc supports_dt_relr {} {
432 if { ([istarget x86_64-*-*]
433 || [istarget i?86-*-*]
434 || [istarget powerpc64*-*-*])
435 && ([istarget *-*-linux*]
436 || [istarget *-*-gnu*]) } {
442 # Compare two files line-by-line. FILE_1 is the actual output and FILE_2
443 # is the expected output. Ignore blank lines in either file.
445 # FILE_2 is a series of regexps, comments and # directives. The directives
449 # Treat the test as a PASS if everything up till this point has
450 # matched. Ignore any remaining lines in either FILE_1 or FILE_2.
453 # Reverse the sense of the test: expect differences to exist.
457 # Skip all lines in FILE_1 until the first that matches REGEXP.
460 # Optionally match REGEXP against line from FILE_1. If the REGEXP
461 # does not match then the next line from FILE_2 is tried.
463 # Other # lines are comments. Regexp lines starting with the `!' character
464 # specify inverse matching (use `\!' for literal matching against a leading
465 # `!'). Skip empty lines in both files.
467 # The first optional argument is a list of regexp substitutions of the form:
469 # EXP1 SUBSPEC1 EXP2 SUBSPEC2 ...
471 # This tells the function to apply each regexp substitution EXPi->SUBSPECi
472 # in order to every line of FILE_2.
474 # Return nonzero if differences exist.
475 proc regexp_diff { file_1 file_2 args } {
483 if { [llength $args] > 0 } {
484 set ref_subst [lindex $args 0]
486 if { [llength $args] > 1 } {
487 perror "Too many arguments to regexp_diff"
491 if [file exists $file_1] then {
492 set file_a [open $file_1 r]
494 perror "$file_1 doesn't exist"
498 if [file exists $file_2] then {
499 set file_b [open $file_2 r]
501 perror "$file_2 doesn't exist"
506 verbose " Regexp-diff'ing: $file_1 $file_2" 2
511 while { [string length $line_a] == 0 } {
512 # Ignore blank line in FILE_1.
513 if { [gets $file_a line_a] == $eof } {
518 while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
519 if { [string match "#pass" $line_b] } {
523 } elseif { [string match "#failif" $line_b] } {
524 send_log "fail if no difference\n"
525 verbose "fail if no difference" 3
527 } elseif { [string match "#..." $line_b] } {
528 if { [gets $file_b line_b] == $eof } {
533 set negated [expr { [string index $line_b 0] == "!" }]
534 set line_bx [string range $line_b $negated end]
535 set n [expr { $negated ? "! " : "" }]
536 # Substitute on the reference.
537 foreach {name value} $ref_subst {
538 regsub -- $name $line_bx $value line_bx
540 verbose "looking for $n\"^$line_bx$\"" 3
541 while { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
542 verbose "skipping \"$line_a\"" 3
543 if { [gets $file_a line_a] == $eof } {
549 } elseif { [string match "#\\?*" $line_b] } {
551 set line_b [string replace $line_b 0 1]
552 set negated [expr { [string index $line_b 0] == "!" }]
553 set line_bx [string range $line_b $negated end]
554 set n [expr { $negated ? "! " : "" }]
555 # Substitute on the reference.
556 foreach {name value} $ref_subst {
557 regsub -- $name $line_bx $value line_bx
559 verbose "optional match for $n\"^$line_bx$\"" 3
560 if { [expr [regexp "^$line_bx$" "$line_a"] != $negated] } {
565 if { [gets $file_b line_b] == $eof } {
573 } elseif { $end_1 && $end_2 } {
575 } elseif { $end_1 } {
576 send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
577 verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
580 } elseif { $end_2 } {
581 send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
582 verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
586 set negated [expr { [string index $line_b 0] == "!" }]
587 set line_bx [string range $line_b $negated end]
588 set n [expr { $negated ? "! " : "" }]
589 set s [expr { $negated ? " " : "" }]
590 # Substitute on the reference.
591 foreach {name value} $ref_subst {
592 regsub -- $name $line_bx $value line_bx
594 verbose "regexp $n\"^$line_bx$\"\nline \"$line_a\"" 3
595 if { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
596 send_log "regexp_diff match failure\n"
597 send_log "regexp $n\"^$line_bx$\"\nline $s\"$line_a\"\n"
598 verbose "regexp_diff match failure\n" 3
604 if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
605 send_log "$file_1 and $file_2 are different lengths\n"
606 verbose "$file_1 and $file_2 are different lengths" 3
610 if { $fail_if_match } {
611 if { $differences == 0 } {
624 # prune_warnings_extra -- delete extra warnings from TEXT.
627 # ld: warning: /lib64/ld-linux-x86-64.so.2: unsupported GNU_PROPERTY_TYPE (5) type : 0xc0010001
628 proc prune_warnings_extra { text } {
630 # Warnings are only pruned from non-experimental code (ie code not
631 # on a release branch). For experimental code we want the warnings
632 # as they indicate that the sources need to be updated to recognise
633 # the new properties.
634 if { "$experimental" == "false" } {
635 # The "\\1" is to try to preserve a "\n" but only if necessary.
636 regsub -all "(^|\n)(\[^\n\]*: warning:\[^\n\]*unsupported GNU_PROPERTY_TYPE\[^\n\]*\n?)+" $text "\\1" text
638 # PR binutils/23898: It is OK to have gaps in build notes.
639 regsub -all "(^|\n)(\[^\n\]*: Warning: Gap in build notes detected from\[^\n\]*\n?)+" $text "\\1" text
640 regsub -all "(^|\n)(\[^\n\]*: warning:\[^\n\]*missing \\.note\\.GNU-stack section\[^\n\]*\n?)+" $text "\\1" text
641 regsub -all "(^|\n)(\[^\n\]*: NOTE: This behaviour is deprecated\[^\n\]*\n?)+" $text "\\1" text
642 regsub -all "(^|\n)(\[^\n\]*: warning:\[^\n\]*has a LOAD segment with RWX permissions\[^\n\]*\n?)+" $text "\\1" text
643 regsub -all "(^|\n)(\[^\n\]*: warning:\[^\n\]*has a TLS segment with execute permission\[^\n\]*\n?)+" $text "\\1" text
647 # This definition is taken from an unreleased version of DejaGnu. Once
648 # that version gets released, and has been out in the world for a few
649 # months at least, it may be safe to delete this copy.
650 if ![string length [info proc prune_warnings]] {
652 # prune_warnings -- delete various system verbosities from TEXT
655 # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
657 # Sites with particular verbose os's may wish to override this in site.exp.
659 proc prune_warnings { text } {
660 # This is from sun4's. Do it for all machines for now.
661 # The "\\1" is to try to preserve a "\n" but only if necessary.
662 regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
663 # It might be tempting to get carried away and delete blank lines, etc.
664 # Just delete *exactly* what we're ask to, and that's it.
665 set text [prune_warnings_extra $text]
668 } elseif { [info procs saved-prune_warnings] == [list] } {
669 rename prune_warnings saved-prune_warnings
670 proc prune_warnings { text } {
671 set text [saved-prune_warnings $text]
672 set text [prune_warnings_extra $text]
677 # run_dump_test FILE (optional:) EXTRA_OPTIONS
679 # Assemble a .s file, then run some utility on it and check the output.
680 # Optionally generate the .s file first by running the compiler.
682 # There should be an assembly language file named FILE.s in the test
683 # suite directory, and a pattern file called FILE.d. run_dump_test
684 # will assemble FILE.s, optionally run objcopy on the object file,
685 # optionally run ld, optionally run another objcopy, optionally run
686 # another tool under test specified by PROG, then run a dump tool like
687 # addr2line, nm, objdump, readelf or size on the object file to produce
688 # textual output, and then analyze that with regexps.
689 # The FILE.d file specifies what program to run, and what to expect in
692 # The FILE.d file begins with zero or more option lines, which specify
693 # flags to pass to the assembler, the program to run to dump the
694 # assembler's output, and the options it wants. The option lines have
699 # OPTION is the name of some option, like "name" or "objdump", and
700 # VALUE is OPTION's value. The valid options are described below.
701 # Whitespace is ignored everywhere, except within VALUE. The option
702 # list ends with the first line that doesn't match the above syntax.
703 # However, a line within the options that begins with a #, but doesn't
704 # have a recognizable option name followed by a colon, is considered a
705 # comment and entirely ignored.
707 # The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of
708 # two-element lists. The first element of each is an option name, and
709 # the second additional arguments to be added on to the end of the
710 # option list as given in FILE.d. (If omitted, no additional options
713 # The interesting options are:
716 # The name of this test, passed to DejaGNU's `pass' and `fail'
717 # commands. If omitted, this defaults to FILE, the root of the
718 # .s and .d files' names.
721 # When assembling, pass FLAGS to the assembler.
722 # If assembling several files, you can pass different assembler
723 # options in the "source" directives. See below.
724 # Multiple instances of this directive tells run_dump_test to run the test
725 # multiple times -- one time with each set of flags provided.
726 # Each instance will run exactly as a file with a single "as" line, it is
727 # not possible to condition any behaviour on which set of "as" flags is
728 # used. That means that the "source" specific options are appended to
729 # the "as" flags for their corresponding files, and any extra processing
730 # (e.g. with "ld" and "objcopy") is repeated for each test.
733 # Link assembled files using FLAGS, in the order of the "source"
734 # directives, when using multiple files.
736 # ld_after_inputfiles: FLAGS
737 # Similar to "ld", but put FLAGS after all input files.
740 # Run the compiler with FLAGS (to which -S is added) to generate assembler
741 # source first. source: must be provided and should consist of .c files.
742 # Source-specific CC flags are not supported.
744 # objcopy_objects: FLAGS
745 # Run objcopy with the specified flags after assembling any source
746 # that has the special marker RUN_OBJCOPY in the source specific
749 # objcopy_linked_file: FLAGS
750 # Run objcopy on the linked file with the specified flags.
751 # This lets you transform the linked file using objcopy, before the
752 # result is analyzed by an analyzer program specified below.
755 # The name of a program under test, to run to modify or analyze the
756 # .o file produced by the assembler. Recognised names are: ar,
757 # elfedit, nm, objcopy, ranlib, strings, and strip.
759 # DUMPPROG: PROGRAM-NAME
760 # The name of the program to run to analyze the file produced
761 # by the assembler or the linker. This can be omitted;
762 # run_dump_test will guess which program to run from which of
763 # the flags options below is present.
770 # Use the specified program to analyze the output file, and pass it
771 # FLAGS, in addition to the output name. Note that they are run
772 # with LC_ALL=C in the environment to give consistent sorting of
773 # symbols. If no FLAGS are needed then you can use:
774 # DUMPPROG: [nm objdump readelf addr2line]
775 # instead, or just pass a flag that happens to be the default.
776 # If objdump is the dump tool and we're not dumping binary, nor
777 # have run ld, then the standard section names (.text, .data and
778 # .bss) are replaced by target ones if any (eg. rx-elf uses "P"
779 # instead of .text). The substition is done for both the
780 # objdump options (eg: "-j .text" is replaced by "-j P") and the
783 # source: SOURCE [FLAGS]
784 # Assemble the file SOURCE.s using the flags in the "as" directive
785 # and the (optional) FLAGS. If omitted, the source defaults to
787 # This is useful if several .d files want to share a .s file.
788 # More than one "source" directive can be given, which is useful
789 # when testing linking.
792 # Match against DUMP.d. If omitted, this defaults to FILE.d. This
793 # is useful if several .d files differ by options only. Options are
794 # always read from FILE.d.
796 # target: GLOB|PROC ...
797 # Run this test only on a specified list of targets. More precisely,
798 # in the space-separated list each glob is passed to "istarget" and
799 # each proc is called as a TCL procedure. List items are interpreted
800 # such that procs are denoted by surrounding square brackets, and any
801 # other items are consired globs. If the call evaluates true for any
802 # of them, the test will be run, otherwise it will be marked
805 # notarget: GLOB|PROC ...
806 # Do not run this test on a specified list of targets. Again, each
807 # glob in the space-separated list is passed to "istarget" and each
808 # proc is called as a TCL procedure, and the test is run if it
809 # evaluates *false* for *all* of them. Otherwise it will be marked
812 # alltargets: GLOB|PROC ...
813 # Run this test on a specified list of targets. Again, each
814 # glob in the space-separated list is passed to "istarget" and each
815 # proc is called as a TCL procedure, and the test is run if it
816 # evaluates *true* for *all* of them. Otherwise it will be marked
819 # skip: GLOB|PROC ...
820 # anyskip: GLOB|PROC ...
821 # noskip: GLOB|PROC ...
822 # These are exactly the same as "notarget", "alltargets" and
823 # "target" respectively, except that they do nothing at all if the
824 # check fails. They should only be used in groups, to construct a
825 # single test which is run on all targets but with variant options
826 # or expected output on some targets. (For example, see
827 # gas/arm/inst.d and gas/arm/wince_inst.d.)
829 # xfail: GLOB|PROC ...
830 # Run this test and it is is expected to fail on a specified list
834 # An error with message matching REGEX must be emitted for the test
835 # to pass. The DUMPPROG, addr2line, nm, objdump, readelf and size
836 # options have no meaning and need not supplied if this is present.
837 # Multiple "error" directives append to the expected error message.
840 # Means the same as 'error', except the regular expression lines
841 # are contains in FILE.
844 # Expect a warning matching REGEX. It is an error to issue
845 # both "error" and "warning". Multiple "warning" directives
846 # append to the expected warning message.
848 # warning_output: FILE
849 # Means the same as 'warning', except the regular expression
850 # lines are contains in FILE.
853 # Adding this option will cause the linker to generate a linker
854 # map file, using the -Map=MAPFILE command line option. If
855 # there is no -Map=MAPFILE in the 'ld: FLAGS' then one will be
856 # added to the linker command line. The contents of the
857 # generated MAPFILE are then compared against the regexp lines
858 # in FILE using `regexp_diff' (see below for details).
861 # Means that the section substitution for objdump is disabled.
863 # Each option may occur at most once unless otherwise mentioned.
865 # After the option lines come regexp lines. run_dump_test calls
866 # regexp_diff to compare the output of the dumping tool against the
869 proc run_dump_test { name {extra_options {}} } {
870 global ADDR2LINE ADDR2LINEFLAGS AS ASFLAGS CC_FOR_TARGET CFLAGS_FOR_TARGET
871 global ELFEDIT ELFEDITFLAGS LD LDFLAGS NM NMFLAGS OBJCOPY OBJCOPYFLAGS
872 global OBJDUMP OBJDUMPFLAGS READELF READELFFLAGS STRIP STRIPFLAGS
873 global SIZE SIZEFLAGS
874 global copyfile env runtests srcdir subdir verbose
875 global DT_RELR_LDFLAGS NO_DT_RELR_LDFLAGS
877 if [string match "*/*" $name] {
879 set name [file tail $name]
881 set file "$srcdir/$subdir/$name"
884 if ![runtest_file_p $runtests $name] then {
888 set opt_array [slurp_options "${file}.d"]
889 if { $opt_array == -1 } {
890 perror "error reading options from $file.d"
891 unresolved $subdir/$name
894 set dumpfile tmpdir/dump.out
899 set opts(DUMPPROG) {}
900 set opts(addr2line) {}
901 set opts(alltargets) {}
905 set as_final_flags {}
906 set as_additional_flags {}
911 set opts(error_output) {}
913 set opts(ld_after_inputfiles) {}
918 set opts(notarget) {}
920 set opts(objcopy_linked_file) {}
921 set opts(objcopy_objects) {}
925 set opts(section_subst) {}
934 set opts(warning_output) {}
938 foreach i [concat $opt_array {{} {}} $extra_options] {
939 set opt_name [lindex $i 0]
940 set opt_val [lindex $i 1]
941 if { $opt_name == "" } {
945 if ![info exists opts($opt_name)] {
946 perror "unknown option $opt_name in file $file.d"
947 unresolved $subdir/$name
951 # Allow more substitutions, including tcl functions, for as, ld,
952 # and cc. Not done in general because extra quoting is needed for glob
953 # args used for example in binutils-all/remove-relocs-04.d.
954 if { $opt_name == "as" || $opt_name == "ld" || $opt_name == "cc" } {
955 set opt_val [subst $opt_val]
957 # Just substitute $srcdir and $subdir
958 regsub -all {\$srcdir} "$opt_val" "$srcdir" opt_val
959 regsub -all {\$subdir} "$opt_val" "$subdir" opt_val
962 switch -- $opt_name {
973 # Move any source-specific as-flags to a separate list to
974 # simplify processing.
975 if { [llength $opt_val] > 1 } {
976 lappend asflags [lrange $opt_val 1 end]
977 set opt_val [lindex $opt_val 0]
982 # Create the object file name based on nothing but the source
985 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]].o]
986 # But, sometimes, we have the exact same source filename in
987 # different directories (foo/src.s bar/src.s) which would lead
988 # us to try and create two src.o files. We detect this
989 # conflict here, and instead create src.o and src1.o.
991 while { [lsearch $objfile_names $new_objfile] != -1 } {
994 [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]]${j}.o]
996 lappend objfile_names $new_objfile
1000 && [string length $opts($opt_name)]
1001 && $opt_name != "as" } {
1002 perror "option $opt_name multiply set in $file.d"
1003 unresolved $subdir/$name
1007 # A single "#ld:" with no options should do the right thing.
1008 if { $opt_name == "ld" } {
1011 # Likewise objcopy_linked_file.
1012 if { $opt_name == "objcopy_linked_file" } {
1018 # Append differently whether it's a message (without space) or
1019 # an option or list (with space).
1020 switch -- $opt_name {
1023 append opts($opt_name) $opt_val
1027 set as_additional_flags [concat $as_additional_flags $opt_val]
1029 lappend opts(as) $opt_val
1033 set opts($opt_name) [concat $opts($opt_name) $opt_val]
1038 # Ensure there is something in $opts(as) for the foreach loop below.
1039 if { [llength $opts(as)] == 0 } {
1040 set opts(as) [list " "]
1042 foreach x $opts(as) {
1043 if { [string length $x] && [string length $as_additional_flags] } {
1046 append x $as_additional_flags
1047 regsub {\[big_or_little_endian\]} $x \
1048 [big_or_little_endian] x
1049 lappend as_final_flags $x
1052 regsub {\[big_or_little_endian\]} $opts(ld) \
1053 [big_or_little_endian] opts(ld)
1055 if { $opts(name) == "" } {
1056 set testname "$subdir/$name"
1058 set testname $opts(name)
1062 foreach opt { warning error warning_output error_output } {
1063 if { $opts($opt) != "" } {
1065 perror "$testname: bad mix of warning and error test directives"
1066 unresolved $testname
1073 # Decide early whether we should run the test for this target.
1074 if { [llength $opts(noskip)] > 0 } {
1076 foreach targ $opts(noskip) {
1077 if [match_target $targ] {
1082 if { $targmatch == 0 } {
1086 foreach targ $opts(anyskip) {
1087 if ![match_target $targ] {
1091 foreach targ $opts(skip) {
1092 if [match_target $targ] {
1096 if { [llength $opts(target)] > 0 } {
1098 foreach targ $opts(target) {
1099 if [match_target $targ] {
1104 if { $targmatch == 0 } {
1105 unsupported $testname
1109 foreach targ $opts(alltargets) {
1110 if ![match_target $targ] {
1111 unsupported $testname
1115 foreach targ $opts(notarget) {
1116 if [match_target $targ] {
1117 unsupported $testname
1123 # It's meaningless to require an output-testing method when we
1125 if { $opts(error) == "" && $opts(error_output) == "" } {
1126 if { $opts(DUMPPROG) != "" } {
1127 switch -- $opts(DUMPPROG) {
1128 addr2line { set dumpprogram addr2line }
1129 nm { set dumpprogram nm }
1130 objdump { set dumpprogram objdump }
1131 readelf { set dumpprogram readelf }
1132 size { set dumpprogram size }
1134 perror "unrecognized DUMPPROG option $opts(DUMPPROG) in $file.d"
1135 unresolved $testname
1140 # Guess which program to run, by seeing which option was specified.
1141 foreach p {addr2line nm objdump readelf size} {
1142 if {$opts($p) != ""} {
1143 if {$dumpprogram != ""} {
1144 perror "ambiguous dump program in $file.d"
1145 unresolved $testname
1153 if { $dumpprogram == "" && $opts(map) == "" && !$err_warn } {
1154 perror "dump program unspecified in $file.d"
1155 unresolved $testname
1160 # Possibly compile some of the inputs, and build up a replacement
1161 # for opts(source) with the output .s names substituted in as we go.
1162 # Set the .s names from the objfile_names to take advantage of the
1163 # uniquification that happened earlier.
1164 if { $opts(cc) != ""} {
1168 foreach cfile $opts(source) ofile $objfile_names {
1169 if { [file extension $cfile] != ".c" } {
1170 lappend new_source "$cfile"
1174 if { ! [string match "./*" $cfile] } {
1175 set cfile "$srcdir/$subdir/$cfile"
1177 # ofile is never absolute, so this always works to protect sfile
1178 # from later absolutization.
1179 set sfile "./[file rootname $ofile].s"
1180 set cmd "$CC_FOR_TARGET $CFLAGS_FOR_TARGET -S $opts(cc) -o $sfile $cfile"
1182 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1183 remote_upload host "dump.tmp"
1184 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1185 remote_file host delete "dump.tmp"
1186 remote_file build delete "dump.tmp"
1187 lappend new_source "$sfile"
1188 set cmdret [lindex $cmdret 0]
1190 regsub "\n$" $comp_output "" comp_output
1191 if { $cmdret != 0} {
1192 send_log "compilation of $cfile failed, exit status $cmdret with <$comp_output>"
1193 # Should this be 'unresolved', or is that too silent?
1198 set opts(source) $new_source
1201 if { $opts(source) == "" } {
1202 set sourcefiles [list ${file}.s]
1203 set asflags [list ""]
1204 set objfile_names [list tmpdir/[file tail ${file}].o]
1207 foreach sf $opts(source) {
1208 if { [string match "./*" $sf] } {
1209 lappend sourcefiles "$sf"
1211 lappend sourcefiles "$srcdir/$subdir/$sf"
1216 if { $opts(dump) == "" } {
1219 set dfile $srcdir/$subdir/$opts(dump)
1222 # Time to setup xfailures.
1223 foreach targ $opts(xfail) {
1224 if [match_target $targ] {
1230 foreach as_flags $as_final_flags {
1231 # Assemble each file.
1233 for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
1234 set sourcefile [lindex $sourcefiles $i]
1235 set sourceasflags [lindex $asflags $i]
1236 set run_objcopy_objects 0
1238 if { [string match "*RUN_OBJCOPY*" $sourceasflags] } {
1239 set run_objcopy_objects 1
1241 regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags
1243 set objfile [lindex $objfile_names $i]
1244 catch "exec rm -f $objfile" exec_output
1245 lappend objfiles $objfile
1247 if { $as_flags == "binary" } {
1248 while {[file type $sourcefile] eq "link"} {
1249 set newfile [file readlink $sourcefile]
1250 if {[string index $newfile 0] ne "/"} {
1251 set newfile [file dirname $sourcefile]/$newfile
1253 set sourcefile $newfile
1255 set newfile [remote_download host $sourcefile $objfile]
1257 if { $newfile == "" } {
1261 if { [istarget "hppa*-*-*"] \
1262 && ![istarget "*-*-linux*"] \
1263 && ![istarget "*-*-netbsd*" ] } {
1264 set cmd "sed -e 's/^\[ \]*\.comm \\(\[^,\]*\\),\\(.*\\)/\\1 .comm \\2/' < $sourcefile > tmpdir/asm.s"
1266 set cmdret [remote_exec host [concat sh -c [list "$cmd"]]]
1267 set cmdret [lindex $cmdret 0]
1268 if { $cmdret != 0 } {
1269 perror "sed failure"
1270 unresolved $testname
1273 set sourcefile tmpdir/asm.s
1275 set cmd "$AS $ASFLAGS $as_flags $sourceasflags -o $objfile $sourcefile"
1278 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1279 remote_upload host "dump.tmp"
1280 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1281 remote_file host delete "dump.tmp"
1282 remote_file build delete "dump.tmp"
1283 set cmdret [lindex $cmdret 0]
1285 if { $cmdret == 0 && $run_objcopy_objects } {
1286 set cmd "$OBJCOPY $opts(objcopy_objects) $objfile"
1289 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \
1290 "" "/dev/null" "dump.tmp"]
1291 remote_upload host "dump.tmp"
1292 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1293 remote_file host delete "dump.tmp"
1294 remote_file build delete "dump.tmp"
1295 set cmdret [lindex $cmdret 0]
1299 # Perhaps link the file(s).
1300 if { $cmdret == 0 && $run_ld } {
1301 set objfile "tmpdir/dump"
1302 catch "exec rm -f $objfile" exec_output
1307 if [check_relro_support] {
1308 set ld_extra_opt "-z norelro"
1311 # Add -L$srcdir/$subdir so that the linker command can use
1312 # linker scripts in the source directory.
1313 set cmd "$LD $ld_extra_opt $LDFLAGS -L$srcdir/$subdir \
1314 $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
1316 # If needed then check for, or add a -Map option.
1318 if { $opts(map) != "" } then {
1319 if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then {
1320 # Found existing mapfile option
1321 verbose -log "Existing mapfile '$mapfile' found"
1323 # No mapfile option.
1324 set mapfile "tmpdir/dump.map"
1325 verbose -log "Adding mapfile '$mapfile'"
1326 set cmd "$cmd -Map=$mapfile"
1331 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1332 remote_upload host "dump.tmp"
1333 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1334 remote_file host delete "dump.tmp"
1335 remote_file build delete "dump.tmp"
1336 set cmdret [lindex $cmdret 0]
1338 if { $cmdret == 0 && $run_objcopy } {
1340 set objfile "tmpdir/dump1"
1341 remote_file host delete $objfile
1343 # Note that we don't use OBJCOPYFLAGS here; any flags must be
1344 # explicitly specified.
1345 set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
1348 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"]
1349 remote_upload host "dump.tmp"
1350 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1351 remote_file host delete "dump.tmp"
1352 remote_file build delete "dump.tmp"
1353 set cmdret [lindex $cmdret 0]
1356 set objfile [lindex $objfiles 0]
1359 if { $cmdret == 0 && $opts(PROG) != "" } {
1360 set destopt ${copyfile}.o
1361 switch -- $opts(PROG) {
1362 ar { set program ar }
1367 nm { set program nm }
1368 objcopy { set program objcopy }
1369 ranlib { set program ranlib }
1370 strings { set program strings }
1373 set destopt "-o $destopt"
1376 perror "unrecognized PROG option $opts(PROG) in $file.d"
1377 unresolved $testname
1382 set progopts1 $opts($program)
1383 eval set progopts \$[string toupper $program]FLAGS
1384 eval set binary \$[string toupper $program]
1386 if { ![is_remote host] && [which $binary] == 0 } {
1391 verbose "running $binary $progopts $progopts1" 3
1392 set cmd "$binary $progopts $progopts1 $objfile $destopt"
1394 # Ensure consistent sorting of symbols
1395 if {[info exists env(LC_ALL)]} {
1396 set old_lc_all $env(LC_ALL)
1400 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"]
1401 set cmdret [lindex $cmdret 0]
1402 remote_upload host "dump.tmp"
1403 append comp_output [prune_warnings [file_contents "dump.tmp"]]
1404 remote_file host delete "dump.tmp"
1405 remote_file build delete "dump.tmp"
1406 if {[info exists old_lc_all]} {
1407 set env(LC_ALL) $old_lc_all
1411 if { $destopt != "" } {
1412 set objfile ${copyfile}.o
1416 set want_out(source) ""
1417 set want_out(terminal) 0
1419 if { $opts(error) != "" || $opts(error_output) != "" } {
1420 set want_out(terminal) 1
1423 if { $opts(error) != "" || $opts(warning) != "" } {
1424 set want_out(source) "regex"
1425 if { $opts(error) != "" } {
1426 set want_out(regex) $opts(error)
1428 set want_out(regex) $opts(warning)
1431 set want_out(source) "file"
1432 if { $opts(error_output) != "" } {
1433 set want_out(file) $opts(error_output)
1435 set want_out(file) $opts(warning_output)
1440 regsub "\n$" $comp_output "" comp_output
1441 if { $cmdret != 0 || $comp_output != "" || $want_out(source) != "" } {
1442 set exitstat "succeeded"
1443 if { $cmdret != 0 } { set exitstat "failed" }
1445 if { $want_out(source) == "regex" } {
1446 verbose -log "$exitstat with: <$comp_output>, expected: <$want_out(regex)>"
1447 } elseif { $want_out(source) == "file" } {
1448 verbose -log "$exitstat with: <$comp_output>, expected in file $want_out(file)"
1449 set_file_contents "tmpdir/ld.messages" "$comp_output"
1451 verbose -log "$exitstat with: <$comp_output>, no expected output"
1454 if { (($want_out(source) == "") == ($comp_output == "")) \
1455 && (($cmdret == 0) == ($want_out(terminal) == 0)) \
1456 && ((($want_out(source) == "regex") \
1457 && [regexp -- $want_out(regex) $comp_output]) \
1458 || (($want_out(source) == "file") \
1459 && (![regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$want_out(file)"]))) } {
1460 # We have the expected output.
1461 if { $want_out(terminal) || $dumpprogram == "" } {
1471 # We must not have expected failure if we get here.
1472 if { $want_out(terminal) } {
1477 if { $opts(map) != "" } then {
1478 # Check the map file matches.
1479 set map_pattern_file $srcdir/$subdir/$opts(map)
1480 verbose -log "Compare '$mapfile' against '$map_pattern_file'"
1481 if { [regexp_diff $mapfile $map_pattern_file] } then {
1482 fail "$testname (map file check)"
1484 pass "$testname (map file check)"
1487 if { $dumpprogram == "" } then {
1492 set progopts1 $opts($dumpprogram)
1493 eval set progopts \$[string toupper $dumpprogram]FLAGS
1494 eval set binary \$[string toupper $dumpprogram]
1496 if { ![is_remote host] && [which $binary] == 0 } {
1501 # For objdump of gas output, automatically translate standard section names
1503 if { !$run_ld && $dumpprogram == "objdump" \
1504 && $opts(section_subst) != "no" \
1505 && ![string match "*-b binary*" $progopts1] } {
1506 set sect_names [get_standard_section_names]
1507 if { $sect_names != ""} {
1508 regsub -- "\\.text" $progopts1 "[lindex $sect_names 0]" progopts1
1509 regsub -- "\\.data" $progopts1 "[lindex $sect_names 1]" progopts1
1510 regsub -- "\\.bss" $progopts1 "[lindex $sect_names 2]" progopts1
1514 if { $progopts1 == "" } { set $progopts1 "-r" }
1515 verbose "running $binary $progopts $progopts1" 3
1517 set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
1519 # Ensure consistent sorting of symbols
1520 if {[info exists env(LC_ALL)]} {
1521 set old_lc_all $env(LC_ALL)
1525 set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"]
1526 set cmdret [lindex $cmdret 0]
1527 remote_upload host "dump.tmp"
1528 set comp_output [prune_warnings [file_contents "dump.tmp"]]
1529 remote_file host delete "dump.tmp"
1530 remote_file build delete "dump.tmp"
1531 if {[info exists old_lc_all]} {
1532 set env(LC_ALL) $old_lc_all
1536 if { $cmdret != 0 || $comp_output != "" } {
1537 send_log "exited abnormally with $cmdret, output:$comp_output\n"
1542 if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
1544 # Create the substition list for objdump output.
1546 if { $sect_names != "" } {
1547 set regexp_subst [list "\\\\?\\.text" [lindex $sect_names 0] \
1548 "\\\\?\\.data" [lindex $sect_names 1] \
1549 "\\\\?\\.bss" [lindex $sect_names 2] ]
1552 if { [regexp_diff $dumpfile "${dfile}" $regexp_subst] } then {
1554 if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
1562 proc slurp_options { file } {
1563 # If options_regsub(foo) is set to {a b}, then the contents of a
1564 # "#foo:" line will have regsub -all applied to replace a with b.
1565 global options_regsub
1567 if [catch { set f [open $file r] } x] {
1568 #perror "couldn't open `$file': $x"
1573 # whitespace expression
1576 # whitespace is ignored anywhere except within the options list;
1577 # option names are alphanumeric plus underscore.
1578 set pat "^#${ws}(\[a-zA-Z0-9_\]*)$ws:${ws}(.*)$ws\$"
1579 while { [gets $f line] != -1 } {
1580 set line [string trim $line]
1581 # Whitespace here is space-tab.
1582 if [regexp $pat $line xxx opt_name opt_val] {
1584 if [info exists options_regsub($opt_name)] {
1585 set subst $options_regsub($opt_name)
1586 regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \
1589 lappend opt_array [list $opt_name $opt_val]
1590 } elseif {![regexp "^#" $line ]} {
1598 proc file_contents { filename } {
1599 set file [open $filename r]
1600 set contents [read $file]
1605 proc set_file_contents { filename contents } {
1606 set file [open $filename w]
1607 puts $file "$contents"
1611 # Look for big-endian or little-endian switches in the multlib
1612 # options and translate these into a -EB or -EL switch. Note
1613 # we cannot rely upon proc process_multilib_options to do this
1614 # for us because for some targets the compiler does not support
1615 # -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
1616 # the site.exp file will include the switch "-mbig-endian"
1617 # (rather than "big-endian") which is not detected by proc
1618 # process_multilib_options.
1620 proc big_or_little_endian {} {
1622 if [board_info [target_info name] exists multilib_flags] {
1623 set tmp_flags " [board_info [target_info name] multilib_flags]"
1625 foreach x $tmp_flags {
1655 # Internal procedure: return the names of the standard sections
1657 proc get_standard_section_names {} {
1658 if [istarget "rx-*-elf"] {
1659 return { "P" "D_1" "B_1" }
1661 if { [istarget "alpha*-*-*vms*"] || [is_som_format] } {
1662 return { {\$CODE\$} {\$DATA\$} {\$BSS\$} }