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

📄 trclib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
	(* _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;    /* starting at the word preceding the return adrs, search for jsr or bsr */    for (addr = returnAdrs - 1; addr != NULL; --addr)	if (((*addr & 0xffc0) == 0x4e80) || ((*addr & 0xff00) == 0x6100))	    return (addr);		/* found it */    return (NULL);			/* not found */    }/****************************************************************************** trcFindDest - find destination of call instruction** RETURNS: address to which call instruction (jsr) will branch, or NULL if* unknown*/LOCAL INSTR *trcFindDest    (    INSTR *callAdrs    )    {    if (*callAdrs == JSR_ABS)			/* jsr absolute long mode? */	return ((INSTR *) *(int *)(callAdrs + 1));	/* return next long */    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*/LOCAL int trcCountArgs    (    FAST INSTR *returnAdrs              /* return address of function call */    )    {    FAST INSTR inst;    FAST int nargs;    FAST int tmpNargs;    nargs = 0;    /* if inst is a BRA, use the target of the BRA as the returnAdrs */    returnAdrs = trcFollowBra (returnAdrs);    inst = *returnAdrs;		/* get the instruction */    if (inst == ADD_W)	nargs = *(returnAdrs + 1) >> 2;		/* ADD.W */    else if (inst == ADD_L)	nargs = *(int *)(returnAdrs + 1) >> 2;	/* ADD.L */    else if (((inst & 0xF1FF) == ADDQ_W) || ((inst & 0xF1FF) == ADDQ_L))	{	/* there may be multiple addq's at the return addrs */	do	    {	    /* get the number of bytes and div by 4 to get the number of args */	    tmpNargs = (inst & 0x0E00) >> 11;	/* ADDQ.L or ADDQ.W */	    if (tmpNargs == 0)	    	tmpNargs = 2;			/* 0 => 8 in quick mode */	    nargs += tmpNargs;	    returnAdrs++;			/* sizeof ADDQ */	    inst = *returnAdrs;			/* check next instruction */	    } while (((inst & 0xF1FF) == ADDQ_W) || 		     ((inst & 0xF1FF) == ADDQ_L));	}    else if (inst == LEA_A7)	nargs = *(returnAdrs + 1) >> 2;		/* LEA $x(A7),A7 */    else if ((inst & 0xFFC0) == MOVE_L_A7)	nargs = 1;				/* MOVE.L xxx,(A7) */    else if (inst == MOVE_L_A6_A7)	nargs = 8;				/* MOVE.L (xxx,A6),A7						   # of args unknowable */    else	nargs = 0;				/* no args, or unknown */    return (nargs);    }/****************************************************************************** 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 following the frame pointer 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 jsr 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 jsr-absolute (e.g., indirectly) will not meet these* requirements.** If the above check fails, we search backward from the given pc until a* LINK instruction is found.  If the compiler is putting LINK instructions* as the first instruction 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, to NOT 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 jsr-absolute and* doesn't start with a LINK 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+1]; /* string associated with val */    SYM_TYPE type;		/* type associated with val */    /*     * 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)			/* frame pointer legit? */	{	ip = trcFindCall ((INSTR *) *(fp + 1));	if (ip != NULL)	    {	    ip = trcFindDest (ip);	    if ((ip != NULL) && (ip >= minPc) && (ip <= pc))		return (ip);	    }	}    /* search backward for LINK A6,#xxxx */    for (; pc >= minPc; --pc)	{	if (*trcFollowBra (pc) == LINK_A6)	    return (pc);		/* return address of LINK_A6 */	}    return (minPc);		/* return nearest symbol in sym tbl */    }/*********************************************************************** trcFollowBra - resolve any BRA instructions to final destination** This routine returns a pointer to the next non-BRA instruction to be* executed if the pc were at the specified <adrs>.  That is, if the instruction* at <adrs> is not a BRA, then <adrs> is returned.  Otherwise, if the* instruction at <adrs> is a BRA, then the destination of the BRA is* computed, which then becomes the new <adrs> which is tested as before.* Thus we will eventually return the address of the first non-BRA instruction* to be executed.** The need for this arises because compilers may put BRAs to instructions* that we are interested in, instead of the instruction itself.  For example,* optimizers may replace a stack pop with a BRA to a stack pop.  Or in very* UNoptimized code, the first instruction of a subroutine may be a BRA to* a LINK, instead of a LINK (compiler may omit routine "post-amble" at end* of parsing the routine!).  We call this routine anytime we are looking* for a specific kind of instruction, to help handle such cases.** RETURNS: address that chain of branches points to.*/LOCAL INSTR *trcFollowBra    (    FAST INSTR *adrs    )    {    FAST INSTR inst = *adrs;	/* 16 bit instruction at adrs */    FAST int displacement;    /* while instruction is a BRA, get destination adrs */    while ((inst & 0xff00) == 0x6000)	{	++adrs;			/* point to word following instr */	switch (inst & 0xff)	    {	    case 0:			/* 16 bit displacement */		displacement = (short) *adrs;		break;	    case 0xff:			/* 32 bit displacement */		displacement = (*adrs << 16) | *(adrs + 1);		break;	    default:			/* 8 bit displacement */		displacement = (char) (inst & 0xff);		/* check for branch to self, or to odd displacement */		if ((displacement == 0xfe) || (displacement & 0x01))		    return (--adrs);	/* don't follow it */		break;	    }	adrs = (INSTR *) ((char *) adrs + displacement);	inst = *adrs;		/* get the instruction */	}    return (adrs);    }

⌨️ 快捷键说明

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