forked from Imagelibrary/binutils-gdb
Some MIPS targets use a named section symbol rather than a symbol with
no name as is used with most ELF targets. When renaming sections, the
named section symbol needs to be renamed too.
Rather than fix this bug, I'd originally intended to just correct the
xfail added recently for update-1.o vs update4.o in update-section.exp,
using the same set of targets for the localize-hidden-1 mips xfail.
I'd extracted that target test into a new function, is_bad_symtab. It
turns out to be useful in readelf.exp too.
bfd/
* config.bfd: Delete mips vxworks patterns matched earlier.
Combine mips*-*-none with mips*-*-elf*.
binutils/
* objcopy.c (find_section_rename): Forward declare. Remove
ibfd and sec_ptr param. Add old_name param. Allow for NULL
returned_flags. Move read of section name and flags to..
(setup_section): ..here. Update find_section_rename call.
(filter_symbols): Rename section symbols for renamed sections.
(copy_object): Call filter_symbols when renamed sections.
* testsuite/lib/binutils-common.exp (is_bad_symtab): New.
* testsuite/binutils-all/update-section.exp: Revert 96037eb0
mips xfail.
* testsuite/binutils-all/objcopy.exp (copy_executable): Use
is_bad_symtab.
(localize-hidden-1): xfail if is_bad_symtab.
* testsuite/binutils-all/readelf.exp: Use is_bad_symtab to select
between mips/tmips.
397 lines
11 KiB
Plaintext
397 lines
11 KiB
Plaintext
# Copyright (C) 1993-2016 Free Software Foundation, Inc.
|
|
#
|
|
# This file is part of the GNU Binutils.
|
|
#
|
|
# This file is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
|
# MA 02110-1301, USA.
|
|
|
|
# True if the object format is known to be ELF.
|
|
#
|
|
proc is_elf_format {} {
|
|
# config.sub for these targets curiously transforms a target doublet
|
|
# ending in -elf to -none. eg. m68hc12-elf to m68hc12-unknown-none
|
|
# They are always elf.
|
|
if { [istarget m68hc1*-*] || [istarget xgate-*] } {
|
|
return 1;
|
|
}
|
|
|
|
if { ![istarget *-*-eabi*]
|
|
&& ![istarget *-*-elf*]
|
|
&& ![istarget *-*-freebsd*]
|
|
&& ![istarget *-*-gnu*]
|
|
&& ![istarget *-*-irix5*]
|
|
&& ![istarget *-*-irix6*]
|
|
&& ![istarget *-*-linux*]
|
|
&& ![istarget *-*-nacl*]
|
|
&& ![istarget *-*-netbsd*]
|
|
&& ![istarget *-*-openbsd*]
|
|
&& ![istarget *-*-rtems*]
|
|
&& ![istarget *-*-solaris2*]
|
|
&& ![istarget *-*-sysv4*]
|
|
&& ![istarget *-*-unixware*]
|
|
&& ![istarget avr-*-*]
|
|
&& ![istarget bfin-*-uclinux]
|
|
&& ![istarget frv-*-uclinux*]
|
|
&& ![istarget hppa*64*-*-hpux*]
|
|
&& ![istarget ia64-*-hpux*]
|
|
&& ![istarget sh*-*-uclinux*]
|
|
&& ![istarget tic6x*-*-uclinux*] } {
|
|
return 0
|
|
}
|
|
|
|
if { [istarget *-*-linux*aout*]
|
|
|| [istarget *-*-linux*ecoff*]
|
|
|| [istarget *-*-linux*oldld*]
|
|
|| [istarget *-*-rtemscoff*]
|
|
|| [istarget h8500-*-rtems*]
|
|
|| [istarget i?86-*-freebsd\[12\].*]
|
|
|| [istarget i960-*-rtems*] } {
|
|
return 0
|
|
}
|
|
|
|
if { ![istarget *-*-netbsdelf*]
|
|
&& ( [istarget *-*-netbsd*aout*]
|
|
|| [istarget *-*-netbsdpe*]
|
|
|| [istarget arm*-*-netbsd*]
|
|
|| [istarget sparc-*-netbsd*]
|
|
|| [istarget i*86-*-netbsd*]
|
|
|| [istarget m68*-*-netbsd*]
|
|
|| [istarget vax-*-netbsd*]
|
|
|| [istarget ns32k-*-netbsd*]) } {
|
|
return 0
|
|
}
|
|
|
|
if { [istarget arm-*-openbsd*]
|
|
|| [istarget i386-*-openbsd\[0-2\].*]
|
|
|| [istarget i386-*-openbsd3.\[0-2\]]
|
|
|| [istarget m68*-*-openbsd*]
|
|
|| [istarget ns32k-*-openbsd*]
|
|
|| [istarget sparc-*-openbsd\[0-2\].*]
|
|
|| [istarget sparc-*-openbsd3.\[0-1\]]
|
|
|| [istarget vax-*-openbsd*] } {
|
|
return 0
|
|
}
|
|
|
|
return 1
|
|
}
|
|
|
|
# True if the object format is known to be a.out.
|
|
#
|
|
proc is_aout_format {} {
|
|
if { [istarget *-*-netbsdelf]
|
|
|| [istarget sparc64-*-netbsd*]
|
|
|| [istarget sparc64-*-openbsd*] } {
|
|
return 0
|
|
}
|
|
if { [istarget *-*-*\[ab\]out*]
|
|
|| [istarget *-*-linux*oldld*]
|
|
|| [istarget *-*-bsd*]
|
|
|| [istarget *-*-msdos*]
|
|
|| [istarget arm-*-netbsd*]
|
|
|| [istarget arm-*-openbsd*]
|
|
|| [istarget arm-*-riscix*]
|
|
|| [istarget i?86-*-freebsd\[12\].*]
|
|
|| [istarget i?86-*-netbsd*]
|
|
|| [istarget i?86-*-openbsd\[0-2\]*]
|
|
|| [istarget i?86-*-openbsd3.\[0-2\]*]
|
|
|| [istarget i?86-*-vsta]
|
|
|| [istarget i?86-*-mach*]
|
|
|| [istarget m68*-*-netbsd*]
|
|
|| [istarget m68*-*-openbsd*]
|
|
|| [istarget ns32k-*-*]
|
|
|| [istarget pdp11-*-*]
|
|
|| [istarget sparc*-*-sunos4*]
|
|
|| [istarget sparc*-*-netbsd*]
|
|
|| [istarget sparc*-*-openbsd\[0-2\]*]
|
|
|| [istarget sparc*-*-openbsd3.\[0-1\]*]
|
|
|| [istarget sparc*-fujitsu-none]
|
|
|| [istarget vax-dec-ultrix*]
|
|
|| [istarget vax-*-netbsd] } {
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
# 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
|
|
}
|
|
|
|
return 1
|
|
}
|
|
|
|
# True if the object format is known to be 64-bit ELF.
|
|
#
|
|
proc is_elf64 { binary_file } {
|
|
global READELF
|
|
global READELFFLAGS
|
|
|
|
set readelf_size ""
|
|
catch "exec $READELF $READELFFLAGS -h $binary_file > readelf.out" got
|
|
|
|
if ![string match "" $got] then {
|
|
return 0
|
|
}
|
|
|
|
if { ![regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \
|
|
[file_contents readelf.out] nil readelf_size] } {
|
|
return 0
|
|
}
|
|
|
|
if { $readelf_size == "64" } {
|
|
return 1
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
# True if the ELF target supports STB_GNU_UNIQUE with the ELF header's
|
|
# OSABI field set to ELFOSABI_GNU.
|
|
#
|
|
# 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, i960, and
|
|
# picoJava targets use `_bfd_generic_final_link', which does not
|
|
# support STB_GNU_UNIQUE symbol binding causing assertion failures.
|
|
#
|
|
proc supports_gnu_unique {} {
|
|
if { [istarget *-*-gnu*]
|
|
|| [istarget *-*-linux*]
|
|
|| [istarget *-*-nacl*] } {
|
|
return 1
|
|
}
|
|
if { [istarget "arm*-*-*eabi*"] } {
|
|
return 1
|
|
}
|
|
if { ![istarget "*-*-elf*"] } {
|
|
return 0
|
|
}
|
|
if { [istarget "arm*-*-*"]
|
|
|| [istarget "msp430-*-*"]
|
|
|| [istarget "tic6x-*-*"]
|
|
|| [istarget "visium-*-*"] } {
|
|
return 0
|
|
}
|
|
if { [istarget "am33_2.0-*-*"]
|
|
|| [istarget "d30v-*-*"]
|
|
|| [istarget "dlx-*-*"]
|
|
|| [istarget "i960-*-*"]
|
|
|| [istarget "pj*-*-*"] } {
|
|
return 0
|
|
}
|
|
return 1
|
|
}
|
|
|
|
# True for targets that do not sort .symtab as per the ELF standard.
|
|
# ie. any that have mips_elf32_be_vec, mips_elf32_le_vec,
|
|
# mips_elf32_n_be_vec or mips_elf32_n_le_vec as the primary bfd target
|
|
# vector in config.bfd. When syncing with config.bfd, don't forget that
|
|
# earlier case-matches trump later ones.
|
|
proc is_bad_symtab {} {
|
|
if { ![istarget "mips*-*-*"] } {
|
|
return 0;
|
|
}
|
|
if { [istarget "*-*-chorus*"]
|
|
|| [istarget "*-*-irix5*"]
|
|
|| [istarget "*-*-irix6*"]
|
|
|| [istarget "*-*-none"]
|
|
|| [istarget "*-*-rtems*"]
|
|
|| [istarget "*-*-windiss"] } {
|
|
return 1;
|
|
}
|
|
if { [istarget "*-*-elf*"]
|
|
&& ![istarget "*-sde-*"]
|
|
&& ![istarget "*-mti-*"]
|
|
&& ![istarget "*-img-*"] } {
|
|
return 1;
|
|
}
|
|
if { [istarget "*-*-openbsd*"]
|
|
&& ![istarget "mips64*-*-*"] } {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
# Compare two files line-by-line. FILE_1 is the actual output and FILE_2
|
|
# is the expected output. Ignore blank lines in either file.
|
|
#
|
|
# FILE_2 is a series of regexps, comments and # directives. The directives
|
|
# are:
|
|
#
|
|
# #pass
|
|
# Treat the test as a PASS if everything up till this point has
|
|
# matched. Ignore any remaining lines in either FILE_1 or FILE_2.
|
|
#
|
|
# #failif
|
|
# Reverse the sense of the test: expect differences to exist.
|
|
#
|
|
# #...
|
|
# REGEXP
|
|
# Skip all lines in FILE_1 until the first that matches REGEXP.
|
|
#
|
|
# 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.
|
|
#
|
|
# The first optional argument is a list of regexp substitutions of the form:
|
|
#
|
|
# EXP1 SUBSPEC1 EXP2 SUBSPEC2 ...
|
|
#
|
|
# This tells the function to apply each regexp substitution EXPi->SUBSPECi
|
|
# in order to every line of FILE_2.
|
|
#
|
|
# Return nonzero if differences exist.
|
|
proc regexp_diff { file_1 file_2 args } {
|
|
set eof -1
|
|
set end_1 0
|
|
set end_2 0
|
|
set differences 0
|
|
set diff_pass 0
|
|
set fail_if_match 0
|
|
set ref_subst ""
|
|
if { [llength $args] > 0 } {
|
|
set ref_subst [lindex $args 0]
|
|
}
|
|
if { [llength $args] > 1 } {
|
|
perror "Too many arguments to regexp_diff"
|
|
return 1
|
|
}
|
|
|
|
if [file exists $file_1] then {
|
|
set file_a [open $file_1 r]
|
|
} else {
|
|
perror "$file_1 doesn't exist"
|
|
return 1
|
|
}
|
|
|
|
if [file exists $file_2] then {
|
|
set file_b [open $file_2 r]
|
|
} else {
|
|
perror "$file_2 doesn't exist"
|
|
close $file_a
|
|
return 1
|
|
}
|
|
|
|
verbose " Regexp-diff'ing: $file_1 $file_2" 2
|
|
|
|
while { 1 } {
|
|
set line_a ""
|
|
set line_b ""
|
|
while { [string length $line_a] == 0 } {
|
|
# Ignore blank line in FILE_1.
|
|
if { [gets $file_a line_a] == $eof } {
|
|
set end_1 1
|
|
break
|
|
}
|
|
}
|
|
while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
|
|
if { [string match "#pass" $line_b] } {
|
|
set end_2 1
|
|
set diff_pass 1
|
|
break
|
|
} elseif { [string match "#failif" $line_b] } {
|
|
send_log "fail if no difference\n"
|
|
verbose "fail if no difference" 3
|
|
set fail_if_match 1
|
|
} elseif { [string match "#..." $line_b] } {
|
|
if { [gets $file_b line_b] == $eof } {
|
|
set end_2 1
|
|
set diff_pass 1
|
|
break
|
|
}
|
|
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 "looking for $n\"^$line_bx$\"" 3
|
|
while { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
|
|
verbose "skipping \"$line_a\"" 3
|
|
if { [gets $file_a line_a] == $eof } {
|
|
set end_1 1
|
|
break
|
|
}
|
|
}
|
|
break
|
|
}
|
|
if { [gets $file_b line_b] == $eof } {
|
|
set end_2 1
|
|
break
|
|
}
|
|
}
|
|
|
|
if { $diff_pass } {
|
|
break
|
|
} elseif { $end_1 && $end_2 } {
|
|
break
|
|
} elseif { $end_1 } {
|
|
send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
|
|
verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
|
|
set differences 1
|
|
break
|
|
} elseif { $end_2 } {
|
|
send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
|
|
verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
|
|
set differences 1
|
|
break
|
|
} else {
|
|
set negated [expr { [string index $line_b 0] == "!" }]
|
|
set line_bx [string range $line_b $negated end]
|
|
set n [expr { $negated ? "! " : "" }]
|
|
set s [expr { $negated ? " " : "" }]
|
|
# Substitute on the reference.
|
|
foreach {name value} $ref_subst {
|
|
regsub -- $name $line_bx $value line_bx
|
|
}
|
|
verbose "regexp $n\"^$line_bx$\"\nline \"$line_a\"" 3
|
|
if { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
|
|
send_log "regexp_diff match failure\n"
|
|
send_log "regexp $n\"^$line_bx$\"\nline $s\"$line_a\"\n"
|
|
verbose "regexp_diff match failure\n" 3
|
|
set differences 1
|
|
}
|
|
}
|
|
}
|
|
|
|
if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
|
|
send_log "$file_1 and $file_2 are different lengths\n"
|
|
verbose "$file_1 and $file_2 are different lengths" 3
|
|
set differences 1
|
|
}
|
|
|
|
if { $fail_if_match } {
|
|
if { $differences == 0 } {
|
|
set differences 1
|
|
} else {
|
|
set differences 0
|
|
}
|
|
}
|
|
|
|
close $file_a
|
|
close $file_b
|
|
|
|
return $differences
|
|
}
|