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

📄 mdarm.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                break;
            case ID_PREFETCH_ABORT:     // Code page fault
                addr = pctx->Pc;
                
                DEBUGMSG(ZONE_PAGING, (L"ExD: ID_PREFETCH_ABORT\r\n"));

    doPageFault:
                DEBUGMSG(ZONE_PAGING, (L"ExD: addr = %8.8lx\r\n",addr));
                fInKMode = (GetContextMode(pctx) != USER_MODE);

                // er.ExceptionInformation[0] == read or write (1 for write)
                if (!InSysCall () 
                    && (fInKMode || !(addr & 0x80000000))
                    // writing to shared section require KMode access
                    && (!IsInSharedSection(addr) || !er.ExceptionInformation[0] || fInKMode)
                    && ProcessPageFault(er.ExceptionInformation[0], addr)) {

                    pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);

                    DEBUGMSG(ZONE_PAGING, (L"ExD: continuing.  lr = %8.8lx\r\n", pctx->Lr));
                    
                    goto continueExecution;
                }
                er.ExceptionCode = STATUS_ACCESS_VIOLATION;
                er.ExceptionInformation[1] = addr;
                er.NumberParameters = 2;
                break;
            case ID_STACK_FAULT:    // Stack overflow
                er.ExceptionCode = STATUS_STACK_OVERFLOW;
                er.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
                break;
        }
    }
    if ((er.ExceptionCode != STATUS_BREAKPOINT) && !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->Pc, dwOfstRA = pctx->Lr;
        pszNamePC = FindModuleNameAndOffset (dwOfstPC, &dwOfstPC);
        pszNameRA = FindModuleNameAndOffset (dwOfstRA, &dwOfstRA);
        
        if (!((DWORD) pProcName & 0x80000000)
            && (((DWORD) pProcName >> VA_SECTION) != (DWORD) (pCurProc->procnum+1)))
            pProcName = L"";
        NKDbgPrintfW(L"%a: Thread=%8.8lx Proc=%8.8lx '%s'\r\n",IdStrings[id+1], pth, pCurProc, pProcName);
        NKDbgPrintfW(L"AKY=%8.8lx PC=%8.8lx(%s+0x%8.8lx) RA=%8.8lx(%s+0x%8.8lx) BVA=%8.8lx FSR=%8.8lx\r\n", 
            pCurThread->aky, pctx->Pc, pszNamePC, dwOfstPC, pctx->Lr, pszNameRA, dwOfstRA, addr, fsr);
        if (IsNoFaultSet ()) {
            NKDbgPrintfW(L"TLSKERN_NOFAULT set... bypassing kernel debugger.\r\n");
        }
    }
    // Unlink the EXCINFO structure from the threads call stack chain.
    pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);

    if (!(pexi->linkage & 1) && IsValidKPtr (pexi)) {
        // from RaiseException, free the callstack structure
        FreeMem (pexi, HEAP_CALLSTACK);
    }
    // Invoke the kernel debugger to attempt to debug the exception before
    // letting the program resolve the condition via SEH.
    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->Pc < (DWORD)pvHDNotifyExdi || pctx->Pc > ((DWORD)pvHDNotifyExdi + HD_NOTIFY_MARGIN))
                    RETAILMSG(1, (TEXT("DEBUG_BREAK @%8.8lx MD=%2x Ignored.\r\n"), pctx->Pc,
                            pctx->Psr & 0xFF));
                pctx->Pc += ThumbMode ? 2 : 4;  // skip over the BREAK instruction
            } else {
                // Terminate the process.
                RETAILMSG(1, (TEXT("\r\nUnhandled exception %8.8lx:\r\n"), er.ExceptionCode));
                if (InSysCall()) {
                    DumpFrame(pth, (PCPUCONTEXT)&pctx->Psr, id, addr, 0);
                    lpNKHaltSystem ();
                    FakeNKHaltSystem ();
                } else {
                    if (!GET_DEAD(pth)) {
                        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->Sp = (DWORD) pth->tlsPtr - SECURESTK_RESERVE - (PAGE_SIZE >> 1);
                        }
                        SET_DEAD(pth);
                        //pth->tlsSecure[TLSSLOT_KERNEL] |= TLSKERN_TRYINGTODIE;
                        pctx->Pc = (ULONG)pExcpExitThread;
                        pctx->R0 = er.ExceptionCode;    // argument: exception code
                        pctx->R1 = (ULONG)er.ExceptionAddress; // argument: exception address
                        RETAILMSG(1, (TEXT("Terminating thread %8.8lx\r\n"), pth));
                    } else {
                        DumpFrame(pth, (PCPUCONTEXT)&pctx->Psr, id, addr, 0);
                        RETAILMSG(1, (TEXT("Can't terminate thread %8.8lx, sleeping forever\r\n"), pth));
                        SurrenderCritSecs();
                        Sleep(INFINITE);
                        DEBUGCHK(0);    // should never get here
                    }
                }
            }
        }
    }
    if ((id == ID_DATA_ABORT) || (id == ID_PREFETCH_ABORT))
        GuardCommit(addr);
