aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binutils/ChangeLog6
-rw-r--r--binutils/testsuite/binutils-all/aarch64/in-order.d28
-rw-r--r--binutils/testsuite/binutils-all/aarch64/out-of-order.d17
-rw-r--r--opcodes/ChangeLog5
-rw-r--r--opcodes/aarch64-dis.c44
5 files changed, 93 insertions, 7 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 121c54d..1c6c354 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,5 +1,11 @@
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-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.
diff --git a/binutils/testsuite/binutils-all/aarch64/in-order.d b/binutils/testsuite/binutils-all/aarch64/in-order.d
new file mode 100644
index 0000000..090337f
--- /dev/null
+++ b/binutils/testsuite/binutils-all/aarch64/in-order.d
@@ -0,0 +1,28 @@
+#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:
+
+0000000000400000 <v1>:
+ 400000: 8b010000 add x0, x0, x1
+ 400004: 00000000 \.word 0x00000000
+
+Disassembly of section .func2:
+
+0000000000400008 <\.func2>:
+ 400008: 8b010000 add x0, x0, x1
+
+Disassembly of section \.func3:
+
+000000000040000c <\.func3>:
+ 40000c: 8b010000 add x0, x0, x1
+ 400010: 8b010000 add x0, x0, x1
+ 400014: 8b010000 add x0, x0, x1
+ 400018: 8b010000 add x0, x0, x1
+ 40001c: 8b010000 add x0, x0, x1
+ 400020: 00000000 \.word 0x00000000
diff --git a/binutils/testsuite/binutils-all/aarch64/out-of-order.d b/binutils/testsuite/binutils-all/aarch64/out-of-order.d
index 410f37f..f78adec 100644
--- a/binutils/testsuite/binutils-all/aarch64/out-of-order.d
+++ b/binutils/testsuite/binutils-all/aarch64/out-of-order.d
@@ -1,10 +1,20 @@
#PROG: objcopy
#ld: -T out-of-order.T
-#objdump: -d
+#objdump: -D
#name: Check if disassembler can handle sections in different order than header
.*: +file format .*aarch64.*
+Disassembly of section \.global:
+
+00000000ffe00000 <\.global>:
+ ffe00000: 00000001 \.word 0x00000001
+ ffe00004: 00000000 \.word 0x00000000
+ ffe00008: 00000001 \.word 0x00000001
+ ffe0000c: 00000000 \.word 0x00000000
+ ffe00010: 00000001 \.word 0x00000001
+ ffe00014: 00000000 \.word 0x00000000
+
Disassembly of section \.func2:
0000000004018280 <\.func2>:
@@ -25,3 +35,8 @@ Disassembly of section \.func3:
401500c: 8b010000 add x0, x0, x1
4015010: 8b010000 add x0, x0, x1
4015014: 00000000 \.word 0x00000000
+
+Disassembly of section \.rodata:
+
+0000000004015018 <\.rodata>:
+ 4015018: 00000004 \.word 0x00000004
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 81fe9f0..e5705d7 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,10 @@
2019-03-25 Tamar Christina <tamar.christina@arm.com>
+ * aarch64-dis.c (print_insn_aarch64): Update the mapping symbol search
+ order.
+
+2019-03-25 Tamar Christina <tamar.christina@arm.com>
+
* aarch64-dis.c (last_stop_offset): New.
(print_insn_aarch64): Use stop_offset.
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
index fc7e95d..1f931d0 100644
--- a/opcodes/aarch64-dis.c
+++ b/opcodes/aarch64-dis.c
@@ -3318,14 +3318,26 @@ print_insn_aarch64 (bfd_vma pc,
/* 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)
@@ -3334,13 +3346,20 @@ print_insn_aarch64 (bfd_vma pc,
/* 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. */
- if (n < last_mapping_sym && info->stop_offset == last_stop_offset)
+ 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]);
@@ -3356,13 +3375,24 @@ print_insn_aarch64 (bfd_vma pc,
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;
@@ -3400,6 +3430,8 @@ print_insn_aarch64 (bfd_vma pc,
size = (pc & 1) ? 1 : 2;
}
}
+ else
+ last_type = type;
if (last_type == MAP_DATA)
{