📄 mdsched.c
字号:
/* Copyright (c) 1999-2000 Microsoft Corporation. All rights reserved. */#include "kernel.h"#ifdef MIPS_HAS_FPUvoid SaveFloatContext(PTHREAD);void RestoreFloatContext(PTHREAD);DWORD GetAndClearFloatCode(void);BOOL HandleHWFloatException(EXCEPTION_RECORD *er, PCONTEXT pctx, CAUSE cause);void FPUFlushContext(void);#endif#ifdef MIPS16SUPPORTconst wchar_t NKSignon[] = TEXT("Windows CE Kernel for MIPS16 Built on ") TEXT(__DATE__) TEXT(" at ") TEXT(__TIME__) TEXT("\r\n");#elseconst wchar_t NKSignon[] = TEXT("Windows CE Kernel for MIPS Built on ") TEXT(__DATE__) TEXT(" at ") TEXT(__TIME__) TEXT("\r\n");#endif// Define breakpoint instruction values.#define MIPS32_BREAK(_t) ((SPEC_OP << 26) | ((_t) << 16) | BREAK_OP)#if defined(MIPS16SUPPORT)#define MIPS16_BREAK(_t) ((RR_OP16 << 11) | ((_t) << 5) | BREAK_OP16)#endifvoid DumpDwords(PDWORD pdw, int len) { int lc; lc = 0; NKDbgPrintfW(L"Dumping %d dwords", len); for (lc = 0 ; len ; ++pdw, ++lc, --len) { if (!(lc & 3)) NKDbgPrintfW(L"\r\n%8.8lx -", pdw); NKDbgPrintfW(L" %8.8lx", *pdw); } NKDbgPrintfW(L"\r\n");}void DumpFrame(PTHREAD pth, PICONTEXT pctx, CAUSE cause, ULONG badVAddr, int level) { ulong addr; PDWORD pdw; NKDbgPrintfW(L"Exception %03x Thread=%8.8lx AKY=%8.8lx PC=%8.8lx BVA=%8.8lx\r\n", cause.XCODE, pth, pCurThread->aky, pctx->Fir, badVAddr); NKDbgPrintfW(L"SR=%8.8lx AT=%8.8lx V0=%8.8lx V1=%8.8lx\r\n", pctx->Psr, pctx->IntAt, pctx->IntV0, pctx->IntV1); NKDbgPrintfW(L"A0=%8.8lx A1=%8.8lx A2=%8.8lx A3=%8.8lx\r\n", pctx->IntA0, pctx->IntA1, pctx->IntA2, pctx->IntA3); NKDbgPrintfW(L"T0=%8.8lx T1=%8.8lx T2=%8.8lx T3=%8.8lx\r\n", pctx->IntT0, pctx->IntT1, pctx->IntT2, pctx->IntT3); NKDbgPrintfW(L"T4=%8.8lx T5=%8.8lx T6=%8.8lx T7=%8.8lx\r\n", pctx->IntT4, pctx->IntT5, pctx->IntT6, pctx->IntT7); NKDbgPrintfW(L"S0=%8.8lx S1=%8.8lx S2=%8.8lx S3=%8.8lx\r\n", pctx->IntS0, pctx->IntS1, pctx->IntS2, pctx->IntS3); NKDbgPrintfW(L"S4=%8.8lx S5=%8.8lx S6=%8.8lx S7=%8.8lx\r\n", pctx->IntS4, pctx->IntS5, pctx->IntS6, pctx->IntS7); NKDbgPrintfW(L"T8=%8.8lx T9=%8.8lx LO=%8.8lx HI=%8.8lx\r\n", pctx->IntT8, pctx->IntT9, pctx->IntLo, pctx->IntHi); NKDbgPrintfW(L"GP=%8.8lx SP=%8.8lx S8=%8.8lx RA=%8.8lx\r\n", pctx->IntGp, pctx->IntSp, pctx->IntS8, pctx->IntRa); if (level > 1) { addr = (pctx->Fir & -4) - 8*4; pdw = VerifyAccess((PVOID)addr, VERIFY_KERNEL_OK, CurAKey); if (pdw) DumpDwords((PDWORD)addr, 12); }}typedef struct _tlbentry { ulong lo0; ulong lo1; ulong hi; ulong mask;} TLBENTRY;typedef TLBENTRY *PTLBENTRY;// Value of PRId register (least significant 16 bits)WORD ProcessorRevision;BOOL HookInterrupt(int hwInterruptNumber, FARPROC pfnHandler) { if (hwInterruptNumber > 5) return FALSE; ISRTable[hwInterruptNumber] = (DWORD)pfnHandler; KData.basePSR |= (0x0400 << hwInterruptNumber); return TRUE;}BOOL UnhookInterrupt(int hwInterruptNumber, FARPROC pfnHandler) { extern int DisabledInterruptHandler(); if (hwInterruptNumber > 5 || ISRTable[hwInterruptNumber] != (DWORD)pfnHandler) return FALSE; ISRTable[hwInterruptNumber] = (DWORD)DisabledInterruptHandler; KData.basePSR &= ~(0x0400 << hwInterruptNumber); return TRUE;}/* Machine dependent thread creation */#define STKALIGN 8#define STKMSK (STKALIGN-1)// normal thread stack: from top, TLS then args then freevoid MDCreateThread(PTHREAD pTh, LPVOID lpStack, DWORD cbStack, LPVOID lpBase, LPVOID lpStart, DWORD dwVMBase, BOOL kmode, ulong param) { if (!((ulong)lpStack>>VA_SECTION)) lpStack = (LPVOID)((ulong)(lpStack) + dwVMBase); pTh->dwStackBase = (DWORD)lpStack; memset(&pTh->ctx, 0xBD, sizeof(pTh->ctx)); // Leave room for arguments and TLS on the stack pTh->ctx.IntSp = (ulong)lpStack + cbStack - (TLS_MINIMUM_AVAILABLE*4) - 4*4; pTh->dwStackBound = pTh->ctx.IntSp & ~(PAGE_SIZE-1); pTh->tlsPtr = (LPDWORD)((ulong)lpStack+cbStack-(TLS_MINIMUM_AVAILABLE*4)); 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; pTh->ctx.Psr = (kmode || bAllKMode) ? KERNEL_MODE : USER_MODE;#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 buf then buf2 then buf2 (ascii) then args then freeLPCWSTR MDCreateMainThread1(PTHREAD pTh, LPVOID lpStack, DWORD cbStack, DWORD dwVMBase, LPBYTE buf, ulong buflen, LPBYTE buf2, ulong buflen2) { LPCWSTR pcmdline; if (!((ulong)lpStack>>VA_SECTION)) lpStack = (LPVOID)((ulong)(lpStack) + dwVMBase); pTh->dwStackBase = (DWORD)lpStack; pcmdline = (LPCWSTR)((LPBYTE)lpStack+cbStack-(TLS_MINIMUM_AVAILABLE*4)-((buflen+STKMSK)&~STKMSK)); memcpy((LPBYTE)lpStack+cbStack-(TLS_MINIMUM_AVAILABLE*4)-((buflen+STKMSK)&~STKMSK), buf,buflen); memcpy((LPBYTE)lpStack+cbStack-(TLS_MINIMUM_AVAILABLE*4)-((buflen+STKMSK)&~STKMSK)- ((buflen2+STKMSK)&~STKMSK),buf2,buflen2); pTh->pOwnerProc->lpszProcName = (LPWSTR)((ulong)lpStack+cbStack-(TLS_MINIMUM_AVAILABLE*4)-((buflen+STKMSK)&~STKMSK)-((buflen2+STKMSK)&~STKMSK)); KPlpvTls = pTh->tlsPtr = (LPDWORD)((ulong)lpStack+cbStack-(TLS_MINIMUM_AVAILABLE*4)); return pcmdline;}void MDCreateMainThread2(PTHREAD pTh, DWORD cbStack, LPVOID lpBase, LPVOID lpStart, BOOL kmode, ulong p1, ulong p2, ulong buflen, ulong buflen2, ulong p4) { memset(&pTh->ctx, 0xBD, sizeof(pTh->ctx)); // Leave room for arguments on the stack pTh->ctx.IntSp = pTh->dwStackBase + cbStack - (TLS_MINIMUM_AVAILABLE*4) - 8*4 - ((buflen+STKMSK)&~STKMSK) - ((buflen2+STKMSK)&~STKMSK); pTh->dwStackBound = pTh->ctx.IntSp & ~(PAGE_SIZE-1); pTh->ctx.IntA0 = (ulong)lpStart; pTh->ctx.IntA1 = p1; pTh->ctx.IntA2 = p2; pTh->ctx.IntA3 = pTh->dwStackBase+cbStack-(TLS_MINIMUM_AVAILABLE*4)-((buflen+STKMSK)&~STKMSK); ((LPDWORD)pTh->ctx.IntSp)[4] = p4; pTh->ctx.IntK0 = 0; pTh->ctx.IntK1 = 0; pTh->ctx.IntRa = 0; pTh->ctx.Fir = (ULONG)lpBase; pTh->ctx.Psr = (kmode || bAllKMode) ? KERNEL_MODE : USER_MODE;#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 oldMode; 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) - sizeof(CALLSTACK)); if (!((DWORD)pexi & 0x80000000) && DemandCommit((DWORD)pexi)) { stackaddr = (DWORD)pexi & ~(PAGE_SIZE-1); if ((stackaddr >= pth->dwStackBound) || (stackaddr < pth->dwStackBase) || ((pth->dwStackBound = stackaddr) >= (pth->dwStackBase + MIN_STACK_RESERVE)) || TEST_STACKFAULT(pth)) { KCALLPROFOFF(0); return 1; // restart instruction } SET_STACKFAULT(pth); cause.XCODE = 30; // stack fault exception code badVAddr = (DWORD)pexi; } if (pth->ctx.Fir != (ulong)CaptureContext+4) { pexi->causeAndMode = cause; pexi->lowSp = (UCHAR)(pth->ctx.IntSp & 63); pexi->oldFir = pth->ctx.Fir; 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 = 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_FPUvoid SwitchFPUOwner(PCONTEXT pctx) { KCALLPROFON(61); if (g_CurFPUOwner != pCurThread) { if (g_CurFPUOwner) SaveFloatContext(g_CurFPUOwner); g_CurFPUOwner = pCurThread; RestoreFloatContext(pCurThread); } KCALLPROFOFF(61);}#endifvoid ExceptionDispatch(PCONTEXT pctx) { PTHREAD pth; PEXCINFO pexi; EXCEPTION_RECORD er; ULONG badVAddr; int xcode; CAUSE cause; PEXCARGS pea; BOOL bHandled; 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, pexi->oldMode); 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)) { pea = (PEXCARGS)pctx->IntSp; 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"), pea->dwExceptionCode, pea->dwExceptionFlags, pea->cArguments, pexi)); 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; } } } 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 + 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; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -