📄 singlestep.c
字号:
/* * Decode all load/store register offset instructions */static void decode_lsro_inst(ex_regs_t *regs, union arm_insn inst){ /* * Only support direct loads of the PC * * According to the ARM(R) manual, automatic updates of the PC * are UNPREDICTABLE (ie implementation defined). */ if ((inst.lsro.Rd == REG_PC) && (inst.lsro.L_bit == LS_LOAD)) { unsigned long operand = load_store_register_operand(regs, inst.lsro.P_bit, inst.lsro.U_bit, inst.lsro.Rn, inst.lsro.Rm, inst.lsro.shift, inst.lsro.shift_immed);#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("Decoded an load/store w/ register offset instruction.\n"); bsp_printf("inst.lsro.Rm = 0x%x\n", inst.lsro.Rm); bsp_printf("inst.lsro.rsv2 = 0x%x\n", inst.lsro.rsv2); bsp_printf("inst.lsro.shift = 0x%x\n", inst.lsro.shift); bsp_printf("inst.lsro.shift_immed = 0x%x\n", inst.lsro.shift_immed); bsp_printf("inst.lsro.Rd = 0x%x\n", inst.lsro.Rd); bsp_printf("inst.lsro.Rn = 0x%x\n", inst.lsro.Rn); bsp_printf("inst.lsro.L_bit = 0x%x\n", inst.lsro.L_bit); bsp_printf("inst.lsro.W_bit = 0x%x\n", inst.lsro.W_bit); bsp_printf("inst.lsro.B_bit = 0x%x\n", inst.lsro.B_bit); bsp_printf("inst.lsro.U_bit = 0x%x\n", inst.lsro.U_bit); bsp_printf("inst.lsro.P_bit = 0x%x\n", inst.lsro.P_bit); bsp_printf("inst.lsro.rsv1 = 0x%x\n", inst.lsro.rsv1); bsp_printf("inst.lsro.cond = 0x%x\n", inst.lsro.cond); bsp_printf("operand = 0x%x\n", operand);#endif /* DEBUG_SINGLESTEP_VERBOSE */ handle_pc_load(inst.lsro.B_bit, operand); }}/* * Decode all load/store halfword/signed byte immediate offset instructions */static void decode_lshwi_inst(ex_regs_t *regs, union arm_insn inst){ /* * According to the ARM(R) Manual, if Rd is PC then * the result is unpredictable. Don't do anything * here. Just return. */}/* * Decode all load/store halfword/signed byte register offset instructions */static void decode_lshwr_inst(ex_regs_t *regs, union arm_insn inst){ /* * According to the ARM(R) Manual, if Rd is PC then * the result is unpredictable. Don't do anything * here. Just return. */}/* * Decode all swap/swap byte instructions */static void decode_swap_inst(ex_regs_t *regs, union arm_insn inst){ /* * According to the ARM(R) Manual, if Rd is PC then * the result is unpredictable. Don't do anything * here. Just return. */}/* * Decode all load/store multiple instructions */static void decode_lsm_inst(ex_regs_t *regs, union arm_insn inst){ /* * Only support direct load multiples where the PC is in the * register list. * * According to the ARM(R) manual, automatic updates of the PC * are UNPREDICTABLE (ie implementation defined). */ if ((inst.lsm.L_bit == LS_LOAD) && (inst.lsm.Reg_List & (0x1 << REG_PC))) { unsigned char *regs_array = (unsigned char *)regs; unsigned char *Rn_ptr = ®s_array[bsp_regbyte(inst.lsm.Rn)]; unsigned long Rn_val = *((unsigned long *)(Rn_ptr)); unsigned long offset_to_pc = 0; int i; unsigned long **dest = 0;#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("Decoded an load multiple instruction.\n"); bsp_printf("inst.lsm.Reg_List = 0x%x\n", inst.lsm.Reg_List); bsp_printf("inst.lsm.Rn = 0x%x\n", inst.lsm.Rn); bsp_printf("inst.lsm.L_bit = 0x%x\n", inst.lsm.L_bit); bsp_printf("inst.lsm.W_bit = 0x%x\n", inst.lsm.W_bit); bsp_printf("inst.lsm.S_bit = 0x%x\n", inst.lsm.S_bit); bsp_printf("inst.lsm.U_bit = 0x%x\n", inst.lsm.U_bit); bsp_printf("inst.lsm.P_bit = 0x%x\n", inst.lsm.P_bit); bsp_printf("inst.lsm.rsv1 = 0x%x\n", inst.lsm.rsv1); bsp_printf("inst.lsm.cond = 0x%x\n", inst.lsm.cond);#endif /* DEBUG_SINGLESTEP_VERBOSE */ if (inst.lsm.U_bit == 0) { /* * We are using a ascending stack. * That means the PC is actually the register * nearest to Rn currently. */ if (inst.lsm.P_bit == 1) /* * Using a pre-decrement. */ offset_to_pc = -bsp_regsize(REG_PC); else offset_to_pc = 0; } else { /* * We are using an descending stack. * That means the PC is actually the register * farthest from Rn currently. * * Find the number of registers stored before the PC */ for (i = 0; i < REG_PC; i++) { if ((inst.lsm.Reg_List & (0x1 << i)) != 0) { /* * Bit #i is set. Increment our count. */ offset_to_pc += bsp_regsize(i); } } /* * Adjust the offset if we do a decrement/increment __BEFORE__ * the write. */ if (inst.lsm.P_bit == 1) offset_to_pc += bsp_regsize(REG_PC); } /* * Now let's calculate the real address of the stored PC * making sure to mask out the two LO bits. */ dest = (unsigned long **)((Rn_val + offset_to_pc) & ~0x3);#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("Rn_val = 0x%08lx\n", Rn_val); bsp_printf("offset_to_pc = 0x%08lx\n", offset_to_pc); bsp_printf("dest = 0x%08lx\n", dest); bsp_printf("*dest = 0x%08lx\n", *dest);#endif /* DEBUG_SINGLESTEP_VERBOSE */ insert_ss_break(*dest); }}/* * Decode all coprocessor data processing instructions */static void decode_cpdp_inst(ex_regs_t *regs, union arm_insn inst){ /* * Can't possibly predict what this instruction will do. * Don't do anything here. Just return. */}/* * Decode all coprocessor register transfer instructions */static void decode_cprt_inst(ex_regs_t *regs, union arm_insn inst){ /* * Can't possibly predict what this instruction will do. * Don't do anything here. Just return. */}/* * Decode all coprocessor load/store instructions */static void decode_cpls_inst(ex_regs_t *regs, union arm_insn inst){ /* * Can't possibly predict what this instruction will do. * Don't do anything here. Just return. */}/* * Decode all branch/branch w/ link instructions */static void decode_bbl_inst(ex_regs_t *regs, union arm_insn inst){ unsigned long disp = inst.bbl.offset; /* * Sign extend the 24 bit value */ if (disp & 0x00800000) disp |= 0xff000000; /* * Convert to long words */ disp <<= 2; /* * Note: when the processor actually executes this instruction, the pc * will point to the address of the current instruction + 8 because * of the fetch/decode/execute cycle */ disp += 8; insert_ss_break((unsigned long *)(regs->_pc + disp));}/* * Decode all swi instructions */static void decode_swi_inst(ex_regs_t *regs, union arm_insn inst){ /* * Can't possibly predict where we should set the breakpoint for this. * Don't do anything here. Just return. */}/* * Decode all undefined instructions */static void decode_undef_inst(ex_regs_t *regs, union arm_insn inst){ /* * Can't possibly predict what this instruction will do. * Don't do anything here. Just return. */}/* * Set breakpoint instructions for single stepping. */voidbsp_singlestep_setup(void *registers){ ex_regs_t *regs = (ex_regs_t *)registers; union arm_insn inst; if (bsp_memory_read((void*)(regs->_pc), 0, ARM_INST_SIZE * 8, 1, &(inst.word)) == 0) { /* * Unable to read the instruction at the current address. * Let's not do anything with this. We can't set breakpoints * so let's get out now. */ return; } /* * Handle the simple case -- linear code */ insert_ss_break((unsigned long *)(regs->_pc + ARM_INST_SIZE)); /* * Now, we need to decode the instructions and figure out what * they would do. */ if ((inst.mrs.rsv1 == MRS_RSV1_VALUE) && (inst.mrs.rsv2 == MRS_RSV2_VALUE)) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("MRS type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_mrs_inst(regs, inst); } else if ((inst.misr.rsv1 == MISR_RSV1_VALUE) && (inst.misr.rsv2 == MISR_RSV2_VALUE)) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("MISR type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_misr_inst(regs, inst); } else if ((inst.mrsr.rsv1 == MRSR_RSV1_VALUE) && (inst.mrsr.rsv2 == MRSR_RSV2_VALUE) && (inst.mrsr.rsv3 == MRSR_RSV3_VALUE)) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("MRSR type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_mrsr_inst(regs, inst); } else if (inst.dpi.rsv1 == DPI_RSV1_VALUE) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("DPI type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_dpi_inst(regs, inst); } else if ((inst.bx.rsv1 == BX_RSV1_VALUE) && (inst.bx.rsv2 == BX_RSV2_VALUE)) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("BX type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_bx_inst(regs, inst); } else if ((inst.dpis.rsv1 == DPIS_RSV1_VALUE) && (inst.dpis.rsv2 == DPIS_RSV2_VALUE)) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("DPIS type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_dpis_inst(regs, inst); } else if ((inst.dprs.rsv1 == DPRS_RSV1_VALUE) && (inst.dprs.rsv2 == DPRS_RSV2_VALUE) && (inst.dprs.rsv3 == DPRS_RSV3_VALUE)) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("DPRS type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_dprs_inst(regs, inst); } else if ((inst.m.rsv1 == M_RSV1_VALUE) && (inst.m.rsv2 == M_RSV2_VALUE)) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("M type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_m_inst(regs, inst); } else if ((inst.ml.rsv1 == ML_RSV1_VALUE) && (inst.ml.rsv2 == ML_RSV2_VALUE)) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("ML type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_ml_inst(regs, inst); } else if (inst.lsio.rsv1 == LSIO_RSV1_VALUE) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("LSIO type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_lsio_inst(regs, inst); } else if ((inst.lsro.rsv1 == LSRO_RSV1_VALUE) && (inst.lsro.rsv2 == LSRO_RSV2_VALUE)) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("LSRO type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_lsro_inst(regs, inst); } else if ((inst.lshwi.rsv1 == LSHWI_RSV1_VALUE) && (inst.lshwi.rsv2 == LSHWI_RSV2_VALUE) && (inst.lshwi.rsv3 == LSHWI_RSV3_VALUE) && (inst.lshwi.rsv4 == LSHWI_RSV4_VALUE)) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("LSHWI type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_lshwi_inst(regs, inst); } else if ((inst.lshwr.rsv1 == LSHWR_RSV1_VALUE) && (inst.lshwr.rsv2 == LSHWR_RSV2_VALUE) && (inst.lshwr.rsv3 == LSHWR_RSV3_VALUE) && (inst.lshwr.rsv4 == LSHWR_RSV4_VALUE)) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("LSHWR type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_lshwr_inst(regs, inst); } else if ((inst.swap.rsv1 == SWAP_RSV1_VALUE) && (inst.swap.rsv2 == SWAP_RSV2_VALUE) && (inst.swap.rsv3 == SWAP_RSV3_VALUE)) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("SWAP type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_swap_inst(regs, inst); } else if (inst.lsm.rsv1 == LSM_RSV1_VALUE) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("LSM type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_lsm_inst(regs, inst); } else if ((inst.cpdp.rsv1 == CPDP_RSV1_VALUE) && (inst.cpdp.rsv2 == CPDP_RSV2_VALUE)) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("CPDP type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_cpdp_inst(regs, inst); } else if ((inst.cprt.rsv1 == CPRT_RSV1_VALUE) && (inst.cprt.rsv2 == CPRT_RSV2_VALUE)) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("CPRT type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_cprt_inst(regs, inst); } else if (inst.cpls.rsv1 == CPLS_RSV1_VALUE) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("CPLS type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_cpls_inst(regs, inst); } else if (inst.bbl.rsv1 == BBL_RSV1_VALUE) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("BBL type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_bbl_inst(regs, inst); } else if (inst.swi.rsv1 == SWI_RSV1_VALUE) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("SWI type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_swi_inst(regs, inst); } else if ((inst.undef.rsv1 == UNDEF_RSV1_VALUE) && (inst.undef.rsv2 == UNDEF_RSV2_VALUE)) {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("UNDEF type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ decode_undef_inst(regs, inst); } else {#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("Unknown instruction type: 0x%08lx\n", inst.word);#endif /* DEBUG_SINGLESTEP_VERBOSE */ }}voidbsp_skip_instruction(void *registers){ ex_regs_t *regs = (ex_regs_t *)registers; regs->_pc += ARM_INST_SIZE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -