📄 singlestep.c
字号:
{ case 0x0: break; case 0x1: mem_value = ror(mem_value, 8); break; case 0x2: mem_value = ror(mem_value, 16); break; case 0x3: mem_value = ror(mem_value, 24); break; } } else { /* * Byte load of the PC */ if (bsp_memory_read((void*)operand, 0, 8, 1, &mem_value) == 0) { /* * Unable to read the memory address. * Don't try any further. */#if DEBUG_SINGLESTEP bsp_printf("Setting BP at *(0x%08lx): Error\n", operand & ~0x3);#endif /* DEBUG_SINGLESTEP */ return; } else {#if DEBUG_SINGLESTEP bsp_printf("Setting BP at *(0x%08lx): data <0x%08lx>\n", operand & ~0x3, mem_value);#endif /* DEBUG_SINGLESTEP */ } } insert_ss_break((unsigned long *)mem_value);}/* * Calculate a load/store w/ Immediate offset operand based on input * source register, offset value, and opcode (add/sub) */static unsigned long load_store_immediate_operand(ex_regs_t *regs, unsigned p_bit, unsigned u_bit, unsigned Rn, unsigned offset){ unsigned char *regs_array = (unsigned char *)regs; unsigned char *reg_ptr = ®s_array[bsp_regbyte(Rn)]; unsigned long rc = *((unsigned long *)(reg_ptr)); BSP_ASSERT((Rn >= 0) && (Rn <= 0xf)); BSP_ASSERT(bsp_regsize(Rn) == sizeof(unsigned long)); BSP_ASSERT((offset >= 0) && (offset <= 0xfff)); BSP_ASSERT((p_bit >= 0) && (p_bit <= 1)); BSP_ASSERT((u_bit >= 0) && (u_bit <= 1)); /* * According to the ARM(R) Manual, if Rn is PC then, * the value used is the address of the current instruction * plus 8 */ if (Rn == REG_PC) rc += 8; /* * Do the update pre-index update */ if (p_bit == LS_INDEX_PRE) { if (u_bit == LS_OFFSET_SUB) rc -= offset; else /* opcode == LS_OFFSET_ADD */ rc += offset; } return (rc);}/* * Calculate a load/store w/ Register offset operand based on input * source register, offset value, and opcode (add/sub) * * This calculates the appropriate pre-indexed operand */static unsigned long load_store_register_operand(ex_regs_t *regs, unsigned p_bit, unsigned u_bit, unsigned Rn, unsigned Rm, unsigned shift, unsigned shift_immed){ unsigned char *regs_array = (unsigned char *)regs; unsigned char *Rn_ptr = ®s_array[bsp_regbyte(Rn)]; unsigned long Rn_val = *((unsigned long *)(Rn_ptr)); unsigned long rc, index; BSP_ASSERT((Rn >= 0) && (Rn <= 0xf)); BSP_ASSERT((Rm >= 0) && (Rm <= 0xf)); BSP_ASSERT(bsp_regsize(Rn) == sizeof(unsigned long)); BSP_ASSERT(bsp_regsize(Rm) == sizeof(unsigned long)); BSP_ASSERT((p_bit >= 0) && (p_bit <= 1)); BSP_ASSERT((u_bit >= 0) && (u_bit <= 1)); BSP_ASSERT((shift >= 0) && (shift <= 0x3)); BSP_ASSERT((shift_immed >= 0) && (shift_immed <= 0x1F)); /* * According to the ARM(R) Manual, if Rn is PC then * the value used is the address of the current * instruction plus 8 */ if (Rn == REG_PC) Rn_val += 8; /* * According to the ARM(R) Manual, if Rm is PC then * the result is unpredictable. Don't do anything * here. Just return. */ if (Rm == REG_PC) return 0; index = immediate_shift_operand(regs, shift_immed, shift, Rm); rc = Rn_val; /* * Do the update pre-index update */ if (p_bit == LS_INDEX_PRE) { if (u_bit == LS_OFFSET_SUB) rc = Rn_val - index; else /* opcode == LS_OFFSET_ADD */ rc = Rn_val + index; } return (rc);}/* * Decode all data processing immediate instructions */static void decode_dpi_inst(ex_regs_t *regs, union arm_insn inst){ if (inst.dpi.Rd == REG_PC) { unsigned long operand = ror(inst.dpi.immediate, (inst.dpi.rotate << 1)); unsigned long *dest = 0; unsigned carry = ((union arm_psr)(unsigned long)(regs->_cpsr)).psr.c_bit; unsigned char *regs_array = (unsigned char *)regs; unsigned char *Rn_ptr = ®s_array[bsp_regbyte(inst.dpi.Rn)]; unsigned long Rn_val = *((unsigned long *)(Rn_ptr));#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("Decoded an data processing immediate instruction.\n"); bsp_printf("inst.dpi.immediate = 0x%x\n", inst.dpi.immediate); bsp_printf("inst.dpi.rotate = 0x%x\n", inst.dpi.rotate); bsp_printf("inst.dpi.Rd = 0x%x\n", inst.dpi.Rd); bsp_printf("inst.dpi.Rn = 0x%x\n", inst.dpi.Rn); bsp_printf("inst.dpi.S_bit = 0x%x\n", inst.dpi.S_bit); bsp_printf("inst.dpi.opcode = 0x%x\n", inst.dpi.opcode); bsp_printf("inst.dpi.cond = 0x%x\n", inst.dpi.cond); bsp_printf("operand = 0x%x\n", operand);#endif /* DEBUG_SINGLESTEP_VERBOSE */ /* * According to the ARM(R) Manual, if Rn is PC then * the value used is the address of the current * instruction plus 8 */ if (inst.dpi.Rn == REG_PC) Rn_val += 8; switch (inst.dpi.opcode) { case DP_OPCODE_ADC: dest = (unsigned long *)(Rn_val + operand + carry); break; case DP_OPCODE_ADD: dest = (unsigned long *)(Rn_val + operand); break; case DP_OPCODE_AND: dest = (unsigned long *)(Rn_val & operand); break; case DP_OPCODE_BIC: dest = (unsigned long *)(Rn_val & ~operand); break; case DP_OPCODE_EOR: dest = (unsigned long *)(Rn_val ^ operand); break; case DP_OPCODE_MOV: dest = (unsigned long *)operand; break; case DP_OPCODE_MVN: dest = (unsigned long *)(~operand); break; case DP_OPCODE_ORR: dest = (unsigned long *)(Rn_val | operand); break; case DP_OPCODE_RSB: dest = (unsigned long *)(operand - Rn_val); break; case DP_OPCODE_RSC: dest = (unsigned long *)(operand - Rn_val - !carry); break; case DP_OPCODE_SBC: dest = (unsigned long *)(Rn_val - operand - !carry); break; case DP_OPCODE_SUB: dest = (unsigned long *)(Rn_val - operand); break; default: dest = (unsigned long *)0; break; } dest = (unsigned long *)((unsigned long)dest & ~0x3); insert_ss_break(dest); }}/* * Decode all data processing immediate w/ shift instructions */static void decode_dpis_inst(ex_regs_t *regs, union arm_insn inst){ if (inst.dpis.Rd == REG_PC) { unsigned long operand = immediate_shift_operand(regs, inst.dpis.shift_immed, inst.dpis.shift, inst.dpis.Rm); unsigned long *dest = 0; unsigned carry = ((union arm_psr)(unsigned long)(regs->_cpsr)).psr.c_bit; unsigned char *regs_array = (unsigned char *)regs; unsigned char *Rn_ptr = ®s_array[bsp_regbyte(inst.dpis.Rn)]; unsigned long Rn_val = *((unsigned long *)(Rn_ptr));#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("Decoded an data processing immediate shift instruction.\n"); bsp_printf("inst.dpis.Rm = 0x%x\n", inst.dpis.Rm); bsp_printf("inst.dpis.shift = 0x%x\n", inst.dpis.shift); bsp_printf("inst.dpis.shift_immed = 0x%x\n", inst.dpis.shift_immed); bsp_printf("inst.dpis.Rd = 0x%x\n", inst.dpis.Rd); bsp_printf("inst.dpis.Rn = 0x%x\n", inst.dpis.Rn); bsp_printf("inst.dpis.S_bit = 0x%x\n", inst.dpis.S_bit); bsp_printf("inst.dpis.opcode = 0x%x\n", inst.dpis.opcode); bsp_printf("inst.dpis.cond = 0x%x\n", inst.dpis.cond); bsp_printf("operand = 0x%x\n", operand);#endif /* DEBUG_SINGLESTEP_VERBOSE */ /* * According to the ARM(R) Manual, if Rn is PC then * the value used is the address of the current * instruction plus 8 */ if (inst.dpis.Rn == REG_PC) Rn_val += 8; switch (inst.dpis.opcode) { case DP_OPCODE_ADC: dest = (unsigned long *)(Rn_val + operand + carry); break; case DP_OPCODE_ADD: dest = (unsigned long *)(Rn_val + operand); break; case DP_OPCODE_AND: dest = (unsigned long *)(Rn_val & operand); break; case DP_OPCODE_BIC: dest = (unsigned long *)(Rn_val & ~operand); break; case DP_OPCODE_EOR: dest = (unsigned long *)(Rn_val ^ operand); break; case DP_OPCODE_MOV: dest = (unsigned long *)operand; break; case DP_OPCODE_MVN: dest = (unsigned long *)(~operand); break; case DP_OPCODE_ORR: dest = (unsigned long *)(Rn_val | operand); break; case DP_OPCODE_RSB: dest = (unsigned long *)(operand - Rn_val); break; case DP_OPCODE_RSC: dest = (unsigned long *)(operand - Rn_val - !carry); break; case DP_OPCODE_SBC: dest = (unsigned long *)(Rn_val - operand - !carry); break; case DP_OPCODE_SUB: dest = (unsigned long *)(Rn_val - operand); break; default: dest = (unsigned long *)0; break; } dest = (unsigned long *)((unsigned long)dest & ~0x3); insert_ss_break(dest); }}/* * Decode all data processing register w/ shift instructions */static void decode_dprs_inst(ex_regs_t *regs, union arm_insn inst){ if (inst.dprs.Rd == REG_PC) { unsigned long operand = register_shift_operand(regs, inst.dprs.Rs, inst.dprs.shift, inst.dprs.Rm); unsigned long *dest = 0; unsigned carry = ((union arm_psr)(unsigned long)(regs->_cpsr)).psr.c_bit; unsigned char *regs_array = (unsigned char *)regs; unsigned char *Rn_ptr = ®s_array[bsp_regbyte(inst.dprs.Rn)]; unsigned long Rn_val = *((unsigned long *)(Rn_ptr));#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("Decoded an data processing register shift instruction.\n"); bsp_printf("inst.dprs.Rm = 0x%x\n", inst.dprs.Rm); bsp_printf("inst.dprs.rsv3 = 0x%x\n", inst.dprs.rsv3); bsp_printf("inst.dprs.shift = 0x%x\n", inst.dprs.shift); bsp_printf("inst.dprs.rsv2 = 0x%x\n", inst.dprs.rsv2); bsp_printf("inst.dprs.Rs = 0x%x\n", inst.dprs.Rs); bsp_printf("inst.dprs.Rd = 0x%x\n", inst.dprs.Rd); bsp_printf("inst.dprs.Rn = 0x%x\n", inst.dprs.Rn); bsp_printf("inst.dprs.S_bit = 0x%x\n", inst.dprs.S_bit); bsp_printf("inst.dprs.opcode = 0x%x\n", inst.dprs.opcode); bsp_printf("inst.dprs.rsv1 = 0x%x\n", inst.dprs.rsv1); bsp_printf("inst.dprs.cond = 0x%x\n", inst.dprs.cond); bsp_printf("operand = 0x%x\n", operand);#endif /* DEBUG_SINGLESTEP_VERBOSE */ /* * According to the ARM(R) Manual, if Rn is PC then * the value used is the address of the current * instruction plus 8 */ if (inst.dprs.Rn == REG_PC) Rn_val += 8; switch (inst.dprs.opcode) { case DP_OPCODE_ADC: dest = (unsigned long *)(Rn_val + operand + carry); break; case DP_OPCODE_ADD: dest = (unsigned long *)(Rn_val + operand); break; case DP_OPCODE_AND: dest = (unsigned long *)(Rn_val & operand); break; case DP_OPCODE_BIC: dest = (unsigned long *)(Rn_val & ~operand); break; case DP_OPCODE_EOR: dest = (unsigned long *)(Rn_val ^ operand); break; case DP_OPCODE_MOV: dest = (unsigned long *)operand; break; case DP_OPCODE_MVN: dest = (unsigned long *)(~operand); break; case DP_OPCODE_ORR: dest = (unsigned long *)(Rn_val | operand); break; case DP_OPCODE_RSB: dest = (unsigned long *)(operand - Rn_val); break; case DP_OPCODE_RSC: dest = (unsigned long *)(operand - Rn_val - !carry); break; case DP_OPCODE_SBC: dest = (unsigned long *)(Rn_val - operand - !carry); break; case DP_OPCODE_SUB: dest = (unsigned long *)(Rn_val - operand); break; default: dest = (unsigned long *)0; break; } dest = (unsigned long *)((unsigned long)dest & ~0x3); insert_ss_break(dest); }}/* * Decode all multiply instructions */static void decode_m_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 multiply long instructions */static void decode_ml_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 move from status register instructions */static void decode_mrs_inst(ex_regs_t *regs, union arm_insn inst){#if 0 if (inst.mrs.Rd == REG_PC) { unsigned long *dest = 0;#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("Decoded an move from status register instruction.\n"); bsp_printf("inst.mrs.SBZ = 0x%x\n", inst.mrs.SBZ); bsp_printf("inst.mrs.Rd = 0x%x\n", inst.mrs.Rd); bsp_printf("inst.mrs.SBO = 0x%x\n", inst.mrs.SBO); bsp_printf("inst.mrs.rsv2 = 0x%x\n", inst.mrs.rsv2); bsp_printf("inst.mrs.R_bit = 0x%x\n", inst.mrs.R_bit); bsp_printf("inst.mrs.rsv1 = 0x%x\n", inst.mrs.rsv1); bsp_printf("inst.mrs.cond = 0x%x\n", inst.mrs.cond);#endif /* DEBUG_SINGLESTEP_VERBOSE */ if (inst.mrs.R_bit == 1) dest = (unsigned long *)regs->_spsr; else dest = (unsigned long *)regs->_cpsr; dest = (unsigned long *)((unsigned long)dest & ~0x3); insert_ss_break(dest); }#endif}/* * Decode all move immediate to status register instructions */static void decode_misr_inst(ex_regs_t *regs, union arm_insn inst){ /* * Can't update the PC w/ this instruction. * Don't set any more breakpoints */}/* * Decode all move register to status registers instructions */static void decode_mrsr_inst(ex_regs_t *regs, union arm_insn inst){ /* * Can't update the PC w/ this instruction. * Don't set any more breakpoints */}/* * Decode all branch/exchange instructions */static void decode_bx_inst(ex_regs_t *regs, union arm_insn inst){ unsigned long operand = branch_exchange_operand(regs, inst.bx.Rm);#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("Decoded an branch/exchange shift instruction.\n"); bsp_printf("inst.bx.Rm = 0x%x\n", inst.bx.Rm); bsp_printf("inst.bx.rsv2 = 0x%x\n", inst.bx.rsv2); bsp_printf("inst.bx.SBO3 = 0x%x\n", inst.bx.SBO3); bsp_printf("inst.bx.SBO2 = 0x%x\n", inst.bx.SBO2); bsp_printf("inst.bx.SBO1 = 0x%x\n", inst.bx.SBO1); bsp_printf("inst.bx.rsv1 = 0x%x\n", inst.bx.rsv1); bsp_printf("inst.bx.cond = 0x%x\n", inst.bx.cond); bsp_printf("operand = 0x%x\n", operand);#endif /* DEBUG_SINGLESTEP_VERBOSE */ insert_ss_break((unsigned long *)operand);}/* * Decode all load/store immediate offset instructions */static void decode_lsio_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.lsio.Rd == REG_PC) && (inst.lsio.L_bit == LS_LOAD)) { unsigned long operand = load_store_immediate_operand(regs, inst.lsio.P_bit, inst.lsio.U_bit, inst.lsio.Rn, inst.lsio.immediate);#if DEBUG_SINGLESTEP_VERBOSE bsp_printf("Decoded an load/store w/ immediate offset instruction.\n"); bsp_printf("inst.lsio.immediate = 0x%x\n", inst.lsio.immediate); bsp_printf("inst.lsio.Rd = 0x%x\n", inst.lsio.Rd); bsp_printf("inst.lsio.Rn = 0x%x\n", inst.lsio.Rn); bsp_printf("inst.lsio.L_bit = 0x%x\n", inst.lsio.L_bit); bsp_printf("inst.lsio.W_bit = 0x%x\n", inst.lsio.W_bit); bsp_printf("inst.lsio.B_bit = 0x%x\n", inst.lsio.B_bit); bsp_printf("inst.lsio.U_bit = 0x%x\n", inst.lsio.U_bit); bsp_printf("inst.lsio.P_bit = 0x%x\n", inst.lsio.P_bit); bsp_printf("inst.lsio.rsv1 = 0x%x\n", inst.lsio.rsv1); bsp_printf("inst.lsio.cond = 0x%x\n", inst.lsio.cond); bsp_printf("operand = 0x%x\n", operand);#endif /* DEBUG_SINGLESTEP_VERBOSE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -