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

📄 trclib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
* trcStack (&regSet, (FUNCPTR) printRtn, tid);* .CE** SEE ALSO: tt()** NOMANUAL*/void trcStack    (    REG_SET *  pRegSet,        /* pointer to a task register set */    FUNCPTR    printRtn,       /* routine to print single function call */    int        tid             /* task's id */    )    {    STATUS     symStatus = ERROR;    int        val       = 0;    /* Extract the program counter (EIP), stack pointer (ESP), and     * frame pointer (EBP) values from the register structure.     */    const INSTR * const  pc  = pRegSet->pc;    const int * const    sp  = (int *) pRegSet->esp;    const int *          fp  = (int *) pRegSet->ebp;    const char * const   pStackBase  = taskTcb(tid)->pStackBase;    const char * const   pStackLimit = taskTcb(tid)->pStackLimit;    /* Find the address of the next instruction that is not a JMP. */    const INSTR * const  addr = trcFollowJmp (pc);    /* use default print routine if none specified */    if (printRtn == NULL)        {        printRtn = (FUNCPTR) trcDefaultPrint;        }    /* If there is a symbol table, use it to test whether (pc) is on     * the first instruction of a subroutine.     */    if (sysSymTbl != NULL)        {        char *     pName = NULL;  /* function name from symbol table */        SYM_TYPE   type;          /* function type from symbol table */        symStatus = symByValueFind (sysSymTbl, (int) pc, &pName, &val, &type);        if (pName != NULL)            {            free (pName);         /* new API requires this */            }        }    /*     * if the current routine doesn't have a stack frame, then we fake one     * by putting the old one on the stack and making fp point to that;     * we KNOW we don't have a stack frame in a few restricted but useful     * cases:     *  1) we are at a PUSH %EBP MOV %ESP %EBP or RET or ENTER instruction,     *  2) we are the first instruction of a subroutine (this may NOT be     *     a PUSH %EBP MOV %ESP %EBP instruction with some compilers)     */    if ((DSM (addr,     PUSH_EBP, PUSH_EBP_MASK) &&          DSM (addr + 1, MOV_ESP0, MOV_ESP0_MASK) &&         DSM (addr + 2, MOV_ESP1, MOV_ESP1_MASK)) ||        (DSM (addr,   ENTER,    ENTER_MASK)    ||         DSM (addr,   RET,      RET_MASK)      ||         DSM (addr,   RETADD,   RETADD_MASK))   ||        ((symStatus == OK) && (val == (int) pc)))        {        /* The stack frame is not created yet, so we'll simulate one by         * first saving the value (ESP-1), storing the current EBP value         * at that location, then setting EBP to the location where its         * old value was saved.  This is approximately equivalent to:         *         *     func:         *         push  ebp         *         mov   ebp, esp         *     ...         */        int stackSave = *(sp - 1);        *((int *) sp - 1) = (int) fp;        fp = (sp - 1);        trcStackLvl (fp, pc, pStackBase, pStackLimit, printRtn);        *((int *) sp - 1) = stackSave;    /* restore saved stack variable */        }    else if (DSM (addr - 1, PUSH_EBP, PUSH_EBP_MASK) &&              DSM (addr,     MOV_ESP0, MOV_ESP0_MASK) &&             DSM (addr + 1, MOV_ESP1, MOV_ESP1_MASK))        {        fp = sp;        trcStackLvl (fp, pc, pStackBase, pStackLimit, printRtn);        }    else        {        trcStackLvl (fp, pc, pStackBase, pStackLimit, printRtn);        }    }/********************************************************************************* trcStackLvl - recursive stack trace routine** This routine is recursive, being called once for each level of routine* nesting.** INTERNAL* Whether or not the return address is at (frame ptr + 1) really depends* upon whether the current frame was compiled with -msse and whether the* current routine has locals passed from the caller.  In the latter case,* EBX is pushed, in addition to EBP and ESI for the former case.  The* following fragments illustrate the cases typically encountered when* -msse is used to build a body of code:**     int foo (int) { int x; ... }*     -------------------------------------------*     foo:*        55                      push   %ebp*        56                      push   %esi*        53                      push   %ebx*        89 e6                   mov    %esp,%esi*     ...*     foo.aligned:*        55                      push   %ebp*        56                      push   %esi*        53                      push   %ebx*        89 e6                   mov    %esp,%esi*     ...**     int foo (int) { ... }*     -------------------------------------------*     foo:*        55                      push   %ebp*        56                      push   %esi*        89 e6                   mov    %esp,%esi*     ...*     foo.aligned:*        55                      push   %ebp*        56                      push   %esi*        89 e6                   mov    %esp,%esi*     ...** RETURNS: N/A** NOMANUAL*/LOCAL void trcStackLvl    (    const int *    fp,          /* stack frame pointer */    const INSTR *  pc,          /* program counter */    const char *   pStackBase,  /* stack bottom (highest memory address) */    const char *   pStackLimit, /* stack top (lowest memory address) */    FUNCPTR        printRtn     /* routine to print single function call */    )    {    const INSTR *  returnAdrs;    /* XXX NOTE XXX     * (fp+2) is supposed to represent the stack address of the arguments     * passed to this frame.  This value should be wrapped in a macro in     * case there is a requirement to change it.     */    if ((((char *)(fp + 2) + (MAX_TASK_ARGS * sizeof(int))) > pStackBase) ||        ((char *)(fp) < pStackLimit))        {        return;        }    /* XXX NOTE XXX     * This assumption does not work in the case of stack frames generated     * with the -msse compiler option.  We have to dynamically determine     * whether we are in a routine where the return address is at a scaled     * offset of 1, 2, or 3 from the frame pointer for the current routine.     *     *     returnAdrs = (const INSTR *) *(fp + 1);     */    returnAdrs = trcFindReturnAddr (fp, pc);    /* handle oldest calls first */    trcStackLvl ((const int *)(*fp), returnAdrs, pStackBase,                 pStackLimit, printRtn);    (* printRtn) (trcFindCall (returnAdrs), trcFindFuncStart (pc),                  trcCountArgs (returnAdrs), fp + 2);    }/********************************************************************************* trcFindReturnAddr - find the return address of a function** Given a program counter <pc> and a frame pointer <fp> for a function* with an "activated" stack frame, this routine will find the address in* the calling function to which the function will return.** INTERNAL* The Tornado 2.2 cross-compiler subroutine prologues are typically* generated as follows:**     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*     ...*     8b 65 00   mov    0x0(%ebp),%esp*     5e         pop    %esi*     5d         pop    %ebp*     c3         ret**     = 8b65005e 5dc3 ==> [esp+8] has the return address**     OR*     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*     ...*     8b 65 00   mov    0x0(%ebp),%esp*     5b         pop    %ebx*     5e         pop    %esi*     5d         pop    %ebp*     c3         ret**     = 8b65 005b5e5d c3 ==> [esp+12] has the return address** In other words, extract unaligned stack pointer from the location* specified in EBP, then get the return address at an offset from the* unaligned stack pointer.** RETURNS: The return address for some active function.** NOMANUAL*/LOCAL const INSTR * trcFindReturnAddr    (    const int *    fp,          /* stack frame pointer */    const INSTR *  pc           /* program counter */    )    {    FOREVER        {        if (DSM (pc, LEAVE,  LEAVE_MASK))            {            return (const INSTR *) *(fp + 1);            }        if (DSM (pc, RET, RET_MASK) || DSM (pc, RETADD, RETADD_MASK))            {            if ((UINT32) *(pc - 4) == 0x5d5e5b00)                {                /* this is not exactly right ... */                fp += 3;                return (const INSTR *) (*fp);                }            else if ((UINT32) *(pc - 4) == 0x5d5e0065)                {                /* this is not exactly right ... */                fp += 2;                return (const INSTR *) (*fp);                }            ++fp;            return (const INSTR *) (*fp);            }        ++pc;        }    }/********************************************************************************* 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.** RETURNS: N/A** NOMANUAL*/LOCAL void trcDefaultPrint    (    const INSTR * callAdrs,   /* address from which function was called */    const INSTR * funcAdrs,   /* address of function called */    int           nargs,      /* number of arguments in function call */    const int *   args        /* pointer to function args */    )    {    int     i;    BOOL    doingDefault = FALSE;    /* if there is no printErr routine do nothing */    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))        {

⌨️ 快捷键说明

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