forked from Imagelibrary/binutils-gdb
Similar to the AArch64 patches the Arm disassembler has the same issues with
out of order sections but also a few short comings.
For one thing there are multiple code blocks to determine mapping symbols, and
they all work slightly different, and neither fully correct. The first thing
this patch does is centralise the mapping symbols search into one function
mapping_symbol_for_insn. This function is then updated to perform a search in
a similar way as AArch64.
Their used to be a value has_mapping_symbols which was used to determine the
default disassembly for objects that have no mapping symbols. The problem with
the approach was that it was determining this value in the same loop that needed
it, which is why this field could take on the states -1, 0, 1 where -1 means
"don't know". However this means that until you actually find a mapping symbol
or reach the end of the disassembly glob, you don't know if you did the right
action or not, and if you didn't you can't correct it anymore.
This is why the two jump-reloc-veneers-* testcases end up disassembling some
insn as data when they shouldn't.
Out of order here refers to an object file where sections are not listed in a
monotonic increasing VMA order.
The ELF ABI for Arm [1] specifies the following for mapping symbols:
1) A text section must always have a corresponding mapping symbol at it's
start.
2) Data sections do not require any mapping symbols.
3) The range of a mapping symbol extends from the address it starts on up to
the next mapping symbol (exclusive) or section end (inclusive).
However there is no defined order between a symbol and it's corresponding
mapping symbol in the symbol table. This means that while in general we look
up for a corresponding mapping symbol, we have to make at least one check of
the symbol below the address being disassembled.
When disassembling different PCs within the same section, the search for mapping
symbol can be cached somewhat. We know that the mapping symbol corresponding to
the current PC is either the previous one used, or one at the same address as
the current PC.
However this optimization and mapping symbol search must stop as soon as we
reach the end or start of the section. Furthermore if we're only disassembling
a part of a section, the search is a allowed to search further than the current
chunk, but is not allowed to search past it (The mapping symbol if there, must
be at the same address, so in practice we usually stop at PC+4).
lastly, since only data sections don't require a mapping symbol the default
mapping type should be DATA and not INSN as previously defined, however if the
binary has had all its symbols stripped than this isn't very useful. To fix
this we determine the default based on the section flags. This will allow the
disassembler to be more useful on stripped binaries. If there is no section
than we assume you to be disassembling INSN.
[1] https://developer.arm.com/docs/ihi0044/latest/elf-for-the-arm-architecture-abi-2018q4-documentation#aaelf32-table4-7
binutils/ChangeLog:
* testsuite/binutils-all/arm/in-order-all.d: New test.
* testsuite/binutils-all/arm/in-order.d: New test.
* testsuite/binutils-all/arm/objdump.exp: Support .d tests.
* testsuite/binutils-all/arm/out-of-order-all.d: New test.
* testsuite/binutils-all/arm/out-of-order.T: New test.
* testsuite/binutils-all/arm/out-of-order.d: New test.
* testsuite/binutils-all/arm/out-of-order.s: New test.
ld/ChangeLog:
* testsuite/ld-arm/jump-reloc-veneers-cond-long.d: Update disassembly.
* testsuite/ld-arm/jump-reloc-veneers-long.d: Update disassembly.
opcodes/ChangeLog:
* arm-dis.c (struct arm_private_data): Remove has_mapping_symbols.
(mapping_symbol_for_insn): Implement new algorithm.
(print_insn): Remove duplicate code.
128 lines
3.4 KiB
Plaintext
128 lines
3.4 KiB
Plaintext
# Copyright (C) 2004-2019 Free Software Foundation, Inc.
|
|
|
|
# This program 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.
|
|
|
|
if {![istarget "arm*-*-*"]} then {
|
|
return
|
|
}
|
|
|
|
if {![is_remote host] && [which $OBJDUMP] == 0} then {
|
|
perror "$OBJDUMP does not exist"
|
|
return
|
|
}
|
|
|
|
send_user "Version [binutil_version $OBJDUMP]"
|
|
|
|
###########################
|
|
# Set up the test of movem.s
|
|
###########################
|
|
|
|
if {![binutils_assemble $srcdir/$subdir/thumb2-cond.s tmpdir/thumb2-cond.o]} then {
|
|
fail "thumb2-cond (assembling)"
|
|
} else {
|
|
|
|
if [is_remote host] {
|
|
set objfile [remote_download host tmpdir/thumb2-cond.o]
|
|
} else {
|
|
set objfile tmpdir/thumb2-cond.o
|
|
}
|
|
|
|
# Make sure that conditional instructions are correctly decoded.
|
|
|
|
set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS --disassemble --start-address=6 $objfile"]
|
|
|
|
set want "bcc.w\[ \t\]*e12.*bx\[ \t\]*lr"
|
|
|
|
if [regexp $want $got] then {
|
|
pass "thumb2-cond test1"
|
|
} else {
|
|
fail "thumb2-cond test1"
|
|
}
|
|
|
|
set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS --disassemble --start-address=10 $objfile"]
|
|
|
|
set want "bx\[ \t\]*lr"
|
|
|
|
if [regexp $want $got] then {
|
|
pass "thumb2-cond test2"
|
|
} else {
|
|
fail "thumb2-cond test2"
|
|
}
|
|
}
|
|
|
|
###########################
|
|
# Set up the test of multiple disassemblies
|
|
###########################
|
|
|
|
if {![binutils_assemble $srcdir/$subdir/simple.s tmpdir/simple.o]} then {
|
|
fail "multiple input files"
|
|
} else {
|
|
|
|
if [is_remote host] {
|
|
set objfile [remote_download host tmpdir/simple.o]
|
|
} else {
|
|
set objfile tmpdir/simple.o
|
|
}
|
|
|
|
# Make sure multiple disassemblies come out the same
|
|
|
|
set got [binutils_run $OBJDUMP "-dr $objfile $objfile"]
|
|
|
|
set want "$objfile:\[ \]*file format.*$objfile:\[ \]*file format.*push.*add.*sub.*str.*add.*ldmfd"
|
|
|
|
if [regexp $want $got] then {
|
|
pass "multiple input files"
|
|
} else {
|
|
fail "multiple input files"
|
|
}
|
|
}
|
|
|
|
if {![binutils_assemble $srcdir/$subdir/rvct_symbol.s tmpdir/rvct_symbol.o]} then {
|
|
fail "skip rvct symbol"
|
|
} else {
|
|
|
|
if [is_remote host] {
|
|
set objfile [remote_download host tmpdir/rvct_symbol.o]
|
|
} else {
|
|
set objfile tmpdir/rvct_symbol.o
|
|
}
|
|
|
|
# Make sure multiple disassemblies come out the same
|
|
|
|
set got [binutils_run $OBJDUMP "-D $objfile $objfile"]
|
|
|
|
set want "foo.*global_a.*global_b"
|
|
|
|
if [regexp $want $got] then {
|
|
pass "skip rvct symbol"
|
|
} else {
|
|
fail "skip rvct symbol"
|
|
}
|
|
}
|
|
|
|
###########################
|
|
# Set up generic test framework
|
|
###########################
|
|
|
|
set tempfile tmpdir/armtemp.o
|
|
set copyfile tmpdir/armcopy
|
|
|
|
set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
|
|
foreach t $test_list {
|
|
# We need to strip the ".d", but can leave the dirname.
|
|
verbose [file rootname $t]
|
|
run_dump_test [file rootname $t]
|
|
}
|