aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binutils/ChangeLog11
-rw-r--r--binutils/testsuite/binutils-all/arm/in-order-all.d50
-rw-r--r--binutils/testsuite/binutils-all/arm/in-order.d28
-rw-r--r--binutils/testsuite/binutils-all/arm/objdump.exp14
-rw-r--r--binutils/testsuite/binutils-all/arm/out-of-order-all.d50
-rw-r--r--binutils/testsuite/binutils-all/arm/out-of-order.T14
-rw-r--r--binutils/testsuite/binutils-all/arm/out-of-order.d27
-rw-r--r--binutils/testsuite/binutils-all/arm/out-of-order.s29
-rw-r--r--ld/ChangeLog5
-rw-r--r--ld/testsuite/ld-arm/jump-reloc-veneers-cond-long.d2
-rw-r--r--ld/testsuite/ld-arm/jump-reloc-veneers-long.d5
-rw-r--r--opcodes/ChangeLog6
-rw-r--r--opcodes/arm-dis.c249
13 files changed, 339 insertions, 151 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index aad8bdd..83aa37c 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,5 +1,16 @@
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-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:
diff --git a/binutils/testsuite/binutils-all/arm/in-order-all.d b/binutils/testsuite/binutils-all/arm/in-order-all.d
new file mode 100644
index 0000000..3a098dd
--- /dev/null
+++ b/binutils/testsuite/binutils-all/arm/in-order-all.d
@@ -0,0 +1,50 @@
+#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:
+
+00400000 <v1>:
+ 400000: e0800001 add r0, r0, r1
+ 400004: 00000000 andeq r0, r0, r0
+
+Disassembly of section \.func2:
+
+00400008 <\.func2>:
+ 400008: e0800001 add r0, r0, r1
+
+Disassembly of section \.func3:
+
+0040000c <\.func3>:
+ 40000c: e0800001 add r0, r0, r1
+ 400010: e0800001 add r0, r0, r1
+ 400014: e0800001 add r0, r0, r1
+ 400018: e0800001 add r0, r0, r1
+ 40001c: e0800001 add r0, r0, r1
+ 400020: 00000000 andeq r0, r0, r0
+
+Disassembly of section \.rodata:
+
+00400024 <\.rodata>:
+ 400024: 00000004 andeq r0, r0, r4
+
+Disassembly of section \.global:
+
+00410028 <__data_start>:
+ 410028: 00000001 andeq r0, r0, r1
+ 41002c: 00000001 andeq r0, r0, r1
+ 410030: 00000001 andeq r0, r0, r1
+
+Disassembly of section \.ARM\.attributes:
+
+00000000 <\.ARM\.attributes>:
+ 0: 00001141 andeq r1, r0, r1, asr #2
+ 4: 61656100 cmnvs r5, r0, lsl #2
+ 8: 01006962 tsteq r0, r2, ror #18
+ c: 00000007 andeq r0, r0, r7
+ 10: Address 0x0000000000000010 is out of bounds.
+
diff --git a/binutils/testsuite/binutils-all/arm/in-order.d b/binutils/testsuite/binutils-all/arm/in-order.d
new file mode 100644
index 0000000..a0b63c2
--- /dev/null
+++ b/binutils/testsuite/binutils-all/arm/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 .*arm.*
+
+Disassembly of section \.func1:
+
+00400000 <v1>:
+ 400000: e0800001 add r0, r0, r1
+ 400004: 00000000 \.word 0x00000000
+
+Disassembly of section \.func2:
+
+00400008 <\.func2>:
+ 400008: e0800001 add r0, r0, r1
+
+Disassembly of section \.func3:
+
+0040000c <\.func3>:
+ 40000c: e0800001 add r0, r0, r1
+ 400010: e0800001 add r0, r0, r1
+ 400014: e0800001 add r0, r0, r1
+ 400018: e0800001 add r0, r0, r1
+ 40001c: e0800001 add r0, r0, r1
+ 400020: 00000000 \.word 0x00000000
diff --git a/binutils/testsuite/binutils-all/arm/objdump.exp b/binutils/testsuite/binutils-all/arm/objdump.exp
index 5013b18..33e3fd1 100644
--- a/binutils/testsuite/binutils-all/arm/objdump.exp
+++ b/binutils/testsuite/binutils-all/arm/objdump.exp
@@ -111,3 +111,17 @@ if {![binutils_assemble $srcdir/$subdir/rvct_symbol.s tmpdir/rvct_symbol.o]} the
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]
+}
diff --git a/binutils/testsuite/binutils-all/arm/out-of-order-all.d b/binutils/testsuite/binutils-all/arm/out-of-order-all.d
new file mode 100644
index 0000000..58c4057
--- /dev/null
+++ b/binutils/testsuite/binutils-all/arm/out-of-order-all.d
@@ -0,0 +1,50 @@
+#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:
+
+ffe00000 <\.global>:
+ffe00000: 00000001 andeq r0, r0, r1
+ffe00004: 00000001 andeq r0, r0, r1
+ffe00008: 00000001 andeq r0, r0, r1
+
+Disassembly of section \.func2:
+
+04018280 <\.func2>:
+ 4018280: e0800001 add r0, r0, r1
+
+Disassembly of section \.func1:
+
+04005000 <v1>:
+ 4005000: e0800001 add r0, r0, r1
+ 4005004: 00000000 andeq r0, r0, r0
+
+Disassembly of section \.func3:
+
+04015000 <\.func3>:
+ 4015000: e0800001 add r0, r0, r1
+ 4015004: e0800001 add r0, r0, r1
+ 4015008: e0800001 add r0, r0, r1
+ 401500c: e0800001 add r0, r0, r1
+ 4015010: e0800001 add r0, r0, r1
+ 4015014: 00000000 andeq r0, r0, r0
+
+Disassembly of section \.rodata:
+
+04015018 <\.rodata>:
+ 4015018: 00000004 andeq r0, r0, r4
+
+Disassembly of section \.ARM\.attributes:
+
+00000000 <\.ARM\.attributes>:
+ 0: 00001141 andeq r1, r0, r1, asr #2
+ 4: 61656100 cmnvs r5, r0, lsl #2
+ 8: 01006962 tsteq r0, r2, ror #18
+ c: 00000007 andeq r0, r0, r7
+ 10: Address 0x0000000000000010 is out of bounds.
+
diff --git a/binutils/testsuite/binutils-all/arm/out-of-order.T b/binutils/testsuite/binutils-all/arm/out-of-order.T
new file mode 100644
index 0000000..489ae80
--- /dev/null
+++ b/binutils/testsuite/binutils-all/arm/out-of-order.T
@@ -0,0 +1,14 @@
+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
diff --git a/binutils/testsuite/binutils-all/arm/out-of-order.d b/binutils/testsuite/binutils-all/arm/out-of-order.d
new file mode 100644
index 0000000..9351af7
--- /dev/null
+++ b/binutils/testsuite/binutils-all/arm/out-of-order.d
@@ -0,0 +1,27 @@
+#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:
+
+04018280 <\.func2>:
+ 4018280: e0800001 add r0, r0, r1
+
+Disassembly of section \.func1:
+
+04005000 <v1>:
+ 4005000: e0800001 add r0, r0, r1
+ 4005004: 00000000 \.word 0x00000000
+
+Disassembly of section \.func3:
+
+04015000 <\.func3>:
+ 4015000: e0800001 add r0, r0, r1
+ 4015004: e0800001 add r0, r0, r1
+ 4015008: e0800001 add r0, r0, r1
+ 401500c: e0800001 add r0, r0, r1
+ 4015010: e0800001 add r0, r0, r1
+ 4015014: 00000000 \.word 0x00000000
diff --git a/binutils/testsuite/binutils-all/arm/out-of-order.s b/binutils/testsuite/binutils-all/arm/out-of-order.s
new file mode 100644
index 0000000..4e43ddf
--- /dev/null
+++ b/binutils/testsuite/binutils-all/arm/out-of-order.s
@@ -0,0 +1,29 @@
+ .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 1
+ .word 1
+ .word 1
+
+ .section .rodata
+ .word 4
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 2853c09..0029150 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,8 @@
+2019-03-25 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-03-21 Sudakshina Das <sudi.das@arm.com>
* testsuite/ld-aarch64/aarch64-elf.exp: Add new test.
diff --git a/ld/testsuite/ld-arm/jump-reloc-veneers-cond-long.d b/ld/testsuite/ld-arm/jump-reloc-veneers-cond-long.d
index d818cf5..88481f0 100644
--- a/ld/testsuite/ld-arm/jump-reloc-veneers-cond-long.d
+++ b/ld/testsuite/ld-arm/jump-reloc-veneers-cond-long.d
@@ -10,7 +10,7 @@ Disassembly of section destsect:
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
...
diff --git a/ld/testsuite/ld-arm/jump-reloc-veneers-long.d b/ld/testsuite/ld-arm/jump-reloc-veneers-long.d
index 6bd5652..ae176be 100644
--- a/ld/testsuite/ld-arm/jump-reloc-veneers-long.d
+++ b/ld/testsuite/ld-arm/jump-reloc-veneers-long.d
@@ -10,8 +10,9 @@ Disassembly of section destsect:
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
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 433e43f..7b7237f 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,11 @@
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-03-25 Tamar Christina <tamar.christina@arm.com>
+
* aarch64-dis.c (print_insn_aarch64):
Implement override.
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 71d7c52..d47ef32 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -56,15 +56,14 @@ struct arm_private_data
/* 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;
};
@@ -6351,52 +6350,114 @@ static bfd_boolean
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;
@@ -6535,9 +6596,9 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
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;
}
@@ -6554,121 +6615,13 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
&& 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);