diff options
author | oharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2009-09-08 06:18:45 +0000 |
---|---|---|
committer | oharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2009-09-08 06:18:45 +0000 |
commit | 5dae4753ff9a6ca87104ef09aa128e1425826049 (patch) | |
tree | e487d9272546b4d0ca98a84c522f1582b79f7a2e /src/target/armv7a.c | |
parent | 57e12b7e452b0f397ca3e1501ef1a2eb61f5a9aa (diff) | |
download | riscv-openocd-5dae4753ff9a6ca87104ef09aa128e1425826049.zip riscv-openocd-5dae4753ff9a6ca87104ef09aa128e1425826049.tar.gz riscv-openocd-5dae4753ff9a6ca87104ef09aa128e1425826049.tar.bz2 |
David Brownell <david-b@pacbell.net>
Provide an "armv7a disassemble" command. Current omissions include
VFP (except as coprocessor instructions), Neon, and various Thumb2
opcodes that are not available in ARMv7-M processors.
git-svn-id: svn://svn.berlios.de/openocd/trunk@2676 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src/target/armv7a.c')
-rw-r--r-- | src/target/armv7a.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/target/armv7a.c b/src/target/armv7a.c index 547a33b..3eb0f3e 100644 --- a/src/target/armv7a.c +++ b/src/target/armv7a.c @@ -23,6 +23,7 @@ #include "replacements.h" #include "armv7a.h" +#include "arm_disassembler.h" #include "target.h" #include "register.h" @@ -269,9 +270,86 @@ static int handle_dap_info_command(struct command_context_s *cmd_ctx, return dap_info_command(cmd_ctx, swjdp, apsel); } +static int +handle_armv7a_disassemble_command(struct command_context_s *cmd_ctx, + char *cmd, char **args, int argc) +{ + target_t *target = get_current_target(cmd_ctx); + armv4_5_common_t *armv4_5 = target->arch_info; + int thumb = 0; + int count = 1; + uint32_t address; + int i; + + if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC) { + command_print(cmd_ctx, "current target isn't an ARM target"); + return ERROR_OK; + } + + /* REVISIT: eventually support ThumbEE disassembly too; + * some opcodes work differently. + */ + + switch (argc) { + case 3: + if (strcmp(args[2], "thumb") != 0) + goto usage; + thumb = 1; + /* FALL THROUGH */ + case 2: + count = strtoul(args[1], NULL, 0); + /* FALL THROUGH */ + case 1: + address = strtoul(args[0], NULL, 0); + if (address & 0x01) { + if (!thumb) { + command_print(cmd_ctx, "Disassemble as Thumb"); + thumb = 1; + } + address &= ~1; + } + break; + default: +usage: + command_print(cmd_ctx, + "usage: armv4_5 disassemble <address> [<count> ['thumb']]"); + return ERROR_OK; + } + + for (i = 0; i < count; i++) { + arm_instruction_t cur_instruction; + int retval; + + if (thumb) { + retval = thumb2_opcode(target, address, &cur_instruction); + if (retval != ERROR_OK) + return retval; + + address += cur_instruction.instruction_size; + } else { + uint32_t opcode; + + retval = target_read_u32(target, address, &opcode); + if (retval != ERROR_OK) + return retval; + + retval = arm_evaluate_opcode(opcode, address, + &cur_instruction); + if (retval != ERROR_OK) + return retval; + + address += 4; + } + command_print(cmd_ctx, "%s", cur_instruction.text); + } + + return ERROR_OK; +} + int armv7a_register_commands(struct command_context_s *cmd_ctx) { command_t *arm_adi_v5_dap_cmd; + command_t *armv7a_cmd; arm_adi_v5_dap_cmd = register_command(cmd_ctx, NULL, "dap", NULL, COMMAND_ANY, @@ -297,5 +375,13 @@ int armv7a_register_commands(struct command_context_s *cmd_ctx) "set/get number of extra tck for mem-ap memory " "bus access [0-255]"); + armv7a_cmd = register_command(cmd_ctx, NULL, "armv7a", + NULL, COMMAND_ANY, + "ARMv7-A specific commands"); + + register_command(cmd_ctx, armv7a_cmd, "disassemble", + handle_armv7a_disassemble_command, COMMAND_EXEC, + "disassemble instructions <address> [<count> ['thumb']]"); + return ERROR_OK; } |