continueExecution:

#if defined(THUMBSUPPORT)
    //
    // Update PSR based on ARM/Thumb continuation:
    //
    if ( pctx->Pc & 0x01 ){
        pctx->Psr |= THUMB_STATE;
    } else {
        pctx->Psr &= ~THUMB_STATE;
    }
#endif
    
    // 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 (id == ID_STACK_FAULT)
        CLEAR_STACKFAULT(pth);
    if (GET_DYING(pth) && !GET_DEAD(pth) && (pCurProc == pth->pOwnerProc)) {
        SET_DEAD(pth);
        CLEAR_USERBLOCK(pth);
        CLEAR_DEBUGWAIT(pth);
        pctx->Pc = (ULONG)pExcpExitThread;
        pctx->R0 = er.ExceptionCode;    // argument: exception code
        pctx->R1 = (ULONG)er.ExceptionAddress; // argument: exception address
    }   
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PVOID 
Phys2Virt(
    DWORD pfn
    ) 
{
    int i = 0;
    DWORD va;       // Virtual Base Address of section
    DWORD pa;       // Physical Base Address of section
    DWORD pau;      // Physical Address Upper Bound of section
    DWORD pfnmb;    // PFN rounded down to 1MB
    //
    // The end of the table is marked by an entry with a ZERO size.
    //
    while(g_pOEMAddressTable[i].dwSize) {
        va = g_pOEMAddressTable[i].dwVA & 0x1FF00000;
        pa = g_pOEMAddressTable[i].dwPA & 0xFFF00000;
        pau = pa + (g_pOEMAddressTable[i].dwSize << 20) - 1;
        pfnmb = pfn & 0xfff00000;
        if ((pfnmb >= pa) && (pfnmb <= pau))
            return ((PVOID) ((pfn - pa) + va + 0x80000000));
        i++;
    }
    DEBUGMSG(ZONE_PHYSMEM, (TEXT("Phys2Virt() : PFN (0x%08X) not found!\r\n"), pfn));
    return NULL;
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPVOID MDValidateKVA (DWORD dwAddr)
{
    // kernel data and page table territory...
    if (   ((dwAddr >= 0xFFFD0000) && (dwAddr < 0xFFFD4000))
        || ((dwAddr >= 0xFFFF0000) && (dwAddr < 0xFFFF1000))
        || ((dwAddr >= 0xFFFF2000) && (dwAddr < 0xFFFF3000))
        || ((dwAddr >= 0xFFFF4000) && (dwAddr < 0xFFFF5000))
        || ((dwAddr >= 0xFFFFC000) && (dwAddr < 0xFFFFD000)))
        return (LPVOID) dwAddr;

    if (dwAddr < 0xc0000000) {
        int i;
        DWORD dwCachedAddr = dwAddr & ~0x20000000;  // use cached address to do comparision
        
        // check the OEM address map to see if the address we've been 
        // handed is indeed mapped...
        for (i = 0; g_pOEMAddressTable[i].dwSize; i ++) {
            if((g_pOEMAddressTable[i].dwVA <= dwCachedAddr)
                && (dwCachedAddr < (g_pOEMAddressTable[i].dwVA + (g_pOEMAddressTable[i].dwSize << 20)))) {
                return (LPVOID) dwAddr;
            }
        }
    }
    return NULL;
}

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

void MDInitSecureStack(LPBYTE lpStack)
{
}

/* Machine dependent thread creation */
// normal thread stack: from top, TLS then 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;

    // Leave room for arguments and TLS and PRETLS on the stack
    pTh->ctx.Sp = (ulong)pTh->tlsPtr - SIZE_PRETLS;
    KSTKBOUND(pTh) = pTh->ctx.Sp & ~(PAGE_SIZE-1);
    pTh->ctx.R0 = (ulong)lpStart;
    pTh->ctx.R1 = param;
    pTh->ctx.Lr = 4;
    pTh->ctx.Pc = (ULONG)lpBase;
    if (kmode || bAllKMode) {
        pTh->ctx.Psr = KERNEL_MODE;
        KTHRDINFO (pTh) |= UTLS_INKMODE;
    } else {
        pTh->ctx.Psr = USER_MODE;
        KTHRDINFO (pTh) &= ~UTLS_INKMODE;
    }
    pTh->ctx.Fpscr = 0;
    pTh->ctx.FpExc = 0;
    memset (pTh->ctx.FpExtra, 0, sizeof (pTh->ctx.FpExtra));
#if defined(THUMBSUPPORT)
    if ( (pTh->ctx.Pc & 0x01) != 0 ){
        pTh->ctx.Psr |= THUMB_STATE;
    }
#endif

    DEBUGMSG(ZONE_SCHEDULE, (L"MDCT: pTh=%8.8lx Pc=%8.8lx Psr=%4.4x GP=%8.8lx Sp=%8.8lx\r\n", pTh, pTh->ctx.Pc, pTh->ctx.Psr, pTh->ctx.R9, pTh->ctx.Sp));
}

// main thread stack: from top, TLS then buf then buf2 then buf2 (ascii) then args then free
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
MDSetupMainThread (
    PTHREAD pTh,
    LPBYTE pCurSP,
    LPVOID lpBase,
    LPVOID lpStart,
    BOOL kmode,
    ulong dwModCnt
    ) 
{
    LPDWORD pArgs = ((LPDWORD) pCurSP) - 4; // 4 arguments on stack
    PPROCESS pprc = pTh->pOwnerProc;

    pTh->ctx.Sp = (ulong)pArgs;
    KSTKBOUND(pTh) = pTh->ctx.Sp & ~(PAGE_SIZE-1);
    pTh->ctx.R0 = (ulong) lpStart;           // arg #0
    pTh->ctx.R1 = (ulong) pprc->hProc;       // arg #1 - hInstance
    pTh->ctx.R2 = dwModCnt;                  // arg #2
    pTh->ctx.R3 = (ulong)pprc->pcmdline;     // arg #3 - cmdline
    pArgs[0] = (DWORD) hCoreDll;             // arg #4
    pArgs[1] = pprc->e32.e32_sect14rva;      // arg #5
    pArgs[2] = pprc->e32.e32_sect14size;     // arg #6
    pArgs[3] = (DWORD) pprc->BasePtr;        // arg #7
    
    pTh->ctx.Lr = 4;
    pTh->ctx.Pc = (ULONG)lpBase;
    if (kmode || bAllKMode) {
        pTh->ctx.Psr = KERNEL_MODE;
        KTHRDINFO (pTh) |= UTLS_INKMODE;
    } else {
        pTh->ctx.Psr = USER_MODE;
        KTHRDINFO (pTh) &= ~UTLS_INKMODE;
    }
    pTh->ctx.Fpscr = 0;
    pTh->ctx.FpExc = 0;
    memset (pTh->ctx.FpExtra, 0, sizeof (pTh->ctx.FpExtra));
#if defined(THUMBSUPPORT)
    if ( (pTh->ctx.Pc & 0x01) != 0 ){
        pTh->ctx.Psr |= THUMB_STATE;
    }
#endif

    DEBUGMSG(ZONE_SCHEDULE, (L"MDCMainT: pTh=%8.8lx Pc=%8.8lx Psr=%4.4x TOC=%8.8lx Sp=%8.8lx\r\n", pTh, pTh->ctx.Pc, pTh->ctx.Psr, pTh->ctx.R9, pTh->ctx.Sp));
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL 
DoThreadGetContext(
    HANDLE hTh,
    PCONTEXT lpContext
    ) 
{
    PTHREAD pth;
    if (!(pth = HandleToThread(hTh))) {

⌨️ 快捷键说明

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