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

📄 mdx86.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 4 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------

#include "kernel.h"

#define Naked void __declspec(naked)

extern FXSAVE_AREA g_InitialFPUState;
extern KIDTENTRY g_aIntDescTable[];

extern void (*lpNKHaltSystem)(void);
extern void FakeNKHaltSystem (void);

// Default processor type & revision level information.
DWORD CEProcessorType = PROCESSOR_INTEL_486;
WORD ProcessorLevel = 0;
WORD ProcessorRevision = 0;
DWORD ProcessorFeatures = 0;
DWORD ProcessorFeaturesEx = 0;
DWORD CEInstructionSet = PROCESSOR_X86_32BIT_INSTRUCTION;

DWORD dwFPType;

const wchar_t NKCpuType [] = TEXT("x86");

#define PtrCurThd  [KData].pCurThd
#define PtrCurProc  [KData].pCurPrc

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

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
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,
    PCONTEXT pctx,
    int id,
    int level
    ) 
{
    NKDbgPrintfW(L"Exception %02x Thread=%8.8lx AKY=%8.8lx EIP=%8.8lx\r\n",
            id, pth, pCurThread->aky, pctx->Eip);
    NKDbgPrintfW(L"Eax=%8.8lx Ebx=%8.8lx Ecx=%8.8lx Edx=%8.8lx\r\n",
            pctx->Eax, pctx->Ebx, pctx->Ecx, pctx->Edx);
    NKDbgPrintfW(L"Esi=%8.8lx Edi=%8.8lx Ebp=%8.8lx Esp=%8.8lx\r\n",
            pctx->Esi, pctx->Edi, pctx->Ebp, pctx->Esp);
    NKDbgPrintfW(L"CS=%4.4lx DS=%4.4lx ES=%4.4lx SS=%4.4lx FS=%4.4lx GS=%4.4lx\r\n",
            pctx->SegCs, pctx->SegDs, pctx->SegEs, pctx->SegSs, pctx->SegFs, pctx->SegGs);
    NKDbgPrintfW(L"Flags=%8.8lx\r\n",
            pctx->EFlags);
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
DumpTctx(
    PTHREAD pth,
    int id,
    ulong addr,
    int level
    ) 
{
    ulong espValue, ssValue;
    if ((pth->ctx.TcxCs&0xFFFF) == KGDT_R0_CODE) {
        espValue = pth->ctx.TcxNotEsp+16;
        ssValue = KGDT_R0_DATA;
    } else {
        espValue = pth->ctx.TcxEsp;
        ssValue = pth->ctx.TcxSs;
    }
    NKDbgPrintfW(L"Exception %02x Thread=%8.8lx Proc=%8.8lx '%s'\r\n",
            id, pth, hCurProc, pCurProc->lpszProcName ? pCurProc->lpszProcName : L"");
    NKDbgPrintfW(L"EIP=%8.8lx AKY=%8.8lx Flags=%8.8lx EA=%8.8lx\r\n", 
            pth->ctx.TcxEip, pCurThread->aky, pth->ctx.TcxEFlags, addr);
    NKDbgPrintfW(L"Eax=%8.8lx Ebx=%8.8lx Ecx=%8.8lx Edx=%8.8lx\r\n",
            pth->ctx.TcxEax, pth->ctx.TcxEbx, pth->ctx.TcxEcx, pth->ctx.TcxEdx);
    NKDbgPrintfW(L"Esi=%8.8lx Edi=%8.8lx Ebp=%8.8lx Esp=%8.8lx\r\n",
            pth->ctx.TcxEsi, pth->ctx.TcxEdi, pth->ctx.TcxEbp, espValue);
    NKDbgPrintfW(L"CS=%4.4lx DS=%4.4lx ES=%4.4lx SS=%4.4lx FS=%4.4lx GS=%4.4lx\r\n",
            pth->ctx.TcxCs, pth->ctx.TcxDs, pth->ctx.TcxEs, ssValue,
            pth->ctx.TcxFs, pth->ctx.TcxGs);
    if (level > 1) {
        PDWORD pdw;
        int count = 16;
        addr = espValue;
        if (pth->ctx.TcxEbp >= espValue)
            count = (pth->ctx.TcxEbp+16 - espValue) / 4;
        pdw = VerifyAccess((PVOID)addr, VERIFY_KERNEL_OK, CurAKey);
        if (pdw)
            DumpDwords((PDWORD)addr, count);
    }
}

typedef struct ExcInfo {
    DWORD   linkage;
    ULONG   oldEip;
    UINT    oldMode0;
    UCHAR   id;
    UCHAR   oldTFlag;
    USHORT  error;
    ULONG   info;
    UCHAR   lowSp;
    UCHAR   pad[3];
} EXCINFO;
typedef EXCINFO *PEXCINFO;

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



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void SafeIdentifyCpu(void)
{
    __asm {

        pushfd
        cli

        pushfd                          // Save EFLAGS to stack
        pop     eax                     // Store EFLAGS in EAX
        mov     ecx,eax                 // Save in ECX for testing later
        xor     eax,00200000h           // Switch bit 21
        push    eax                     // Copy changed value to stack
        popfd                           // Save changed EAX to EFLAGS
        pushfd                          // Push EFLAGS to top of stack
        pop     eax                     // Store EFLAGS in EAX
        cmp     eax,ecx                 // See if bit 21 has changed
        jz      cpuid_trap              // If no change,no CPUID

        // CPUID is supported
        mov     eax, 1                  // get the family and stepping
        _emit   0fh                     // cpuid instruction
        _emit   0a2h
        mov     ebx, eax
        mov     ecx, eax
        shr     ebx, 4
        and     ebx, 0Fh                // (ebx) = model
        and     ecx, 0Fh                // (ecx) = stepping
        shr     eax, 8
        and     eax, 0Fh                // (eax) = family
        cmp     eax, 4
        jne     cpu_not_p4
        mov     eax, PROCESSOR_INTEL_486
        jmp     short cpuid_store
cpu_not_p4:
        cmp     eax, 5
        jne     short cpu_not_p5
        mov     eax, PROCESSOR_INTEL_PENTIUM
        jmp     short cpuid_store
cpu_not_p5:
        mov     eax, PROCESSOR_INTEL_PENTIUMII
cpuid_store:
        mov     CEProcessorType, eax
        mov     ProcessorLevel, bx
        mov     ProcessorRevision, cx
        mov     ProcessorFeatures, edx

        // Let's get extended CPUID data (EAX = 0x80000001)
        mov     eax, 0x80000001
        _emit   0fh                     // cpuid instruction
        _emit   0a2h
        mov     ProcessorFeaturesEx, edx

cpuid_trap:
        popfd
    }
}

#pragma warning(disable:4733)
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL 
HandleException(
    PTHREAD pth,
    int id,
    ulong addr
    ) 
{
    PEXCINFO pexi;
    DWORD stackaddr, *pArgs;
    KCALLPROFON(0);
#if 0
    NKDbgPrintfW(L"Exception %02x Thread=%8.8lx(%8.8lx) IP=%8.8lx EA=%8.8lx Err=%4.4x\r\n",
            id, pCurThread,pth, pth->ctx.TcxEip, addr, pth->ctx.TcxError & 0xFFFF);
#endif

    pexi = (struct ExcInfo *)((pth->ctx.TcxEsp & ~63) - 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);
        DumpTctx(pth, id, addr, 10);
        pth->ctx.TcxEsp = (DWORD) pth->tlsPtr - SIZE_PRETLS - 512;  // arbitrary safe address
        pArgs = (LPDWORD) pth->ctx.TcxEsp;
        pArgs[0] = 0;                       // no return address
        pArgs[1] = STATUS_STACK_OVERFLOW;   // argument, exception code
        pArgs[2] = pth->ctx.TcxEip;         // argument, exception address
        pth->ctx.TcxEip = (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);
        id = 0xFF;      // stack fault exception code
        addr = (DWORD)pexi;
        break;
    case DCMT_OLD:
        // already commited. do nothing
        break;
    default:
        DEBUGCHK (0);
    }

    // Setup to capture the exception context in kernel mode but
    // running in thread context to allow preemption and stack growth.
    if (pth->ctx.TcxEip != (ulong)CaptureContext) {
        pexi->id = id;
        pexi->lowSp = (CHAR)(pth->ctx.TcxEsp & 63);
        pexi->oldEip = pth->ctx.TcxEip;
        ((PCALLSTACK) pexi)->dwPrcInfo = CST_IN_KERNEL | ((KERNEL_MODE == GetThreadMode(pth))? 0 : CST_MODE_FROM_USER);
        pexi->info = addr;
        if (id != 16)
            pexi->error = (USHORT)pth->ctx.TcxError;
        else {
            WORD status;
            _asm fnstsw status;
            pexi->error = status;
            _asm fnclex;            
        }
        pexi->oldTFlag = (UCHAR)(pth->ctx.TcxEFlags >> 8) & 1;
        pexi->linkage = (DWORD)pCurThread->pcstkTop | 1;
        pCurThread->pcstkTop = (PCALLSTACK)pexi;
        pth->ctx.TcxEsp = (DWORD)pexi;
        pth->ctx.TcxEFlags &= ~0x0100; // Unset TF while in the debugger
        pth->ctx.TcxEip = (ulong)CaptureContext;
        //if (pexi->oldMode != KERNEL_MODE)
            SetThreadMode(pth, KERNEL_MODE);
        KCALLPROFOFF(0);
        return TRUE;            // continue execution
    }
    DumpTctx(pth, id, addr, 10);
    RETAILMSG(1, (TEXT("Halting thread %8.8lx\r\n"), pCurThread));
    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;



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL 
SetCPUHardwareWatch(
    LPVOID lpv,
    DWORD dwFlags
    ) 
{
    static PPROCESS pOwnerProc;
    
    if (!InSysCall()) 
        return KCall((PKFN)SetCPUHardwareWatch, lpv, dwFlags);
        
    KCALLPROFON(73);

    if (lpv == 0) {
        // dwFlags=0 means check to see if we want to take this breakpoint
        if (dwFlags == (DWORD)-1) {
            // check to see which breakpoint went off and
            // clear the debug register
            DWORD dwReason;
            DWORD dwMask=~0xf;
            _asm {
                mov eax, dr6
                mov dwReason, eax
                and eax, dwMask
                mov dr6, eax
            }
            // was the zeroptr breakpoint hit?
            if (dwReason&0x2 && pOwnerProc != pCurProc) {
                OutputDebugString(L"zero mapped breakpoint hit in wrong process!\r\n");
                KCALLPROFOFF(73);
                return 0;
            }
            KCALLPROFOFF(73);
            return 1;
        } else {
            // dwFlags=1 means disable the data watchpoint
            dwFlags = ~0xf;
            _asm {
                mov eax, dr7
                and eax, dwFlags
                mov dr7, eax
            }
            KCALLPROFOFF(73);
            return 1;
        }
    } else {
        DWORD dwMask=~0xff000f;
        LPVOID lpvZero=(LPVOID)UnMapPtr(lpv);
        if (dwFlags == HARDWARE_WATCH_READ) {
            dwFlags = 0xff000a;
        } else {
            dwFlags = 0xdd000a;
        }

⌨️ 快捷键说明

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