aboutsummaryrefslogtreecommitdiff
path: root/opcodes/arm-dis.c
diff options
context:
space:
mode:
authorRenlin Li <renlin.li@arm.com>2016-01-25 15:06:54 +0000
committerRenlin Li <renlin.li@arm.com>2016-01-25 15:14:29 +0000
commit5bc5ae8810c03b55f46b9e575389c3fa85a62b5c (patch)
tree5f45709baabdf530ce930b0d65e083ef6c30ee6c /opcodes/arm-dis.c
parenta2077e254098828614ef6621cf8df28185e711d0 (diff)
downloadgdb-5bc5ae8810c03b55f46b9e575389c3fa85a62b5c.zip
gdb-5bc5ae8810c03b55f46b9e575389c3fa85a62b5c.tar.gz
gdb-5bc5ae8810c03b55f46b9e575389c3fa85a62b5c.tar.bz2
[PATCH[ARM]Check mapping symbol while backward searching for IT block.
opcodes/ * arm-dis.c (mapping_symbol_for_insn): New function. (find_ifthen_state): Call mapping_symbol_for_insn(). gas/ * testsuite/gas/arm/thumb2_it_search.d: New. * testsuite/gas/arm/thumb2_it_search.s: New.
Diffstat (limited to 'opcodes/arm-dis.c')
-rw-r--r--opcodes/arm-dis.c81
1 files changed, 78 insertions, 3 deletions
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.