当前位置:首页 > 浅析eCos系统Redboot内置GDB功能的具体代码实现
(HAL_STUB_HW_BREAKPOINT_LIST_SIZE > 0) __install_hw_breakpoint_list(); #endif #if defined(HAL_STUB_HW_WATCHPOINT_LIST_SIZE) && (HAL_STUB_HW_WATCHPOINT_LIST_SIZE > 0) __install_hw_watchpoint_list(); #endif
HAL_ICACHE_SYNC(); }
//==================== __install_traps
==>__cleanup_vec = &handle_exception_cleanup; __init_vec = &handle_exception_init; static void
handle_exception_cleanup( void ) {
static int orig_registers_set = 0;
interruptible(0); // 禁止虚拟向量表中DEBUG串口中断
// Expand the HAL_SavedRegisters structure into the GDB register // array format.
HAL_GET_GDB_REGISTERS(®isters[0], _hal_registers); // 拷贝_hal_registers中内容到GDB专用寄存器registers中 _registers = ®isters[0]; // 当前使用的register寄存器指向GDB专用寄存器
if (!orig_registers_set) { int i;
for (i = 0; i < (sizeof(registers)/sizeof(registers[0])); i++) orig_registers[i] = registers[i];
_registers = &orig_registers[0]; // 将orig_registers作为下面操作语句临时使用的register寄存器 if (__is_breakpoint_function ()) // 如果当前PC位于breakpoint or trap instruction,那么if成立
__skipinst (); // pc+2或+4,调整pc数值,跳过当前位于breakpoint or trap instruction的语句
_registers = ®isters[0];// 将_registers还原回去 orig_registers_set = 1; } ...
#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
// If we continued instead of stepping, when there was a break set // ie. we were stepping within a critical region, clear the break,
and
// that flag. If we stopped for some other reason, this has no effect.
if ( cyg_hal_gdb_running_step ) { cyg_hal_gdb_running_step = 0;
cyg_hal_gdb_remove_break(get_register (PC)); // 将break_buffer.targetAddr存放的pc处原始code内容,拷贝回*pc处,替换原有break内容. }
// FIXME: (there may be a better way to do this)
// If we hit a breakpoint set by the gdb interrupt stub, make it // seem like an interrupt rather than having hit a breakpoint. cyg_hal_gdb_break = cyg_hal_gdb_remove_break(get_register (PC)); #endif
#if defined(HAL_STUB_HW_WATCHPOINT) || defined(HAL_STUB_HW_BREAKPOINT) // For HW watchpoint/breakpoint support, we need to know if we // stopped because of watchpoint or hw break. We do that here // before GDB has a chance to remove the watchpoints and save // the information for later use in building response packets. _hw_stop_reason = HAL_STUB_IS_STOPPED_BY_HARDWARE(_watch_data_addr); #endif }
int
cyg_hal_gdb_remove_break (target_register_t pc) {
if ( cyg_hal_gdb_running_step )
return 0; // Do not remove the break: we must hit it!
if (pc == UNMAKE_THUMB_ADDR(break_buffer.targetAddr)) { // 如果当前pc就是break断点设置处,那么将暂存到break_buffer中的原始code代码恢复到break点[luther.gliethttp]
if (IS_THUMB_ADDR(break_buffer.targetAddr)) { *(cyg_uint16*)pc = break_buffer.savedInstr.thumb_instr; } else { *(cyg_uint32*)pc = break_buffer.savedInstr.arm_instr; }
break_buffer.targetAddr = 0;
__data_cache(CACHE_FLUSH); // 清空dcache
__instruction_cache(CACHE_FLUSH); // 清空icache [luther.gliethttp]
return 1; }
return 0; }
__handle_exception
==>__cleanup_vec ();即:handle_exception_cleanup(); ==>
packages/hal/arm/arch/v2_0/src/arm_stub.c
// Return the currently-saved value corresponding to register REG of // the exception context. target_register_t
get_register (regnames_t reg) {
target_register_t val;
int offset = reg_offset(reg);
if (REGSIZE(reg) > sizeof(target_register_t) || offset == -1) return -1;
val = _registers[offset/sizeof(target_register_t)];
return val; }
//====================
int __is_bsp_syscall(void) {
unsigned long pc = get_register(PC);
unsigned long cpsr = get_register(PS); // condition codes
if (_hal_registers->vector == CYGNUM_HAL_EXCEPTION_INTERRUPT) { if (cpsr & CPSR_THUMB_ENABLE)
return *(unsigned short *)pc == 0xdf18;//反汇编后为指令swi 24 else
return *(unsigned *)pc == 0xef180001;//反汇编后为指令swi 0x00180001 }
return 0;
}
luther@gliethttp:/vobs/ecos$ ghex2 luther.asm.bin 然后输入01 00 18 ef十六进制,保存.
luther@gliethttp:/vobs/ecos$ arm-elf-objdump -DS -b binary -m arm luther.asm.bin 反汇编数据如下:
luther.asm.bin: file format binary
arm-elf-objdump: luther.asm.bin: no symbols Disassembly of section .data:
00000000 <.data>:
0: ef180001 swi 0x00180001 同样的反汇编thumb代码
luther@gliethttp:/vobs/ecos$ ghex2 luther.asm.bin 然后输入18 df十六进制,保存.
luther@gliethttp:/vobs/ecos$ arm-elf-objdump -DS -b binary -m arm -M force-thumb luther.asm.bin
luther.asm.bin: file format binary
arm-elf-objdump: luther.asm.bin: no symbols Disassembly of section .data:
00000000 <.data>:
0: df18 swi 24 //====================
#define SYS_exit 1 #define SYS_interrupt 1000 int
hal_syscall_handler(void) // 由packages/cygmon/v2_0/misc/arm/cpu.h|446|定义引用 // #define SYSCALL() asm volatile(\swi %0\: /* No outputs */ : \{
int func, arg1, arg2, arg3, arg4; int err, sig;
#if 0
union arm_insn inst;
// What is the instruction we were executing //
共分享92篇相关文档