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

📄 trclib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
	 (val == (int) pc)))	{	/* no stack frame - fake one */	stackSave[0] = *(sp - 1);	/* save values we're going to clobber */	stackSave[1] = *(sp - 2);	stackSave[2] = *(sp - 3);	stackSave[3] = *(sp - 4);	*(sp - 1) = (int)pc;#if (ARM_THUMB)	*(sp - 2) = (int)lr;		/* use the extracted return address */#else	*(sp - 2) = (int)pRegSet->r[14];#endif	*(sp - 3) = (int)pRegSet->spReg;	*(sp - 4) = (int)fp;	fp = sp - 1;				/* points at saved PC */        if (vxMemProbe ((char *)fp, VX_READ, 2, (char *)&insn) != OK    ||            tcb->pStackBase < (char *)fp || tcb->pStackEnd > (char *)fp ||            vxMemProbe ((char *)pc, VX_READ, 2, (char *)&insn) != OK)            {            if (_func_printErr != NULL)                (* _func_printErr) ("trcStack aborted: error in top frame\n");            return;			/* stack is untraceable */            }	trcStackLvl (tcb, fp, pc, 0, printRtn);	/* do stack trace */	*(sp - 1) = stackSave[0];		/* restore stack */	*(sp - 2) = stackSave[1];	*(sp - 3) = stackSave[2];	*(sp - 4) = stackSave[3];	}    else	{        if (vxMemProbe ((char *)fp, VX_READ, 2, (char *)&insn) != OK    ||            tcb->pStackBase < (char *)fp || tcb->pStackEnd > (char *)fp ||            vxMemProbe ((char *)pc, VX_READ, 2, (char *)&insn) != OK)            {            if (_func_printErr != NULL)                (* _func_printErr) ("trcStack aborted: error in top frame\n");            return;			/* stack is untraceable */            }	trcStackLvl (tcb, fp, pc, 0, printRtn);	/* do stack trace */	}    }/********************************************************************************* trcStackLvl - recursive stack trace routine** This routine is recursive, being called once for each level of routine* nesting.  The maximum recursion depth is limited to 40 to prevent* garbage stacks from causing this routine to continue unbounded.* The "depth" parameter on the original call should be 0.*/LOCAL void trcStackLvl    (    WIND_TCB *tcb,      /* task control block */    FAST int *fp,       /* stack frame pointer */    INSTR *pc,          /* program counter */    int depth,          /* recursion depth */    FUNCPTR printRtn    /* routine to print single function call */    )    {    FAST INSTR *returnAdrs;    INSTR       insn;    if (fp == NULL || vxMemProbe ((char *)fp, VX_READ, 2, (char *)&insn) != OK ||        vxMemProbe ((char *)(fp - 1), VX_READ, 2, (char *)&insn) != OK ||        vxMemProbe ((char *)(fp - 3), VX_READ, 2, (char *)&insn) != OK ||        tcb->pStackBase < (char *)fp || tcb->pStackEnd > (char *)fp ||        vxMemProbe ((char *)pc, VX_READ, 2, (char *)&insn) != OK)        {        if (_func_printErr != NULL)            (* _func_printErr) ("trcStack aborted: error in frame\n");	return;			/* stack is untraceable */        }    returnAdrs = (INSTR *) *(fp - 1);    /*     * Handle oldest calls first, up to MAX_TRACE_DEPTH of them     * Note: unlike on other architectures, the previous fp is not     * found at *fp but at *(fp - 3).     */    if ((*(fp - 3) != 0) && (depth < MAX_TRACE_DEPTH))	trcStackLvl (tcb, (int *) *(fp - 3), returnAdrs, depth + 1, printRtn);    (* printRtn) (trcFindCall (returnAdrs), trcFindFuncStart (fp, pc),		  trcCountArgs (returnAdrs), fp + 1);    }/********************************************************************************* trcDefaultPrint - print a function call** This routine is called by trcStack() to print each level in turn.** If nargs is specified as 0, then a default number of args (trcDefaultArgs)* is printed in brackets ("[..]"), since this often indicates that the* number of args is unknown.** NOTE: no args can be printed as code generator of gccarm provides no*	way to determine what they are.*/LOCAL void trcDefaultPrint    (    INSTR *callAdrs,            /* address from which function was called */    INSTR *funcAdrs,            /* address of function called */    FAST int nargs,             /* number of arguments in function call */    int *args                   /* pointer to function args */    )    {    FAST int ix;    BOOL doingDefault = FALSE;    /* if there is no printErr routine do nothing */    if (_func_printErr == NULL)	return;    /* print call address and function address */    (* _func_printErr) ("%6x: %x (", callAdrs, funcAdrs);    /* if no args are specified, print out default number (see doc at top) */    if ((nargs == 0) && (trcDefaultArgs != 0))	{	doingDefault = TRUE;	nargs = trcDefaultArgs;	(* _func_printErr) ("[");	}    /* print args */    for (ix = 0; ix < nargs; ++ix)	{	if (ix != 0)	    (* _func_printErr) (", ");	(* _func_printErr) ("%x", args[ix]);	}    if (doingDefault)	(* _func_printErr) ("]");    (* _func_printErr) (")\n");    }/********************************************************************************* trcFindCall - get address from which function was called** RETURNS: address from which current subroutine was called, or NULL.*/LOCAL INSTR *trcFindCall    (    INSTR *returnAdrs           /* return address */    )    {    FAST INSTR *addr;    INSTR       insn;    /* check for bad return address */    if (returnAdrs == NULL ||        vxMemProbe ((char *)returnAdrs, VX_READ, 2, (char *)&insn) != OK)        {	return NULL;        }    /*     * Starting at the word preceding the return adrs, search for an     * instruction which changes the PC. The ARM version, just like the 68K     * one, keeps stepping back until it finds one or hits 0. It could stop     * after n instructions.     */#if (ARM_THUMB)    /* return address will have bit 0 set; mask it off */    for (addr = (INSTR *)((UINT32)returnAdrs & ~1) - 1; addr != NULL; --addr)	if (thumbInstrChangesPc(addr))	    return addr;		/* found it */#else    for (addr = returnAdrs - 1; addr != NULL; --addr)	if (armInstrChangesPc(addr))	    return addr;		/* found it */#endif    return NULL;			/* not found */    }/********************************************************************************* trcFindDest - find destination of call instruction** RETURNS: address to which call instruction will branch, or NULL if* unknown*/LOCAL INSTR *trcFindDest    (    INSTR *callAdrs    )    {	/*	 * Extract offset, sign extend it and add it to current PC,	 * adjusting for the pipeline.	 */#if (ARM_THUMB)    /* BL comes in two halves */    if (INSTR_IS(*callAdrs, T_BL0) && INSTR_IS(*(callAdrs + 1), T_BL1))	return (INSTR *)((INT32)callAdrs + 4 +	    (((((INT32)*callAdrs) << 21) >> 9) |	     ((((INT32)*(callAdrs+1)) & 0x07FF) << 1)));#else    if (INSTR_IS(*callAdrs, BL))	return (INSTR *)((INT32)callAdrs + 8 + ((INT32)(*callAdrs << 8) >> 6));#endif    return NULL;				/* don't know destination */    }/********************************************************************************* trcCountArgs - find number of arguments to function** This routine finds the number of arguments passed to the called function* by examining the stack-pop at the return address.  Many compilers offer* optimization that defeats this (e.g., by coalescing stack-pops), so a return* value of 0 may mean "don't know".** RETURNS: number of arguments of function** NOTE: no args can be printed as code generator of gccarm provides no*	way to determine what they are.*/LOCAL int trcCountArgs    (    FAST INSTR *returnAdrs              /* return address of function call */    )    {    return 0;				/* no args or unknown */    }/********************************************************************************* trcFindFuncStart - find the starting address of a function** This routine finds the starting address of a function by one of several ways.** If the given frame pointer points to a legitimate frame pointer, then the* long word preceding the long word pointed to by the frame pointer should* be the return address of the function call.  Then the instruction preceding* the return address would be the function call, and the address can be gotten* from there, provided that the call was to an absolute address. If it was,* use that address as the function address.  Note that a routine that is* called by other than a BL (e.g., indirectly) will not meet these* requirements.** If the above check fails, we search backward from the given pc until a* routine entry sequence is found (see trcStack() above for description of* routine prologues).** If the compiler is inserting these sequences at the beginning of ALL* subroutines, then this will reliably find the start of the routine.* However, some compilers allow routines, especially "leaf" routines that* don't call any other routines, NOT to have stack frames, which will cause* this search to fail.** In either of the above cases, the value is bounded by the nearest routine* in the system symbol table, if there is one.  If neither method returns a* legitimate value, then the value from the symbol table is used.  Note that* the routine may not be in the symbol table if it is LOCAL, etc.** Note that the start of a routine that is not called by BL and* doesn't start with a frame creation sequence and isn't in the symbol table,* may not be possible to locate.*/LOCAL INSTR *trcFindFuncStart    (    int *fp,                    /* frame pointer resulting from function call */    FAST INSTR *pc              /* address somewhere within the function */    )    {    FAST INSTR *ip;		/* instruction pointer */    FAST INSTR *minPc;		/* lower bound on program counter */    int         val;		/* address gotten from symbol table */    char name[MAX_SYS_SYM_LEN];	/* string associated with val */    SYM_TYPE    type;		/* type associated with val */    INSTR       insn;    /*     * if there is a symbol table, use value from table that's <= pc as     * lower bound for function start     */    minPc = NULL;    if ((sysSymTbl != NULL) && (_func_symFindByValue != NULL) &&	((* _func_symFindByValue) (sysSymTbl, (int) pc, name,				   &val, &type) == OK))	{	minPc = (INSTR *) val;	}    /* try to find current function by looking up call */    if (fp != NULL &&        vxMemProbe ((char *)(fp - 1), VX_READ, 2, (char *)&insn) == OK) /* frame pointer valid? */	{	ip = trcFindCall ((INSTR *) *(fp - 1));	if (ip != NULL)	    {	    ip = trcFindDest (ip);	    if ((ip != NULL) && (ip >= minPc) && (ip <= pc))		return (ip);	    }	}    /*     * Search backward for routine entry sequence (prologue),     * for possible sequences, refer to trcStack() above.     */#if (ARM_THUMB)    for (; pc >= minPc; --pc)	{	if ((INSTR_IS(pc[0], T_PUSH_LO) &&	     INSTR_IS(pc[1], T_SUB_SP_16) &&	     INSTR_IS(pc[2], T_PUSH) &&	     INSTR_IS(pc[3], T_ADD_LO_SP)) ||	    (INSTR_IS(pc[0], T_SUB_SP_16) &&	     INSTR_IS(pc[1], T_PUSH) &&	     INSTR_IS(pc[2], T_ADD_LO_SP)) ||	    (INSTR_IS(pc[0], T_SUB_SP_16) &&	     INSTR_IS(pc[1], T_ADD_LO_SP)))	    return pc;	   /* return address of first instruction of prologue */	}#else    for (; pc >= minPc; --pc)	{	if (INSTR_IS(pc[0], MOV_IP_SP) &&	    ((INSTR_IS(pc[1], STMDB_SPP_FP_IP_LR_PC) &&	      INSTR_IS(pc[2], SUB_FP_IP_4)) ||	     (INSTR_IS(pc[2], STMDB_SPP_FP_IP_LR_PC) &&	      INSTR_IS(pc[3], SUB_FP_IP_4PLUS) &&	      (INSTR_IS(pc[1], STMDB_SPP_AREGS) ||	       INSTR_IS(pc[1], SUB_SP_SP)))))	    return pc;		/* return address of MOV ip,sp */	}#endif    return minPc;		/* return nearest symbol in sym tbl */    }

⌨️ 快捷键说明

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