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

📄 trclib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
    (    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;    /* print call address and function address */    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;        printErr ("[");        }    /* print args */    for (ix = 0; ix < nargs; ++ix)        {        if (ix != 0)            printErr (", ");#if (CPU == MIPS64)        printErr ("%x", args[ix * 2]);#else /* (CPU == MIPS64) */        printErr ("%x", args[ix]);#endif /* (CPU == MIPS64) */        }    if (doingDefault)        printErr ("]");    printErr (")\n");    }/****************************************************************************** trcFindFuncStart - find the starting address of a function** This routine finds the starting address of a function.* For MIPS processors, to find the start of a function, we use the instruction* where the function was called from to compute it. The call was one of  * a "jal", "jalr" or "BxAL[L]" instruction. For "jalr", it will be impossible* to determine the target address since the contents of the target register* have been lost along the way.*/LOCAL INSTR *trcFindFuncStart    (    REG_SET *   regs,   /* general purpose registers */    INSTR *     callpc  /* pc of the calling point */    )    {#ifdef DBG_PRINTF        (void)printf("trcFindFuncStart entry.\n");#endif /* DBG_PRINTF */    /* compute the target of the call instruction which will be the     * entry point (i.e., starting address) of the current function.     * If the call was by a "jalr" instruction, then there is no way      * to reconstruct the entry point since the register contents have     * been lost.     */    if (mips16Instructions((ULONG)callpc))        {        callpc = (INSTR *)((int)callpc & ~0x1);        if (M16_INSTR_OPCODE(*(UINT16 *)callpc) == M16_JALNX_INSTR)            {            ULONG dstAddr;            dstAddr = ((*(UINT16 *)callpc) << 16) + (*((UINT16 *)callpc + 1));            dstAddr = M16_JALX_IMM(dstAddr) | (((ULONG)callpc) & 0xf0000000);            return ( (INSTR *)dstAddr);            }        else            return (NULL);        }    if (DSM (callpc, JAL_INSTR, GENERAL_OPCODE_MASK))        {        /* Jump And Link -- target address specified by shifting the offset          * left 2 bits and then "or"ing it with the upper 4 bits of the pc.         */        return ( (INSTR *) (((*callpc & TARGET_MASK) << 2) |                             ((int) callpc & 0xf0000000)) );        }    if (DSM (callpc,(BCOND | BLTZAL_INSTR),             (GENERAL_OPCODE_MASK | BCOND_MASK)) ||        DSM (callpc,(BCOND | BGEZAL_INSTR),             (GENERAL_OPCODE_MASK | BCOND_MASK)) ||        DSM (callpc,(BCOND | BLTZALL_INSTR),             (GENERAL_OPCODE_MASK | BCOND_MASK)) ||        DSM (callpc,(BCOND | BGEZALL_INSTR),             (GENERAL_OPCODE_MASK | BCOND_MASK)))        {        /* Branch And Link -- target address specified by shifting the          * offset left 2 bits with sign extension and then adding it to the         * address of the instruction in the delay slot.  Note that the "C"          * compiler automatically sign extends the "short" part of the          * instruction (i.e., the lower 16 bits).         */        return (callpc + 1 + (short) (*callpc & 0xFFFF));        }    /* either the call was via a "jalr" or there was a bad instruction where     * we thought we were called from     */    return (NULL);    }/****************************************************************************** trcGetFuncInfo - get address from which function was called** Determines specific info about the current function, such as the* address where it was called from, the stack frame size (if any) and* whether the stack frame has already been allocated.*/LOCAL void trcGetFuncInfo    (    int         depth,      /* recursion depth */    REG_SET *   regs,       /* general purpose registers */    char *      sp,         /* stack pointer */    INSTR *     pc,         /* current pc */    INSTR **    pCallAddr,  /* receives address from which this function called */    int *       pFrameSize  /* receives stack frame size */    )    {    FAST int        ix;    FAST int        scanDepth;    FAST INSTR *    scanpc;    INSTR *         retAddr;    *pFrameSize = (int) 0;    retAddr = (INSTR *) NULL;#ifdef DBG_PRINTF    (void)printf("trcGetFuncInfo depth=%d pc=%08x sp=%08x\n", depth, pc, sp);#endif /* DBG_PRINTF */    /* scan instructions forward until the end of function or the max     * scan count is reached. If we find a "sw ra,x(sp)" or a "jr ra"     * then the return address in already in register "ra".  If we find     * a "lw ra,x(sp)" then the return address is saved in offset "x"     * on the stack. If the instruction space is corrupted, could get     * a bus error eventually or could find a return address for a      * neighboring subprogram. The calling pc is determined by subtracting     * 2 instructions from the return address. The stack frame size, if     * found, and whether it is allocated, are passed out.     */    /* check if the pc belongs to a mips16 function */    if (mips16Instructions((ULONG)pc))        {        ULONG scanPc = (ULONG)pc & ~0x1;        ULONG addr = (ULONG)NULL;        for (ix = 0; ix < MAX_SCAN_DEPTH; ix++)            {            if (((*(UINT16 *)scanPc) & M16_I8_MASK) == M16_I8_SWRASP)                 {                /* sw ra,x(sp) */                addr = regs->raReg;                }            else if ((*(UINT16 *)scanPc) == M16_JR_RA_INSTR)                {                /* jr ra */                if (addr == (ULONG)NULL)                    addr = regs->raReg;                ix = MAX_SCAN_DEPTH - 2;                }            else if ((*(UINT16 *)scanPc) == M16_JR_A3_INSTR)                 {                /*  jr a3 */                if (addr == (ULONG)NULL)                    addr = regs->a3Reg;                ix = MAX_SCAN_DEPTH - 2;                }            else if ((M16_INSTR_OPCODE(*(UINT16 *)scanPc) == M16_LWSP_INSTR) &&                     (M16_RX(*(UINT16 *)scanPc) == M16_REG_7) )                {                /* lw a3,x(sp) */                addr = *(ULONG *)((int)sp + *pFrameSize +                                   M16_RI_OFFSET(*(UINT16 *)scanPc));                }            else if (((*(UINT16 *)scanPc) & M16_I8_MASK) == M16_ADJSP_INSTR)                  {                /* adjsp */                *pFrameSize += ((int)((*(UINT16 *)scanPc) & 0xff) << 24) >> 21;                }            scanPc += dsmNbytes(scanPc);            }  /* end for */        /* make sure address aligned at 2 byte boundary */        *pCallAddr = (INSTR *)((addr & ~0x1) - 6);        return;        } /* end if (mips16Instructions((ULONG)pc)) */    scanDepth = MAX_SCAN_DEPTH;    if (depth == 0)        {        /* Check insn we're sitting on to see if we're at the first         * instruction of the function         */        if (DSM(pc, (ADDIU_INSTR | SP << RT_POS),                (GENERAL_OPCODE_MASK | RT_MASK)))            {            /* match "[d]addiu sp,sp,-offset"             * First instruction of function, innermost frame, don't scan.             */            scanDepth = -1;            retAddr = (INSTR*) ((int)regs->raReg);  /* return point */            }            else            {            /* If in innermost frame, don't disassemble instruction we're             * sitting on, as we haven't executed it yet.             */            scanDepth--;            }        }    for (ix = scanDepth, scanpc = pc; ix >= 0; ix--, scanpc--)        {        /* match "jr ra" means ran off the top and missed the         * beginning of the function.         */        if (DSM(scanpc,(SPECIAL | JR_INSTR | RA << RS_POS),                (GENERAL_OPCODE_MASK | SPECIAL_MASK | RS_MASK)))            {#ifdef DBG_PRINTF            (void)printf("trcGetFuncInfo depth=%d match jr ra\n", depth);#endif /* DBG_PRINTF */            /* If in innermost frame, assume return in ra. */            if (depth == 0)                retAddr = (INSTR*) ((int)regs->raReg);  /* return point */            break;            }        /* match "addiu sp,sp,+-offset" to determine stack frame size.         * Note that the "C" compiler takes care of sign extension         * from "short" to "int" when we extract the immediate part of         * the instruction.          */        else if (DSM(scanpc, (ADDIU_INSTR | SP << RT_POS),                     (GENERAL_OPCODE_MASK | RT_MASK)))            {#ifdef DBG_PRINTF            (void)printf("trcGetFuncInfo depth=%d match addiu sp,sp,+-offset\n", depth);#endif /* DBG_PRINTF */            if ((short)(*scanpc & 0xFFFF) > 0)                {                /* stack frame de-allocation implies we may have                 * run off the top of the function.  Stop searching.                 */                if (retAddr == NULL)                    {                    retAddr = (INSTR*) ((int)regs->raReg);                    break;                    }                }            /* If we hit this before 'sw/sd ra,x(sp)', this means we're             * stopped between the allocation of the stack frame and the             * save of RA on the stack.  If this happens anywhere other             * than the innermost frame, it's illegal code and we're probabaly             * actually lost.             */            *pFrameSize -= (short)(*scanpc & 0xFFFF);   /* get the immediate offset */            if ((depth == 0) && (retAddr == NULL))                {                retAddr = (INSTR*) ((int)regs->raReg);                break;                }            if (retAddr != NULL)                {                /* Have frameSize and retAddr, done with this frame. */                break;                }            }#if (CPU == MIPS64)        /* match "sd ra,x(sp)" means return address is on the stack */        else if (DSM(scanpc,(SD_INSTR | RA << RT_POS | SP << BASE_POS),                     (GENERAL_OPCODE_MASK | RT_MASK | BASE_MASK)))            {#ifdef DBG_PRINTF            (void)printf("trcGetFuncInfo depth=%d sp=%08x scanpc=%08x match sd ra,x(sp)\n", depth,sp,*scanpc);#endif /* DBG_PRINTF */#if (_BYTE_ORDER == _BIG_ENDIAN)            retAddr = (INSTR *) *(int *)((int)sp + (short)(*scanpc & 0xFFFF) + 4);#else /* (_BYTE_ORDER == _BIG_ENDIAN) */            retAddr = (INSTR *) *(int *)((int)sp + (short)(*scanpc & 0xFFFF));#endif /* (_BYTE_ORDER == _BIG_ENDIAN) */#ifdef DBG_PRINTF            (void)printf("trcGetFuncInfo depth=%d retAddr=%08x\n", depth,retAddr);#endif /* DBG_PRINTF */            }#endif /* (CPU == MIPS64) */        /* match "sw ra,x(sp)" means return address is on the stack */        else if (DSM(scanpc,(SW_INSTR | RA << RT_POS | SP << BASE_POS),                     (GENERAL_OPCODE_MASK | RT_MASK | BASE_MASK)))            {#ifdef DBG_PRINTF            (void)printf("trcGetFuncInfo depth=%d sp=%08x scanpc=%08x match sw ra,x(sp)\n", depth,sp,*scanpc);#endif /* DBG_PRINTF */            retAddr = (INSTR *) *(int *)((int)sp + (short)(*scanpc & 0xFFFF));#ifdef DBG_PRINTF            (void)printf("trcGetFuncInfo depth=%d retAddr=%08x\n", depth,retAddr);#endif /* DBG_PRINTF */            }        }    /* if a return address was found, subtract 2 instructions from it to     * determine the calling point, or set it to NULL      */    if (mips16Instructions((ULONG)retAddr) )        {        /* Need to handle differently if it comes from a 16 bit function.          * subtract 2 instructions: one 32 bit, jal(x) and one 16 bit delay slot         */        if (retAddr != NULL)            {            retAddr = (INSTR *)(((int)retAddr & ~0x1) - 6);            *pCallAddr = retAddr;            }        else            *pCallAddr = NULL;         }    else        *pCallAddr =  (retAddr != NULL) ? (retAddr - 2) : NULL;    }

⌨️ 快捷键说明

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