aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog5
-rw-r--r--gas/testsuite/gas/arm/thumb2_it_search.d12
-rw-r--r--gas/testsuite/gas/arm/thumb2_it_search.s8
-rw-r--r--opcodes/ChangeLog5
-rw-r--r--opcodes/arm-dis.c81
5 files changed, 108 insertions, 3 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 83f4077..3cb5f14 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2016-01-25 Renlin Li <renlin.li@arm.com>
+
+ * testsuite/gas/arm/thumb2_it_search.d: New.
+ * testsuite/gas/arm/thumb2_it_search.s: New.
+
2016-01-21 Nick Clifton <nickc@redhat.com>
PR gas/19454
diff --git a/gas/testsuite/gas/arm/thumb2_it_search.d b/gas/testsuite/gas/arm/thumb2_it_search.d
new file mode 100644
index 0000000..6758ef8
--- /dev/null
+++ b/gas/testsuite/gas/arm/thumb2_it_search.d
@@ -0,0 +1,12 @@
+#name: 32-bit Thumb conditional instructions backward search
+#as: -march=armv6kt2
+#skip: *-*-*aout*
+#source: thumb2_it_search.s
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+0 <[^>]+> f3af 8000 nop.w
+0+4 <[^>]+> bf080000 .word 0xbf080000
+0+8 <[^>]+> f3af 8000 nop.w
diff --git a/gas/testsuite/gas/arm/thumb2_it_search.s b/gas/testsuite/gas/arm/thumb2_it_search.s
new file mode 100644
index 0000000..a29cb51
--- /dev/null
+++ b/gas/testsuite/gas/arm/thumb2_it_search.s
@@ -0,0 +1,8 @@
+ .text
+ .thumb
+ .syntax unified
+ .thumb_func
+f:
+ nop.w
+ .long 0xbf080000
+ nop.w
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 8c0648a..130a4a7 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,8 @@
+2016-01-25 Renlin Li <renlin.li@arm.com>
+
+ * arm-dis.c (mapping_symbol_for_insn): New function.
+ (find_ifthen_state): Call mapping_symbol_for_insn().
+
2016-01-20 Matthew Wahab <matthew.wahab@arm.com>
* aarch64-opc.c (operand_general_constraint_met_p): Check validity
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 56da264..481270e 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -5947,6 +5947,10 @@ parse_disassembler_options (char *options)
}
}
+static bfd_boolean
+mapping_symbol_for_insn (bfd_vma pc, struct disassemble_info *info,
+ enum map_type *map_symbol);
+
/* Search back through the insn stream to determine if this instruction is
conditionally executed. */
@@ -6009,9 +6013,15 @@ find_ifthen_state (bfd_vma pc,
}
if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
{
- /* This could be an IT instruction. */
- seen_it = insn;
- it_count = count >> 1;
+ enum map_type type = MAP_ARM;
+ bfd_boolean found = mapping_symbol_for_insn (addr, info, &type);
+
+ if (!found || (found && type == MAP_THUMB))
+ {
+ /* This could be an IT instruction. */
+ seen_it = insn;
+ it_count = count >> 1;
+ }
}
if ((insn & 0xf800) >= 0xe800)
count++;
@@ -6095,6 +6105,71 @@ get_sym_code_type (struct disassemble_info *info,
return FALSE;
}
+/* Search the mapping symbol state for instruction at pc. This is only
+ applicable for elf target.
+
+ There is an assumption Here, info->private_data contains the correct AND
+ up-to-date information about current scan process. The information will be
+ used to speed this search process.
+
+ Return TRUE if the mapping state can be determined, and map_symbol
+ will be updated accordingly. Otherwise, return FALSE. */
+
+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_boolean found = FALSE;
+ enum map_type type = MAP_ARM;
+ struct arm_private_data *private_data;
+
+ if (info->private_data == NULL || info->symtab_size == 0
+ || 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]);
+
+ if (pc >= addr)
+ {
+ if (get_map_sym_type (info, start, &type))
+ found = TRUE;
+ }
+ else
+ {
+ for (n = start - 1; n >= 0; n--)
+ {
+ if (get_map_sym_type (info, n, &type))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+
+ /* 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;
+ }
+
+ *map_symbol = type;
+ return found;
+}
+
/* Given a bfd_mach_arm_XXX value, this function fills in the fields
of the supplied arm_feature_set structure with bitmasks indicating
the support base architectures and coprocessor extensions.