⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trclib.c

📁 vxworks的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
*/ static INSTR * trcFindFuncStart    (    INSTR * pc,		/* program counter within current proc */    INSTR * returnPc	/* return address */    )    {    INSTR * 	pInstr;    int		branchAddr;    /* first check if there is a branch instruction before the returnPc */    pInstr = returnPc - 1;    if ((INST_CMP (pInstr, INST_B, INST_B_MASK)) ||	(INST_CMP (pInstr, INST_BC, INST_B_MASK)))	{	/* extract address from instruction and sign extend */	if (INST_CMP (pInstr, INST_B, INST_B_MASK))	    {	    branchAddr = *pInstr & 0x03fffffc;	    if (branchAddr & 0x02000000)		branchAddr |= 0xfc000000;	    }	else	    {	    branchAddr = *pInstr & 0xfffc;	    if (branchAddr & 0x8000)		branchAddr |= 0xffff0000;	    }	/* if branch is not absolute, add in relative address */	if (!_IFIELD_AA (*pInstr))	    branchAddr += (int)pInstr;	return ((INSTR *)branchAddr);	}    /* if that fails, try to scan backwards for "stwu sp, xxx(sp)" */    if (!BOGUS_PC(pc - trcScanDepth, pInstr))	{	for (pInstr = pc; pInstr > pc - trcScanDepth; pInstr--)	    {	    if (INST_CMP (pInstr, INST_STWU_SP, INST_HIGH_MASK))		return (pInstr);	    }	}    /* if all else fails, return "pc" as a guess */    return (pc);    }/******************************************************************************** trcPrologueFrameAllocated - check if stack frame is allocated** Start at "procAddr" and scan forwards up to MAX_PROLOGUE_SIZE instructions.* If we get to our PC before we see an "allocate stack frame" instruction,* then the current procedure does not have an allocated stack frame.** RETURNS: TRUE if frame is allocated, else false*/static BOOL trcPrologueFrameAllocated    (    INSTR *procAddr,		/* address of procedure */    INSTR *pc			/* current PC value */    )    {    INSTR *pInstr;    for (pInstr = procAddr; pInstr < procAddr + MAX_PROLOGUE_SIZE; pInstr++)	{	if (INST_CMP (pInstr, INST_STWU_SP, INST_HIGH_MASK))	    return (TRUE);	if (pInstr == pc)	    return (FALSE);	}    return (TRUE);    }/******************************************************************************** trcInfoGet - get info on top stack frame.** This routine grabs the stack pointer and pc from the register set.* It then computes the frame pointer and return PC.* The later two require care:*	Usually both are on the stack.*	Sometimes the return PC is in the link register. This is true in*	  a leaf procedure, or during a procedure prologue.*	Sometimes the frame pointer is the stack pointer. This happens*	  when a frame has not been allocated for the current proc.*	  Leaf procedures often do not allocate stack frames. Non-leaf*	  procedures have no frames during the prologue and epilogue).* This procedure scans forward up to MAX_SCAN_DEPTH instructions from* the current PC looking for instructions that might give us a clue* as to which case we are in.* If the scan doesn't find any of the instructions is is looking for,* then it assumes we are in the normal case (frame allocated and* return PC saved to stack).* * XXX - If we are in a function epilogue and have just popped the* procedure frame, this routine will mistakenly skip the next* frame down.** A little sanity checking is done. If the stack pointer, frame pointer* PC or return PC are bogus, we return ERROR.** RETURNS: OK or ERROR if there was trouble parsing the frame.*/ static STATUS trcInfoGet    (    int		tid,			/* task ID */    REG_SET *	pRegs,			/* task's registers */    INSTR **	pPc,			/* return PC here */    INSTR **	pReturnPc,		/* return calling PC here */    char **	pSp,			/* return stack pointer here */    char **	pFp			/* return frame pointer here */    )    {    BOOL	frameAllocated = TRUE;    BOOL	returnPcOnStack = TRUE;    INSTR *	pInstr;    INSTR *	pc;    INSTR *	procAddr;    char *	fp;    char *	sp;    pc = (INSTR *)pRegs->pc;    sp = (char *)pRegs->spReg;    if (BOGUS_SP(sp, taskTcb(tid)->pStackEnd, taskTcb(tid)->pStackBase))	return (ERROR);    if (BOGUS_PC(pc, pInstr))	goto skipscan;    if (BOGUS_PC(pc + trcScanDepth, pInstr))	goto skipscan;    /* Scan forward from current PC to see how the link register is used */    for (pInstr = pc; pInstr < pc + trcScanDepth; pInstr++)	{	/* mfspr lr,rx => in proc prologue with return PC in link register */        if (INST_CMP(pInstr, INST_MFLR, INST_MTSPR_MASK))	    {	    procAddr = trcFindFuncStart (pc, (INSTR *)pRegs->lr);	    returnPcOnStack = FALSE;	    if (trcPrologueFrameAllocated(procAddr, pc))		frameAllocated = TRUE;	    else		frameAllocated = FALSE;	    break;	    }	/* bclr => in proc epilogue with return PC in link register */        if (INST_CMP(pInstr, INST_BCLR, INST_BCLR_MASK))	    {	    returnPcOnStack = FALSE;	    frameAllocated = TRUE;	/* XXX - not always true in epilogue */	    break;	    }	/* mtspr lr, rx => return PC in link register */        if (INST_CMP(pInstr, INST_MTLR, INST_MTSPR_MASK))	    {	    returnPcOnStack = TRUE;	    frameAllocated = TRUE;	/* XXX - not always true in epilogue */	    break;	    }	/* "stwu r1, rx" (but no mtspr lr, rx) */	if (INST_CMP (pInstr, INST_STWU_SP, INST_HIGH_MASK))	    {	    returnPcOnStack = FALSE;	    frameAllocated = FALSE;	    break;	    }	}skipscan:    if (frameAllocated)	{	fp = FP_FROM_STACK (sp);	if (BOGUS_SP (fp, sp, taskTcb(tid)->pStackBase))	    return (ERROR);	}    else	{	fp = sp;			/* no frame => sp=fp */	sp -= _STACK_ALIGN_SIZE;	/* fake a stack pointer */	}    /* store away the info */    *pPc = pc;    *pSp = sp;    *pFp = fp;    if (returnPcOnStack)	*pReturnPc = RETURN_PC_FROM_STACK (*pFp);    else	*pReturnPc = (INSTR *)pRegs->lr;    if (BOGUS_PC(*pReturnPc, pInstr))	return (ERROR);    return (OK);    }/******************************************************************************** trcGetArgs - get function arguments from the stack.** XXX - No way to do this if the code is not compiled with "-g"* because the power PC calling conventions do not require* argumenst to be pushed on the stack.* This routine is based on disassembled GNU code, which contains* the following sequence near the proc prologue:**     mfspr        r0, LR		# standard prologue*     stw          r31, 0xfffc(r1)	# standard prologue*     stw          r0, 0x4(r1)		# standard prologue*     stwu         r1, 0xffc0(r1)	# standard prologue*     or           r31, r1, r1		# r31 = stack pointer*     stw          r3, 0x18(r31)	# save arg0 0x18 bytes from sp*     stw          r4, 0x1c(r31)	# save arg1 0x1c bytes from sp*     stw          r5, 0x20(r31)	# save arg2 0x1c bytes from sp*	...** So we scan the function prologue looking for this pattern,* and if we find them we copy the args from the stack.* The ABI says nothing about this, so GNU or anouther compiler vendor* can change this at any time and break this stack tracer.** RETURNS: the number of arguments retrieved.*/ static int trcGetArgs    (    INSTR *procAddr,    char *sp,    int *args    )    {    int nArgs = 0;    INSTR *pInstr;    for (pInstr = procAddr; pInstr < procAddr + MAX_PROLOGUE_SIZE; pInstr++)	{	if (INST_CMP (pInstr, STW(nArgs + 3), STW_REG_MASK))	    {	    args[nArgs] = *(int *)(sp + (*pInstr & 0xffff));	    nArgs++;	    if (nArgs >= MAX_TASK_ARGS)		break;	    }	/* a branch instuction means function prologue is over */        if (INST_CMP (pInstr, INST_BCLR, INST_BCLR_MASK) ||	    INST_CMP (pInstr, INST_B, INST_B_MASK))	    break;	}    return (nArgs);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -