From 97cc8322cef8027db22a24b7e011e5386171d97f Mon Sep 17 00:00:00 2001 From: TC Wan Date: Wed, 1 Dec 2010 17:54:07 +0800 Subject: fix undef_handler, initial design for next instruction decode Fixed error in handling Thumb instructions in undef_handler. Initial Design for Next Instruction Decoding --- .project | 11 +++++++++++ Debugger/debug_stub.S | 29 +++++++++++++++++++++++++++++ Debugger/debug_stub.h | 2 +- Debugger/undef_handler.S | 6 ++++-- 4 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 .project diff --git a/.project b/.project new file mode 100644 index 0000000..15b12fc --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ + + + armdebug + + + + + + + + diff --git a/Debugger/debug_stub.S b/Debugger/debug_stub.S index 98bc968..030ce40 100644 --- a/Debugger/debug_stub.S +++ b/Debugger/debug_stub.S @@ -155,6 +155,25 @@ debug_cmdJumpTable: .word _dbg__nop /* '?' */ .word 0 +/* + * To determine the next instruction to execute, we need to check current (breakpointed) instruction + * and determine whether it will be executed or not. This necessitates a mini instruction decoder + * that can check the type of instruction, as well as if it'll affect the PC. + * The instruction decoder used here is table based. Each entry in the table consists of: + * Instruction Identifier (IID), Instruction Bitmask (IBM), Instruction Handler Address (IHA) + * Null entries are placed at the end of the table. + * + * This allows for a flexible approach to handling instructions that we're interested in, at the expense + * of memory usage. + * + * For ARM, the IID & IBM are both 4 bytes, whereas the Thumb IID & IBM are 2 bytes. + * The IHA is always 4 bytes. + */ + +/* ARM Instruction Decode Table */ + +/* Thumb Instruction Decode Table */ + .code 32 .text @@ -1245,8 +1264,18 @@ _dbg_next_instruction_addr: /* Here, r0 contains the instruction which will be reexecuted when program resumes. We need to dissect it to see if * it is a branch instruction. + * For ARM instructions, we also need to evaluate the current (breakpointed) instruction to see if it'll execute. + * If not, then the next instruction is the instruction following the current instruction. */ 2: + /* Use R5 to store candidate next instruction address */ + teq r4, #0 /* Check if it is ARM or Thumb instruction */ + beq _next_instr_is_arm +_next_instr_is_thumb: + add r5, r2, #2 /* set next Thumb instruction address */ + _is_thumb_branch_instr r0 /* check if the current instruction is a branch instruction */ +_next_instr_is_arm: + add r5, r2, #4 /* Is ARM, set next ARM instruction address */ @@@@@@@@@ bx lr diff --git a/Debugger/debug_stub.h b/Debugger/debug_stub.h index 7849d56..311fa93 100644 --- a/Debugger/debug_stub.h +++ b/Debugger/debug_stub.h @@ -97,7 +97,7 @@ #define BKPT32_AUTO_BKPT 0x00080000 /* ARM BKPT Auto-Step Flag (for CONT support) */ #define BKPT32_MANUAL_BKPT 0x0007FF0F /* Manually inserted ARM Breakpoint */ -#define BKPT16_INSTR 0xBE00 /* Thumb BKPT instruction (not supported currently) */ +#define BKPT16_INSTR 0xBE00 /* Thumb BKPT instruction */ #define BKPT16_ENUM_MASK 0x00FF /* Thumb BKPT Enum Mask */ #define BKPT16_AUTO_BKPT 0x0080 /* Thumb BKPT Auto-Step Flag (for CONT support) */ #define BKPT16_MANUAL_BKPT 0x007F /* Manually inserted Thumb Breakpoint */ diff --git a/Debugger/undef_handler.S b/Debugger/undef_handler.S index c160179..34bca92 100644 --- a/Debugger/undef_handler.S +++ b/Debugger/undef_handler.S @@ -37,11 +37,11 @@ undef_handler: stmfd sp, {r0-r15}^ /* Save workspace, user mode's pc via 'S' flag */ sub sp, sp, #(4*16) /* Need to manually update SP(undef) */ mrs r1, spsr /* Copy SPSR to r0 */ - sub r0, lr, #-4 /* LR points to instruction after UNDEF instruction */ - stmfd sp!, {r0,r1} /* Save UNDEF instruction addr and previous mode's CPSR to stack */ tst r1, #CPSR_THUMB /* Check for Thumb Mode */ beq _is_arm /* Clear, so it's ARM mode */ _is_thumb: + sub r0, lr, #-2 /* LR points to instruction after UNDEF instruction */ + stmfd sp!, {r0,r1} /* Save UNDEF instruction addr and previous mode's CPSR to stack */ ldrh r0, [r0] /* load UNDEF instruction into r0 */ ldr r1, =BKPT16_ENUM_MASK /* Thumb BKPT enum mask */ bic r2, r0, r1 /* leave only opcode */ @@ -54,6 +54,8 @@ _is_thumb: ldr lr, =dbg__thumb_bkpt_handler /* handle BKPT, BKPT index in r0 */ mov pc, lr /* Invoke Debugger State (Supervisor Mode) */ _is_arm: + sub r0, lr, #-4 /* LR points to instruction after UNDEF instruction */ + stmfd sp!, {r0,r1} /* Save UNDEF instruction addr and previous mode's CPSR to stack */ ldr r0, [r0] /* load UNDEF instruction into r0 */ ldr r1, =BKPT32_ENUM_MASK /* ARM BKPT enum mask */ bic r2, r0, r1 /* leave only opcode */ -- cgit v1.2.3