diff options
-rw-r--r-- | gas/ChangeLog | 5 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/thumb2_it_search.d | 12 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/thumb2_it_search.s | 8 | ||||
-rw-r--r-- | opcodes/ChangeLog | 5 | ||||
-rw-r--r-- | opcodes/arm-dis.c | 81 |
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. |