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

📄 mdsched.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    LPVOID lpStack,
    DWORD cbStack,
    LPVOID lpBase,
    LPVOID lpStart,
    BOOL kmode,
    ulong param
    ) 
{
    DEBUGCHK ((ulong)lpStack>>VA_SECTION);

#ifdef DEBUG
    // Clear out the register context for debugging.
    memset(&pTh->ctx, 0xBD, sizeof(pTh->ctx));
#endif
    pTh->tlsPtr = TLSPTR (lpStack, cbStack);
    // Leave room for arguments and PRETLS on the stack
    pTh->ctx.IntSp = (ulong) pTh->tlsPtr - SIZE_PRETLS - 4*REG_SIZE;

    KSTKBASE(pTh) = (DWORD) lpStack;
    KSTKBOUND(pTh) = (DWORD) pTh->ctx.IntSp & ~(PAGE_SIZE-1);

    pTh->ctx.IntA0 = (ulong)lpStart;
    pTh->ctx.IntA1 = param;
    pTh->ctx.IntK0 = 0;
    pTh->ctx.IntK1 = 0;
    pTh->ctx.IntRa = 0;
    pTh->ctx.Fir = (ULONG)lpBase;
    if (kmode || bAllKMode) {
        pTh->ctx.Psr = PSR_XX_C | PSR_FR_C | PSR_UX_C | KERNEL_MODE;
        KTHRDINFO (pTh) |= UTLS_INKMODE;
    } else {
        pTh->ctx.Psr = PSR_XX_C | PSR_FR_C | PSR_UX_C | USER_MODE;
        KTHRDINFO (pTh) &= ~UTLS_INKMODE;
    }
#ifdef MIPS_HAS_FPU
    pTh->ctx.Fsr = 0x01000000; // handle no exceptions
#endif
    pTh->ctx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
}

// main thread stack: from top, TLS then PRETLS then buf then buf2 (ascii) then args then free


void MDInitSecureStack(LPBYTE lpStack)
{
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
MDSetupMainThread (
    PTHREAD pTh,
    LPBYTE pCurSP,
    LPVOID lpBase,
    LPVOID lpStart,
    BOOL kmode,
    ulong dwModCnt
    ) 
{
    REG_TYPE *pArgs;
    PPROCESS pprc = pTh->pOwnerProc;
    
#ifdef DEBUG
    // Clear out the register context for debugging.
    memset(&pTh->ctx, 0xBD, sizeof(pTh->ctx));
#endif

    // Leave room for arguments, PRETLS, command line, and program name on the stack
    pTh->ctx.IntSp = (DWORD) pCurSP - 8*REG_SIZE;       // 8 arguments
    KSTKBOUND(pTh) = (DWORD) pTh->ctx.IntSp & ~(PAGE_SIZE-1);

    pArgs = (REG_TYPE*)pTh->ctx.IntSp;
    pTh->ctx.IntA0 = (ulong)lpStart;
    pTh->ctx.IntA2 = dwModCnt;
    pTh->ctx.IntA3 = (DWORD) pprc->pcmdline;
#if defined(MIPSIV)
	// Make sure we sign extend pointer arguments (i.e. hInstance and hPrevInstance)
    pTh->ctx.IntA1 = (long) pprc->hProc;
    pArgs[4] = (long) hCoreDll;
    pArgs[7] = (long) pprc->BasePtr;
#else
    pTh->ctx.IntA1 = (DWORD) pprc->hProc;
    pArgs[4] = (DWORD) hCoreDll;
    pArgs[7] = (DWORD) pprc->BasePtr;
#endif
    pArgs[5] = pprc->e32.e32_sect14rva;
    pArgs[6] = pprc->e32.e32_sect14size;

    pTh->ctx.IntK0 = 0;
    pTh->ctx.IntK1 = 0;
    pTh->ctx.IntRa = 0;
    pTh->ctx.Fir = (ULONG)lpBase;
    if (kmode || bAllKMode) {
        pTh->ctx.Psr = PSR_XX_C | PSR_FR_C | PSR_UX_C | KERNEL_MODE;
        KTHRDINFO (pTh) |= UTLS_INKMODE;
    } else {
        pTh->ctx.Psr = PSR_XX_C | PSR_FR_C | PSR_UX_C | USER_MODE;
        KTHRDINFO (pTh) &= ~UTLS_INKMODE;
    }
#ifdef MIPS_HAS_FPU
    pTh->ctx.Fsr = 0x01000000; // handle no exceptions
#endif
    pTh->ctx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
}

typedef struct ExcInfo {
    DWORD   linkage;
    ULONG   oldFir;
    UINT    oldMode0;
    CAUSE   causeAndMode;
    ULONG   badVAddr;
    UCHAR   lowSp;
    UCHAR   pad[3];
} EXCINFO;
typedef EXCINFO *PEXCINFO;

ERRFALSE(sizeof(EXCINFO) <= sizeof(CALLSTACK));
ERRFALSE(offsetof(EXCINFO,linkage) == offsetof(CALLSTACK,pcstkNext));
ERRFALSE(offsetof(EXCINFO,oldFir) == offsetof(CALLSTACK,retAddr));
//ERRFALSE(offsetof(EXCINFO,oldMode) == offsetof(CALLSTACK,pprcLast));
ERRFALSE(64 >= sizeof(CALLSTACK));

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL 
HandleException(
    PTHREAD pth,
    CAUSE cause,
    ULONG badVAddr
    ) 
{
    PEXCINFO pexi;
    DWORD stackaddr;
    KCALLPROFON(0);
#if 0
    NKDbgPrintfW(L"Exception %03x Thread=%8.8lx(%8.8lx) Proc=%8.8lx '%s'\r\n",
        cause.XCODE, pCurThread,pth, hCurProc, pCurProc->lpszProcName ? pCurProc->lpszProcName : L"");
    NKDbgPrintfW(L"AKY=%8.8lx PC=%8.8lx RA=%8.8lx BVA=%8.8lx\r\n",
        pCurThread->aky, pth->ctx.Fir, pth->ctx.IntRa, badVAddr);
#endif

    pexi = (struct ExcInfo *)((pth->ctx.IntSp & ~63) - ALIGNSTK (sizeof(CALLSTACK)));

    // before we touch pexi, we need to commit stack or we'll fault while
    // accessing it.
    switch (DemandCommit ((DWORD) pexi, pth)) {
    case DCMT_FAILED:
        // fatal stack error
        NKDbgPrintfW (L"Fatal Stack Error, Terminating thread %8.8lx\r\n", pth);
        DumpFrame(pth, &pth->ctx, cause, badVAddr, 10);
        pth->ctx.IntA0 = STATUS_STACK_OVERFLOW;
        pth->ctx.IntA1 = pth->ctx.Fir;
        pth->ctx.IntSp = (DWORD) pth->tlsPtr - SIZE_PRETLS - 512;  // arbitrary safe address
        pth->ctx.Fir = (DWORD) pExcpExitThread;
        KCALLPROFOFF(0);
        return TRUE;
    case DCMT_NEW:
        // commited a new page. check if we hit the last page.
        // generate stack overflow exception if yes.
        stackaddr = (DWORD)pexi & ~(PAGE_SIZE-1);
        if ((stackaddr >= KSTKBOUND(pth))
            || ((KSTKBOUND(pth) = stackaddr) >= (KSTKBASE(pth) + MIN_STACK_RESERVE))
            || TEST_STACKFAULT(pth)) {
            KCALLPROFOFF(0);
            return TRUE; // restart instruction
        }
        SET_STACKFAULT(pth);
        cause.XCODE = 30;   // stack fault exception code
        badVAddr = (DWORD)pexi;
        break;
    case DCMT_OLD:
        // already commited. do nothing
        break;
    default:
        DEBUGCHK (0);
    }


    if (pth->ctx.Fir != (ulong)CaptureContext+4) {
        pexi->causeAndMode = cause;
        pexi->lowSp = (UCHAR)(pth->ctx.IntSp & 63);
        pexi->oldFir = pth->ctx.Fir;
        ((PCALLSTACK) pexi)->dwPrcInfo = CST_IN_KERNEL | (((KERNEL_MODE == GetThreadMode(pth)) || InDebugger)? 0 : CST_MODE_FROM_USER);
        //pexi->oldMode = GetThreadMode(pth);
        pexi->badVAddr = badVAddr;
        pexi->linkage = (DWORD)pCurThread->pcstkTop | 1;
        pCurThread->pcstkTop = (PCALLSTACK)pexi;
        pth->ctx.IntSp = (DWORD)pexi;
        pth->ctx.Psr = PSR_XX_C | PSR_FR_C | PSR_UX_C | KERNEL_MODE;
        pth->ctx.Fir = (ulong)CaptureContext;
        KCALLPROFOFF(0);
        return TRUE;            // continue execution
    }
    DumpFrame(pth, &pth->ctx, cause, badVAddr, 10);
    RETAILMSG(1, (TEXT("Halting thread %8.8lx\r\n"), pth));
    SurrenderCritSecs();
    SET_RUNSTATE(pth,RUNSTATE_BLOCKED);
    RunList.pth = 0;
    SetReschedule();
    KCALLPROFOFF(0);
    return 0;
}

typedef struct _EXCARGS {
    DWORD dwExceptionCode;      /* exception code   */
    DWORD dwExceptionFlags;     /* continuable exception flag   */
    DWORD cArguments;           /* number of arguments in array */
    DWORD *lpArguments;         /* address of array of arguments    */
} EXCARGS;
typedef EXCARGS *PEXCARGS;
    
extern BOOL SetCPUHardwareWatch(LPVOID, DWORD);

#ifdef MIPS_HAS_FPU


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
SwitchFPUOwner(
    PCONTEXT pctx
    ) 
{
    KCALLPROFON(61);
    if (g_CurFPUOwner != pCurThread) {
        if (g_CurFPUOwner)
            SaveFloatContext(g_CurFPUOwner);
        g_CurFPUOwner = pCurThread;
        RestoreFloatContext(pCurThread);
    }
    KCALLPROFOFF(61);
}
#endif



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
ExceptionDispatch(
    PCONTEXT pctx
    ) 
{
    PTHREAD pth;
    PEXCINFO pexi;
    EXCEPTION_RECORD er;
    ULONG badVAddr;
    int xcode;
    CAUSE cause;
    PEXCARGS pea;
    DWORD dwThrdInfo = KTHRDINFO (pCurThread);  // need to save it since it might get changed during exception handling
    pth = pCurThread;
    
    // Get the EXCINFO off the thread's callstack.
    pexi = (PEXCINFO)pth->pcstkTop;

    DEBUGMSG(ZONE_SEH, (TEXT("ExceptionDispatch: pexi=%8.8lx Fir=%8.8lx\r\n"),pexi, pexi->oldFir));
    // Update CONTEXT with infomation saved in the EXCINFO structure
    pctx->Fir = pexi->oldFir;
    SetContextMode(pctx, (((PCALLSTACK)pexi)->dwPrcInfo & CST_MODE_FROM_USER)? USER_MODE : KERNEL_MODE);
#if (_M_MRX000 >= 5000) 
    // Mips4
    pctx->Psr |= PSR_XX_C | PSR_FR_C | PSR_UX_C;
#endif
    pctx->IntSp = (ULONG)pctx + sizeof(CONTEXT);
    memset(&er, 0, sizeof(er));
    er.ExceptionAddress = (PVOID)pctx->Fir;
    // Check for RaiseException call versus a CPU detected exception.
    // RaiseException just becomes a call to CaptureContext as a KPSL.
    // HandleExcepion sets the LSB of the callstack linkage but ObjectCall
    // does not.
    if (!(pexi->linkage & 1)) {
                       
        xcode = -1;
        pctx->Fir -= 4;     // to avoid boundary problems at the end of a try block.
        DEBUGMSG(ZONE_SEH, (TEXT("Raising exception %x flags=%x args=%d pexi=%8.8lx\r\n"),
                                pctx->IntA0, pctx->IntA1, pctx->IntA2, pexi));
        er.ExceptionCode = (DWORD)pctx->IntA0;
        er.ExceptionFlags = (DWORD)pctx->IntA1;
        if (pctx->IntA3 && pctx->IntA2) {
            if (pctx->IntA2 > EXCEPTION_MAXIMUM_PARAMETERS) {
                er.ExceptionCode = STATUS_INVALID_PARAMETER;
                er.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
            } else {
                memcpy(er.ExceptionInformation, (void*)pctx->IntA3, (DWORD)pctx->IntA2*sizeof(DWORD));
                er.NumberParameters = (DWORD)pctx->IntA2;
            }
        }
    } else {
        // CPU detected exception. Extract some additional information about
        // the cause of the exception from the EXCINFO (CALLSTACK) structure.
        badVAddr = pexi->badVAddr;
        cause = pexi->causeAndMode;
        xcode = pexi->causeAndMode.XCODE;
        pctx->Fir = pexi->oldFir;
        pctx->IntSp += pexi->lowSp + ALIGNSTK (sizeof(CALLSTACK));
        if (((xcode == 2) || (xcode == 3)) && AutoCommit(badVAddr)) {
            pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);
            goto continueExecution;
        }
        switch (xcode) {
        case 0:     // RaiseException or invalid system call
            er.ExceptionCode = STATUS_INVALID_SYSTEM_SERVICE;
            if ((pea = (PEXCARGS)badVAddr) != 0) {
                                er.ExceptionCode = pea->dwExceptionCode;
                er.ExceptionFlags = pea->dwExceptionFlags;
                if (pea->lpArguments && pea->cArguments) {
                    if (pea->cArguments > EXCEPTION_MAXIMUM_PARAMETERS) {
                        er.ExceptionCode = STATUS_INVALID_PARAMETER;
                        er.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
                    } else {
                        memcpy(er.ExceptionInformation, pea->lpArguments,
                                pea->cArguments*sizeof(DWORD));
                        er.NumberParameters = pea->cArguments;
                    }
                }
            }
            break;
        case 5:     // Address error (store)
        case 4:     // Address error (load or instruction fetch)
            if (GetContextMode(pctx) != USER_MODE || !(badVAddr&0x80000000)) {
                er.ExceptionCode = STATUS_DATATYPE_MISALIGNMENT;
                break;
            }
            goto accessError;
        case 2:     // TLB miss (load or instruction fetch)
        case 3:     // TLB Miss (store)
        case 1:     // TLB modification
            if (!InSysCall ()
                && ((GetContextMode(pctx) != USER_MODE) || !(badVAddr&0x80000000))
                && ProcessPageFault((xcode==3) || (xcode == 1), badVAddr)) {
                pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);
                goto continueExecution;
            }
    accessError:
            er.ExceptionInformation[0] = xcode & 1;
            er.ExceptionCode = STATUS_ACCESS_VIOLATION;
            er.ExceptionInformation[1] = badVAddr;
            er.NumberParameters = 2;
            break;
        case 6:     // Bus error (instruction fetch)
        case 7:     // Bus error (data reference)
            er.ExceptionInformation[0] = xcode & 1;
            er.ExceptionCode = STATUS_ACCESS_VIOLATION;
            er.ExceptionInformation[1] = badVAddr;
            er.NumberParameters = 2;
            break;
        case 9:     // Breakpoint
            if (IsMIPS16Supported && (pctx->Fir & 1)) {  // MIPS16 mode
                er.ExceptionInformation[0] = *(USHORT *)(pctx->Fir & ~1);
                er.ExceptionCode = STATUS_BREAKPOINT;
                if (er.ExceptionInformation[0] == MIPS16_BREAK (DIVIDE_BY_ZERO_BREAKPOINT)) {
                    er.ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO;
                } else if (er.ExceptionInformation[0] == MIPS16_BREAK (MULTIPLY_OVERFLOW_BREAKPOINT) ||
                           er.ExceptionInformation[0] == MIPS16_BREAK (DIVIDE_OVERFLOW_BREAKPOINT)) {
                    er.ExceptionCode = STATUS_INTEGER_OVERFLOW;
                } else if (er.ExceptionInformation[0] == MIPS16_BREAK (BREAKIN_BREAKPOINT)) {
                    pctx->Fir += 2;
                }
            } else {  // MIPS32 mode

⌨️ 快捷键说明

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