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

📄 mdsh3.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 4 页
字号:
                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 && !IsNoFaultMsgSet ()) {
        // if we faulted in DllMain doing PROCESS_ATTACH, the process name will
        // be pointing to other process's (the creator) address space. Make sure
        // we don't fault on displaying process name.
        LPWSTR pProcName = pCurProc->lpszProcName? pCurProc->lpszProcName : L"";
        LPCWSTR pszNamePC, pszNameRA;
        DWORD dwOfstPC = pctx->Fir, dwOfstRA = pctx->PR;
        pszNamePC = FindModuleNameAndOffset (dwOfstPC, &dwOfstPC);
        pszNameRA = FindModuleNameAndOffset (dwOfstRA, &dwOfstRA);
        if (!((DWORD) pProcName & 0x80000000)
            && (((DWORD) pProcName >> VA_SECTION) != (DWORD) (pCurProc->procnum+1)))
            pProcName = L"";
        NKDbgPrintfW(L"Exception %03x Thread=%8.8lx Proc=%8.8lx '%s'\r\n",
                     exc<<5, pth, hCurProc, pProcName);
        NKDbgPrintfW(L"AKY=%8.8lx PC=%8.8lx(%s+0x%8.8lx) RA=%8.8lx(%s+0x%8.8lx) TEA=%8.8lx\r\n",
                     pCurThread->aky, pctx->Fir, pszNamePC, dwOfstPC, pctx->PR, pszNameRA, dwOfstRA, info);
        if (IsNoFaultSet ()) {
            NKDbgPrintfW(L"TLSKERN_NOFAULT set... bypassing kernel debugger.\r\n");
        }
    }

    DEBUGMSG (ZONE_SEH, (L"ExceptionDispatch: PSR = %8.8lx\r\n", pctx->Psr));
    // 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 (!(pexi->linkage & 1) && IsValidKPtr (pexi)) {
        // from RaiseException, free the callstack structure
        FreeMem (pexi, HEAP_CALLSTACK);
    }
    if (!UserDbgTrap(&er,pctx,FALSE) && (IsNoFaultSet () || !HDException(&er, pctx, FALSE))) {
        BOOL bHandled = FALSE;
        // don't pass a break point exception to NKDispatchException
        if (er.ExceptionCode != STATUS_BREAKPOINT) {
            // to prevent recursive exception due to user messed-up TLS
            KTHRDINFO (pth) &= ~UTLS_INKMODE;
            bHandled = NKDispatchException(pth, &er, pctx);
        }
        if (!bHandled && !UserDbgTrap(&er, pctx, TRUE) && !HDException(&er, pctx, TRUE)) {
            if (er.ExceptionCode == STATUS_BREAKPOINT) {
                if (!pvHDNotifyExdi || pctx->Fir < (DWORD)pvHDNotifyExdi || pctx->Fir > ((DWORD)pvHDNotifyExdi + HD_NOTIFY_MARGIN))
                    RETAILMSG(1, (TEXT("DEBUG_BREAK @%8.8lx Ignored.\r\n"), pctx->Fir));
                pctx->Fir += 2;     // skip over the trapa instruction
            } else {
                // Terminate the process.
                RETAILMSG(1, (TEXT("\r\nUnhandled exception %8.8lx:\r\n"),
                              er.ExceptionCode));
                if (InSysCall()) {
                    DumpFrame(pth, pctx, exc<<5, info);
                    lpNKHaltSystem ();
                    FakeNKHaltSystem ();
                } else {
                    if (!GET_DEAD(pth)) {
                        PCALLSTACK pcstk = pth->pcstkTop;
                        while (pcstk && !pcstk->akyLast) {
                            pth->pcstkTop = (PCALLSTACK) ((DWORD) pcstk->pcstkNext & ~1);
                            if (IsValidKPtr (pcstk)) {
                                FreeMem (pcstk, HEAP_CALLSTACK);
                            }
                            pcstk = pth->pcstkTop;
                        }
                        DEBUGCHK (!pcstk);   // should this happen, we have a fault in callback that wasn't handled
                                             // by PSL
                        // clean up all the temporary callstack
                        if (er.ExceptionCode == STATUS_STACK_OVERFLOW) {
                            // stack overflow, not much we can do. Make sure we have enough room to run
                            // pExcpExitThread
                            // randomly picked a valid SP
                            pctx->R15 = (DWORD) pth->tlsPtr - SECURESTK_RESERVE - (PAGE_SIZE >> 1);
                        }
                        SET_DEAD(pth);
                        //pth->tlsSecure[TLSSLOT_KERNEL] |= TLSKERN_TRYINGTODIE;
                        pctx->Fir = (ULONG)pExcpExitThread;
                        pctx->R4 = er.ExceptionCode;     // argument: exception code
                        pctx->R5 = (ULONG)er.ExceptionAddress;  // argument: exception address
                        RETAILMSG(1, (TEXT("Terminating thread %8.8lx, PSR = %8.8lx\r\n"), pth, pctx->Psr));
                    } else {
                        DumpFrame(pth, pctx, exc<<5, info);
                        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:

    // restore ThrdInfo
    KTHRDINFO (pth) = dwThrdInfo;
    
    // 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)pExcpExitThread;
        pctx->R4 = er.ExceptionCode;     // argument: exception code
        pctx->R5 = (ULONG)er.ExceptionAddress;  // argument: exception address
    }   
    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
}


/* Machine dependent constants */
const DWORD cbMDStkAlign = 4;                   // stack 4 bytes aligned

//------------------------------------------------------------------------------
// normal thread stack: from top, TLS, PRETLS, then args then free
//------------------------------------------------------------------------------
void 
MDCreateThread(
    PTHREAD pTh,
    LPVOID  lpStack,
    DWORD   cbStack,
    LPVOID  lpBase,
    LPVOID  lpStart,
    BOOL    kmode,
    ulong   param
    ) 
{
    DEBUGCHK ((ulong)lpStack>>VA_SECTION);

    pTh->tlsPtr = TLSPTR (lpStack, cbStack);
    KSTKBASE(pTh) = (DWORD)lpStack;
    // Clear all registers: Esp. fpu state for SH-4
    memset(&pTh->ctx, 0, sizeof(pTh->ctx));
    // Leave room for arguments and TLS and PRETLS on the stack
    pTh->ctx.R15 = (ulong) pTh->tlsPtr - SIZE_PRETLS - 4*4;
    KSTKBOUND(pTh) = pTh->ctx.R15 & ~(PAGE_SIZE-1);

    pTh->ctx.R4 = (ulong)lpStart;
    pTh->ctx.R5 = param;
    pTh->ctx.PR = 0;
#ifdef SH4
    pTh->ctx.Psr = SR_FPU_DISABLED; // disable floating point
    pTh->ctx.Fpscr = 0x40000;  // handle no exceptions
#else
    pTh->ctx.Psr = 0;           // disable DSP
#endif
    pTh->ctx.Fir = (ULONG)lpBase;
    pTh->ctx.ContextFlags = CONTEXT_FULL;
    if (kmode || bAllKMode) {
        SetThreadMode (pTh, KERNEL_MODE);
        KTHRDINFO (pTh) |= UTLS_INKMODE;
    } else {
        SetThreadMode (pTh, USER_MODE);
        KTHRDINFO (pTh) &= ~UTLS_INKMODE;
    }
}



//------------------------------------------------------------------------------
// main thread stack: from top, TLS then buf then buf2 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
    ) 
{
    LPDWORD pArgs;
    PPROCESS pprc = pTh->pOwnerProc;
    // Clear all registers: Esp. fpu state for SH-4
    memset(&pTh->ctx, 0, sizeof(pTh->ctx));
    
    // Leave room for arguments on stack
    pTh->ctx.R15 = ((ulong) pCurSP - 8*4) & ~7;
    KSTKBOUND(pTh) = pTh->ctx.R15 & ~(PAGE_SIZE-1);

    pArgs = (LPDWORD)pTh->ctx.R15;
    pTh->ctx.R4 = (ulong)lpStart;
    pTh->ctx.R5 = (ulong)pprc->hProc;
    pTh->ctx.R6 = dwModCnt;
    pTh->ctx.R7 = (ulong) pprc->pcmdline;
    pArgs[4] = (DWORD) hCoreDll;
    pArgs[5] = pprc->e32.e32_sect14rva;
    pArgs[6] = pprc->e32.e32_sect14size;
    pArgs[7] = (DWORD) pprc->BasePtr;
    
    pTh->ctx.PR = 0;
#ifdef SH4
    pTh->ctx.Psr = SR_FPU_DISABLED; // disable floating point
    pTh->ctx.Fpscr = 0x40000;  // handle no exceptions
#else
    pTh->ctx.Psr = 0;           // disable DSP
#endif
    pTh->ctx.Fir = (ULONG)lpBase;
    if (kmode || bAllKMode) {
        SetThreadMode (pTh, KERNEL_MODE);
        KTHRDINFO (pTh) |= UTLS_INKMODE;
    } else {
        SetThreadMode (pTh, USER_MODE);
        KTHRDINFO (pTh) &= ~UTLS_INKMODE;
    }
    pTh->ctx.ContextFlags = CONTEXT_FULL;
}


// For the SH3 the compiler generated exception functions expect the following input arguments:
//  Exception Filter: r4 = frame, r5 = exception pointers
//  Termination Handler: r4 = frame, r5 = abnormal term flag

#define __C_ExecuteExceptionFilter(eptr, fn, efrm) ((fn)((efrm), (eptr)))
#define __C_ExecuteTerminationHandler(bAb, fn, efrm) ((fn)((efrm), (bAb)))


//------------------------------------------------------------------------------
//  Routine Description:
//      This function scans the scope tables associated with the specified
//      procedure and calls exception and termination handlers as necessary.
//  
//  Arguments:
//      ExceptionRecord - Supplies a pointer to an exception record.
//  
//      EstablisherFrame - Supplies a pointer to frame of the establisher function.
//  
//      ContextRecord - Supplies a pointer to a context record.
//  
//      DispatcherContext - Supplies a pointer to the exception dispatcher or
//          unwind dispatcher context.
//  
//  Return Value:
//      If the exception is handled by one of the exception filter routines, then
//      there is no return from this routine and RtlUnwind is called. Otherwise,
//      an exception disposition value of continue execution or continue search is
//      returned.
//------------------------------------------------------------------------------
EXCEPTION_DISPOSITION __C_specific_handler(
    PEXCEPTION_RECORD ExceptionRecord,
    PVOID EstablisherFrame, 
    PCONTEXT ContextRecord, 
    PDISPATCHER_CONTEXT DispatcherContext
    ) 
{
    ULONG ControlPc;
    EXCEPTION_FILTER ExceptionFilter;
    EXCEPTION_POINTERS ExceptionPointers;
    PRUNTIME_FUNCTION FunctionEntry;
    ULONG Index;
    PSCOPE_TABLE ScopeTable;
    ULONG TargetPc;
    TERMINATION_HANDLER TerminationHandler;
    LONG Value;
    
    // Get address of where control left the establisher, the address of the
    // function table entry that describes the function, and the address of
    // the scope table.
    ControlPc = DispatcherContext->ControlPc;
    FunctionEntry = DispatcherContext->FunctionEntry;
    ScopeTable = (PSCOPE_TABLE)(FunctionEntry->HandlerData);
    // If an unwind is not in progress, then scan the scope table and call
    // the appropriate exception filter routines. Otherwise, scan the scope
    // table and call the appropriate termination handlers using the target
    // PC obtained from the context record.
    // are called.
    if (IS_DISPATCHING(ExceptionRecord->ExceptionFlags)) {
        // Scan the scope table and call the appropriate exception filter
        // routines.
        ExceptionPointers.ExceptionRecord = ExceptionRecord;
        ExceptionPointers.ContextRecord = ContextRecord;
        for (Index = 0; Index < ScopeTable->Count; Index += 1) {
            if ((ControlPc >= ScopeTable->ScopeRecord[Index].BeginAddress) &&
                (ControlPc < ScopeTable->ScopeRecord[Index].EndAddress) &&
                ScopeTable->ScopeRecord[Index].JumpTarget) {
                // Call the exception filter routine.
                ExceptionFilter = (EXCEPTION_FILTER)ScopeTable->ScopeRecord[Index].HandlerAddress;
                Value = __C_ExecuteExceptionFilter(&ExceptionPointers,ExceptionFilter,(ULONG)EstablisherFrame);
                // If the return value is less than zero, then dismiss the
                // exception. Otherwise, if the value is greater than zero,
                // then unwind to the target exception handler. Otherwise,
                // continue the search for an exception filter.
                if (Value < 0)
                    return ExceptionContinueExecution;
                else if (Value > 0) {
                    DispatcherContext->ControlPc = ScopeTable->ScopeRecord[Index].JumpTarget;
                    return ExceptionExecuteHandler;
                }
            }
        }
    } else {
        // Scan the scope table and call the appropriate termination handler
        // routines.

⌨️ 快捷键说明

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