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

📄 trclib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (_func_printErr == NULL)	return;    /* print call address and function address */    (* _func_printErr) ("%8x: %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 (i = 0; i < nargs; ++i)	{	if (i != 0)	    (* _func_printErr) (", ");	(* _func_printErr) ("%x", args[i]);	}    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;    int ix = 0;    /* starting at the word preceding the return adrs, search for CALL */    for (addr = returnAdrs - 1; addr != NULL; --addr)	{	if ((DSM(addr,   CALL_INDIR0, CALL_INDIR0_MASK) &&	     DSM(addr+1, CALL_INDIR1, CALL_INDIR1_MASK)) ||	    (DSM(addr,   CALL_DIR,    CALL_DIR_MASK)))	    {	    return (addr);		/* found it */	    }	if (ix++ > MAX_LOOPCOUNT)	/* XXX */	    break;	}    return (NULL);			/* not found */    }/****************************************************************************** trcFindDest - find destination of call instruction** RETURNS: address to which call instruction (CALL) will branch or NULL if* unknown*/LOCAL INSTR *trcFindDest    (    INSTR *callAdrs    )    {    int displacement;		/* PC relative offset */    INSTR *pc;			/* program counter */    if (DSM(callAdrs, CALL_DIR, CALL_DIR_MASK))	{	displacement = *(int *)(callAdrs + 1);	pc = (INSTR *)((int)callAdrs + 1 + sizeof(int));	return ((INSTR *) ((int)pc + displacement));	}        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 *addr;    FAST int nbytes;    /* if inst is a JMP, use the target of the JMP as the returnAdrs */    addr = trcFollowJmp (returnAdrs);    if (DSM(addr,   ADDI08_0, ADDI08_0_MASK) &&        DSM(addr+1, ADDI08_1, ADDI08_1_MASK))	{	nbytes = *(char *)(addr + 2);	}    else if (DSM(addr,   ADDI32_0, ADDI32_0_MASK) &&             DSM(addr+1, ADDI32_1, ADDI32_1_MASK))	{	nbytes = *(int *)(addr + 2);	}    else if (DSM(addr,   LEAD08_0, LEAD08_0_MASK) &&             DSM(addr+1, LEAD08_1, LEAD08_1_MASK) &&             DSM(addr+2, LEAD08_2, LEAD08_2_MASK))	{	nbytes = *(char *)(addr + 3);	}    else if (DSM(addr,   LEAD32_0, LEAD32_0_MASK) &&             DSM(addr+1, LEAD32_1, LEAD32_1_MASK) &&             DSM(addr+2, LEAD08_2, LEAD08_2_MASK))	{	nbytes = *(int *)(addr + 3);	}    else	{	nbytes = 0;				/* no args, or unknown */	}    if (nbytes < 0)	nbytes = 0 - nbytes;    return (nbytes >> 2);    }/****************************************************************************** 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 CALL was to an pc-relative address. If it was,* use that address as the function address.  Note that a routine that is* called by other than a call-direct (e.g. indirectly) will not meet these* requirements.* * If the above check fails, we search backward from the given pc until a* PUSH %EBP MOV %ESP %EBP instruction is found.  If the compiler is putting * PUSH %EBP MOV %ESP %EBP 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 use.  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 call-direct and* doesn't start with a PUSH %EBP MOV %ESP %EBP 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 */    int ix = 0;    /*     * 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 PUSH %EBP MOV %ESP %EBP */    for (; pc >= minPc; --pc)	{	/* XXX 	it often causes an exception in excTask then shell doesn't restart.	ip = trcFollowJmp (pc);	*/        ip = pc;	if ((DSM(ip,   PUSH_EBP, PUSH_EBP_MASK) &&	     DSM(ip+1, MOV_ESP0, MOV_ESP0_MASK) &&	     DSM(ip+2, MOV_ESP1, MOV_ESP1_MASK)) ||	    (DSM(ip,   ENTER,    ENTER_MASK)))	    {	    return (pc);		/* return address of PUSH or ENTER */	    }	if (ix++ > MAX_LOOPCOUNT)	/* XXX */	    break;	}    return (minPc);		/* return nearest symbol in symtbl */    }/*********************************************************************** trcFollowJmp - resolve any JMP instructions to final destination** This routine returns a pointer to the next non-JMP instruction to be* executed if the pc were at the specified <adrs>.  That is, if the instruction* at <adrs> is not a JMP, then <adrs> is returned.  Otherwise, if the* instruction at <adrs> is a JMP, then the destination of the JMP is* computed, which then becomes the new <adrs> which is tested as before.* Thus we will eventually return the address of the first non-JMP instruction* to be executed.** The need for this arises because compilers may put JMPs to instructions* that we are interested in, instead of the instruction itself.  For example,* optimizers may replace a stack pop with a JMP to a stack pop.  Or in very* UNoptimized code, the first instruction of a subroutine may be a JMP to* a PUSH %EBP MOV %ESP %EBP, instead of a PUSH %EBP MOV %ESP %EBP (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 *trcFollowJmp    (    FAST INSTR *addr    )    {    FAST int displacement;		/* PC relative offset */    FAST int length;			/* instruction length */    /* while instruction is a JMP, get destination adrs */    while (DSM(addr, JMPD08, JMPD08_MASK) ||	   DSM(addr, JMPD32, JMPD32_MASK))	{	if (DSM(addr, JMPD08, JMPD08_MASK))	    {	    displacement = *(char *)(addr + 1);	    length = 2;	    addr = (INSTR *) (addr + length + displacement);	    }	else if (DSM(addr, JMPD32, JMPD32_MASK))	    {	    displacement = *(int *)(addr + 1);	    length = 5;	    addr = (INSTR *) (addr + length + displacement);	    }	}    return (addr);    }

⌨️ 快捷键说明

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