-# Copyright (C) 1993-2019 Free Software Foundation, Inc.
+# Copyright (C) 1993-2020 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
# True if the object format is known to be PE COFF.
#
proc is_pecoff_format {} {
- if { ![istarget *-*-mingw*]
- && ![istarget *-*-cygwin*]
- && ![istarget *-*-cegcc*]
- && ![istarget *-*-pe*] } {
- return 0
+ if { [istarget *-*-beospe*]
+ || [istarget *-*-cegcc*]
+ || [istarget *-*-cygwin*]
+ || [istarget *-*-interix*]
+ || [istarget *-*-mingw*]
+ || [istarget *-*-netbsdpe*]
+ || [istarget *-*-pe*]
+ || [istarget *-*-winnt*] } {
+ return 1
}
-
- return 1
+ return 0
}
proc is_som_format {} {
# in square brackets or as machine triplet otherwise.
#
proc match_target { target } {
- if [string match {\[*\]} $target] {
+ if [regexp {^!?\[.*\]$} $target] {
return $target
} else {
return [istarget $target]
}
}
-# True if the ELF target supports STB_GNU_UNIQUE with the ELF header's
-# OSABI field set to ELFOSABI_GNU.
+# True if the ELF target supports setting the ELF header OSABI field
+# to ELFOSABI_GNU or ELFOSABI_FREEBSD, a requirement for STT_GNU_IFUNC
+# symbol and SHF_GNU_MBIND section support.
#
# This generally depends on the target OS only, however there are a
# number of exceptions for bare metal targets as follows. The MSP430
-# and Visium targets set OSABI to ELFOSABI_STANDALONE and cannot
-# support STB_GNU_UNIQUE. Likewise non-EABI ARM targets set OSABI to
-# ELFOSABI_ARM, and TI C6X targets to ELFOSABI_C6000_*. Finally
-# rather than `bfd_elf_final_link' AM33/2.0, D30V, DLX, and
-# picoJava targets use `_bfd_generic_final_link', which does not
-# support STB_GNU_UNIQUE symbol binding causing assertion failures.
+# and Visium targets set OSABI to ELFOSABI_STANDALONE. Likewise
+# non-EABI ARM targets set OSABI to ELFOSABI_ARM
#
-proc supports_gnu_unique {} {
+# Note that some TI C6X targets use ELFOSABI_C6000_* but one doesn't,
+# so we don't try to sort out tic6x here. (The effect is that linker
+# testcases will generally need to exclude tic6x or use a -m option.)
+#
+proc supports_gnu_osabi {} {
if { [istarget *-*-gnu*]
|| [istarget *-*-linux*]
- || [istarget *-*-nacl*] } {
- return 1
- }
- if { [istarget "arm*-*-*eabi*"] } {
+ || [istarget *-*-nacl*]
+ || ( [istarget *-*-*bsd*] && ![istarget arm*-*-netbsd*] )
+ || [istarget *-*-symbianelf]
+ || [istarget *-*-lynxos]
+ || ( [istarget *-*-nto*] && ![istarget arm*-*-*] )
+ || [istarget *-*-irix*]
+ || [istarget *-*-*eabi*]
+ || [istarget *-*-rtems*] } {
return 1
}
if { [istarget "wasm32*-*-*"] } {
}
if { [istarget "arm*-*-*"]
|| [istarget "msp430-*-*"]
- || [istarget "tic6x-*-*"]
|| [istarget "visium-*-*"] } {
return 0
}
- if { [istarget "am33_2.0-*-*"]
- || [istarget "d30v-*-*"]
+ return 1
+}
+
+# Return true if target uses the generic_link_hash_table linker.
+proc is_generic { } {
+ if { [istarget "d30v-*-*"]
|| [istarget "dlx-*-*"]
|| [istarget "pj*-*-*"]
+ || [istarget "s12z-*-*"]
|| [istarget "xgate-*-*"] } {
+ return 1
+ }
+ return 0
+}
+
+# True if the ELF target supports STB_GNU_UNIQUE.
+#
+# This require ELFOSABI_GNU, and `bfd_elf_final_link'.
+#
+proc supports_gnu_unique {} {
+ if { [istarget *-*-freebsd*] } {
return 0
}
- return 1
+ if { [supports_gnu_osabi] && ![is_generic] } {
+ return 1
+ }
+ return 0
}
# True for targets that do not sort .symtab as per the ELF standard.
# REGEXP
# Skip all lines in FILE_1 until the first that matches REGEXP.
#
+# #?REGEXP
+# Optionally match REGEXP against line from FILE_1. If the REGEXP
+# does not match then the next line from FILE_2 is tried.
+#
# Other # lines are comments. Regexp lines starting with the `!' character
# specify inverse matching (use `\!' for literal matching against a leading
# `!'). Skip empty lines in both files.
}
}
break
+ } elseif { [string match "#\\?*" $line_b] } {
+ if { ! $end_1 } {
+ set line_b [string replace $line_b 0 1]
+ set negated [expr { [string index $line_b 0] == "!" }]
+ set line_bx [string range $line_b $negated end]
+ set n [expr { $negated ? "! " : "" }]
+ # Substitute on the reference.
+ foreach {name value} $ref_subst {
+ regsub -- $name $line_bx $value line_bx
+ }
+ verbose "optional match for $n\"^$line_bx$\"" 3
+ if { [expr [regexp "^$line_bx$" "$line_a"] != $negated] } {
+ break
+ }
+ }
}
if { [gets $file_b line_b] == $eof } {
set end_2 1
# When assembling, pass FLAGS to the assembler.
# If assembling several files, you can pass different assembler
# options in the "source" directives. See below.
+# Multiple instances of this directive tells run_dump_test to run the test
+# multiple times -- one time with each set of flags provided.
+# Each instance will run exactly as a file with a single "as" line, it is
+# not possible to condition any behaviour on which set of "as" flags is
+# used. That means that the "source" specific options are appended to
+# the "as" flags for their corresponding files, and any extra processing
+# (e.g. with "ld" and "objcopy") is repeated for each test.
#
# ld: FLAGS
# Link assembled files using FLAGS, in the order of the "source"
set opts(anyskip) {}
set opts(ar) {}
set opts(as) {}
+ set as_final_flags {}
+ set as_additional_flags {}
set opts(dump) {}
set opts(elfedit) {}
set opts(error) {}
lappend objfile_names $new_objfile
}
default {
- if { !$in_extra && [string length $opts($opt_name)] } {
+ if { !$in_extra
+ && [string length $opts($opt_name)]
+ && $opt_name != "as" } {
perror "option $opt_name multiply set in $file.d"
unresolved $subdir/$name
return
error {
append opts($opt_name) $opt_val
}
+ as {
+ if { $in_extra } {
+ set as_additional_flags [concat $as_additional_flags $opt_val]
+ } else {
+ lappend opts(as) $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)
+ # Ensure there is something in $opts(as) for the foreach loop below.
+ if { [llength $opts(as)] == 0 } {
+ set opts(as) [list " "]
+ }
+ foreach x $opts(as) {
+ if { [string length $x] && [string length $as_additional_flags] } {
+ append x " "
+ }
+ append x $as_additional_flags
+ regsub {\[big_or_little_endian\]} $x \
+ [big_or_little_endian] x
+ lappend as_final_flags $x
}
+ regsub {\[big_or_little_endian\]} $opts(ld) \
+ [big_or_little_endian] opts(ld)
+
if { $opts(name) == "" } {
set testname "$subdir/$name"
} else {
} else {
set sourcefiles {}
foreach sf $opts(source) {
- if { [string match "/*" $sf] } {
+ if { [string match "./*" $sf] } {
lappend sourcefiles "$sf"
} else {
lappend sourcefiles "$srcdir/$subdir/$sf"
# 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*"] \
- && ![istarget "*-*-netbsd*" ] } {
- 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]
+ if [match_target $targ] {
+ setup_xfail "*-*-*"
+ break
}
}
- # 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 ""
- global ld
- set ld "$LD"
- 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 \
+ foreach as_flags $as_final_flags {
+ # 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 { $as_flags == "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*"] \
+ && ![istarget "*-*-netbsd*" ] } {
+ 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
+ continue
+ }
+ set sourcefile tmpdir/asm.s
+ }
+ set cmd "$AS $ASFLAGS $as_flags $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 ""
+ global ld
+ set ld "$LD"
+ 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 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
+ continue
+ }
+ }
+
+ 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
+ continue
+ }
+
+ 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
+ continue
+ }
+ } else {
+ fail $testname
+ continue
+ }
+ }
+
+ # We must not have expected failure if we get here.
+ if { $opts(error) != "" } {
+ fail $testname
+ continue
+ }
+
+ 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 {
+ continue
+ }
+ }
+
+ 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
+ continue
+ }
+
+ # 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
+ continue
+ }
+
+ 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 }
+ continue
+ }
+
+ pass $testname
}
-
- 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 } {
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} {
+ switch -glob $x {
+ *big*endian -
+ eb -
+ EB -
+ -eb -
+ -EB -
+ -mb -
+ -meb {
set flags " -EB"
return $flags
}
- {*little*endian el EL -el -EL -ml -mel} {
+ *little*endian -
+ el -
+ EL -
+ -el -
+ -EL -
+ -ml -
+ -mel {
set flags " -EL"
return $flags
}