summaryrefslogtreecommitdiff
path: root/src/target/armv7a.c
diff options
context:
space:
mode:
authoroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2009-09-08 06:18:45 +0000
committeroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2009-09-08 06:18:45 +0000
commit5dae4753ff9a6ca87104ef09aa128e1425826049 (patch)
treee487d9272546b4d0ca98a84c522f1582b79f7a2e /src/target/armv7a.c
parent57e12b7e452b0f397ca3e1501ef1a2eb61f5a9aa (diff)
downloadopenocd+libswd-5dae4753ff9a6ca87104ef09aa128e1425826049.tar.gz
openocd+libswd-5dae4753ff9a6ca87104ef09aa128e1425826049.tar.bz2
openocd+libswd-5dae4753ff9a6ca87104ef09aa128e1425826049.tar.xz
openocd+libswd-5dae4753ff9a6ca87104ef09aa128e1425826049.zip
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.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/target/armv7a.c b/src/target/armv7a.c
index 547a33bb..3eb0f3ed 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;
}