summaryrefslogtreecommitdiff
path: root/opcodes/arm-dis.c
diff options
context:
space:
mode:
authorThomas Troeger <tstroege@gmx.de>2020-01-13 12:36:55 +0000
committerNick Clifton <nickc@redhat.com>2020-01-13 12:36:55 +0000
commit1d67fe3b6e696fccb902d9919b9e58b7299a3205 (patch)
tree84e284092b19da0c349671ccc287d8afd7c1c4b6 /opcodes/arm-dis.c
parenta4f2b7c5d931f2aa27851b59ae5817a6ee43cfcb (diff)
downloadbinutils-gdb-1d67fe3b6e696fccb902d9919b9e58b7299a3205.tar.gz
Add an option to objdump's disassembler to generate ascii art diagrams showing the destinations of flow control instructions.
binutils* objdump.c (visualize_jumps, color_output, extended_color_output) (detected_jumps): New variables. (usage): Add the new jump visualization options. (option_values): Add new option value. (long_options): Add the new option. (jump_info_new, jump_info_free): New functions. (jump_info_min_address, jump_info_max_address): Likewise. (jump_info_end_address, jump_info_is_start_address): Likewise. (jump_info_is_end_address, jump_info_size): Likewise. (jump_info_unlink, jump_info_insert): Likewise. (jump_info_add_front, jump_info_move_linked): Likewise. (jump_info_intersect, jump_info_merge): Likewise. (jump_info_sort, jump_info_visualize_address): Likewise. (disassemble_jumps): New function - used to locate jumps. (disassemble_bytes): Add ascii art generation. (disassemble_section): Add scan to locate jumps. (main): Parse the new visualization option. * doc/binutils.texi: Document the new feature. * NEWS: Mention the new feature. opcodes * arm-dis.c (print_insn_arm): Fill in insn info fields for control flow instructions. (print_insn_thumb16, print_insn_thumb32): Likewise. (print_insn): Initialize the insn info. * i386-dis.c (print_insn): Initialize the insn info fields, and detect jumps.
Diffstat (limited to 'opcodes/arm-dis.c')
-rw-r--r--opcodes/arm-dis.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 55ec321bedf..b174f8335cd 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -9886,7 +9886,13 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
case 'b':
{
bfd_vma disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
- info->print_address_func (disp * 4 + pc + 8, info);
+ bfd_vma target = disp * 4 + pc + 8;
+ info->print_address_func (target, info);
+
+ /* Fill in instruction information. */
+ info->insn_info_valid = 1;
+ info->insn_type = dis_branch;
+ info->target = target;
}
break;
@@ -10024,6 +10030,11 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
address += 2;
info->print_address_func (address, info);
+
+ /* Fill in instruction information. */
+ info->insn_info_valid = 1;
+ info->insn_type = dis_branch;
+ info->target = address;
}
break;
@@ -10388,6 +10399,11 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
+ ((given & 0x00f8) >> 2)
+ ((given & 0x0200) >> 3));
info->print_address_func (address, info);
+
+ /* Fill in instruction information. */
+ info->insn_info_valid = 1;
+ info->insn_type = dis_branch;
+ info->target = address;
}
break;
@@ -10461,8 +10477,14 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
case 'B':
reg = ((reg ^ (1 << bitend)) - (1 << bitend));
- info->print_address_func (reg * 2 + pc + 4, info);
+ bfd_vma target = reg * 2 + pc + 4;
+ info->print_address_func (target, info);
value_in_comment = 0;
+
+ /* Fill in instruction information. */
+ info->insn_info_valid = 1;
+ info->insn_type = dis_branch;
+ info->target = target;
break;
case 'c':
@@ -11019,7 +11041,13 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
offset |= (given & 0x000007ff) << 1;
offset -= (1 << 20);
- info->print_address_func (pc + 4 + offset, info);
+ bfd_vma target = pc + 4 + offset;
+ info->print_address_func (target, info);
+
+ /* Fill in instruction information. */
+ info->insn_info_valid = 1;
+ info->insn_type = dis_branch;
+ info->target = target;
}
break;
@@ -11043,6 +11071,11 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
offset &= ~2u;
info->print_address_func (offset, info);
+
+ /* Fill in instruction information. */
+ info->insn_info_valid = 1;
+ info->insn_type = dis_branch;
+ info->target = offset;
}
break;
@@ -11715,6 +11748,14 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
bfd_boolean found = FALSE;
struct arm_private_data *private_data;
+ /* Clear instruction information field. */
+ info->insn_info_valid = 0;
+ info->branch_delay_insns = 0;
+ info->data_size = 0;
+ info->insn_type = dis_noninsn;
+ info->target = 0;
+ info->target2 = 0;
+
if (info->disassembler_options)
{
parse_arm_disassembler_options (info->disassembler_options);