📄 wdbbplib.c
字号:
pBp->bp_action = pBreakPoint->action.actionType;#if ((CPU_FAMILY == ARM) && ARM_THUMB) pBp->bp_callRtn = (void (*)())((UINT32)pBreakPoint->action.callRtn | 1);#else /* CPU_FAMILY == ARM */ pBp->bp_callRtn = (void (*)())pBreakPoint->action.callRtn;#endif /* CPU_FAMILY == ARM */ pBp->bp_callArg = pBreakPoint->action.callArg; pBp->bp_instr = *(INSTR *)addr; if (pBreakPoint->numArgs > 1) /* second argument is count */ pBp->bp_count = pBreakPoint->args[1]; else pBp->bp_count = 0; /* XXX - hack because host tools pass wrong info */ if ((pBp->bp_action == 0) || (pBp->bp_action == WDB_ACTION_STOP)) pBp->bp_action = WDB_ACTION_STOP | WDB_ACTION_NOTIFY; /* set the context ID */ switch (pBreakPoint->context.contextType) { case WDB_CTX_SYSTEM: pBp->bp_task = BP_SYS; break; case WDB_CTX_ANY_TASK: pBp->bp_task = BP_ANY_TASK; break; case WDB_CTX_TASK: default: pBp->bp_task = pBreakPoint->context.contextId; } wdbTaskLock (); /* disable task switching */ dll_insert(&pBp->bp_chain, &bpList); wdbTaskUnlock (); /* re-enable task switching */ if (pBreakPoint->context.contextType != WDB_CTX_SYSTEM) if (_wdbTaskBpAdd != NULL) _wdbTaskBpAdd (pBreakPoint); *pId = (UINT32)pBp; return (WDB_OK); }#if DBG_HARDWARE_BP/********************************************************************************* wdbHwBpAdd - Handle a hardware break point add request** The wdbBpAdd() function is used to add break points form the agent.** NOMANUAL*/static UINT32 wdbHwBpAdd ( WDB_EVTPT_ADD_DESC * pBreakPoint, /* breakpoint to add */ UINT32 * pId /* breakpoint ID */ ) { BRKPT * pBp; dll_t * pDll; int status; DBG_REGS dbgRegs; /* debug registers */ int contextId; /* context ID */ UINT32 addr; /* breakpoint address */ UINT32 count = 0; /* breakpoint count */ int type = DEFAULT_HW_BP; /* hardware type */ switch (pBreakPoint->numArgs) { default: case 3: type = pBreakPoint->args[2]; /* FALL THROUGH */ case 2: count = pBreakPoint->args[1]; /* FALL THROUGH */ case 1: addr = pBreakPoint->args[0]; break; case 0: return (WDB_ERR_INVALID_PARAMS); } /* check validity of hardware breakpoint address */ if (wdbDbgHwAddrCheck (addr, type, (FUNCPTR) pWdbRtIf->memProbe) != OK) return (WDB_ERR_MEM_ACCES); /* check the agent mode */ switch (pBreakPoint->context.contextType) { case WDB_CTX_SYSTEM: if (!wdbIsNowExternal()) return (WDB_ERR_AGENT_MODE); break; default: if (!wdbIsNowTasking()) return (WDB_ERR_AGENT_MODE); } /* set the context ID */ switch (pBreakPoint->context.contextType) { case WDB_CTX_SYSTEM: contextId = BP_SYS; break; case WDB_CTX_ANY_TASK: contextId = BP_ANY_TASK; break; case WDB_CTX_TASK: default: contextId = pBreakPoint->context.contextId; } /* clean dbgRegs structure */ memset (&dbgRegs, 0, sizeof (DBG_REGS)); /* fill dbgRegs structure with all hardware breakpoints */ wdbTaskLock (); /* disable task switching */ for (pDll = dll_head(&bpList); pDll != dll_end(&bpList); pDll = dll_next(pDll)) { pBp = BP_BASE(pDll); /* check if found breakpoint is applicable to new breakpoint context */ if (((contextId == BP_SYS) && (pBp->bp_task == BP_SYS)) || ((contextId == BP_ANY_TASK) && (pBp->bp_task != BP_SYS)) || ((contextId != BP_SYS) && (pBp->bp_task == BP_ANY_TASK))) { if (pBp->bp_flags & BRK_HARDWARE) { if ((status = wdbDbgHwBpSet (&dbgRegs, pBp->bp_flags & BRK_HARDMASK, (UINT32) pBp->bp_addr)) != OK) { wdbTaskUnlock (); /* re-enable task switching */ return (status); } } } } wdbTaskUnlock (); /* re-enable task switching */ if ((status = wdbDbgHwBpSet (&dbgRegs, type, addr)) != OK) return (status); if (dll_empty (&bpFreeList)) return (WDB_ERR_EVENTPOINT_TABLE_FULL); wdbTaskLock (); /* disable task switching */ pBp = BP_BASE(dll_tail (&bpFreeList)); dll_remove (&pBp->bp_chain); wdbTaskUnlock (); /* re-enable task switching */ pBp->bp_flags = BP_HOST | type | BRK_HARDWARE; pBp->bp_addr = (INSTR *)addr; pBp->bp_action = pBreakPoint->action.actionType; pBp->bp_count = count; pBp->bp_callRtn = (void (*)())pBreakPoint->action.callRtn; pBp->bp_callArg = pBreakPoint->action.callArg; pBp->bp_task = contextId; /* * XXX - MS hack because host tools pass wrong info. * XXX - DBT This has been corrected in tornado 2.0 host tools but we * must keep this hack for backward compatibility. */ if ((pBp->bp_action == 0) || (pBp->bp_action == WDB_ACTION_STOP)) pBp->bp_action = WDB_ACTION_STOP | WDB_ACTION_NOTIFY; wdbTaskLock (); /* disable task switching */ dll_insert(&pBp->bp_chain, &bpList); wdbTaskUnlock (); /* re-enable task switching */ if (pBreakPoint->context.contextType != WDB_CTX_SYSTEM) if (_wdbTaskBpAdd != NULL) _wdbTaskBpAdd (pBreakPoint); *pId = (UINT32)pBp; return (WDB_OK); }#endif /* DBG_HARDWARE_BP *//********************************************************************************* wdbBpDelete - Handle a break point delete request** The wdbBpDelete() function is used to delete break points.** NOMANUAL*/static UINT32 wdbBpDelete ( TGT_ADDR_T * pId ) { dll_t * pDll; dll_t * pNextDll; BRKPT * pBp; pBp = *(BRKPT **) pId; /* * Breakpoint ID of -1 means remove all breakpoints. * We can only remove breakpoints set by the host tools. Breakpoints * set from target shell can't be removed */ wdbTaskLock (); /* disable task switching */ if ((int ) pBp == -1) { for (pDll = dll_head(&bpList); pDll != dll_end(&bpList); pDll = pNextDll) { pNextDll = dll_next(pDll); if (BP_BASE(pDll)->bp_flags & BP_HOST) wdbDbgBpRemove (BP_BASE(pDll)); } wdbTaskUnlock (); /* re-enable task switching */ return (WDB_OK); } /* else just remove one breakpoint */ for (pDll = dll_head(&bpList); pDll != dll_end(&bpList); pDll = dll_next(pDll)) { if (BP_BASE(pDll) == pBp) { wdbDbgBpRemove (pBp); wdbTaskUnlock (); /* re-enable task switching */ return (WDB_OK); } } wdbTaskUnlock (); /* re-enable task switching */ return (WDB_ERR_INVALID_EVENTPOINT); } #if DBG_NO_SINGLE_STEP/********************************************************************************* wdbTrap - handle hitting of breakpoint** This routine handles the breakpoint trap. It is called only from its * special stub routine (usually in assembly language) which is connected* to the breakpoint trap. It is used by targets that have to multiplex* tracing and breakpoint.** NOMANUAL*/static void wdbTrap ( int level, INSTR * addr, void * pInfo, WDB_IU_REGS * pRegisters, void * pDbgRegs, BOOL hardware ) { /* check for task level breakpoint trap */ if (wdbIsNowTasking()) { _wdbTaskBpTrap (level, (INSTR *) pRegisters->reg_pc, pInfo, pRegisters, pDbgRegs, hardware); /* NOTREACHED */ } /* first handle "step mode" (trace emulation) */ if (wdbSysBpMode != 0) { wdbTrace (level, pInfo, pRegisters); /* NOTREACHED */ } /* must be a system level breakpoint */ wdbDbgBpRemoveAll (); /* remove all breakpoints */ wdbBreakpoint (level, pInfo, pRegisters, pDbgRegs, hardware); /* NOTREACHED */ }#endif /* DBG_NO_SINGLE_STEP *//********************************************************************************* wdbTrace - handle trace exception** This routine handles the trace trap. It is called only* from its special assembly language stub routine which is connected* to the trace trap.** NOMANUAL*/static void wdbTrace ( int level, void * pInfo, WDB_IU_REGS * pRegisters ) {#if !DBG_NO_SINGLE_STEP /* check for task level breakpoint trace */ if (wdbIsNowTasking()) { _wdbTaskBpTrace (level, pInfo, pRegisters); /* NOTREACHED */ }#else /* !DBG_NO_SINGLE_STEP */ usrBreakpointSet (wdbSysNpc, wdbSysNpcInstr);#endif /* DBG_NO_SINGLE_STEP */ /* system mode step */ wdbDbgTraceModeClear ((REG_SET *) pRegisters, wdbBpData); wdbBpAddr = (TGT_ADDR_T) pRegisters->reg_pc; /* update wdbBpAddr */ if (wdbSysBpMode == WDB_STEP_OVER) { wdbSysBpMode = 0; wdbBpInstall (); WDB_CTX_LOAD (pRegisters); /* NOTREACHED */ } if ((wdbSysBpMode == WDB_STEP_RANGE) && (wdbSysStepStart <= (INSTR *) wdbBpAddr) && ((INSTR * ) wdbBpAddr < wdbSysStepEnd)) {#if DBG_NO_SINGLE_STEP wdbSysNpc = wdbDbgGetNpc (pRegisters); wdbSysNpcInstr = *wdbSysNpc; usrBreakpointSet (wdbSysNpc, DBG_BREAK_INST);#endif /* DBG_NO_SINGLE_STEP */ wdbBpData = wdbDbgTraceModeSet((REG_SET *) pRegisters); WDB_CTX_LOAD (pRegisters); /* NOTREACHED */ } /* blindly assume WDB_STEP */ wdbSysBpMode = 0; wdbSuspendSystem (pRegisters, wdbSysBpPost, 0); /* NOTREACHED */ }/********************************************************************************* wdbBreakpoint - handle hitting of breakpoint** This routine handles the breakpoint trap. It is called only from its * special stub routine (usually in assembly language) which is connected* to the breakpoint trap.** NOMANUAL*/static void wdbBreakpoint ( int level, void * pInfo, WDB_IU_REGS * pRegisters, void * pDbgRegs, BOOL hardware ) { BRKPT bpInfo; /* breakpoint info structure */ UINT32 type = 0; /* breakpoint type */ void (*callBack)() = NULL;#if !DBG_NO_SINGLE_STEP /* check for task level breakpoint trap */ if (wdbIsNowTasking()) { _wdbTaskBpBreakpoint (level, pInfo, pRegisters, pDbgRegs, hardware); /* NOTREACHED */ }#endif /* !DBG_NO_SINGLE_STEP */ wdbBpAddr = (UINT32) pRegisters->reg_pc;#if DBG_HARDWARE_BP /* If it is a hardware breakpoint, update type and addr variable. */ if (hardware) wdbDbgHwBpFind (pDbgRegs, &type, &wdbBpAddr);#endif /* DBG_HARDWARE_BP */ /* must be a system level breakpoint */ wdbDbgBpGet ((INSTR *)wdbBpAddr, BP_SYS, type, &bpInfo); /* * On some CPU (eg I960CX), the hardware breakpoint exception is sent only * after the instruction was executed. In that case, we consider that * the breakpoint address is the address where the processor is stopped, * not the real breakpoint address. */#if DBG_HARDWARE_BP && defined (BRK_INST) if (type == (BRK_INST | BRK_HARDWARE)) wdbBpAddr = (UINT32) pRegisters->reg_pc;#endif /* DBG_HARDWARE_BP && defined (BRK_INST) */ if (bpInfo.bp_action & WDB_ACTION_CALL) bpInfo.bp_callRtn (bpInfo.bp_callArg, pRegisters); if (bpInfo.bp_action & WDB_ACTION_NOTIFY) callBack = wdbSysBpPost;#if CPU_FAMILY == MIPS /* * On MIPS CPUs, when a breakpoint exception occurs in a branch delay slot, * the PC has been changed in the breakpoint handler to match with the * breakpoint address. * Once the matching has been made, the PC is modified to have its normal * value (the preceding jump instruction). */ if (pRegisters->cause & CAUSE_BD) /* Are we in a branch delay slot ? */ pRegisters->reg_pc--;#endif /* CPU_FAMILY == MIPS */ if (bpInfo.bp_action & (WDB_ACTION_NOTIFY | WDB_ACTION_STOP)) { if (!(bpInfo.bp_action & WDB_ACTION_STOP)) wdbOneShot = TRUE; wdbSuspendSystem (pRegisters, callBack, 0); /* NOTREACHED */ } /* !WDB_ACTION_STOP means continue (e.g., step over this breakpoint) */#if DBG_NO_SINGLE_STEP wdbSysNpc = wdbDbgGetNpc (pRegisters); wdbSysNpcInstr = *wdbSysNpc; usrBreakpointSet (wdbSysNpc, DBG_BREAK_INST);#endif /* DBG_NO_SINGLE_STEP */ wdbSysBpMode = WDB_STEP_OVER; wdbBpData = wdbDbgTraceModeSet((REG_SET *) pRegisters); WDB_CTX_LOAD(pRegisters); }/******************************************************************************** wdbE - target side code to support the windview "e" command*/ void wdbE ( int * pData, WDB_IU_REGS * pRegisters ) { int (*conditionFunc)() = (int (*)())pData[0]; int conditionArg = pData[1]; int eventNum = pData[2]; if ((conditionFunc == NULL) || (conditionFunc (conditionArg) == OK)) EVT_CTX_BUF (eventNum, pRegisters->reg_pc, 0, NULL); }/******************************************************************************** wdbTaskLock - lock the current task if the agent is running in task mode** This routine locks the current task is the agent is running in * task mode.* * RETURNS : N/A** NOMANUAL*/ LOCAL void wdbTaskLock (void) { if (wdbIsNowTasking() && (pWdbRtIf->taskLock != NULL)) (*pWdbRtIf->taskLock) (); }/******************************************************************************** wdbTaskUnlock - unlock the current task if the agent is running in task mode** This routine unlocks the current task is the agent is running in * task mode.* * RETURNS : N/A** NOMANUAL*/ LOCAL void wdbTaskUnlock (void) { if (wdbIsNowTasking() && (pWdbRtIf->taskUnlock != NULL)) (*pWdbRtIf->taskUnlock) (); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -