+2019-04-01 Tamar Christina <tamar.christina@arm.com>
+
+ Backport from mainline.
+ 2019-03-26 Tamar Christina <tamar.christina@arm.com>
+
+ * testsuite/binutils-all/aarch64/in-order-all.d: Update.
+ * testsuite/binutils-all/aarch64/in-order.d: Likewise.
+ * testsuite/binutils-all/aarch64/out-of-order-all.d: Likewise.
+ * testsuite/binutils-all/aarch64/out-of-order.d: Likewise.
+ * testsuite/binutils-all/aarch64/out-of-order.s: Likewise.
+ * testsuite/binutils-all/arm/in-order-all.d: Likewise.
+ * testsuite/binutils-all/arm/in-order.d: Likewise.
+ * testsuite/binutils-all/arm/out-of-order-all.d: Likewise.
+ * testsuite/binutils-all/arm/out-of-order.d: Likewise.
+ * testsuite/binutils-all/arm/out-of-order.s: Likewise.
+
+2019-04-01 Tamar Christina <tamar.christina@arm.com>
+
+ Backport from mainline.
+ 2019-03-25 Tamar Christina <tamar.christina@arm.com>
+
+ * 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.
+
+2019-04-01 Tamar Christina <tamar.christina@arm.com>
+
+ Backport from mainline.
+ 2019-03-25 Tamar Christina <tamar.christina@arm.com>
+
+ * testsuite/binutils-all/aarch64/in-order-all.d: New test.
+ * testsuite/binutils-all/aarch64/out-of-order-all.d: New test.
+ * testsuite/binutils-all/aarch64/out-of-order.d: Update.
+
+2019-04-01 Tamar Christina <tamar.christina@arm.com>
+
+ Backport from mainline.
+ 2019-03-25 Tamar Christina <tamar.christina@arm.com>
+
+ * testsuite/binutils-all/aarch64/in-order.d: New test.
+ * testsuite/binutils-all/aarch64/out-of-order.d: Disassemble data as
+ well.
+
+2019-04-01 Tamar Christina <tamar.christina@arm.com>
+
+ Backport from mainline.
+ 2019-03-25 Tamar Christina <tamar.christina@arm.com>
+
+ * objdump.c (disassemble_bytes): Pass stop_offset.
+ * testsuite/binutils-all/aarch64/out-of-order.T: New test.
+ * testsuite/binutils-all/aarch64/out-of-order.d: New test.
+ * testsuite/binutils-all/aarch64/out-of-order.s: New test.
+
2019-02-02 Nick Clifton <nickc@redhat.com>
* configure: Regenerate.
disassembling code of course, and when -D is in effect. */
inf->stop_vma = section->vma + stop_offset;
+ inf->stop_offset = stop_offset;
octets = (*disassemble_fn) (section->vma + addr_offset, inf);
inf->stop_vma = 0;
--- /dev/null
+#PROG: objcopy
+#source: out-of-order.s
+#ld: -e v1 -Ttext-segment=0x400000
+#objdump: -D
+#name: Check if disassembler can handle all sections in default order
+
+.*: +file format .*aarch64.*
+
+Disassembly of section \.func1:
+
+.+ <v1>:
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 00000000 \.inst 0x00000000 ; undefined
+
+Disassembly of section \.func2:
+
+.+ <\.func2>:
+[^:]+: 8b010000 add x0, x0, x1
+
+Disassembly of section \.func3:
+
+.+ <\.func3>:
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 00000000 \.inst 0x00000000 ; undefined
+
+Disassembly of section \.rodata:
+
+.+ <\.rodata>:
+[^:]+: 00000000 \.inst 0x00000000 ; undefined
+
+Disassembly of section .global:
+
+.+ <.+>:
+ ...
--- /dev/null
+#PROG: objcopy
+#source: out-of-order.s
+#ld: -e v1 -Ttext-segment=0x400000
+#objdump: -d
+#name: Check if disassembler can handle sections in default order
+
+.*: +file format .*aarch64.*
+
+Disassembly of section \.func1:
+
+.+ <v1>:
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 00000000 \.word 0x00000000
+
+Disassembly of section .func2:
+
+.+ <\.func2>:
+[^:]+: 8b010000 add x0, x0, x1
+
+Disassembly of section \.func3:
+
+.+ <\.func3>:
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 00000000 \.word 0x00000000
--- /dev/null
+#PROG: objcopy
+#source: out-of-order.s
+#ld: -T out-of-order.T
+#objdump: -D
+#name: Check if disassembler can handle all sections in different order than header
+
+.*: +file format .*aarch64.*
+
+Disassembly of section \.global:
+
+.+ <\.global>:
+ ...
+
+Disassembly of section \.func2:
+
+.+ <\.func2>:
+[^:]+: 8b010000 add x0, x0, x1
+
+Disassembly of section \.func1:
+
+.+ <v1>:
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 00000000 \.inst 0x00000000 ; undefined
+
+Disassembly of section \.func3:
+
+.+ <\.func3>:
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 00000000 \.inst 0x00000000 ; undefined
+
+Disassembly of section \.rodata:
+
+.+ <\.rodata>:
+[^:]+: 00000000 \.inst 0x00000000 ; undefined
--- /dev/null
+ENTRY(v1)
+SECTIONS
+{
+ . = 0xffe00000;
+ .global : { *(.global) }
+ . = 0x4018280;
+ .func2 : { *(.func2) }
+ . = 0x4005000;
+ .func1 : { *(.func1) }
+ . = 0x4015000;
+ .func3 : { *(.func3) }
+ .data : { *(.data) }
+ .rodata : { *(.rodata) }
+}
\ No newline at end of file
--- /dev/null
+#PROG: objcopy
+#ld: -T out-of-order.T
+#objdump: -d
+#name: Check if disassembler can handle sections in different order than header
+
+.*: +file format .*aarch64.*
+
+Disassembly of section \.func2:
+
+.+ <\.func2>:
+[^:]+: 8b010000 add x0, x0, x1
+
+Disassembly of section \.func1:
+
+.+ <v1>:
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 00000000 \.word 0x00000000
+
+Disassembly of section \.func3:
+
+.+ <\.func3>:
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 8b010000 add x0, x0, x1
+[^:]+: 00000000 \.word 0x00000000
--- /dev/null
+ .text
+ .global v1
+ .section .func1,"ax",@progbits
+ .type v1 %function
+ .size v1, 4
+v1:
+ add x0, x0, x1
+ .word 0
+
+ .section .func2,"ax",@progbits
+ add x0, x0, x1
+
+ .section .func3,"ax",@progbits
+ add x0, x0, x1
+ add x0, x0, x1
+ add x0, x0, x1
+ add x0, x0, x1
+ add x0, x0, x1
+ .word 0
+
+ .data
+ .section .global,"aw",@progbits
+ .xword 0
+ .xword 0
+ .xword 0
+
+ .section .rodata
+ .word 0
--- /dev/null
+#PROG: objcopy
+#source: out-of-order.s
+#ld: -e v1 -Ttext-segment=0x400000
+#objdump: -D
+#name: Check if disassembler can handle all sections in default order
+
+.*: +file format .*arm.*
+
+Disassembly of section \.func1:
+
+.+ <v1>:
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: 00000000 andeq r0, r0, r0
+
+Disassembly of section \.func2:
+
+.+ <\.func2>:
+[^:]+: e0800001 add r0, r0, r1
+
+Disassembly of section \.func3:
+
+.+ <\.func3>:
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: 00000000 andeq r0, r0, r0
+
+Disassembly of section \.rodata:
+
+.+ <\.rodata>:
+[^:]+: 00000000 andeq r0, r0, r0
+
+Disassembly of section \.global:
+
+.+ <.+>:
+ ...
+
+Disassembly of section \.ARM\.attributes:
+
+.+ <\.ARM\.attributes>:
+[^:]+: .+
+[^:]+: .+
+[^:]+: .+
+[^:]+: .+
+[^:]+: .+
+
--- /dev/null
+#PROG: objcopy
+#source: out-of-order.s
+#ld: -e v1 -Ttext-segment=0x400000
+#objdump: -d
+#name: Check if disassembler can handle sections in default order
+
+.*: +file format .*arm.*
+
+Disassembly of section \.func1:
+
+.+ <v1>:
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: 00000000 \.word 0x00000000
+
+Disassembly of section \.func2:
+
+.+ <\.func2>:
+[^:]+: e0800001 add r0, r0, r1
+
+Disassembly of section \.func3:
+
+.+ <\.func3>:
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: 00000000 \.word 0x00000000
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]
+}
--- /dev/null
+#PROG: objcopy
+#source: out-of-order.s
+#ld: -T out-of-order.T
+#objdump: -D
+#name: Check if disassembler can handle all sections in different order than header
+
+.*: +file format .*arm.*
+
+Disassembly of section \.global:
+
+.+ <\.global>:
+ ...
+
+Disassembly of section \.func2:
+
+.+ <\.func2>:
+[^:]+: e0800001 add r0, r0, r1
+
+Disassembly of section \.func1:
+
+.+ <v1>:
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: 00000000 andeq r0, r0, r0
+
+Disassembly of section \.func3:
+
+.+ <\.func3>:
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: 00000000 andeq r0, r0, r0
+
+Disassembly of section \.rodata:
+
+.+ <\.rodata>:
+[^:]+: 00000000 andeq r0, r0, r0
+
+Disassembly of section \.ARM\.attributes:
+
+.+ <\.ARM\.attributes>:
+[^:]+: .+
+[^:]+: .+
+[^:]+: .+
+[^:]+: .+
+[^:]+: .+
+
--- /dev/null
+ENTRY(v1)
+SECTIONS
+{
+ . = 0xffe00000;
+ .global : { *(.global) }
+ . = 0x4018280;
+ .func2 : { *(.func2) }
+ . = 0x4005000;
+ .func1 : { *(.func1) }
+ . = 0x4015000;
+ .func3 : { *(.func3) }
+ .data : { *(.data) }
+ .rodata : { *(.rodata) }
+}
\ No newline at end of file
--- /dev/null
+#PROG: objcopy
+#ld: -T out-of-order.T
+#objdump: -d
+#name: Check if disassembler can handle sections in different order than header
+
+.*: +file format .*arm.*
+
+Disassembly of section \.func2:
+
+.+ <\.func2>:
+[^:]+: e0800001 add r0, r0, r1
+
+Disassembly of section \.func1:
+
+.+ <v1>:
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: 00000000 \.word 0x00000000
+
+Disassembly of section \.func3:
+
+.+ <\.func3>:
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: e0800001 add r0, r0, r1
+[^:]+: 00000000 \.word 0x00000000
--- /dev/null
+ .text
+ .arm
+ .global v1
+ .section .func1,"ax",%progbits
+ .type v1 %function
+ .size v1, 4
+v1:
+ add r0, r0, r1
+ .word 0
+
+ .section .func2,"ax",%progbits
+ add r0, r0, r1
+
+ .section .func3,"ax",%progbits
+ add r0, r0, r1
+ add r0, r0, r1
+ add r0, r0, r1
+ add r0, r0, r1
+ add r0, r0, r1
+ .word 0
+
+ .data
+ .section .global,"aw",%progbits
+ .word 0
+ .word 0
+ .word 0
+
+ .section .rodata
+ .word 0
+2019-04-01 Tamar Christina <tamar.christina@arm.com>
+
+ Backport from mainline.
+ 2019-03-25 Tamar Christina <tamar.christina@arm.com>
+
+ * dis-asm.h (struct disassemble_info): Add stop_offset.
+
2019-02-02 Nick Clifton <nickc@redhat.com>
2.32 Release.
file being disassembled. */
bfd_vma stop_vma;
+ /* The end range of the current range being disassembled. This is required
+ in order to notify the disassembler when it's currently handling a
+ different range than it was before. This prevent unsafe optimizations when
+ disassembling such as the way mapping symbols are found on AArch64. */
+ bfd_vma stop_offset;
+
} disassemble_info;
/* This struct is used to pass information about valid disassembler
+2019-04-01 Tamar Christina <tamar.christina@arm.com>
+
+ * testsuite/ld-arm/jump-reloc-veneers-cond-long.d: Update disassembly.
+ * testsuite/ld-arm/jump-reloc-veneers-long.d: Update disassembly.
+
2019-02-09 Vineet Gupta <vgupta@synopsys.com>
* emultempl/arclinux.em: Delete special INIT/FINI handling.
Disassembly of section .text:
000080.. <[^>]*>:
- 80..: (8002f040|f0408002) .word 0x(8002f040|f0408002)
+ 80..: f040 8002 bne.w 8008 <__dest_veneer>
80..: 0000 movs r0, r0
...
Disassembly of section .text:
000080.. <[^>]*>:
- 80..: (b802f000|f000b802) .word 0x(b802f000|f000b802)
- 80..: 00000000 andeq r0, r0, r0
+ 80..: f000 b802 b.w 8008 <__dest_veneer>
+ 80..: 0000 movs r0, r0
+ ...
000080.. <[^>]*>:
80..: 4778 bx pc
+2019-04-01 Tamar Christina <tamar.christina@arm.com>
+
+ Backport from mainline.
+ 2019-03-25 Tamar Christina <tamar.christina@arm.com>
+
+ * arm-dis.c (struct arm_private_data): Remove has_mapping_symbols.
+ (mapping_symbol_for_insn): Implement new algorithm.
+ (print_insn): Remove duplicate code.
+
+2019-04-01 Tamar Christina <tamar.christina@arm.com>
+
+ Backport from mainline.
+ 2019-03-25 Tamar Christina <tamar.christina@arm.com>
+
+ * aarch64-dis.c (print_insn_aarch64):
+ Implement override.
+
+2019-04-01 Tamar Christina <tamar.christina@arm.com>
+
+ Backport from mainline.
+ 2019-03-25 Tamar Christina <tamar.christina@arm.com>
+
+ * aarch64-dis.c (print_insn_aarch64): Update the mapping symbol search
+ order.
+
+2019-04-01 Tamar Christina <tamar.christina@arm.com>
+
+ Backport from mainline.
+ 2019-03-25 Tamar Christina <tamar.christina@arm.com>
+
+ * aarch64-dis.c (last_stop_offset): New.
+ (print_insn_aarch64): Use stop_offset.
+
2019-03-12 Andreas Krebbel <krebbel@linux.ibm.com>
Backport from mainline
static enum map_type last_type;
static int last_mapping_sym = -1;
+static bfd_vma last_stop_offset = 0;
static bfd_vma last_mapping_addr = 0;
/* Other options */
/* Aarch64 instructions are always little-endian */
info->endian_code = BFD_ENDIAN_LITTLE;
+ /* Default to DATA. A text section is required by the ABI to contain an
+ INSN mapping symbol at the start. A data section has no such
+ requirement, hence if no mapping symbol is found the section must
+ contain only data. This however isn't very useful if the user has
+ fully stripped the binaries. If this is the case use the section
+ attributes to determine the default. If we have no section default to
+ INSN as well, as we may be disassembling some raw bytes on a baremetal
+ HEX file or similar. */
+ enum map_type type = MAP_DATA;
+ if ((info->section && info->section->flags & SEC_CODE) || !info->section)
+ type = MAP_INSN;
+
/* First check the full symtab for a mapping symbol, even if there
are no usable non-mapping symbols for this address. */
if (info->symtab_size != 0
&& bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
{
- enum map_type type = MAP_INSN;
int last_sym = -1;
- bfd_vma addr;
+ bfd_vma addr, section_vma = 0;
+ bfd_boolean can_use_search_opt_p;
int n;
if (pc <= last_mapping_addr)
/* Start scanning at the start of the function, or wherever
we finished last time. */
n = info->symtab_pos + 1;
- if (n < last_mapping_sym)
+
+ /* If the last stop offset is different from the current one it means we
+ are disassembling a different glob of bytes. As such the optimization
+ would not be safe and we should start over. */
+ can_use_search_opt_p = last_mapping_sym >= 0
+ && info->stop_offset == last_stop_offset;
+
+ if (n >= last_mapping_sym && can_use_search_opt_p)
n = last_mapping_sym;
- /* Scan up to the location being disassembled. */
+ /* Look down while we haven't passed the location being disassembled.
+ The reason for this is that there's no defined order between a symbol
+ and an mapping symbol that may be at the same address. We may have to
+ look at least one position ahead. */
for (; n < info->symtab_size; n++)
{
addr = bfd_asymbol_value (info->symtab[n]);
if (!found)
{
n = info->symtab_pos;
- if (n < last_mapping_sym)
+ if (n >= last_mapping_sym && can_use_search_opt_p)
n = last_mapping_sym;
/* No mapping symbol found at this address. Look backwards
- for a preceeding one. */
+ for a preceeding one, but don't go pass the section start
+ otherwise a data section with no mapping symbol can pick up
+ a text mapping symbol of a preceeding section. The documentation
+ says section can be NULL, in which case we will seek up all the
+ way to the top. */
+ if (info->section)
+ section_vma = info->section->vma;
+
for (; n >= 0; n--)
{
+ addr = bfd_asymbol_value (info->symtab[n]);
+ if (addr < section_vma)
+ break;
+
if (get_sym_code_type (info, n, &type))
{
last_sym = n;
last_mapping_sym = last_sym;
last_type = type;
+ last_stop_offset = info->stop_offset;
/* Look a little bit ahead to see if we should print out
less than four bytes of data. If there's a symbol,
size = (pc & 1) ? 1 : 2;
}
}
+ else
+ last_type = type;
- if (last_type == MAP_DATA)
+ /* PR 10263: Disassemble data if requested to do so by the user. */
+ if (last_type == MAP_DATA && ((info->flags & DISASSEMBLE_DATA) == 0))
{
/* size was set above. */
info->bytes_per_chunk = size;
/* The features to use when disassembling optional instructions. */
arm_feature_set features;
- /* Whether any mapping symbols are present in the provided symbol
- table. -1 if we do not know yet, otherwise 0 or 1. */
- int has_mapping_symbols;
-
/* Track the last type (although this doesn't seem to be useful) */
enum map_type last_type;
/* Tracking symbol table information */
int last_mapping_sym;
+
+ /* The end range of the current range being disassembled. */
+ bfd_vma last_stop_offset;
bfd_vma last_mapping_addr;
};
mapping_symbol_for_insn (bfd_vma pc, struct disassemble_info *info,
enum map_type *map_symbol)
{
- bfd_vma addr;
- int n, start = 0;
+ bfd_vma addr, section_vma = 0;
+ int n, last_sym = -1;
bfd_boolean found = FALSE;
- enum map_type type = MAP_ARM;
+ bfd_boolean can_use_search_opt_p = FALSE;
+
+ /* Default to DATA. A text section is required by the ABI to contain an
+ INSN mapping symbol at the start. A data section has no such
+ requirement, hence if no mapping symbol is found the section must
+ contain only data. This however isn't very useful if the user has
+ fully stripped the binaries. If this is the case use the section
+ attributes to determine the default. If we have no section default to
+ INSN as well, as we may be disassembling some raw bytes on a baremetal
+ HEX file or similar. */
+ enum map_type type = MAP_DATA;
+ if ((info->section && info->section->flags & SEC_CODE) || !info->section)
+ type = MAP_ARM;
struct arm_private_data *private_data;
- if (info->private_data == NULL || info->symtab_size == 0
+ if (info->private_data == NULL
|| bfd_asymbol_flavour (*info->symtab) != bfd_target_elf_flavour)
return FALSE;
private_data = info->private_data;
- if (pc == 0)
- start = 0;
- else
- start = private_data->last_mapping_sym;
- start = (start == -1)? 0 : start;
- addr = bfd_asymbol_value (info->symtab[start]);
+ /* First, look for mapping symbols. */
+ if (info->symtab_size != 0)
+ {
+ if (pc <= private_data->last_mapping_addr)
+ private_data->last_mapping_sym = -1;
+
+ /* Start scanning at the start of the function, or wherever
+ we finished last time. */
+ n = info->symtab_pos + 1;
+
+ /* If the last stop offset is different from the current one it means we
+ are disassembling a different glob of bytes. As such the optimization
+ would not be safe and we should start over. */
+ can_use_search_opt_p
+ = private_data->last_mapping_sym >= 0
+ && info->stop_offset == private_data->last_stop_offset;
+
+ if (n >= private_data->last_mapping_sym && can_use_search_opt_p)
+ n = private_data->last_mapping_sym;
+
+ /* Look down while we haven't passed the location being disassembled.
+ The reason for this is that there's no defined order between a symbol
+ and an mapping symbol that may be at the same address. We may have to
+ look at least one position ahead. */
+ for (; n < info->symtab_size; n++)
+ {
+ addr = bfd_asymbol_value (info->symtab[n]);
+ if (addr > pc)
+ break;
+ if (get_map_sym_type (info, n, &type))
+ {
+ last_sym = n;
+ found = TRUE;
+ }
+ }
- if (pc >= addr)
- {
- if (get_map_sym_type (info, start, &type))
- found = TRUE;
- }
- else
+ if (!found)
+ {
+ n = info->symtab_pos;
+ if (n >= private_data->last_mapping_sym && can_use_search_opt_p)
+ n = private_data->last_mapping_sym;
+
+ /* No mapping symbol found at this address. Look backwards
+ for a preceeding one, but don't go pass the section start
+ otherwise a data section with no mapping symbol can pick up
+ a text mapping symbol of a preceeding section. The documentation
+ says section can be NULL, in which case we will seek up all the
+ way to the top. */
+ if (info->section)
+ section_vma = info->section->vma;
+
+ for (; n >= 0; n--)
+ {
+ addr = bfd_asymbol_value (info->symtab[n]);
+ if (addr < section_vma)
+ break;
+
+ if (get_map_sym_type (info, n, &type))
+ {
+ last_sym = n;
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ /* If no mapping symbol was found, try looking up without a mapping
+ symbol. This is done by walking up from the current PC to the nearest
+ symbol. We don't actually have to loop here since symtab_pos will
+ contain the nearest symbol already. */
+ if (!found)
{
- for (n = start - 1; n >= 0; n--)
+ n = info->symtab_pos;
+ if (n >= 0 && get_sym_code_type (info, n, &type))
{
- if (get_map_sym_type (info, n, &type))
- {
- found = TRUE;
- break;
- }
+ last_sym = n;
+ found = TRUE;
}
}
- /* No mapping symbols were found. A leading $d may be
- omitted for sections which start with data; but for
- compatibility with legacy and stripped binaries, only
- assume the leading $d if there is at least one mapping
- symbol in the file. */
- if (!found && private_data->has_mapping_symbols == 1)
- {
- type = MAP_DATA;
- found = TRUE;
- }
+ private_data->last_mapping_sym = last_sym;
+ private_data->last_type = type;
+ private_data->last_stop_offset = info->stop_offset;
*map_symbol = type;
return found;
during disassembly.... */
select_arm_features (info->mach, & private.features);
- private.has_mapping_symbols = -1;
private.last_mapping_sym = -1;
private.last_mapping_addr = 0;
+ private.last_stop_offset = 0;
info->private_data = & private;
}
&& bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
{
bfd_vma addr;
- int n, start;
+ int n;
int last_sym = -1;
enum map_type type = MAP_ARM;
- /* Start scanning at the start of the function, or wherever
- we finished last time. */
- /* PR 14006. When the address is 0 we are either at the start of the
- very first function, or else the first function in a new, unlinked
- executable section (eg because of -ffunction-sections). Either way
- start scanning from the beginning of the symbol table, not where we
- left off last time. */
- if (pc == 0)
- start = 0;
- else
- {
- start = info->symtab_pos + 1;
- if (start < private_data->last_mapping_sym)
- start = private_data->last_mapping_sym;
- }
- found = FALSE;
-
- /* First, look for mapping symbols. */
- if (private_data->has_mapping_symbols != 0)
- {
- /* Scan up to the location being disassembled. */
- for (n = start; n < info->symtab_size; n++)
- {
- addr = bfd_asymbol_value (info->symtab[n]);
- if (addr > pc)
- break;
- if (get_map_sym_type (info, n, &type))
- {
- last_sym = n;
- found = TRUE;
- }
- }
-
- if (!found)
- {
- /* No mapping symbol found at this address. Look backwards
- for a preceding one. */
- for (n = start - 1; n >= 0; n--)
- {
- if (get_map_sym_type (info, n, &type))
- {
- last_sym = n;
- found = TRUE;
- break;
- }
- }
- }
-
- if (found)
- private_data->has_mapping_symbols = 1;
-
- /* No mapping symbols were found. A leading $d may be
- omitted for sections which start with data; but for
- compatibility with legacy and stripped binaries, only
- assume the leading $d if there is at least one mapping
- symbol in the file. */
- if (!found && private_data->has_mapping_symbols == -1)
- {
- /* Look for mapping symbols, in any section. */
- for (n = 0; n < info->symtab_size; n++)
- if (is_mapping_symbol (info, n, &type))
- {
- private_data->has_mapping_symbols = 1;
- break;
- }
- if (private_data->has_mapping_symbols == -1)
- private_data->has_mapping_symbols = 0;
- }
-
- if (!found && private_data->has_mapping_symbols == 1)
- {
- type = MAP_DATA;
- found = TRUE;
- }
- }
-
- /* Next search for function symbols to separate ARM from Thumb
- in binaries without mapping symbols. */
- if (!found)
- {
- /* Scan up to the location being disassembled. */
- for (n = start; n < info->symtab_size; n++)
- {
- addr = bfd_asymbol_value (info->symtab[n]);
- if (addr > pc)
- break;
- if (get_sym_code_type (info, n, &type))
- {
- last_sym = n;
- found = TRUE;
- }
- }
-
- if (!found)
- {
- /* No mapping symbol found at this address. Look backwards
- for a preceding one. */
- for (n = start - 1; n >= 0; n--)
- {
- if (get_sym_code_type (info, n, &type))
- {
- last_sym = n;
- found = TRUE;
- break;
- }
- }
- }
- }
+ found = mapping_symbol_for_insn (pc, info, &type);
+ last_sym = private_data->last_mapping_sym;
- private_data->last_mapping_sym = last_sym;
- private_data->last_type = type;
is_thumb = (private_data->last_type == MAP_THUMB);
is_data = (private_data->last_type == MAP_DATA);