From 8ffb70eb57f527817840ff33982c085b0bec86bc Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 13 Sep 2018 14:45:47 +0930 Subject: [PATCH] Consolidate run_dump_test This merges the three versions of run_dump_test. Improved warning handling versus the old gas version shows up a number of tests that need their disassembly updating: arm-linuxeabi +FAIL: ARM v1 instructions arm-linuxeabi +FAIL: Accepted v8-a with ARMv8.1 AdvSIMD. arm-linuxeabi +FAIL: bl local instructions for v4t. arm-linuxeabi +FAIL: UDF and some that now fail due to detecting assembly warnings: h8300-elf +FAIL: binutils-all/strip-13 h8300-elf +FAIL: binutils-all/strip-14 h8300-elf +FAIL: binutils-all/strip-15 I've generally kept the union of all run_dump_test features, except that the ld target aliases "cfi" and "shared" have disappeared, as has the binutils substitution of $srcdir as $scrdir/$subdir. binutils/ * testsuite/binutils-all/add-symbol.d: Add "section_subst: no". * testsuite/binutils-all/elfedit.exp: Don't set tempfile or copyfile. * testsuite/binutils-all/symbols-1.d, * testsuite/binutils-all/symbols-2.d, * testsuite/binutils-all/symbols-3.d, * testsuite/binutils-all/symbols-4.d: Quote '*' and '!'. * testsuite/binutils-all/add-empty-section.d, * testsuite/binutils-all/add-section.d, * testsuite/binutils-all/elfedit.exp, * testsuite/binutils-all/note-1.d, * testsuite/binutils-all/pr23633.d: Add $subdir after $srcdir. * testsuite/config/default.exp (AS, ASFLAGS): Define. * testsuite/config/hppa.sed: Handle all common symbols. * testsuite/lib/binutils-common.exp (run_dump_test): New proc, merged from three other versions. (slurp_options, file_contents, set_file_contents): Likewise. (big_or_little_endian, get_standard_section_names): Likewise. * testsuite/lib/utils-lib.exp (run_dump_test): Delete. (slurp_options, proc file_contents): Delete. (get_standard_section_names): Delete. gas/ * testsuite/config/default.exp: Make tmpdir. * testsuite/lib/gas-defs.exp (run_dump_test): Delete. (get_standard_section_names, slurp_options): Delete. ld/ * testsuite/ld-d10v/reloc-007.d, * testsuite/ld-d10v/reloc-008.d, * testsuite/ld-d10v/reloc-015.d, * testsuite/ld-d10v/reloc-016.d: Remove "error:". * testsuite/ld-elf/eh-frame-hdr.d, * testsuite/ld-elf/eh5.d, * testsuite/ld-gc/personality.d: Replace "cfi" and "shared" in target list with appropriate proc. * testsuite/ld-elf/frame.exp: Use check_shared_lib_support rather than "istarget shared". * testsuite/lib/ld-lib.exp (proc big_or_little_endian): Delete. (run_dump_test, slurp_options, file_contents): Delete. (set_file_contents, istarget): Delete. --- binutils/ChangeLog | 23 + .../binutils-all/add-empty-section.d | 2 +- binutils/testsuite/binutils-all/add-section.d | 2 +- binutils/testsuite/binutils-all/add-symbol.d | 1 + binutils/testsuite/binutils-all/elfedit.exp | 8 - binutils/testsuite/binutils-all/note-1.d | 2 +- binutils/testsuite/binutils-all/pr23633.d | 2 +- binutils/testsuite/binutils-all/symbols-1.d | 2 +- binutils/testsuite/binutils-all/symbols-2.d | 2 +- binutils/testsuite/binutils-all/symbols-3.d | 2 +- binutils/testsuite/binutils-all/symbols-4.d | 2 +- binutils/testsuite/config/default.exp | 7 + binutils/testsuite/config/hppa.sed | 4 +- binutils/testsuite/lib/binutils-common.exp | 890 ++++++++++++++++++ binutils/testsuite/lib/utils-lib.exp | 561 ----------- gas/ChangeLog | 6 + gas/testsuite/config/default.exp | 2 + gas/testsuite/lib/gas-defs.exp | 496 ---------- ld/ChangeLog | 16 + ld/testsuite/ld-d10v/reloc-007.d | 1 - ld/testsuite/ld-d10v/reloc-008.d | 1 - ld/testsuite/ld-d10v/reloc-015.d | 1 - ld/testsuite/ld-d10v/reloc-016.d | 1 - ld/testsuite/ld-elf/eh-frame-hdr.d | 2 +- ld/testsuite/ld-elf/eh5.d | 2 +- ld/testsuite/ld-elf/frame.exp | 2 +- ld/testsuite/ld-gc/personality.d | 2 +- ld/testsuite/lib/ld-lib.exp | 790 ---------------- 28 files changed, 959 insertions(+), 1873 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 4dd3d35de5d..d5c315d9eb9 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,26 @@ +2018-09-15 Alan Modra + + * testsuite/binutils-all/add-symbol.d: Add "section_subst: no". + * testsuite/binutils-all/elfedit.exp: Don't set tempfile or copyfile. + * testsuite/binutils-all/symbols-1.d, + * testsuite/binutils-all/symbols-2.d, + * testsuite/binutils-all/symbols-3.d, + * testsuite/binutils-all/symbols-4.d: Quote '*' and '!'. + * testsuite/binutils-all/add-empty-section.d, + * testsuite/binutils-all/add-section.d, + * testsuite/binutils-all/elfedit.exp, + * testsuite/binutils-all/note-1.d, + * testsuite/binutils-all/pr23633.d: Add $subdir after $srcdir. + * testsuite/config/default.exp (AS, ASFLAGS): Define. + * testsuite/config/hppa.sed: Handle all common symbols. + * testsuite/lib/binutils-common.exp (run_dump_test): New proc, + merged from three other versions. + (slurp_options, file_contents, set_file_contents): Likewise. + (big_or_little_endian, get_standard_section_names): Likewise. + * testsuite/lib/utils-lib.exp (run_dump_test): Delete. + (slurp_options, proc file_contents): Delete. + (get_standard_section_names): Delete. + 2018-09-15 Alan Modra * testsuite/binutils-all/copy-2.d, diff --git a/binutils/testsuite/binutils-all/add-empty-section.d b/binutils/testsuite/binutils-all/add-empty-section.d index c9162a505c7..ecb6a88dbe0 100644 --- a/binutils/testsuite/binutils-all/add-empty-section.d +++ b/binutils/testsuite/binutils-all/add-empty-section.d @@ -1,7 +1,7 @@ #PROG: objcopy #name: objcopy add-empty-section #source: empty.s -#objcopy: --add-section NEW=$srcdir/empty-file +#objcopy: --add-section NEW=$srcdir/$subdir/empty-file #readelf: -S --wide #... diff --git a/binutils/testsuite/binutils-all/add-section.d b/binutils/testsuite/binutils-all/add-section.d index 37a24cf5d25..d3d43d7f525 100644 --- a/binutils/testsuite/binutils-all/add-section.d +++ b/binutils/testsuite/binutils-all/add-section.d @@ -1,7 +1,7 @@ #PROG: objcopy #name: objcopy add-section #source: empty.s -#objcopy: --add-section NEW=$srcdir/empty.s +#objcopy: --add-section NEW=$srcdir/$subdir/empty.s #objdump: -s -j NEW .*: +file format .* diff --git a/binutils/testsuite/binutils-all/add-symbol.d b/binutils/testsuite/binutils-all/add-symbol.d index b4eed09869d..4c1166c083e 100644 --- a/binutils/testsuite/binutils-all/add-symbol.d +++ b/binutils/testsuite/binutils-all/add-symbol.d @@ -3,6 +3,7 @@ #source: symbols.s #objcopy: --add-symbol NEW=0x1234 --add-symbol NEW_DATA=.data:0x4321,local #objdump: --syms +#section_subst: no .*: +file format .* diff --git a/binutils/testsuite/binutils-all/elfedit.exp b/binutils/testsuite/binutils-all/elfedit.exp index 5f99fdd44f7..60c56075bcb 100644 --- a/binutils/testsuite/binutils-all/elfedit.exp +++ b/binutils/testsuite/binutils-all/elfedit.exp @@ -20,14 +20,6 @@ if ![is_elf_format] { return } -if ![is_remote host] { - set tempfile tmpdir/bintest.o - set copyfile tmpdir/bintest -} else { - set tempfile [remote_download host tmpdir/bintest.o] - set copyfile bintest -} - run_dump_test "elfedit-1" run_dump_test "elfedit-2" run_dump_test "elfedit-3" diff --git a/binutils/testsuite/binutils-all/note-1.d b/binutils/testsuite/binutils-all/note-1.d index c3dee97f60b..89cbfb0e505 100644 --- a/binutils/testsuite/binutils-all/note-1.d +++ b/binutils/testsuite/binutils-all/note-1.d @@ -1,6 +1,6 @@ #PROG: objcopy #readelf: -S --wide -#objcopy: --add-section .note=$srcdir/note-1.d +#objcopy: --add-section .note=$srcdir/$subdir/note-1.d #name: add notes section #source: copytest.s #notarget: h8300-*-* diff --git a/binutils/testsuite/binutils-all/pr23633.d b/binutils/testsuite/binutils-all/pr23633.d index efe7938e663..39677f22495 100644 --- a/binutils/testsuite/binutils-all/pr23633.d +++ b/binutils/testsuite/binutils-all/pr23633.d @@ -1,6 +1,6 @@ #source: pr23633.s #PROG: objcopy -#objcopy: -S --keep-symbols=$srcdir/pr23633.list +#objcopy: -S --keep-symbols=$srcdir/$subdir/pr23633.list #objdump: -s #... diff --git a/binutils/testsuite/binutils-all/symbols-1.d b/binutils/testsuite/binutils-all/symbols-1.d index bfcd6aa1bfd..f73adcbaf3a 100644 --- a/binutils/testsuite/binutils-all/symbols-1.d +++ b/binutils/testsuite/binutils-all/symbols-1.d @@ -1,6 +1,6 @@ #name: localize 'fo*' but not 'foo' #PROG: objcopy -#objcopy: -w -L !foo -L fo* +#objcopy: -w -L \!foo -L fo\* #source: symbols.s #nm: -n diff --git a/binutils/testsuite/binutils-all/symbols-2.d b/binutils/testsuite/binutils-all/symbols-2.d index b9fd9073876..da38ff12551 100644 --- a/binutils/testsuite/binutils-all/symbols-2.d +++ b/binutils/testsuite/binutils-all/symbols-2.d @@ -1,6 +1,6 @@ #name: weaken 'fo*' but not 'foo' #PROG: objcopy -#objcopy: -w -W !foo -W fo* +#objcopy: -w -W \!foo -W fo\* #source: symbols.s #nm: -n diff --git a/binutils/testsuite/binutils-all/symbols-3.d b/binutils/testsuite/binutils-all/symbols-3.d index d415e981f86..ffe34001db6 100644 --- a/binutils/testsuite/binutils-all/symbols-3.d +++ b/binutils/testsuite/binutils-all/symbols-3.d @@ -1,6 +1,6 @@ #name: weaken 'fo*' but not 'foo', localize foo. #PROG: objcopy -#objcopy: -w -W !foo -W fo* -L foo +#objcopy: -w -W \!foo -W fo\* -L foo #source: symbols.s #nm: -n diff --git a/binutils/testsuite/binutils-all/symbols-4.d b/binutils/testsuite/binutils-all/symbols-4.d index 6dd2900efc2..0391c7c89d6 100644 --- a/binutils/testsuite/binutils-all/symbols-4.d +++ b/binutils/testsuite/binutils-all/symbols-4.d @@ -1,6 +1,6 @@ #name: weaken '*' but not 'foo' or 'bar' #PROG: objcopy -#objcopy: -w -W !foo -W !bar -W * +#objcopy: -w -W \!foo -W \!bar -W \* #source: symbols.s #nm: -n diff --git a/binutils/testsuite/config/default.exp b/binutils/testsuite/config/default.exp index c5acd46e8fe..6c55be66f55 100644 --- a/binutils/testsuite/config/default.exp +++ b/binutils/testsuite/config/default.exp @@ -21,6 +21,13 @@ load_lib utils-lib.exp +if ![info exists AS] then { + set AS [findfile $base_dir/../gas/as-new $base_dir/../gas/as-new [transform as]] +} +if ![info exists ASFLAGS] then { + set ASFLAGS "" +} + if ![info exists NM] then { set NM [findfile $base_dir/nm-new $base_dir/nm-new [transform nm]] } diff --git a/binutils/testsuite/config/hppa.sed b/binutils/testsuite/config/hppa.sed index 5b1b808f6ba..f21c42237ea 100644 --- a/binutils/testsuite/config/hppa.sed +++ b/binutils/testsuite/config/hppa.sed @@ -1,4 +1,4 @@ s/# Old OSF sed blows up if you have a sed command starting with "#"// s/# Avoid it by putting the comments within real sed commands.// -s/# Fix the definition of common_symbol to be correct for the PA assemblers.// -s/ \.comm common_symbol,4/common_symbol .comm 4/ +s/# Fix .comm syntax to be correct for the PA assemblers.// +s/^[ ]*\.comm \([^,]*\),\(.*\)/\1 .comm \2/ diff --git a/binutils/testsuite/lib/binutils-common.exp b/binutils/testsuite/lib/binutils-common.exp index bac140774b0..4aa5c7c9791 100644 --- a/binutils/testsuite/lib/binutils-common.exp +++ b/binutils/testsuite/lib/binutils-common.exp @@ -444,3 +444,893 @@ if ![string length [info proc prune_warnings]] { return $text } } + +# run_dump_test FILE (optional:) EXTRA_OPTIONS +# +# Assemble a .s file, then run some utility on it and check the output. +# +# There should be an assembly language file named FILE.s in the test +# suite directory, and a pattern file called FILE.d. run_dump_test +# will assemble FILE.s, optionally run objcopy on the object file, +# optionally run ld, optionally run another objcopy, optionally run +# another tool under test specified by PROG, then run a dump tool like +# addr2line, nm, objdump, readelf or size on the object file to produce +# textual output, and then analyze that with regexps. +# The FILE.d file specifies what program to run, and what to expect in +# its output. +# +# The FILE.d file begins with zero or more option lines, which specify +# flags to pass to the assembler, the program to run to dump the +# assembler's output, and the options it wants. The option lines have +# the syntax: +# +# # OPTION: VALUE +# +# OPTION is the name of some option, like "name" or "objdump", and +# VALUE is OPTION's value. The valid options are described below. +# Whitespace is ignored everywhere, except within VALUE. The option +# list ends with the first line that doesn't match the above syntax. +# However, a line within the options that begins with a #, but doesn't +# have a recognizable option name followed by a colon, is considered a +# comment and entirely ignored. +# +# The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of +# two-element lists. The first element of each is an option name, and +# the second additional arguments to be added on to the end of the +# option list as given in FILE.d. (If omitted, no additional options +# are added.) +# +# The interesting options are: +# +# name: TEST-NAME +# The name of this test, passed to DejaGNU's `pass' and `fail' +# commands. If omitted, this defaults to FILE, the root of the +# .s and .d files' names. +# +# as: FLAGS +# When assembling, pass FLAGS to the assembler. +# If assembling several files, you can pass different assembler +# options in the "source" directives. See below. +# +# ld: FLAGS +# Link assembled files using FLAGS, in the order of the "source" +# directives, when using multiple files. +# +# ld_after_inputfiles: FLAGS +# Similar to "ld", but put FLAGS after all input files. +# +# objcopy_objects: FLAGS +# Run objcopy with the specified flags after assembling any source +# that has the special marker RUN_OBJCOPY in the source specific +# flags. +# +# objcopy_linked_file: FLAGS +# Run objcopy on the linked file with the specified flags. +# This lets you transform the linked file using objcopy, before the +# result is analyzed by an analyzer program specified below. +# +# PROG: PROGRAM-NAME +# The name of a program under test, to run to modify or analyze the +# .o file produced by the assembler. Recognised names are: ar, +# elfedit, nm, objcopy, ranlib, strings, and strip. +# +# DUMPPROG: PROGRAM-NAME +# The name of the program to run to analyze the file produced +# by the assembler or the linker. This can be omitted; +# run_dump_test will guess which program to run from which of +# the flags options below is present. +# +# addr2line: FLAGS +# nm: FLAGS +# objdump: FLAGS +# readelf: FLAGS +# size: FLAGS +# Use the specified program to analyze the output file, and pass it +# FLAGS, in addition to the output name. Note that they are run +# with LC_ALL=C in the environment to give consistent sorting of +# symbols. If no FLAGS are needed then you can use: +# DUMPPROG: [nm objdump readelf addr2line] +# instead, or just pass a flag that happens to be the default. +# If objdump is the dump tool and we're not dumping binary, nor +# have run ld, then the standard section names (.text, .data and +# .bss) are replaced by target ones if any (eg. rx-elf uses "P" +# instead of .text). The substition is done for both the +# objdump options (eg: "-j .text" is replaced by "-j P") and the +# reference file. +# +# source: SOURCE [FLAGS] +# Assemble the file SOURCE.s using the flags in the "as" directive +# and the (optional) FLAGS. If omitted, the source defaults to +# FILE.s. +# This is useful if several .d files want to share a .s file. +# More than one "source" directive can be given, which is useful +# when testing linking. +# +# dump: DUMP +# Match against DUMP.d. If omitted, this defaults to FILE.d. This +# is useful if several .d files differ by options only. Options are +# always read from FILE.d. +# +# target: GLOB|PROC ... +# Run this test only on a specified list of targets. More precisely, +# in the space-separated list each glob is passed to "istarget" and +# each proc is called as a TCL procedure. List items are interpreted +# such that procs are denoted by surrounding square brackets, and any +# other items are consired globs. If the call evaluates true for any +# of them, the test will be run, otherwise it will be marked +# unsupported. +# +# notarget: GLOB|PROC ... +# Do not run this test on a specified list of targets. Again, each +# glob in the space-separated list is passed to "istarget" and each +# proc is called as a TCL procedure, and the test is run if it +# evaluates *false* for *all* of them. Otherwise it will be marked +# unsupported. +# +# alltargets: GLOB|PROC ... +# Run this test on a specified list of targets. Again, each +# glob in the space-separated list is passed to "istarget" and each +# proc is called as a TCL procedure, and the test is run if it +# evaluates *true* for *all* of them. Otherwise it will be marked +# unsupported. +# +# skip: GLOB|PROC ... +# anyskip: GLOB|PROC ... +# noskip: GLOB|PROC ... +# These are exactly the same as "notarget", "alltargets" and +# "target" respectively, except that they do nothing at all if the +# check fails. They should only be used in groups, to construct a +# single test which is run on all targets but with variant options +# or expected output on some targets. (For example, see +# gas/arm/inst.d and gas/arm/wince_inst.d.) +# +# xfail: GLOB|PROC ... +# Run this test and it is is expected to fail on a specified list +# of targets. +# +# error: REGEX +# An error with message matching REGEX must be emitted for the test +# to pass. The DUMPPROG, addr2line, nm, objdump, readelf and size +# options have no meaning and need not supplied if this is present. +# Multiple "error" directives append to the expected error message. +# +# error_output: FILE +# Means the same as 'error', except the regular expression lines +# are contains in FILE. +# +# warning: REGEX +# Expect a warning matching REGEX. It is an error to issue +# both "error" and "warning". Multiple "warning" directives +# append to the expected warning message. +# +# warning_output: FILE +# Means the same as 'warning', except the regular expression +# lines are contains in FILE. +# +# map: FILE +# Adding this option will cause the linker to generate a linker +# map file, using the -Map=MAPFILE command line option. If +# there is no -Map=MAPFILE in the 'ld: FLAGS' then one will be +# added to the linker command line. The contents of the +# generated MAPFILE are then compared against the regexp lines +# in FILE using `regexp_diff' (see below for details). +# +# section_subst: no +# Means that the section substitution for objdump is disabled. +# +# Each option may occur at most once unless otherwise mentioned. +# +# After the option lines come regexp lines. run_dump_test calls +# regexp_diff to compare the output of the dumping tool against the +# regexps in FILE.d. +# +proc run_dump_test { name {extra_options {}} } { + global ADDR2LINE ADDR2LINEFLAGS AS ASFLAGS ELFEDIT ELFEDITFLAGS LD LDFLAGS + global NM NMFLAGS OBJCOPY OBJCOPYFLAGS OBJDUMP OBJDUMPFLAGS + global READELF READELFFLAGS STRIP STRIPFLAGS + global copyfile env ld_elf_shared_opt runtests srcdir subdir verbose + + if [string match "*/*" $name] { + set file $name + set name [file tail $name] + } else { + set file "$srcdir/$subdir/$name" + } + + if ![runtest_file_p $runtests $name] then { + return + } + + set opt_array [slurp_options "${file}.d"] + if { $opt_array == -1 } { + perror "error reading options from $file.d" + unresolved $subdir/$name + return + } + set dumpfile tmpdir/dump.out + set run_ld 0 + set run_objcopy 0 + set objfile_names {} + set opts(PROG) {} + set opts(DUMPPROG) {} + set opts(addr2line) {} + set opts(alltargets) {} + set opts(anyskip) {} + set opts(ar) {} + set opts(as) {} + set opts(dump) {} + set opts(elfedit) {} + set opts(error) {} + set opts(error_output) {} + set opts(ld) {} + set opts(ld_after_inputfiles) {} + set opts(map) {} + set opts(name) {} + set opts(nm) {} + set opts(noskip) {} + set opts(notarget) {} + set opts(objcopy) {} + set opts(objcopy_linked_file) {} + set opts(objcopy_objects) {} + set opts(objdump) {} + set opts(ranlib) {} + set opts(readelf) {} + set opts(section_subst) {} + set opts(size) {} + set opts(strings) {} + set opts(strip) {} + set opts(skip) {} + set opts(source) {} + set opts(strip) {} + set opts(target) {} + set opts(warning) {} + set opts(warning_output) {} + set opts(xfail) {} + + set in_extra 0 + foreach i [concat $opt_array {{} {}} $extra_options] { + set opt_name [lindex $i 0] + set opt_val [lindex $i 1] + if { $opt_name == "" } { + set in_extra 1 + continue + } + if ![info exists opts($opt_name)] { + perror "unknown option $opt_name in file $file.d" + unresolved $subdir/$name + return + } + + # Allow more substitutions, including tcl functions, for as and ld. + # Not done in general because extra quoting is needed for glob + # args used for example in binutils-all/remove-relocs-04.d. + if { $opt_name == "as" || $opt_name == "ld" } { + set opt_val [subst $opt_val] + } else { + # Just substitute $srcdir and $subdir + regsub -all {\$srcdir} "$opt_val" "$srcdir" opt_val + regsub -all {\$subdir} "$opt_val" "$subdir" opt_val + } + + switch -- $opt_name { + xfail {} + target {} + alltargets {} + notarget {} + skip {} + anyskip {} + noskip {} + warning {} + error {} + source { + # Move any source-specific as-flags to a separate list to + # simplify processing. + if { [llength $opt_val] > 1 } { + lappend asflags [lrange $opt_val 1 end] + set opt_val [lindex $opt_val 0] + } else { + lappend asflags {} + } + + # Create the object file name based on nothing but the source + # file name. + set new_objfile \ + [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]].o] + # But, sometimes, we have the exact same source filename in + # different directories (foo/src.s bar/src.s) which would lead + # us to try and create two src.o files. We detect this + # conflict here, and instead create src.o and src1.o. + set j 0 + while { [lsearch $objfile_names $new_objfile] != -1 } { + incr j + set new_objfile \ + [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]]${j}.o] + } + lappend objfile_names $new_objfile + } + default { + if { !$in_extra && [string length $opts($opt_name)] } { + perror "option $opt_name multiply set in $file.d" + unresolved $subdir/$name + return + } + + # A single "#ld:" with no options should do the right thing. + if { $opt_name == "ld" } { + set run_ld 1 + } + # Likewise objcopy_linked_file. + if { $opt_name == "objcopy_linked_file" } { + set run_objcopy 1 + } + } + } + + # Append differently whether it's a message (without space) or + # an option or list (with space). + switch -- $opt_name { + warning - + error { + append opts($opt_name) $opt_val + } + default { + set opts($opt_name) [concat $opts($opt_name) $opt_val] + } + } + } + + foreach opt { as ld } { + regsub {\[big_or_little_endian\]} $opts($opt) \ + [big_or_little_endian] opts($opt) + } + + if { $opts(name) == "" } { + set testname "$subdir/$name" + } else { + set testname $opts(name) + } + + set err_warn 0 + foreach opt { warning error warning_output error_output } { + if { $opts($opt) != "" } { + if { $err_warn } { + perror "$testname: bad mix of warning and error test directives" + unresolved $testname + return + } + set err_warn 1 + } + } + + # Decide early whether we should run the test for this target. + if { [llength $opts(noskip)] > 0 } { + set targmatch 0 + foreach targ $opts(noskip) { + if [match_target $targ] { + set targmatch 1 + break + } + } + if { $targmatch == 0 } { + return + } + } + foreach targ $opts(anyskip) { + if ![match_target $targ] { + return + } + } + foreach targ $opts(skip) { + if [match_target $targ] { + return + } + } + if { [llength $opts(target)] > 0 } { + set targmatch 0 + foreach targ $opts(target) { + if [match_target $targ] { + set targmatch 1 + break + } + } + if { $targmatch == 0 } { + unsupported $testname + return + } + } + foreach targ $opts(alltargets) { + if ![match_target $targ] { + unsupported $testname + return + } + } + foreach targ $opts(notarget) { + if [match_target $targ] { + unsupported $testname + return + } + } + + set dumpprogram "" + # It's meaningless to require an output-testing method when we + # expect an error. + if { $opts(error) == "" && $opts(error_output) == "" } { + if { $opts(DUMPPROG) != "" } { + switch -- $opts(DUMPPROG) { + addr2line { set dumpprogram addr2line } + nm { set dumpprogram nm } + objdump { set dumpprogram objdump } + readelf { set dumpprogram readelf } + size { set dumpprogram size } + default { + perror "unrecognized DUMPPROG option $opts(DUMPPROG) in $file.d" + unresolved $testname + return + } + } + } else { + # Guess which program to run, by seeing which option was specified. + foreach p {addr2line nm objdump readelf size} { + if {$opts($p) != ""} { + if {$dumpprogram != ""} { + perror "ambiguous dump program in $file.d" + unresolved $testname + return + } else { + set dumpprogram $p + } + } + } + } + if { $dumpprogram == "" && $opts(map) == "" && !$err_warn } { + perror "dump program unspecified in $file.d" + unresolved $testname + return + } + } + + if { $opts(source) == "" } { + set sourcefiles [list ${file}.s] + set asflags [list ""] + set objfile_names [list tmpdir/[file tail ${file}].o] + } else { + set sourcefiles {} + foreach sf $opts(source) { + if { [string match "/*" $sf] } { + lappend sourcefiles "$sf" + } else { + lappend sourcefiles "$srcdir/$subdir/$sf" + } + } + } + + if { $opts(dump) == "" } { + set dfile ${file}.d + } else { + set dfile $srcdir/$subdir/$opts(dump) + } + + # Time to setup xfailures. + foreach targ $opts(xfail) { + setup_xfail $targ + } + + # Assemble each file. + set objfiles {} + for { set i 0 } { $i < [llength $sourcefiles] } { incr i } { + set sourcefile [lindex $sourcefiles $i] + set sourceasflags [lindex $asflags $i] + set run_objcopy_objects 0 + + if { [string match "*RUN_OBJCOPY*" $sourceasflags] } { + set run_objcopy_objects 1 + } + regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags + + set objfile [lindex $objfile_names $i] + catch "exec rm -f $objfile" exec_output + lappend objfiles $objfile + + if { $opts(as) == "binary" } { + while {[file type $sourcefile] eq "link"} { + set newfile [file readlink $sourcefile] + if {[string index $newfile 0] ne "/"} { + set newfile [file dirname $sourcefile]/$newfile + } + set sourcefile $newfile + } + set newfile [remote_download host $sourcefile $objfile] + set cmdret 0 + if { $newfile == "" } { + set cmdret 1 + } + } else { + if { [istarget "hppa*-*-*"] && ![istarget "*-*-linux*" ] } { + set cmd "sed -e 's/^\[ \]*\.comm \\(\[^,\]*\\),\\(.*\\)/\\1 .comm \\2/' < $sourcefile > tmpdir/asm.s" + send_log "$cmd\n" + set cmdret [remote_exec host [concat sh -c [list "$cmd"]]] + set cmdret [lindex $cmdret 0] + if { $cmdret != 0 } { + perror "sed failure" + unresolved $testname + return + } + set sourcefile tmpdir/asm.s + } + set cmd "$AS $ASFLAGS $opts(as) $sourceasflags -o $objfile $sourcefile" + + send_log "$cmd\n" + set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"] + remote_upload host "dump.tmp" + set comp_output [prune_warnings [file_contents "dump.tmp"]] + remote_file host delete "dump.tmp" + remote_file build delete "dump.tmp" + set cmdret [lindex $cmdret 0] + } + if { $cmdret == 0 && $run_objcopy_objects } { + set cmd "$OBJCOPY $opts(objcopy_objects) $objfile" + + send_log "$cmd\n" + set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \ + "" "/dev/null" "dump.tmp"] + remote_upload host "dump.tmp" + append comp_output [prune_warnings [file_contents "dump.tmp"]] + remote_file host delete "dump.tmp" + remote_file build delete "dump.tmp" + set cmdret [lindex $cmdret 0] + } + } + + # Perhaps link the file(s). + if { $cmdret == 0 && $run_ld } { + set objfile "tmpdir/dump" + catch "exec rm -f $objfile" exec_output + + set ld_extra_opt "" + if { [is_elf_format] && [check_shared_lib_support] } { + set ld_extra_opt "$ld_elf_shared_opt" + } + + # Add -L$srcdir/$subdir so that the linker command can use + # linker scripts in the source directory. + set cmd "$LD $ld_extra_opt $LDFLAGS -L$srcdir/$subdir \ + $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)" + + # If needed then check for, or add a -Map option. + set mapfile "" + if { $opts(map) != "" } then { + if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then { + # Found existing mapfile option + verbose -log "Existing mapfile '$mapfile' found" + } else { + # No mapfile option. + set mapfile "tmpdir/dump.map" + verbose -log "Adding mapfile '$mapfile'" + set cmd "$cmd -Map=$mapfile" + } + } + + send_log "$cmd\n" + set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"] + remote_upload host "dump.tmp" + append comp_output [file_contents "dump.tmp"] + remote_file host delete "dump.tmp" + remote_file build delete "dump.tmp" + set cmdret [lindex $cmdret 0] + + if { $cmdret == 0 && $run_objcopy } { + set infile $objfile + set objfile "tmpdir/dump1" + remote_file host delete $objfile + + # Note that we don't use OBJCOPYFLAGS here; any flags must be + # explicitly specified. + set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile" + + send_log "$cmd\n" + set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "dump.tmp"] + remote_upload host "dump.tmp" + append comp_output [file_contents "dump.tmp"] + remote_file host delete "dump.tmp" + remote_file build delete "dump.tmp" + set cmdret [lindex $cmdret 0] + } + } else { + set objfile [lindex $objfiles 0] + } + + if { $cmdret == 0 && $opts(PROG) != "" } { + set destopt ${copyfile}.o + switch -- $opts(PROG) { + ar { set program ar } + elfedit { + set program elfedit + set destopt "" + } + nm { set program nm } + objcopy { set program objcopy } + ranlib { set program ranlib } + strings { set program strings } + strip { + set program strip + set destopt "-o $destopt" + } + default { + perror "unrecognized PROG option $opts(PROG) in $file.d" + unresolved $testname + return + } + } + + set progopts1 $opts($program) + eval set progopts \$[string toupper $program]FLAGS + eval set binary \$[string toupper $program] + + if { ![is_remote host] && [which $binary] == 0 } { + untested $testname + return + } + + verbose "running $binary $progopts $progopts1" 3 + set cmd "$binary $progopts $progopts1 $objfile $destopt" + + # Ensure consistent sorting of symbols + if {[info exists env(LC_ALL)]} { + set old_lc_all $env(LC_ALL) + } + set env(LC_ALL) "C" + send_log "$cmd\n" + set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"] + set cmdret [lindex $cmdret 0] + remote_upload host "dump.tmp" + append comp_output [prune_warnings [file_contents "dump.tmp"]] + remote_file host delete "dump.tmp" + remote_file build delete "dump.tmp" + if {[info exists old_lc_all]} { + set env(LC_ALL) $old_lc_all + } else { + unset env(LC_ALL) + } + if { $destopt != "" } { + set objfile ${copyfile}.o + } + } + + set want_out(source) "" + set want_out(terminal) 0 + if { $err_warn } { + if { $opts(error) != "" || $opts(error_output) != "" } { + set want_out(terminal) 1 + } + + if { $opts(error) != "" || $opts(warning) != "" } { + set want_out(source) "regex" + if { $opts(error) != "" } { + set want_out(regex) $opts(error) + } else { + set want_out(regex) $opts(warning) + } + } else { + set want_out(source) "file" + if { $opts(error_output) != "" } { + set want_out(file) $opts(error_output) + } else { + set want_out(file) $opts(warning_output) + } + } + } + + regsub "\n$" $comp_output "" comp_output + if { $cmdret != 0 || $comp_output != "" || $want_out(source) != "" } { + set exitstat "succeeded" + if { $cmdret != 0 } { set exitstat "failed" } + + if { $want_out(source) == "regex" } { + verbose -log "$exitstat with: <$comp_output>, expected: <$want_out(regex)>" + } elseif { $want_out(source) == "file" } { + verbose -log "$exitstat with: <$comp_output>, expected in file $want_out(file)" + set_file_contents "tmpdir/ld.messages" "$comp_output" + } else { + verbose -log "$exitstat with: <$comp_output>, no expected output" + } + + if { (($want_out(source) == "") == ($comp_output == "")) \ + && (($cmdret == 0) == ($want_out(terminal) == 0)) \ + && ((($want_out(source) == "regex") \ + && [regexp -- $want_out(regex) $comp_output]) \ + || (($want_out(source) == "file") \ + && (![regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$want_out(file)"]))) } { + # We have the expected output. + if { $want_out(terminal) || $dumpprogram == "" } { + pass $testname + return + } + } else { + fail $testname + return + } + } + + # We must not have expected failure if we get here. + if { $opts(error) != "" } { + fail $testname + return + } + + if { $opts(map) != "" } then { + # Check the map file matches. + set map_pattern_file $srcdir/$subdir/$opts(map) + verbose -log "Compare '$mapfile' against '$map_pattern_file'" + if { [regexp_diff $mapfile $map_pattern_file] } then { + fail "$testname (map file check)" + } else { + pass "$testname (map file check)" + } + + if { $dumpprogram == "" } then { + return + } + } + + set progopts1 $opts($dumpprogram) + eval set progopts \$[string toupper $dumpprogram]FLAGS + eval set binary \$[string toupper $dumpprogram] + + if { ![is_remote host] && [which $binary] == 0 } { + untested $testname + return + } + + # For objdump of gas output, automatically translate standard section names + set sect_names "" + if { !$run_ld && $dumpprogram == "objdump" \ + && $opts(section_subst) != "no" \ + && ![string match "*-b binary*" $progopts1] } { + set sect_names [get_standard_section_names] + if { $sect_names != ""} { + regsub -- "\\.text" $progopts1 "[lindex $sect_names 0]" progopts1 + regsub -- "\\.data" $progopts1 "[lindex $sect_names 1]" progopts1 + regsub -- "\\.bss" $progopts1 "[lindex $sect_names 2]" progopts1 + } + } + + if { $progopts1 == "" } { set $progopts1 "-r" } + verbose "running $binary $progopts $progopts1" 3 + + set cmd "$binary $progopts $progopts1 $objfile > $dumpfile" + + # Ensure consistent sorting of symbols + if {[info exists env(LC_ALL)]} { + set old_lc_all $env(LC_ALL) + } + set env(LC_ALL) "C" + send_log "$cmd\n" + set cmdret [remote_exec host [concat sh -c [list "$cmd 2>dump.tmp"]] "" "/dev/null"] + set cmdret [lindex $cmdret 0] + remote_upload host "dump.tmp" + set comp_output [prune_warnings [file_contents "dump.tmp"]] + remote_file host delete "dump.tmp" + remote_file build delete "dump.tmp" + if {[info exists old_lc_all]} { + set env(LC_ALL) $old_lc_all + } else { + unset env(LC_ALL) + } + if { $cmdret != 0 || $comp_output != "" } { + send_log "exited abnormally with $cmdret, output:$comp_output\n" + fail $testname + return + } + + if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 } + + # Create the substition list for objdump output. + set regexp_subst "" + if { $sect_names != "" } { + set regexp_subst [list "\\\\?\\.text" [lindex $sect_names 0] \ + "\\\\?\\.data" [lindex $sect_names 1] \ + "\\\\?\\.bss" [lindex $sect_names 2] ] + } + + if { [regexp_diff $dumpfile "${dfile}" $regexp_subst] } then { + fail $testname + if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 } + return + } + + pass $testname +} + +proc slurp_options { file } { + # If options_regsub(foo) is set to {a b}, then the contents of a + # "#foo:" line will have regsub -all applied to replace a with b. + global options_regsub + + if [catch { set f [open $file r] } x] { + #perror "couldn't open `$file': $x" + perror "$x" + return -1 + } + set opt_array {} + # whitespace expression + set ws {[ ]*} + set nws {[^ ]*} + # whitespace is ignored anywhere except within the options list; + # option names are alphanumeric plus underscore. + set pat "^#${ws}(\[a-zA-Z0-9_\]*)$ws:${ws}(.*)$ws\$" + while { [gets $f line] != -1 } { + set line [string trim $line] + # Whitespace here is space-tab. + if [regexp $pat $line xxx opt_name opt_val] { + # match! + if [info exists options_regsub($opt_name)] { + set subst $options_regsub($opt_name) + regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \ + opt_val + } + lappend opt_array [list $opt_name $opt_val] + } elseif {![regexp "^#" $line ]} { + break + } + } + close $f + return $opt_array +} + +proc file_contents { filename } { + set file [open $filename r] + set contents [read $file] + close $file + return $contents +} + +proc set_file_contents { filename contents } { + set file [open $filename w] + puts $file "$contents" + close $file +} + +# Look for big-endian or little-endian switches in the multlib +# options and translate these into a -EB or -EL switch. Note +# we cannot rely upon proc process_multilib_options to do this +# for us because for some targets the compiler does not support +# -EB/-EL but it does support -mbig-endian/-mlittle-endian, and +# the site.exp file will include the switch "-mbig-endian" +# (rather than "big-endian") which is not detected by proc +# process_multilib_options. +# +proc big_or_little_endian {} { + + if [board_info [target_info name] exists multilib_flags] { + set tmp_flags " [board_info [target_info name] multilib_flags]" + + foreach x $tmp_flags { + case $x in { + {*big*endian eb EB -eb -EB -mb -meb} { + set flags " -EB" + return $flags + } + {*little*endian el EL -el -EL -ml -mel} { + set flags " -EL" + return $flags + } + } + } + } + + set flags "" + return $flags +} + +# Internal procedure: return the names of the standard sections +# +proc get_standard_section_names {} { + if [istarget "rx-*-*"] { + return { "P" "D_1" "B_1" } + } + if [istarget "alpha*-*-*vms*"] { + # Double quote: for TCL and for sh. + return { "\\\$CODE\\\$" "\\\$DATA\\\$" "\\\$BSS\\\$" } + } + return +} diff --git a/binutils/testsuite/lib/utils-lib.exp b/binutils/testsuite/lib/utils-lib.exp index 5f5ce03f3e1..45c1f03c5e0 100644 --- a/binutils/testsuite/lib/utils-lib.exp +++ b/binutils/testsuite/lib/utils-lib.exp @@ -149,568 +149,7 @@ proc exe_ext {} { } } -# Copied and modified from gas. - -# run_dump_test FILE (optional:) EXTRA_OPTIONS -# -# Assemble a .s file, then run some utility on it and check the output. -# -# There should be an assembly language file named FILE.s in the test -# suite directory, and a pattern file called FILE.d. `run_dump_test' -# will assemble FILE.s, run some tool like `objdump', `objcopy', or -# `nm' on the .o file to produce textual output, and then analyze that -# with regexps. The FILE.d file specifies what program to run, and -# what to expect in its output. -# -# The FILE.d file begins with zero or more option lines, which specify -# flags to pass to the assembler, the program to run to dump the -# assembler's output, and the options it wants. The option lines have -# the syntax: -# -# # OPTION: VALUE -# -# OPTION is the name of some option, like "name" or "objdump", and -# VALUE is OPTION's value. The valid options are described below. -# Whitespace is ignored everywhere, except within VALUE. The option -# list ends with the first line that doesn't match the above syntax. -# However, a line within the options that begins with a #, but doesn't -# have a recognizable option name followed by a colon, is considered a -# comment and entirely ignored. -# -# The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of -# two-element lists. The first element of each is an option name, and -# the second additional arguments to be added on to the end of the -# option list as given in FILE.d. (If omitted, no additional options -# are added.) -# -# The interesting options are: -# -# name: TEST-NAME -# The name of this test, passed to DejaGNU's `pass' and `fail' -# commands. If omitted, this defaults to FILE, the root of the -# .s and .d files' names. -# -# as: FLAGS -# When assembling FILE.s, pass FLAGS to the assembler. -# -# PROG: PROGRAM-NAME -# The name of the program to run to modify or analyze the .o file -# produced by the assembler. This option is required. Recognised -# names are: ar, elfedit, nm, objcopy, ranlib, strings, and strip. -# -# DUMPPROG: PROGRAM-NAME -# The name of the program to run to analyze the .o file after it has -# has been modified by PROG. This can be omitted; run_dump_test will -# guess which program to run by seeing if any of the flags options -# for the recognised dump programs are set. Recognised names are: -# addr2line, nm, objdump, readelf and size. -# -# nm: FLAGS -# objcopy: FLAGS -# objdump: FLAGS -# readelf: FLAGS -# size: FLAGS -# Use the specified program to analyze the .o file, and pass it -# FLAGS, in addition to the .o file name. Note that they are run -# with LC_ALL=C in the environment to give consistent sorting -# of symbols. -# -# source: SOURCE -# Assemble the file SOURCE.s. If omitted, this defaults to FILE.s. -# This is useful if several .d files want to share a .s file. -# -# dump: DUMP -# Match against DUMP.d. If omitted, this defaults to FILE.d. This -# is useful if several .d files differ by options only. Options are -# always read from FILE.d. -# -# target: GLOB|PROC ... -# Run this test only on a specified list of targets. More precisely, -# in the space-separated list each glob is passed to "istarget" and -# each proc is called as a TCL procedure. List items are interpreted -# such that procs are denoted by surrounding square brackets, and any -# other items are considered globs. If the call evaluates true for -# any of them, the test will be run, otherwise it will be marked -# unsupported. -# -# notarget: GLOB|PROC ... -# Do not run this test on a specified list of targets. Again, each -# glob in the space-separated list is passed to "istarget" and each -# proc is called as a TCL procedure, and the test is run if it -# evaluates *false* for *all* of them. Otherwise it will be marked -# unsupported. -# -# skip: GLOB|PROC ... -# noskip: GLOB|PROC ... -# These are exactly the same as "notarget" and "target", -# respectively, except that they do nothing at all if the check -# fails. They should only be used in groups, to construct a single -# test which is run on all targets but with variant options or -# expected output on some targets. (For example, see -# gas/arm/inst.d and gas/arm/wince_inst.d.) -# -# error: REGEX -# An error with message matching REGEX must be emitted for the test -# to pass. The DUMPPROG, addr2line, nm, objdump, readelf and size -# options have no meaning and need not supplied if this is present. -# Multiple "error" directives append to the expected error message. -# -# error_output: FILE -# Means the same as 'error', except the regular expression lines -# are contains in FILE. -# -# warning: REGEX -# Expect a warning matching REGEX. It is an error to issue both -# "error" and "warning". Multiple "warning" directives append to -# the expected linker warning message. -# -# warning_output: FILE -# Means the same as 'warning', except the regular expression -# lines are contains in FILE. -# -# Each option may occur at most once. -# -# After the option lines come regexp lines. `run_dump_test' calls -# `regexp_diff' to compare the output of the dumping tool against the -# regexps in FILE.d. `regexp_diff' is defined in binutils-common.exp; -# see further comments there. - -proc run_dump_test { name {extra_options {}} } { - global subdir srcdir - global OBJDUMP NM OBJCOPY READELF STRIP - global OBJDUMPFLAGS NMFLAGS OBJCOPYFLAGS READELFFLAGS STRIPFLAGS - global ELFEDIT ELFEDITFLAGS - global binutils_run_status - global host_triplet - global env - global copyfile - global tempfile - - if [string match "*/*" $name] { - set file $name - set name [file tail $name] - } else { - set file "$srcdir/$subdir/$name" - } - set opt_array [slurp_options "${file}.d"] - if { $opt_array == -1 } { - perror "error reading options from $file.d" - unresolved $subdir/$name - return - } - set opts(addr2line) {} - set opts(ar) {} - set opts(as) {} - set opts(elfedit) {} - set opts(name) {} - set opts(nm) {} - set opts(objcopy) {} - set opts(objdump) {} - set opts(ranlib) {} - set opts(readelf) {} - set opts(size) {} - set opts(strings) {} - set opts(strip) {} - set opts(PROG) {} - set opts(DUMPPROG) {} - set opts(source) {} - set opts(dump) {} - set opts(error) {} - set opts(warning) {} - set opts(error_output) {} - set opts(warning_output) {} - set opts(target) {} - set opts(notarget) {} - set opts(skip) {} - set opts(noskip) {} - - foreach i $opt_array { - set opt_name [lindex $i 0] - set opt_val [lindex $i 1] - if ![info exists opts($opt_name)] { - perror "unknown option $opt_name in file $file.d" - unresolved $subdir/$name - return - } - - # Permit the option to use $srcdir to refer to the source - # directory. - regsub -all "\\\$srcdir" "$opt_val" "$srcdir/$subdir" opt_val - - switch -- $opt_name { - warning {} - error {} - default { - if [string length $opts($opt_name)] { - perror "option $opt_name multiply set in $file.d" - unresolved $subdir/$name - return - } - } - } - append opts($opt_name) $opt_val - } - - foreach i $extra_options { - set opt_name [lindex $i 0] - set opt_val [lindex $i 1] - if ![info exists opts($opt_name)] { - perror "unknown option $opt_name given in extra_opts" - unresolved $subdir/$name - return - } - - # Permit the option to use $srcdir to refer to the source - # directory. - regsub -all "\\\$srcdir" "$opt_val" "$srcdir/$subdir" opt_val - - # add extra option to end of existing option, adding space - # if necessary. - if { ![regexp "warning|error" $opt_name] - && [string length $opts($opt_name)] } { - append opts($opt_name) " " - } - append opts($opt_name) $opt_val - } - - if { $opts(name) == "" } { - set testname "$subdir/$name" - } else { - set testname $opts(name) - } - verbose "Testing $testname" - - if {$opts(PROG) == ""} { - perror "PROG isn't set in $file.d" - unresolved $testname - return - } - - set destopt "" - switch -- $opts(PROG) { - ar { set program ar } - elfedit { set program elfedit } - nm { set program nm } - objcopy { set program objcopy } - ranlib { set program ranlib } - strings { set program strings } - strip { - set program strip - set destopt "-o" - } - default { - perror "unrecognized program option $opts(PROG) in $file.d" - unresolved $testname - return } - } - - set dumpprogram "" - # It's meaningless to require an output-testing method when we - # expect an error. - if { $opts(error) == "" && $opts(error_output) == "" } { - if { $opts(DUMPPROG) != "" } { - switch -- $opts(DUMPPROG) { - addr2line { set dumpprogram addr2line } - nm { set dumpprogram nm } - objdump { set dumpprogram objdump } - readelf { set dumpprogram readelf } - size { set dumpprogram size } - default { - perror "unrecognized dump program option $opts(DUMPPROG)\ - in $file.d" - unresolved $testname - return - } - } - } else { - # Guess which program to run, by seeing which option was specified. - foreach p {addr2line nm objdump readelf size} { - if {$opts($p) != ""} { - if {$dumpprogram != ""} { - perror "more than one possible dump program specified\ - in $file.d" - unresolved $testname - return - } else { - set dumpprogram $p - } - } - } - } - } - - # Handle skipping the test on specified targets. - # You can have both skip/noskip and target/notarget, but you can't - # have both skip and noskip, or target and notarget, in the same file. - if { $opts(skip) != "" } then { - if { $opts(noskip) != "" } then { - perror "$testname: mixing skip and noskip directives is invalid" - unresolved $testname - return - } - foreach glob $opts(skip) { - if {[match_target $glob]} { return } - } - } - if { $opts(noskip) != "" } then { - set skip 1 - foreach glob $opts(noskip) { - if {[match_target $glob]} { - set skip 0 - break - } - } - if {$skip} { return } - } - if { $opts(target) != "" } then { - set skip 1 - foreach glob $opts(target) { - if {[match_target $glob]} { - set skip 0 - break - } - } - if {$skip} { - unsupported $testname - return - } - } - if { $opts(notarget) != "" } then { - foreach glob $opts(notarget) { - if {[match_target $glob]} { - unsupported $testname - return - } - } - } - - if { $opts(source) == "" } { - set srcfile ${file}.s - } else { - set srcfile $srcdir/$subdir/$opts(source) - } - - if { $opts(dump) == "" } { - set dumpfile ${file}.d - } else { - set dumpfile $srcdir/$subdir/$opts(dump) - } - - if { $opts(as) == "binary" } { - while {[file type $srcfile] eq "link"} { - set newfile [file readlink $srcfile] - if {[string index $newfile 0] ne "/"} { - set newfile [file dirname $srcfile]/$newfile - } - set srcfile $newfile - } - # Make sure we copy the file if we are doing remote host testing. - remote_download host ${srcfile} $tempfile - } else { - set exec_output [binutils_assemble_flags ${srcfile} $tempfile $opts(as)] - if [string match "" $exec_output] then { - send_log "$exec_output\n" - verbose "$exec_output" - fail $testname - return - } - } - - if { (($opts(warning) != "") && ($opts(error) != "")) \ - || (($opts(warning) != "") && ($opts(error_output) != "")) \ - || (($opts(warning) != "") && ($opts(warning_output) != "")) \ - || (($opts(error) != "") && ($opts(warning_output) != "")) \ - || (($opts(error) != "") && ($opts(error_output) != "")) \ - || (($opts(warning_output) != "") && ($opts(error_output) != "")) } { - perror "bad mix of warning, error, warning_output, and error_output\ - test-directives" - unresolved $testname - return - } - - set check_prog(source) "" - set check_prog(terminal) 0 - if { $opts(error) != "" \ - || $opts(warning) != "" \ - || $opts(error_output) != "" \ - || $opts(warning_output) != "" } { - - if { $opts(error) != "" || $opts(error_output) != "" } { - set check_prog(terminal) 1 - } else { - set check_prog(terminal) 0 - } - - if { $opts(error) != "" || $opts(warning) != "" } { - set check_prog(source) "regex" - if { $opts(error) != "" } { - set check_prog(regex) $opts(error) - } else { - set check_prog(regex) $opts(warning) - } - } else { - set check_prog(source) "file" - if { $opts(error_output) != "" } { - set check_prog(file) $opts(error_output) - } else { - set check_prog(file) $opts(warning_output) - } - } - } - - set progopts1 $opts($program) - eval set progopts \$[string toupper $program]FLAGS - eval set binary \$[string toupper $program] - - set exec_output [binutils_run $binary "$progopts $progopts1 $tempfile $destopt ${copyfile}.o"] - set cmdret 0 - if [info exists binutils_run_status] { - set cmdret $binutils_run_status - } - - regsub "\n$" $exec_output "" exec_output - if { $cmdret != 0 || $exec_output != "" || $check_prog(source) != "" } { - set exitstat "succeeded" - if { $cmdret != 0 } { - set exitstat "failed" - } - - if { $check_prog(source) == "regex" } { - verbose -log "$exitstat with: <$exec_output>,\ - expected: <$check_prog(regex)>" - } elseif { $check_prog(source) == "file" } { - verbose -log "$exitstat with: <$exec_output>,\ - expected in file $check_prog(file)" - set_file_contents "tmpdir/prog.messages" "$exec_output" - } else { - verbose -log "$exitstat with: <$exec_output>, no expected output" - } - send_log -- "$exec_output\n" - verbose "$exec_output" - - if { (($check_prog(source) == "") == ($exec_output == "")) \ - && (($cmdret == 0) == ($check_prog(terminal) == 0)) \ - && ((($check_prog(source) == "regex") \ - && ($check_prog(regex) == "") == ($exec_output == "") \ - && [regexp -- $check_prog(regex) $exec_output]) \ - || (($check_prog(source) == "file") \ - && (![regexp_diff "tmpdir/prog.messages" \ - "$srcdir/$subdir/$check_prog(file)"]))) } { - # We have the expected output from prog. - if { $check_prog(terminal) || $program == "" } { - pass $testname - return - } - } else { - fail $testname - return - } - } - - set progopts1 $opts($dumpprogram) - eval set progopts \$[string toupper $dumpprogram]FLAGS - eval set binary \$[string toupper $dumpprogram] - - if { ![is_remote host] && [which $binary] == 0 } { - untested $testname - return - } - - # For objdump, automatically translate standard section names to the targets one, - # if they are different. - set sect_names [get_standard_section_names] - if { $sect_names != "" && $dumpprogram == "objdump"} { - regsub -- "-j \\.text" $progopts1 "-j [lindex $sect_names 0]" progopts1 - regsub -- "-j \\.data" $progopts1 "-j [lindex $sect_names 1]" progopts1 - regsub -- "-j \\.bss" $progopts1 "-j [lindex $sect_names 2]" progopts1 - } - - verbose "running $binary $progopts $progopts1" 3 - - set cmd "$binary $progopts $progopts1 ${copyfile}.o" - - # Ensure consistent sorting of symbols - if {[info exists env(LC_ALL)]} { - set old_lc_all $env(LC_ALL) - } - set env(LC_ALL) "C" - send_log "$cmd\n" - set comp_output [remote_exec host $cmd "" "/dev/null" "tmpdir/dump.out"] - if {[info exists old_lc_all]} { - set env(LC_ALL) $old_lc_all - } else { - unset env(LC_ALL) - } - if { [lindex $comp_output 0] != 0 } then { - send_log "$comp_output\n" - fail $testname - return - } - set comp_output [prune_warnings [lindex $comp_output 1]] - if ![string match "" $comp_output] then { - send_log "$comp_output\n" - fail $testname - return - } - - verbose_eval {[file_contents "tmpdir/dump.out"]} 3 - if { [regexp_diff "tmpdir/dump.out" "${dumpfile}"] } then { - fail $testname - verbose "output is [file_contents "tmpdir/dump.out"]" 2 - return - } - - pass $testname -} - -proc slurp_options { file } { - if [catch { set f [open $file r] } x] { - #perror "couldn't open `$file': $x" - perror "$x" - return -1 - } - set opt_array {} - # whitespace expression - set ws {[ ]*} - set nws {[^ ]*} - # whitespace is ignored anywhere except within the options list; - # option names are alphabetic plus dash - set pat "^#${ws}(\[a-zA-Z-\]*)$ws:${ws}(.*)$ws\$" - while { [gets $f line] != -1 } { - set line [string trim $line] - # Whitespace here is space-tab. - if [regexp $pat $line xxx opt_name opt_val] { - # match! - lappend opt_array [list $opt_name $opt_val] - } elseif {![regexp "^#" $line ]} { - break - } - } - close $f - return $opt_array -} - -proc file_contents { filename } { - set file [open $filename r] - set contents [read $file] - close $file - return $contents -} - proc verbose_eval { expr { level 1 } } { global verbose if $verbose>$level then { eval verbose "$expr" $level } } - -# Internal procedure: return the names of the standard sections -# -proc get_standard_section_names {} { - if [istarget "rx-*-*"] { - return { "P" "D_1" "B_1" } - } - if [istarget "alpha*-*-*vms*"] { - # Double quote: for TCL and for sh. - return { "\\\$CODE\\\$" "\\\$DATA\\\$" "\\\$BSS\\\$" } - } - return -} diff --git a/gas/ChangeLog b/gas/ChangeLog index 9a1a48b3c2c..2a0d429aed3 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2018-09-15 Alan Modra + + * testsuite/config/default.exp: Make tmpdir. + * testsuite/lib/gas-defs.exp (run_dump_test): Delete. + (get_standard_section_names, slurp_options): Delete. + 2018-09-15 Alan Modra * testsuite/gas/mips/aent-2.d, diff --git a/gas/testsuite/config/default.exp b/gas/testsuite/config/default.exp index 2c134f9f1f4..888e90d178a 100644 --- a/gas/testsuite/config/default.exp +++ b/gas/testsuite/config/default.exp @@ -70,4 +70,6 @@ if ![info exists ADDR2LINEFLAGS] then { set ADDR2LINEFLAGS {} } +if ![file isdirectory tmpdir] {catch "exec mkdir tmpdir" status} + gas_init diff --git a/gas/testsuite/lib/gas-defs.exp b/gas/testsuite/lib/gas-defs.exp index fe361357c3f..8192cd911ff 100644 --- a/gas/testsuite/lib/gas-defs.exp +++ b/gas/testsuite/lib/gas-defs.exp @@ -283,19 +283,6 @@ proc gas_init { args } { return } -# Internal procedure: return the names of the standard sections -# -proc get_standard_section_names {} { - if [istarget "rx-*-*"] { - return { "P" "D_1" "B_1" } - } - if [istarget "alpha*-*-*vms*"] { - # Double quote: for TCL and for sh. - return { "\\\$CODE\\\$" "\\\$DATA\\\$" "\\\$BSS\\\$" } - } - return -} - # run_dump_tests TESTCASES EXTRA_OPTIONS # Wrapper for run_dump_test, which is suitable for invoking as # run_dump_tests [lsort [glob -nocomplain $srcdir/$subdir/*.d]] @@ -314,489 +301,6 @@ proc run_dump_tests { testcases {extra_options {}} } { } } - -# run_dump_test FILE (optional:) EXTRA_OPTIONS -# -# Assemble a .s file, then run some utility on it and check the output. -# -# There should be an assembly language file named FILE.s in the test -# suite directory, and a pattern file called FILE.d. `run_dump_test' -# will assemble FILE.s, run some tool like `objdump', `objcopy', or -# `nm' on the .o file to produce textual output, and then analyze that -# with regexps. The FILE.d file specifies what program to run, and -# what to expect in its output. -# -# The FILE.d file begins with zero or more option lines, which specify -# flags to pass to the assembler, the program to run to dump the -# assembler's output, and the options it wants. The option lines have -# the syntax: -# -# # OPTION: VALUE -# -# OPTION is the name of some option, like "name" or "objdump", and -# VALUE is OPTION's value. The valid options are described below. -# Whitespace is ignored everywhere, except within VALUE. The option -# list ends with the first line that doesn't match the above syntax. -# However, a line within the options that begins with a #, but doesn't -# have a recognizable option name followed by a colon, is considered a -# comment and entirely ignored. -# -# The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of -# two-element lists. The first element of each is an option name, and -# the second additional arguments to be added on to the end of the -# option list as given in FILE.d. (If omitted, no additional options -# are added.) -# -# The interesting options are: -# -# name: TEST-NAME -# The name of this test, passed to DejaGNU's `pass' and `fail' -# commands. If omitted, this defaults to FILE, the root of the -# .s and .d files' names. -# -# as: FLAGS -# When assembling FILE.s, pass FLAGS to the assembler. -# -# addr2line: FLAGS -# nm: FLAGS -# objdump: FLAGS -# readelf: FLAGS -# Use the specified program to analyze the .o file, and pass it -# FLAGS, in addition to the .o file name. Note that they are run -# with LC_ALL=C in the environment to give consistent sorting -# of symbols. If no FLAGS are needed then use: -# DUMPPROG: [nm objdump readelf addr2line] -# instead. -# Note: for objdump, we automatically replaces the standard section -# names (.text, .data and .bss) by target ones if any (eg. rx-elf -# uses "P" instead of .text). The substition is done for both -# the objdump options (eg: "-j .text" is replaced by "-j P") and the -# reference file. -# -# source: SOURCE -# Assemble the file SOURCE.s. If omitted, this defaults to FILE.s. -# This is useful if several .d files want to share a .s file. -# -# dump: DUMP -# Match against DUMP.d. If omitted, this defaults to FILE.d. This -# is useful if several .d files differ by options only. Options are -# always read from FILE.d. -# -# target: GLOB|PROC ... -# Run this test only on a specified list of targets. More precisely, -# in the space-separated list each glob is passed to "istarget" and -# each proc is called as a TCL procedure. List items are interpreted -# such that procs are denoted by surrounding square brackets, and any -# other items are consired globs. If the call evaluates true for any -# of them, the test will be run, otherwise it will be marked -# unsupported. -# -# notarget: GLOB|PROC ... -# Do not run this test on a specified list of targets. Again, each -# glob in the space-separated list is passed to "istarget" and each -# proc is called as a TCL procedure, and the test is run if it -# evaluates *false* for *all* of them. Otherwise it will be marked -# unsupported. -# -# skip: GLOB|PROC ... -# noskip: GLOB|PROC ... -# These are exactly the same as "notarget" and "target", -# respectively, except that they do nothing at all if the check -# fails. They should only be used in groups, to construct a single -# test which is run on all targets but with variant options or -# expected output on some targets. (For example, see -# gas/arm/inst.d and gas/arm/wince_inst.d.) -# -# xfail: GLOB|PROC ... -# Run this test and it is is expected to fail on a specified list -# of targets. -# -# error: REGEX -# An error with message matching REGEX must be emitted for the test -# to pass. The DUMPPROG, addr2line, nm, objdump, and readelf options -# have no meaning and need not supplied if this is present. -# -# warning: REGEX -# Expect a gas warning matching REGEX. It is an error to issue -# both "error" and "warning". -# -# warning_output: FILE -# FILE contains regexp lines to be matched against the diagnostic -# output of the assembler. This does not preclude the use of -# DUMPPROG, addr2line, nm, objdump, or readelf. -# -# error_output: FILE -# Means the same as 'warning_output', but also indicates that the assembler -# is expected to exit unsuccessfully (therefore DUMPPROG, addr2line, nm, -# objdump, and readelf have no meaning and should not be supplied). -# -# section-subst: no -# Means that the section substitution for objdump is disabled. -# -# Each option may occur at most once. -# -# After the option lines come regexp lines. `run_dump_test' calls -# `regexp_diff' to compare the output of the dumping tool against the -# regexps in FILE.d. `regexp_diff' is defined in binutils-common.exp; -# see further comments there. - -proc run_dump_test { name {extra_options {}} } { - global subdir srcdir - global OBJDUMP NM AS OBJCOPY READELF - global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS - global ADDR2LINE ADDR2LINEFLAGS - global host_triplet - global env - - if [string match "*/*" $name] { - set file $name - set name [file tail $name] - } else { - set file "$srcdir/$subdir/$name" - } - set opt_array [slurp_options "${file}.d"] - if { $opt_array == -1 } { - perror "error reading options from $file.d" - unresolved $subdir/$name - return - } - set opts(addr2line) {} - set opts(as) {} - set opts(objdump) {} - set opts(nm) {} - set opts(readelf) {} - set opts(name) {} - set opts(DUMPPROG) {} - set opts(source) {} - set opts(dump) {} - set opts(warning_output) {} - set opts(error) {} - set opts(error_output) {} - set opts(warning) {} - set opts(target) {} - set opts(notarget) {} - set opts(skip) {} - set opts(noskip) {} - set opts(xfail) {} - set opts(section-subst) {} - - foreach i $opt_array { - set opt_name [lindex $i 0] - set opt_val [lindex $i 1] - if ![info exists opts($opt_name)] { - perror "unknown option $opt_name in file $file.d" - unresolved $subdir/$name - return - } - if [string length $opts($opt_name)] { - perror "option $opt_name multiply set in $file.d" - unresolved $subdir/$name - return - } - if { $opt_name == "as" } { - set opt_val [subst $opt_val] - } - set opts($opt_name) $opt_val - } - - foreach i $extra_options { - set opt_name [lindex $i 0] - set opt_val [lindex $i 1] - if ![info exists opts($opt_name)] { - perror "unknown option $opt_name given in extra_opts" - unresolved $subdir/$name - return - } - # add extra option to end of existing option, adding space - # if necessary. - if [string length $opts($opt_name)] { - append opts($opt_name) " " - } - append opts($opt_name) $opt_val - } - - if { $opts(name) == "" } { - set testname "$subdir/$name" - } else { - set testname $opts(name) - } - verbose "Testing $testname" - - if { (($opts(warning) != "") && ($opts(error) != "")) \ - || (($opts(warning) != "") && ($opts(warning_output) != "")) \ - || (($opts(error_output) != "") && ($opts(warning_output) != "")) \ - || (($opts(error_output) != "") && ($opts(error) != "")) \ - || (($opts(error_output) != "") && ($opts(warning) != "")) } { - perror "$testname: bad mix of warning_output, error_output, error, and warning test-directives" - unresolved $testname - return - } - if { $opts(error_output) != "" } then { - set opts(warning_output) $opts(error_output) - } - - set dumpprogram "" - # It's meaningless to require an output-testing method when we - # expect an error. - if { $opts(error) == "" && $opts(error_output) == "" } { - if {$opts(DUMPPROG) != ""} { - switch -- $opts(DUMPPROG) { - addr2line { set dumpprogram addr2line } - objdump { set dumpprogram objdump } - nm { set dumpprogram nm } - readelf { set dumpprogram readelf } - default { - perror "unrecognized DUMPPROG option $opts(DUMPPROG) in $file.d" - unresolved $testname - return } - } - } else { - # Guess which program to run, by seeing which option was specified. - foreach p {objdump nm readelf addr2line} { - if {$opts($p) != ""} { - if {$dumpprogram != ""} { - perror "ambiguous dump program in $file.d" - unresolved $testname - return - } else { - set dumpprogram $p - } - } - } - } - if { $dumpprogram == "" && $opts(warning) == "" } { - perror "dump program unspecified in $file.d" - unresolved $testname - return - } - } - - # Handle skipping the test on specified targets. - # You can have both skip/noskip and target/notarget, but you can't - # have both skip and noskip, or target and notarget, in the same file. - if { $opts(skip) != "" } then { - if { $opts(noskip) != "" } then { - perror "$testname: mixing skip and noskip directives is invalid" - unresolved $testname - return - } - foreach glob $opts(skip) { - if {[match_target $glob]} { return } - } - } - if { $opts(noskip) != "" } then { - set skip 1 - foreach glob $opts(noskip) { - if {[match_target $glob]} { - set skip 0 - break - } - } - if {$skip} { return } - } - if { $opts(target) != "" } then { - if { $opts(notarget) != "" } then { - perror "$testname: mixing target and notarget directives is invalid" - unresolved $testname - return - } - set skip 1 - foreach glob $opts(target) { - if {[match_target $glob]} { - set skip 0 - break - } - } - if {$skip} { - unsupported $testname - return - } - } - if { $opts(notarget) != "" } then { - foreach glob $opts(notarget) { - if {[match_target $glob]} { - unsupported $testname - return - } - } - } - - # Setup xfailures. - foreach targ $opts(xfail) { - setup_xfail $targ - } - - if { $opts(source) == "" } { - set sourcefile ${file}.s - } else { - set sourcefile $srcdir/$subdir/$opts(source) - } - - if { $opts(dump) == "" } { - set dumpfile ${file}.d - } else { - set dumpfile $srcdir/$subdir/$opts(dump) - } - - set cmd "$AS $ASFLAGS $opts(as) -o dump.o $sourcefile" - send_log "$cmd\n" - set status [gas_host_run $cmd ""] - set cmdret [lindex $status 0] - set comp_output [prune_warnings [lindex $status 1]] - - set expmsg $opts(error) - if { $opts(warning) != "" } { - set expmsg $opts(warning) - } - if { $cmdret != 0 || $comp_output != "" || $expmsg != "" } then { - # If the executed program writes to stderr and stderr is not - # redirected, exec *always* returns failure, regardless of the - # program exit code. Thankfully, we can retrieve the true - # return status from a special variable. Redirection would - # cause a tcl-specific message to be appended, and we'd rather - # not deal with that if we can help it. - global errorCode - if { $cmdret != 0 && [lindex $errorCode 0] == "NONE" } { - set cmdret 0 - } - - set exitstat "succeeded" - if { $cmdret != 0 } { set exitstat "failed" } - - send_log "$comp_output\n" - verbose "$comp_output" 3 - if { $opts(warning_output) == "" } then { - if { [regexp $expmsg $comp_output] \ - && (($cmdret == 0) == ($opts(warning) != "")) } { - # We have the expected output from gas. - # Return if there's nothing more to do. - if { $opts(error) != "" || $dumpprogram == "" } { - pass $testname - return - } - } else { - verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>" - - fail $testname - return - } - } else { - catch {write_file dump.stderr "$comp_output"} write_output - if ![string match "" $write_output] then { - send_log "error writing dump.stderr: $write_output\n" - verbose "error writing dump.stderr: $write_output" 3 - send_log "$comp_output\n" - verbose "$comp_output" 3 - fail $testname - return - } - set stderrfile $srcdir/$subdir/$opts(warning_output) - verbose "wrote pruned stderr to dump.stderr" 3 - if { [regexp_diff "dump.stderr" "$stderrfile"] } then { - if { $opts(error) != "" } { - verbose -log "$exitstat with: <$comp_output>, expected: <$opts(error)>" - if [regexp $opts(error) $comp_output] { - pass $testname - return - } - } - fail $testname - verbose "pruned stderr is [file_contents "dump.stderr"]" 2 - return - } elseif { $opts(error_output) != "" } then { - pass $testname - return - } - } - } else { - if { $opts(error) != "" || $opts(error_output) != "" } { - fail $testname - } - } - - if { $dumpprogram == "" } { - return - } - set progopts1 $opts($dumpprogram) - eval set progopts \$[string toupper $dumpprogram]FLAGS - eval set binary \$[string toupper $dumpprogram] - - if { ![is_remote host] && [which $binary] == 0 } { - untested $testname - return - } - - # For objdump, automatically translate standard section names to the targets one, - # if they are different. - set sect_names [get_standard_section_names] - if { $sect_names != "" && $dumpprogram == "objdump" && $opts(section-subst) == ""} { - regsub -- "-j \\.text" $progopts1 "-j [lindex $sect_names 0]" progopts1 - regsub -- "-j \\.data" $progopts1 "-j [lindex $sect_names 1]" progopts1 - regsub -- "-j \\.bss" $progopts1 "-j [lindex $sect_names 2]" progopts1 - } - - if { $progopts1 == "" } { set $progopts1 "-r" } - verbose "running $binary $progopts $progopts1" 3 - - set cmd "$binary $progopts $progopts1 dump.o" - set redir ">dump.out" - send_log "$cmd\n" - set status [gas_host_run "$cmd" "$redir"] - set comp_output [prune_warnings [lindex $status 1]] - set comp_output [prune_warnings $comp_output] - if ![string match "" $comp_output] then { - send_log "$comp_output\n" - fail $testname - return - } - - # Create the substition list only for objdump reference. - if { $sect_names != "" && $dumpprogram == "objdump" } { - # Some testcases use ".text" while others use "\.text". - set regexp_subst [list "\\\\?\\.text" [lindex $sect_names 0] \ - "\\\\?\\.data" [lindex $sect_names 1] \ - "\\\\?\\.bss" [lindex $sect_names 2] ] - } else { - set regexp_subst "" - } - - verbose_eval {[file_contents "dump.out"]} 3 - if { [regexp_diff "dump.out" "${dumpfile}" $regexp_subst] } then { - fail $testname - verbose "output is [file_contents "dump.out"]" 2 - return - } - - pass $testname -} - -proc slurp_options { file } { - if [catch { set f [open $file r] } x] { - #perror "couldn't open `$file': $x" - perror "$x" - return -1 - } - set opt_array {} - # whitespace expression - set ws {[ ]*} - set nws {[^ ]*} - # whitespace is ignored anywhere except within the options list; - # option names are alphanumeric plus underscore. - set pat "^#${ws}(\[a-zA-Z0-9_\]*)$ws:${ws}(.*)$ws\$" - while { [gets $f line] != -1 } { - set line [string trim $line] - # Whitespace here is space-tab. - if [regexp $pat $line xxx opt_name opt_val] { - # match! - lappend opt_array [list $opt_name $opt_val] - } elseif {![regexp "^#" $line ]} { - break - } - } - close $f - return $opt_array -} - proc objdump { opts } { global OBJDUMP global comp_output diff --git a/ld/ChangeLog b/ld/ChangeLog index 82127d9dd41..9b7f7fd7e38 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,19 @@ +2018-09-15 Alan Modra + + * testsuite/ld-d10v/reloc-007.d, + * testsuite/ld-d10v/reloc-008.d, + * testsuite/ld-d10v/reloc-015.d, + * testsuite/ld-d10v/reloc-016.d: Remove "error:". + * testsuite/ld-elf/eh-frame-hdr.d, + * testsuite/ld-elf/eh5.d, + * testsuite/ld-gc/personality.d: Replace "cfi" and "shared" in + target list with appropriate proc. + * testsuite/ld-elf/frame.exp: Use check_shared_lib_support rather + than "istarget shared". + * testsuite/lib/ld-lib.exp (proc big_or_little_endian): Delete. + (run_dump_test, slurp_options, file_contents): Delete. + (set_file_contents, istarget): Delete. + 2018-09-15 Alan Modra * testsuite/lib/ld-lib.exp (run_dump_test): Replace PROG diff --git a/ld/testsuite/ld-d10v/reloc-007.d b/ld/testsuite/ld-d10v/reloc-007.d index 293a6df3240..7cc89cd2db6 100644 --- a/ld/testsuite/ld-d10v/reloc-007.d +++ b/ld/testsuite/ld-d10v/reloc-007.d @@ -2,7 +2,6 @@ #ld: -T $srcdir/$subdir/reloc-007.ld #objdump: -D # now that we treat addresses as wrapping, it isn't possible to fail -#error: relocation truncated to fit: R_D10V_18_PCREL # Test 18 bit pc rel reloc bad boundary #pass diff --git a/ld/testsuite/ld-d10v/reloc-008.d b/ld/testsuite/ld-d10v/reloc-008.d index 273a23c35f5..0fb79eac59f 100644 --- a/ld/testsuite/ld-d10v/reloc-008.d +++ b/ld/testsuite/ld-d10v/reloc-008.d @@ -2,7 +2,6 @@ #ld: -T $srcdir/$subdir/reloc-008.ld #objdump: -D # now that we treat addresses as wrapping, it isn't possible to fail -#error: relocation truncated to fit: R_D10V_18_PCREL # Test 18 bit pc rel reloc normal bad #pass diff --git a/ld/testsuite/ld-d10v/reloc-015.d b/ld/testsuite/ld-d10v/reloc-015.d index 043f727e153..7f095da0bfc 100644 --- a/ld/testsuite/ld-d10v/reloc-015.d +++ b/ld/testsuite/ld-d10v/reloc-015.d @@ -2,7 +2,6 @@ #ld: -T $srcdir/$subdir/reloc-015.ld #objdump: -D # now that we treat addresses as wrapping, it isn't possible to fail -#error: relocation truncated to fit: R_D10V_18_PCREL # Test 18 bit pc rel negative reloc bad boundary #pass diff --git a/ld/testsuite/ld-d10v/reloc-016.d b/ld/testsuite/ld-d10v/reloc-016.d index e7d5e8e6f9b..691f9e3bf7b 100644 --- a/ld/testsuite/ld-d10v/reloc-016.d +++ b/ld/testsuite/ld-d10v/reloc-016.d @@ -2,7 +2,6 @@ #ld: -T $srcdir/$subdir/reloc-016.ld #objdump: -D # now that we treat addresses as wrapping, it isn't possible to fail -#error: relocation truncated to fit: R_D10V_18_PCREL # Test 18 bit pc rel negative reloc normal bad #pass diff --git a/ld/testsuite/ld-elf/eh-frame-hdr.d b/ld/testsuite/ld-elf/eh-frame-hdr.d index 12e79f49155..35bf97d0f4f 100644 --- a/ld/testsuite/ld-elf/eh-frame-hdr.d +++ b/ld/testsuite/ld-elf/eh-frame-hdr.d @@ -1,7 +1,7 @@ #source: eh-frame-hdr.s #ld: -e _start --eh-frame-hdr #objdump: -hw -#alltargets: cfi shared +#alltargets: [check_as_cfi] [check_shared_lib_support] #... [0-9] .eh_frame_hdr +0*[12][048c] .* #pass diff --git a/ld/testsuite/ld-elf/eh5.d b/ld/testsuite/ld-elf/eh5.d index 0d30ee38fd9..b74d4cf1e94 100644 --- a/ld/testsuite/ld-elf/eh5.d +++ b/ld/testsuite/ld-elf/eh5.d @@ -3,7 +3,7 @@ #source: eh5b.s #ld: #readelf: -wf -#target: cfi +#target: [check_as_cfi] #xfail: alpha-*-*ecoff hppa64-*-* tile*-*-* visium-*-* Contents of the .eh_frame section: diff --git a/ld/testsuite/ld-elf/frame.exp b/ld/testsuite/ld-elf/frame.exp index 8862ff14a5c..bba8947c166 100644 --- a/ld/testsuite/ld-elf/frame.exp +++ b/ld/testsuite/ld-elf/frame.exp @@ -29,7 +29,7 @@ if ![is_elf_format] { } # No shared lib support on this target. -if ![istarget shared] { +if ![check_shared_lib_support] { return } diff --git a/ld/testsuite/ld-gc/personality.d b/ld/testsuite/ld-gc/personality.d index 5f141835ca5..0c2d426941c 100644 --- a/ld/testsuite/ld-gc/personality.d +++ b/ld/testsuite/ld-gc/personality.d @@ -1,7 +1,7 @@ #name: --gc-sections with __gxx_personality #ld: --gc-sections -e main -L tmpdir -lpersonality #nm: -n -#target: cfi +#target: [check_as_cfi] #failif #... diff --git a/ld/testsuite/lib/ld-lib.exp b/ld/testsuite/lib/ld-lib.exp index edf6e93de54..d6453f19958 100644 --- a/ld/testsuite/lib/ld-lib.exp +++ b/ld/testsuite/lib/ld-lib.exp @@ -185,38 +185,6 @@ proc is_endian_output_format { object_flags } { } } -# Look for big-endian or little-endian switches in the multlib -# options and translate these into a -EB or -EL switch. Note -# we cannot rely upon proc process_multilib_options to do this -# for us because for some targets the compiler does not support -# -EB/-EL but it does support -mbig-endian/-mlittle-endian, and -# the site.exp file will include the switch "-mbig-endian" -# (rather than "big-endian") which is not detected by proc -# process_multilib_options. -# -proc big_or_little_endian {} { - - if [board_info [target_info name] exists multilib_flags] { - set tmp_flags " [board_info [target_info name] multilib_flags]" - - foreach x $tmp_flags { - case $x in { - {*big*endian eb EB -eb -EB -mb -meb} { - set flags " -EB" - return $flags - } - {*little*endian el EL -el -EL -ml -mel} { - set flags " -EL" - return $flags - } - } - } - } - - set flags "" - return $flags -} - # Link a program using ld # proc default_ld_link { ld target objects } { @@ -441,751 +409,6 @@ proc ld_link_defsyms {} { return $flags } -# run_dump_test FILE (optional:) EXTRA_OPTIONS -# Copied from gas testsuite, tweaked and further extended. -# -# Assemble a .s file, then run some utility on it and check the output. -# -# There should be an assembly language file named FILE.s in the test -# suite directory, and a pattern file called FILE.d. `run_dump_test' -# will assemble FILE.s, run some tool like `objdump', `objcopy', or -# `nm' on the .o file to produce textual output, and then analyze that -# with regexps. The FILE.d file specifies what program to run, and -# what to expect in its output. -# -# The FILE.d file begins with zero or more option lines, which specify -# flags to pass to the assembler, the program to run to dump the -# assembler's output, and the options it wants. The option lines have -# the syntax: -# -# # OPTION: VALUE -# -# OPTION is the name of some option, like "name" or "objdump", and -# VALUE is OPTION's value. The valid options are described below. -# Whitespace is ignored everywhere, except within VALUE. The option -# list ends with the first line that doesn't match the above syntax -# (hmm, not great for error detection). -# -# The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of -# two-element lists. The first element of each is an option name, and -# the second additional arguments to be added on to the end of the -# option list as given in FILE.d. (If omitted, no additional options -# are added.) -# -# The interesting options are: -# -# name: TEST-NAME -# The name of this test, passed to DejaGNU's `pass' and `fail' -# commands. If omitted, this defaults to FILE, the root of the -# .s and .d files' names. -# -# as: FLAGS -# When assembling, pass FLAGS to the assembler. -# If assembling several files, you can pass different assembler -# options in the "source" directives. See below. -# -# ld: FLAGS -# Link assembled files using FLAGS, in the order of the "source" -# directives, when using multiple files. -# -# ld_after_inputfiles: FLAGS -# Similar to "ld", but put after all input files. -# -# objcopy_objects: FLAGS -# Run objcopy with the specified flags after assembling any source -# that has the special marker RUN_OBJCOPY in the source specific -# flags. -# -# objcopy_linked_file: FLAGS -# Run objcopy on the linked file with the specified flags. -# This lets you transform the linked file using objcopy, before the -# result is analyzed by an analyzer program specified below (which -# may in turn *also* be objcopy). -# -# DUMPPROG: PROGRAM-NAME -# The name of the program to run to analyze the .o file produced -# by the assembler or the linker output. This can be omitted; -# run_dump_test will guess which program to run by seeing which of -# the flags options below is present. -# -# readelf: FLAGS -# objdump: FLAGS -# nm: FLAGS -# Use the specified program to analyze the assembler or linker -# output file, and pass it FLAGS, in addition to the output name. -# Note that they are run with LC_ALL=C in the environment to give -# consistent sorting of symbols. -# -# source: SOURCE [FLAGS] -# Assemble the file SOURCE.s using the flags in the "as" directive -# and the (optional) FLAGS. If omitted, the source defaults to -# FILE.s. -# This is useful if several .d files want to share a .s file. -# More than one "source" directive can be given, which is useful -# when testing linking. -# -# dump: DUMP -# Match against DUMP.d. If omitted, this defaults to FILE.d. This -# is useful if several .d files differ by options only. Options are -# always read from FILE.d. -# -# xfail: TARGET -# The test is expected to fail on TARGET. This may occur more than -# once. -# -# target: TARGET -# Only run the test for TARGET. -# You may provide target name "cfi" for any target supporting the -# CFI statements. You may provide target name "shared" for any -# target supporting shared libraries. Otherwise TARGET is called -# as a TCL procedure if surrounded by square brackets, or passed -# to "istarget" if not. -# This may occur more than once; the target being tested must match -# at least one. Otherwise the test will be marked unsupported. -# -# alltargets: TARGET -# Only run the test for TARGET. -# The syntax for TARGET is as with 'target'. -# This may occur more than once; the target being tested must match -# all of them. Otherwise the test will be marked unsupported. -# -# notarget: TARGET -# Do not run the test for TARGET. -# The syntax for TARGET is as with 'target'. -# This may occur more than once; the target being tested must not -# match any of them. Otherwise the test will be marked unsupported. -# -# skip: TARGET -# anyskip: TARGET -# noskip: TARGET -# These are exactly the same as "notarget", "alltargets" and -# "target" respectively, except that they do nothing at all if the -# check fails. They should only be used in groups, to construct a -# single test which is run on all targets but with variant options -# or expected output on some targets. (For example, see -# gas/arm/inst.d and gas/arm/wince_inst.d.) -# -# error: REGEX -# An error with message matching REGEX must be emitted for the test -# to pass. The DUMPPROG, readelf, objdump, and nm options have -# no meaning and need not be supplied if this is present. Multiple -# "error" directives append to the expected linker error message. -# -# error_output: FILE -# Means the same as 'error', except the regular expression lines -# are contains in FILE. -# -# warning: REGEX -# Expect a linker warning matching REGEX. It is an error to issue -# both "error" and "warning". Multiple "warning" directives -# append to the expected linker warning message. -# -# warning_output: FILE -# Means the same as 'warning', except the regular expression -# lines are contains in FILE. -# -# map: FILE -# Adding this option will cause the linker to generate a linker -# map file, using the -Map=MAPFILE command line option. If -# there is no -Map=MAPFILE in the 'ld: FLAGS' then one will be -# added to the linker command line. The contents of the -# generated MAPFILE are then compared against the regexp lines -# in FILE using `regexp_diff' (see below for details). -# -# Each option may occur at most once unless otherwise mentioned. -# -# After the option lines come regexp lines. `run_dump_test' calls -# `regexp_diff' to compare the output of the dumping tool against the -# regexps in FILE.d. `regexp_diff' is defined in binutils-common.exp; -# see further comments there. -# -proc run_dump_test { name {extra_options {}} } { - global subdir srcdir - global OBJDUMP NM AS OBJCOPY READELF LD - global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS - global host_triplet runtests - global env verbose - global ld_elf_shared_opt - - if { [is_elf_format] && [check_shared_lib_support] } { - set ld_extra_opt "$ld_elf_shared_opt" - } else { - set ld_extra_opt "" - } - - if [string match "*/*" $name] { - set file $name - set name [file tail $name] - } else { - set file "$srcdir/$subdir/$name" - } - - if ![runtest_file_p $runtests $name] then { - return - } - - set opt_array [slurp_options "${file}.d"] - if { $opt_array == -1 } { - perror "error reading options from $file.d" - unresolved $subdir/$name - return - } - set dumpfile tmpdir/dump.out - set run_ld 0 - set run_objcopy 0 - set objfile_names {} - set opts(as) {} - set opts(ld) {} - set opts(ld_after_inputfiles) {} - set opts(xfail) {} - set opts(target) {} - set opts(alltargets) {} - set opts(notarget) {} - set opts(skip) {} - set opts(anyskip) {} - set opts(noskip) {} - set opts(objdump) {} - set opts(nm) {} - set opts(readelf) {} - set opts(name) {} - set opts(DUMPPROG) {} - set opts(source) {} - set opts(dump) {} - set opts(error) {} - set opts(warning) {} - set opts(error_output) {} - set opts(warning_output) {} - set opts(objcopy_linked_file) {} - set opts(objcopy_objects) {} - set opts(map) {} - - foreach i $opt_array { - set opt_name [lindex $i 0] - set opt_val [lindex $i 1] - if ![info exists opts($opt_name)] { - perror "unknown option $opt_name in file $file.d" - unresolved $subdir/$name - return - } - - switch -- $opt_name { - xfail {} - target {} - alltargets {} - notarget {} - skip {} - anyskip {} - noskip {} - warning {} - error {} - source { - # Move any source-specific as-flags to a separate list to - # simplify processing. - if { [llength $opt_val] > 1 } { - lappend asflags [lrange $opt_val 1 end] - set opt_val [lindex $opt_val 0] - } else { - lappend asflags {} - } - - # Create the object file name based on nothing but the source - # file name. - set new_objfile \ - [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]].o] - # But, sometimes, we have the exact same source filename in - # different directories (foo/src.s bar/src.s) which would lead - # us to try and create two src.o files. We detect this - # conflict here, and instead create src.o and src1.o. - set j 0 - while { [lsearch $objfile_names $new_objfile] != -1 } { - incr j - set new_objfile \ - [concat tmpdir/[file rootname [file tail [lindex $opt_val 0]]]${j}.o] - } - lappend objfile_names $new_objfile - } - default { - if [string length $opts($opt_name)] { - perror "option $opt_name multiply set in $file.d" - unresolved $subdir/$name - return - } - - # A single "# ld:" with no options should do the right thing. - if { $opt_name == "ld" } { - set run_ld 1 - } - # Likewise objcopy_linked_file. - if { $opt_name == "objcopy_linked_file" } { - set run_objcopy 1 - } - } - } - if { $opt_name == "as" || $opt_name == "ld" } { - set opt_val [subst $opt_val] - } - - # Append differently whether it's a message (without space) or - # an option or list (with space). - switch -- $opt_name { - warning - - error { - append opts($opt_name) $opt_val - } - default { - set opts($opt_name) [concat $opts($opt_name) $opt_val] - } - } - } - - foreach i $extra_options { - set opt_name [lindex $i 0] - set opt_val [lindex $i 1] - if ![info exists opts($opt_name)] { - perror "unknown option $opt_name given in extra_opts" - unresolved $subdir/$name - return - } - # Add extra option to end of existing option, adding space - # if necessary. - if { ![regexp "warning|error" $opt_name] - && [string length $opts($opt_name)] } { - append opts($opt_name) " " - } - append opts($opt_name) $opt_val - } - - foreach opt { as ld } { - regsub {\[big_or_little_endian\]} $opts($opt) \ - [big_or_little_endian] opts($opt) - } - - if { $opts(name) == "" } { - set testname "$subdir/$name" - } else { - set testname $opts(name) - } - - # Decide early whether we should run the test for this target. - if { [llength $opts(noskip)] > 0 } { - set targmatch 0 - foreach targ $opts(noskip) { - if [match_target $targ] { - set targmatch 1 - break - } - } - if { $targmatch == 0 } { - return - } - } - foreach targ $opts(anyskip) { - if ![match_target $targ] { - return - } - } - foreach targ $opts(skip) { - if [match_target $targ] { - return - } - } - if { [llength $opts(target)] > 0 } { - set targmatch 0 - foreach targ $opts(target) { - if [match_target $targ] { - set targmatch 1 - break - } - } - if { $targmatch == 0 } { - unsupported $testname - return - } - } - foreach targ $opts(alltargets) { - if ![match_target $targ] { - unsupported $testname - return - } - } - foreach targ $opts(notarget) { - if [match_target $targ] { - unsupported $testname - return - } - } - - set dumpprogram "" - # It's meaningless to require an output-testing method when we - # expect an error. - if { $opts(error) == "" && $opts(error_output) == "" } { - if { $opts(DUMPPROG) != "" } { - switch -- $opts(DUMPPROG) { - objdump { set dumpprogram objdump } - nm { set dumpprogram nm } - readelf { set dumpprogram readelf } - default { - perror "unrecognized DUMPPROG option $opts(DUMPPROG) in $file.d" - unresolved $testname - return - } - } - } else { - # Guess which program to run, by seeing which option was specified. - foreach p {objdump nm readelf} { - if {$opts($p) != ""} { - if {$dumpprogram != ""} { - perror "ambiguous dump program in $file.d" - unresolved $testname - return - } else { - set dumpprogram $p - } - } - } - } - if { $dumpprogram == "" \ - && $opts(map) == "" \ - && $opts(warning) == "" \ - && $opts(warning_output) == "" \ - && $opts(error) == "" \ - && $opts(error_output) == "" } { - perror "dump program unspecified in $file.d" - unresolved $testname - return - } - } - - if { $opts(source) == "" } { - set sourcefiles [list ${file}.s] - set asflags [list ""] - set objfile_names [list tmpdir/[file tail ${file}].o] - } else { - set sourcefiles {} - foreach sf $opts(source) { - if { [string match "/*" $sf] } { - lappend sourcefiles "$sf" - } else { - lappend sourcefiles "$srcdir/$subdir/$sf" - } - } - } - - if { $opts(dump) == "" } { - set dfile ${file}.d - } else { - set dfile $srcdir/$subdir/$opts(dump) - } - - # Time to setup xfailures. - foreach targ $opts(xfail) { - setup_xfail $targ - } - - # Assemble each file. - set objfiles {} - for { set i 0 } { $i < [llength $sourcefiles] } { incr i } { - set sourcefile [lindex $sourcefiles $i] - set sourceasflags [lindex $asflags $i] - set run_objcopy_objects 0 - - if { [string match "*RUN_OBJCOPY*" $sourceasflags] } { - set run_objcopy_objects 1 - } - regsub "RUN_OBJCOPY" $sourceasflags "" sourceasflags - - set objfile [lindex $objfile_names $i] - catch "exec rm -f $objfile" exec_output - lappend objfiles $objfile - set cmd "$AS $ASFLAGS $opts(as) $sourceasflags -o $objfile $sourcefile" - - send_log "$cmd\n" - set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"] - remote_upload host "ld.tmp" - set comp_output [prune_warnings [file_contents "ld.tmp"]] - remote_file host delete "ld.tmp" - remote_file build delete "ld.tmp" - - if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then { - send_log -- "$comp_output\n" - verbose "$comp_output" 3 - - set exitstat "succeeded" - if { $cmdret != 0 } { set exitstat "failed" } - verbose -log "$exitstat with: <$comp_output>" - fail $testname - return - } - - if { $run_objcopy_objects } { - set cmd "$OBJCOPY $opts(objcopy_objects) $objfile" - - send_log "$cmd\n" - set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] \ - "" "/dev/null" "objcopy.tmp"] - remote_upload host "objcopy.tmp" - set comp_output [prune_warnings [file_contents "objcopy.tmp"]] - remote_file host delete "objcopy.tmp" - remote_file build delete "objcopy.tmp" - - if { [lindex $cmdret 0] != 0 \ - || ![string match "" $comp_output] } { - send_log -- "$comp_output\n" - verbose "$comp_output" 3 - - set exitstat "succeeded" - if { $cmdret != 0 } { set exitstat "failed" } - verbose -log "$exitstat with: <$comp_output>" - fail $testname - return - } - } - } - - if { (($opts(warning) != "") && ($opts(error) != "")) \ - || (($opts(warning) != "") && ($opts(error_output) != "")) \ - || (($opts(warning) != "") && ($opts(warning_output) != "")) \ - || (($opts(error) != "") && ($opts(warning_output) != "")) \ - || (($opts(error) != "") && ($opts(error_output) != "")) \ - || (($opts(warning_output) != "") && ($opts(error_output) != "")) } { - perror "$testname: bad mix of warning, error, warning_output, and error_output test-directives" - unresolved $testname - return - } - - set check_ld(source) "" - set check_ld(terminal) 0 - if { $opts(error) != "" \ - || $opts(warning) != "" \ - || $opts(error_output) != "" \ - || $opts(warning_output) != "" } { - - if { $opts(error) != "" || $opts(error_output) != "" } { - set check_ld(terminal) 1 - } else { - set check_ld(terminal) 0 - } - - if { $opts(error) != "" || $opts(warning) != "" } { - set check_ld(source) "regex" - if { $opts(error) != "" } { - set check_ld(regex) $opts(error) - } else { - set check_ld(regex) $opts(warning) - } - } else { - set check_ld(source) "file" - if { $opts(error_output) != "" } { - set check_ld(file) $opts(error_output) - } else { - set check_ld(file) $opts(warning_output) - } - } - } - - # Perhaps link the file(s). - if { $run_ld } { - set objfile "tmpdir/dump" - catch "exec rm -f $objfile" exec_output - - # Add -L$srcdir/$subdir so that the linker command can use - # linker scripts in the source directory. - set cmd "$LD $ld_extra_opt $LDFLAGS -L$srcdir/$subdir \ - $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)" - - # If needed then check for, or add a -Map option. - set mapfile "" - if { $opts(map) != "" } then { - if { [regexp -- "-Map=(\[^ \]+)" $cmd all mapfile] } then { - # Found existing mapfile option - verbose -log "Existing mapfile '$mapfile' found" - } else { - # No mapfile option. - set mapfile "tmpdir/dump.map" - verbose -log "Adding mapfile '$mapfile'" - set cmd "$cmd -Map=$mapfile" - } - } - - send_log "$cmd\n" - set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"] - remote_upload host "ld.tmp" - set comp_output [file_contents "ld.tmp"] - remote_file host delete "ld.tmp" - remote_file build delete "ld.tmp" - set cmdret [lindex $cmdret 0] - - if { $cmdret == 0 && $run_objcopy } { - set infile $objfile - set objfile "tmpdir/dump1" - remote_file host delete $objfile - - # Note that we don't use OBJCOPYFLAGS here; any flags must be - # explicitly specified. - set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile" - - send_log "$cmd\n" - set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"] - remote_upload host "ld.tmp" - append comp_output [file_contents "ld.tmp"] - remote_file host delete "ld.tmp" - remote_file build delete "ld.tmp" - set cmdret [lindex $cmdret 0] - } - - regsub "\n$" $comp_output "" comp_output - if { $cmdret != 0 || $comp_output != "" || $check_ld(source) != "" } then { - set exitstat "succeeded" - if { $cmdret != 0 } { set exitstat "failed" } - - if { $check_ld(source) == "regex" } { - verbose -log "$exitstat with: <$comp_output>, expected: <$check_ld(regex)>" - } elseif { $check_ld(source) == "file" } { - verbose -log "$exitstat with: <$comp_output>, expected in file $check_ld(file)" - set_file_contents "tmpdir/ld.messages" "$comp_output" - } else { - verbose -log "$exitstat with: <$comp_output>, no expected output" - } - send_log -- "$comp_output\n" - verbose "$comp_output" 3 - - if { (($check_ld(source) == "") == ($comp_output == "")) \ - && (($cmdret == 0) == ($check_ld(terminal) == 0)) \ - && ((($check_ld(source) == "regex") \ - && ($check_ld(regex) == "") == ($comp_output == "") \ - && [regexp -- $check_ld(regex) $comp_output]) \ - || (($check_ld(source) == "file") \ - && (![regexp_diff "tmpdir/ld.messages" "$srcdir/$subdir/$check_ld(file)"]))) } { - # We have the expected output from ld. - if { $check_ld(terminal) || $dumpprogram == "" } { - pass $testname - return - } - } else { - fail $testname - return - } - } - - if { $opts(map) != "" } then { - # Check the map file matches. - set map_pattern_file $srcdir/$subdir/$opts(map) - verbose -log "Compare '$mapfile' against '$map_pattern_file'" - if { [regexp_diff $mapfile $map_pattern_file] } then { - fail "$testname (map file check)" - } else { - pass "$testname (map file check)" - } - - if { $dumpprogram == "" } then { - return - } - } - } else { - set objfile [lindex $objfiles 0] - } - - # We must not have expected failure if we get here. - if { $opts(error) != "" } { - fail $testname - return - } - - set progopts1 $opts($dumpprogram) - eval set progopts \$[string toupper $dumpprogram]FLAGS - eval set binary \$[string toupper $dumpprogram] - - if { ![is_remote host] && [which $binary] == 0 } { - untested $testname - return - } - - if { $progopts1 == "" } { set $progopts1 "-r" } - verbose "running $binary $progopts $progopts1" 3 - set cmd "$binary $progopts $progopts1 $objfile > $dumpfile" - - # Ensure consistent sorting of symbols - if {[info exists env(LC_ALL)]} { - set old_lc_all $env(LC_ALL) - } - set env(LC_ALL) "C" - send_log "$cmd\n" - set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"] - set cmdret [lindex $cmdret 0] - remote_upload host "ld.tmp" - set comp_output [prune_warnings [file_contents "ld.tmp"]] - remote_file host delete "ld.tmp" - remote_file build delete "ld.tmp" - if {[info exists old_lc_all]} { - set env(LC_ALL) $old_lc_all - } else { - unset env(LC_ALL) - } - if { $cmdret != 0 || $comp_output != "" } { - send_log "exited abnormally with $cmdret, output:$comp_output\n" - fail $testname - return - } - - if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 } - if { [regexp_diff $dumpfile "${dfile}"] } then { - fail $testname - if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 } - return - } - - pass $testname -} - -proc slurp_options { file } { - # If options_regsub(foo) is set to {a b}, then the contents of a - # "#foo:" line will have regsub -all applied to replace a with b. - global options_regsub - - if [catch { set f [open $file r] } x] { - #perror "couldn't open `$file': $x" - perror "$x" - return -1 - } - set opt_array {} - # whitespace expression - set ws {[ ]*} - set nws {[^ ]*} - # whitespace is ignored anywhere except within the options list; - # option names are alphabetic plus underscore only. - set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$" - while { [gets $f line] != -1 } { - set line [string trim $line] - # Whitespace here is space-tab. - if [regexp $pat $line xxx opt_name opt_val] { - # match! - if [info exists options_regsub($opt_name)] { - set subst $options_regsub($opt_name) - regsub -all -- [lindex $subst 0] $opt_val [lindex $subst 1] \ - opt_val - } - lappend opt_array [list $opt_name $opt_val] - } else { - break - } - } - close $f - return $opt_array -} - -proc file_contents { filename } { - set file [open $filename r] - set contents [read $file] - close $file - return $contents -} - -proc set_file_contents { filename contents } { - set file [open $filename w] - puts $file "$contents" - close $file -} - # Create an archive using ar # proc ar_simple_create { ar aropts target objects } { @@ -2209,19 +1432,6 @@ proc check_ifunc_attribute_available { } { return $ifunc_attribute_available_saved } -# Provide virtual target "cfi" for targets supporting CFI. - -rename "istarget" "istarget_ld" -proc istarget { target } { - if {$target == "cfi"} { - return [check_as_cfi] - } - if {$target == "shared"} { - return [check_shared_lib_support] - } - return [istarget_ld $target] -} - # Return true if libdl is supported. proc check_libdl_available { } { -- 2.30.2