📄 mdsh3.c
字号:
// the cause of the exception from the EXCINFO (CALLSTACK) structure. pctx->R15 += pexi->lowSp + sizeof(CALLSTACK); exc = pexi->exc; info = pexi->info; // Construct an EXCEPTION_RECORD from the EXCINFO structure er.ExceptionInformation[1] = info; // TLB Miss on load or store. Attempt to auto-commit the page. If that fails, // fall through into general exception processing. if (((exc == 0x3) || (exc == 2)) && AutoCommit(info)) { pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1); goto continueExecution; } switch (exc) { case 8: // Address error (store) er.ExceptionInformation[0] = 1; case 7: // Address error (load or instruction fetch) if (GetContextMode(pctx) != USER_MODE || !(info&0x80000000)) { er.ExceptionCode = STATUS_DATATYPE_MISALIGNMENT; break; } goto accessError; case 3: // TLB Miss (store) case 4: // TLB modification case 6: // TLB protection violation (store) er.ExceptionInformation[0] = 1; case 2: // TLB miss (load or instruction fetch) case 5: // TLB protection violation (load) if (ProcessPageFault((exc==3)||(exc==4)||(exc==6), info)) { pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1); goto continueExecution; } accessError: er.ExceptionCode = STATUS_ACCESS_VIOLATION; er.NumberParameters = 2; break;#ifdef SH4 case 0x40: case 0x41: KCall((PKFN)SwitchFPUOwner,pctx); pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1); goto continueExecution; case 9: { // floating point exception DWORD code; code = GetCauseFloatCode();#if 0 NKDbgPrintfW(L"ExceptionAddress 0x%x\r\n", er.ExceptionAddress); NKDbgPrintfW(L"code 0x%x, exc 0x%x\r\n",code,exc);#endif if (code & 0x10) er.ExceptionCode = STATUS_FLOAT_INVALID_OPERATION; else if (code & 0x8) er.ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO; else if (code & 0x4) er.ExceptionCode = STATUS_FLOAT_OVERFLOW; else if (code & 0x2) er.ExceptionCode = STATUS_FLOAT_UNDERFLOW; else if (code & 0x1) er.ExceptionCode = STATUS_FLOAT_INEXACT_RESULT; else { // // Reach here // --if code is 0x20 (FPU error) // --if code is 0x0 (processor thinks an ieee // exception is possible) // // both cases require that fp operation be emulated // for correct ieee result. // // save the fpscr before FPUFlushContext will flush it // to zero. // // FPUFlushContext clears fpscr // FPUFlushContext(); // // Copy current thread fregs and xfreg to user context // memcpy(&pctx->FRegs[0],&pCurThread->ctx.FRegs[0],sizeof(DWORD)*16); memcpy(&pctx->xFRegs[0],&pCurThread->ctx.xFRegs[0],sizeof(DWORD)*16); pctx->Fpscr = pCurThread->ctx.Fpscr; pctx->Fpul = pCurThread->ctx.Fpul; if (HandleHWFloatException(&er,pctx)) { // // update current thread context with user context // memcpy(&pCurThread->ctx.FRegs[0],&pctx->FRegs[0],sizeof(DWORD)*16); memcpy(&pCurThread->ctx.xFRegs[0],&pctx->xFRegs[0],sizeof(DWORD)*16); pCurThread->ctx.Fpul = pctx->Fpul; pCurThread->ctx.Fpscr = pctx->Fpscr; pCurThread->ctx.Psr = pctx->Psr; pctx->Fir+=2; // +2: return control to instruction successor pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1); goto continueExecution; } } // // Update user context fpscr and fpul // pCurThread->ctx.Fpscr = pctx->Fpscr; pCurThread->ctx.Fpul = pctx->Fpul; pCurThread->ctx.Psr = pctx->Psr; break; }#endif case 11: // Breakpoint pctx->Fir -= 2; // backup to the trapa instruction er.ExceptionInformation[0] = info; er.ExceptionCode = STATUS_BREAKPOINT; break; case 12: // Reserved instruction case 13: // Illegal slot instruction#ifdef SH3 // // Assume DSP instruction. // If DSP processor and DSP not enabled, enable the DSP. // if ( SH3DSP && ((pctx->Psr & 0x1000) == 0) ){ KCall((PKFN)SwitchDSPOwner,pctx); pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1); goto continueExecution; }#endif er.ExceptionCode = STATUS_ILLEGAL_INSTRUCTION; break; case 15: // Hardware breakpoint er.ExceptionInformation[0] = info; er.ExceptionCode = STATUS_USER_BREAK; break; case 0xFF: // Stack overflow er.ExceptionCode = STATUS_STACK_OVERFLOW; er.ExceptionFlags = EXCEPTION_NONCONTINUABLE; break; } } if (exc != 11 && exc != 15) { NKDbgPrintfW(L"Exception %03x Thread=%8.8lx Proc=%8.8lx '%s'\r\n", exc<<5, pth, hCurProc, pCurProc->lpszProcName ? pCurProc->lpszProcName : L""); NKDbgPrintfW(L"AKY=%8.8lx PC=%8.8lx RA=%8.8lx TEA=%8.8lx\r\n", pCurThread->aky, pctx->Fir, pctx->PR, info); if (UTlsPtr()[TLSSLOT_KERNEL] & TLSKERN_NOFAULT) { NKDbgPrintfW(L"TLSKERN_NOFAULT set... bypassing kernel debugger.\r\n"); } } // Invoke the kernel debugger to attempt to debug the exception before // letting the program resolve the condition via SEH. pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1); if (!UserDbgTrap(&er,pctx,FALSE) && ((UTlsPtr()[TLSSLOT_KERNEL] & TLSKERN_NOFAULT) || !KDTrap(&er, pctx, FALSE))) { bHandled = NKDispatchException(pth, &er, pctx); if (!bHandled) { if (!UserDbgTrap(&er, pctx, TRUE) && !KDTrap(&er, pctx, TRUE)) { if (er.ExceptionCode == STATUS_BREAKPOINT) { RETAILMSG(1, (TEXT("DEBUG_BREAK @%8.8lx Ignored.\r\n"), pctx->Fir)); DumpFrame(pth, pctx, exc<<5, info); pctx->Fir += 2; // skip over the trapa instruction } else { // Terminate the process. RETAILMSG(1, (TEXT("\r\nUnhandled exception %8.8lx:\r\n"), er.ExceptionCode)); DumpFrame(pth, pctx, exc<<5, info); if (InSysCall()) { OutputDebugStringW(L"Halting system\r\n"); for (;;) ; } else { if (!GET_DEAD(pth)) { SET_DEAD(pth); pctx->Fir = (ULONG)pExitThread; pctx->R0 = 0; RETAILMSG(1, (TEXT("Terminating thread %8.8lx\r\n"), pth)); } else { RETAILMSG(1, (TEXT("Can't terminate thread %8.8lx, sleeping forever\r\n"), pth)); SurrenderCritSecs(); Sleep(INFINITE); DEBUGCHK(0); // should never get here } } } } } } if (exc == 2 || exc == 3) GuardCommit(info); continueExecution: // If returning from handling a stack overflow, reset the thread's stack overflow // flag. It would be good to free the tail of the stack at this time // so that the thread will stack fault again if the stack gets too big. But we // are currently using that stack page. if (exc == 0xFF) CLEAR_STACKFAULT(pth); if (GET_DYING(pth) && !GET_DEAD(pth) && (pCurProc == pth->pOwnerProc)) { SET_DEAD(pth); CLEAR_USERBLOCK(pth); CLEAR_DEBUGWAIT(pth); pctx->Fir = (ULONG)pExitThread; pctx->R0 = 0; } return;}void DumpFrame(PTHREAD pth, PCONTEXT pctx, DWORD dwExc, DWORD info) { DWORD oldCCR; oldCCR = CCR; CCR = 0; // disable the cache to avoid changing its state NKDbgPrintfW(L"Exception %03x Thread=%8.8lx AKY=%8.8lx PC=%8.8lx\r\n", dwExc, pth, pCurThread->aky, pctx->Fir); NKDbgPrintfW(L" R0=%8.8lx R1=%8.8lx R2=%8.8lx R3=%8.8lx\r\n", pctx->R0, pctx->R1, pctx->R2, pctx->R3); NKDbgPrintfW(L" R4=%8.8lx R5=%8.8lx R6=%8.8lx R7=%8.8lx\r\n", pctx->R4, pctx->R5, pctx->R6, pctx->R7); NKDbgPrintfW(L" R8=%8.8lx R9=%8.8lx R10=%8.8lx R11=%8.8lx\r\n", pctx->R8, pctx->R9, pctx->R10, pctx->R11); NKDbgPrintfW(L"R12=%8.8lx R13=%8.8lx R14=%8.8lx R15=%8.8lx\r\n", pctx->R12, pctx->R13, pctx->R14, pctx->R15); NKDbgPrintfW(L" PR=%8.8lx SR=%8.8lx\r\n TEA/TRPA=%8.8x", pctx->PR, pctx->Psr, info); NKDbgPrintfW(L"PTEL=%8.8lx PTEH=%8.8lx MMUCR=%8.8lx TTB=%8.8lx\r\n", MMUPTEL, MMUPTEH, MMUCR, MMUTTB); NKDbgPrintfW(L"CCR=%8.8lx\r\n", oldCCR); CCR = oldCCR; // restore original cache state}// 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; // Clear all registers: Esp. fpu state for SH-4 memset(&pTh->ctx, 0, sizeof(pTh->ctx)); // Leave room for arguments and TLS on the stack pTh->ctx.R15 = (ulong)lpStack + cbStack - (TLS_MINIMUM_AVAILABLE*4) - 4*4; pTh->dwStackBound = pTh->ctx.R15 & ~(PAGE_SIZE-1); pTh->tlsPtr = (LPDWORD)((ulong)lpStack+cbStack-(TLS_MINIMUM_AVAILABLE*4)); pTh->ctx.R4 = (ulong)lpStart; pTh->ctx.R5 = param; pTh->ctx.PR = 0;#ifdef SH4 pTh->ctx.Psr = 0x8000; // disable floating point pTh->ctx.Fpscr = 0x40000; // handle no exceptions#else pTh->ctx.Psr = 0;#endif pTh->ctx.Fir = (ULONG)lpBase; pTh->ctx.ContextFlags = CONTEXT_FULL; SetThreadMode(pTh, ((kmode || bAllKMode) ? KERNEL_MODE : USER_MODE));}// 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+3)&~3)); memcpy((LPBYTE)lpStack+cbStack-(TLS_MINIMUM_AVAILABLE*4)-((buflen+3)&~3),buf,buflen); pTh->pOwnerProc->lpszProcName = (LPWSTR)((LPBYTE)lpStack+cbStack-(TLS_MINIMUM_AVAILABLE*4)-((buflen+3)&~3)-((buflen2+3)&~3)); memcpy(pTh->pOwnerProc->lpszProcName,buf2,buflen2); 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) { // Clear all registers: Esp. fpu state for SH-4 memset(&pTh->ctx, 0, sizeof(pTh->ctx)); // Leave room for arguments on the stack pTh->ctx.R15 = (pTh->dwStackBase + cbStack - (TLS_MINIMUM_AVAILABLE*4) - 8*4 - ((buflen+3)&~3) - ((buflen2+3)&~3)) & ~7; pTh->dwStackBound = pTh->ctx.R15 & ~(PAGE_SIZE-1); pTh->ctx.R4 = (ulong)lpStart; pTh->ctx.R5 = p1; pTh->ctx.R6 = p2; pTh->ctx.R7 = pTh->dwStackBase+cbStack-(TLS_MINIMUM_AVAILABLE*4)-((buflen+3)&~3); ((LPDWORD)pTh->ctx.R15)[4] = p4; pTh->ctx.PR = 0;#ifdef SH4 pTh->ctx.Psr = 0x8000; // disable floating point pTh->ctx.Fpscr = 0x40000; // handle no exceptions#else pTh->ctx.Psr = 0;#endif pTh->ctx.Fir = (ULONG)lpBase; SetThreadMode(pTh, ((kmode || bAllKMode) ? KERNEL_MODE : USER_MODE)); pTh->ctx.ContextFlags = CONTEXT_FULL;}#ifdef XTIMEextern DWORD ExceptionTime;// tick at exception entryvoid SyscallTime(int iSyscall) { DWORD dwTime; dwTime = ExceptionTime - TMUADDR->tcnt1; xt.dwTime[iSyscall]+= dwTime; if ((++xt.dwCount[iSyscall]) == 1) xt.dwMax[iSyscall]=xt.dwMin[iSyscall]= dwTime;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -