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

📄 kdbreak.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 4 页
字号:

    // Examine each entry in the table in turn
    for (Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index++)
    {
        if (g_aBreakpointTable [Index].wRefCount &&
            (g_aBreakpointTable [Index].Flags & KD_BREAKPOINT_SUSPENDED))
        {
            int bph = KdpInstantiateSwBreakpoint (Index + 1); // Attempt instantiations
            if (bph <= KD_BPHND_INVALID_GEN_ERR)
            {
                DEBUGGERMSG (KDZONE_SWBP, (L"  KdpReinstateSuspendedBreakpoints: Reinstate failed for BP %i (Addr=0x%08X)!\r\n",
                                           Index, g_aBreakpointTable [Index].Address));
            }
        }
    }
}


/*++

Routine Description:

    Suspend the breakpoint, if one exists, at the specified location.  It is assumed this routine
    will be called if the debugger "trips" over one of its own breakpoints which was set in code
    intended to be shared by KdStub.  This should allow stepping through such code.

    Note: currently, this function will not suspend more than one (1) breakpoint, under the
    assumption that KdpAddBreakpoint will not instantiate multiple breakpoints at the same location.

Arguments:

    Address - the address of the instruction that was just hit

Return Value:

    TRUE - there was a breakpoint at that location and it was suspended
    FALSE - otherwise

--*/

BOOLEAN KdpSuspendBreakpointIfHitByKd (void * pvAddress)
{ // TODO: Replace this with a call to KdpSuspendAllBreakpoints(). There is no reason to suspend only one.
    BOOLEAN fRet = FALSE;
    ULONG Index;
    BYTE* pbKAddr;

    DEBUGGERMSG (KDZONE_SWBP, (L"++KdpSuspendBreakpointIfHitByKd (0x%08X)\r\n", (DWORD) pvAddress));

    if (Is16BitSupported)
    {
        pvAddress = (void *) (((DWORD) pvAddress) & ~1);
    }

    pbKAddr = (BYTE *) MapToDebuggeeCtxKernEquivIfAcc ((BYTE *) pvAddress, FALSE); // Kernel equivalent

    for (Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index++)
    {
        BYTE *pbBpKAddr = MapToDebuggeeCtxKernEquivIfAcc ((BYTE *) (g_aBreakpointTable [Index].Address), TRUE);
        if (g_aBreakpointTable [Index].wRefCount &&
            !(g_aBreakpointTable [Index].Flags & KD_BREAKPOINT_SUSPENDED) &&
            (pbBpKAddr == pbKAddr))
        {
            fRet = KdpSuspendBreakpoint (Index);
        }
    }

    DEBUGGERMSG (KDZONE_SWBP, (L"--KdpSuspendBreakpointIfHitByKd (%d)\r\n", (int) fRet));

    return fRet;
}


/*++

Routine Description:

    Sanitize a region of memory.  If the specified region of memory contains a breakpoint, write the data
    into the output buffer as it would appear if there were no breakpoints.

    The memory address (pvAddress) is "slotized" relative to the current process' address space before being
    compared with addresses of breakpoints.

Arguments:

    pbClean:     Output buffer to which sanitized memory is written
    pvAddress:   First virtual address of the region of memory to be cleaned.  This must be the actual
                 address of the memory (so it can be matched against the breakpoint table) and it must
                 be readable.
    nSize:       Size of both the output buffer and the memory to be cleaned
    fAlwaysCopy: Copy the memory into the output buffer regardless of whether the memory contains a
                 breakpoint.  Normally, the memory is only copied if a breakpoint was present.

Return Value:

    TRUE  - there was a breakpoint in the specified range and it has been sanitized in the output buffer
    FALSE - otherwise

--*/

BOOL KdpSanitize (BYTE* pbClean, VOID* pvAddress, ULONG nSize, BOOL fAlwaysCopy)
{
    BOOL fRet = FALSE;
    ULONG iBp;
    BYTE* pbKAddr = (BYTE*) MapToDebuggeeCtxKernEquivIfAcc ((BYTE *) pvAddress, TRUE); // Kernel equivalent

    if (pbKAddr)
    {
        if (fAlwaysCopy)
        { // initialize the buffer
            KdpMoveMemory (pbClean, pbKAddr, nSize);
        }

        for (iBp = 0; iBp < BREAKPOINT_TABLE_SIZE; iBp++)
        {
            if (g_aBreakpointTable[iBp].wRefCount &&
                !(g_aBreakpointTable[iBp].Flags & KD_BREAKPOINT_SUSPENDED))
            {
                BYTE *pbBpKAddr = MapToDebuggeeCtxKernEquivIfAcc ((BYTE *) (g_aBreakpointTable [iBp].Address), TRUE);
                if (pbBpKAddr)
                {
                    ULONG nBpSize = sizeof (KDP_BREAKPOINT_TYPE);

#if defined(MIPSII) || defined(THUMBSUPPORT)
                    if (Is16BitSupported && (g_aBreakpointTable[iBp].Flags & KD_BREAKPOINT_16BIT))
                    {
                        nBpSize = sizeof (KDP_BREAKPOINT_16BIT_TYPE);
                    }
#endif
                    if ((pbKAddr < (pbBpKAddr + nBpSize)) &&
                        ((pbKAddr + nSize) > pbBpKAddr))
                    {
                        ULONG nCommonBytes = nBpSize;
                        BYTE* pbSrc = (BYTE*) &g_aBreakpointTable [iBp].Content;
                        BYTE* pbDst = pbClean + (pbBpKAddr - pbKAddr);
                        LONG  lDiff;

                        DEBUGGERMSG (KDZONE_SWBP, (L"  KdpSanitize: cleaning BP h=%d, addr=0x%08X\r\n", iBp + 1, pbBpKAddr));

                        // check for memory buffer beginning in the middle of the breakpoint
                        lDiff = pbKAddr - pbBpKAddr;
                        if (lDiff > 0)
                        {
                            pbSrc  += lDiff;
                            pbDst  += lDiff;
                            nCommonBytes -= lDiff;
                        }

                        // check for memory buffer ending in the middle of the breakpoint
                        lDiff = (pbBpKAddr + nBpSize) - (pbKAddr + nSize);
                        if (lDiff > 0)
                        {
                            nCommonBytes -= lDiff;
                        }

                        KD_ASSERT ((nCommonBytes > 0) && (nCommonBytes <= nBpSize));
                        KD_ASSERT ((pbClean <= pbDst) && ((pbDst + nCommonBytes) <= (pbClean + nSize)));

                        DEBUGGERMSG (KDZONE_SWBP, (L"  KdpSanitize: copy %d byte(s) from 0x%08X to 0x%08X\r\n", nCommonBytes, (DWORD)pbSrc, (DWORD)pbDst));

                        // initialize the clean buffer if it hasn't been done by now
                        if (!fRet && !fAlwaysCopy) memcpy (pbClean, pvAddress, nSize);

                        KdpMoveMemory (pbDst, pbSrc, nCommonBytes);

                        fRet = TRUE;
                    }
                }
                else
                {
                    g_aBreakpointTable [iBp].Flags |= KD_BREAKPOINT_SUSPENDED; // Assume that it is suspended since page is out (faster handling next time)
                }
            }
        }
    }

    return fRet;
}


VOID
KdpManipulateBreakPoint(
    IN DBGKD_COMMAND *pdbgkdCmdPacket,
    IN PSTRING AdditionalData
    )
/*++

Routine Description:

    This function is called in response of a manipulate breakpoint
    message.  Its function is to query/write/set a breakpoint
    and return a handle to the breakpoint.

Arguments:

    pdbgkdCmdPacket - Supplies the command message.

    AdditionalData - Supplies any additional data for the message.

Return Value:

    None.

--*/
{
    // TODO: Add support for physical address breakpoints
    DBGKD_MANIPULATE_BREAKPOINT *a = &pdbgkdCmdPacket->u.ManipulateBreakPoint;
    STRING MessageHeader;
    BOOL fSuccess = FALSE;
    DWORD dwExpAddDataSize;
    DWORD i;
    BOOL fHALBP=FALSE;
    KD_BPINFO bpInfo;

    MessageHeader.Length = sizeof (*pdbgkdCmdPacket);
    MessageHeader.Buffer = (PCHAR) pdbgkdCmdPacket;

    DEBUGGERMSG(KDZONE_BREAK, (L"++KdpManipulateBreakPoint\r\n"));

    if (a->dwMBpFlags & DBGKD_MBP_FLAG_DATABP)
    {
        dwExpAddDataSize = sizeof (DBGKD_DATA_BREAKPOINT_ELEM1);
    }
    else
    {
        dwExpAddDataSize = sizeof (DBGKD_CODE_BREAKPOINT_ELEM1);
    }
    dwExpAddDataSize *= a->dwBpCount;

    if (AdditionalData->Length != dwExpAddDataSize)
    {
        pdbgkdCmdPacket->dwReturnStatus = STATUS_UNSUCCESSFUL;
        KdpSendKdApiCmdPacket (&MessageHeader, AdditionalData);
        DEBUGGERMSG(KDZONE_BREAK, (L"  KdpManipulateBreakPoint: Length mismatch\n"));
    }

    DEBUGGERMSG(KDZONE_BREAK, (L"  KdpManipulateBreakPoint: dwBpCount = %ld\n", a->dwBpCount));
    for (i = 0; i < a->dwBpCount; i++)
    {
        if (a->dwMBpFlags & DBGKD_MBP_FLAG_DATABP)
        { // DATA BP
            // TODO: Add support for triggering on Register change and Data
            DBGKD_DATA_BREAKPOINT_ELEM1 *b = (DBGKD_DATA_BREAKPOINT_ELEM1 *) AdditionalData->Buffer;
            DEBUGGERMSG(KDZONE_BREAK, (L"  KdpManipulateBreakPoint: Address = %08X Flags=%08X dwBpHandle=%08X\n", b[i].dwAddress, b[i].wBpFlags, b[i].dwBpHandle));
            if (g_kdKernData.pKDIoControl)
            { // Try to Hardware Data BP
                if (a->dwMBpFlags & DBGKD_MBP_FLAG_SET)
                {
                    bpInfo.nVersion = 1;
                    bpInfo.ulAddress = ZeroPtr (b[i].dwAddress);
                    bpInfo.ulFlags = 0;
                    bpInfo.ulHandle = 0;
                    if (KDIoControl (KD_IOCTL_SET_DBP, &bpInfo, sizeof (KD_BPINFO)))
                    {
                        fSuccess = TRUE;
                        fHALBP = TRUE;
                        b[i].dwBpHandle = bpInfo.ulHandle | 0x80000000;
                        DEBUGGERMSG(KDZONE_BREAK, (L"  KdpManipulateBreakPoint: Set Hard DBP Address = %08X wBpFlags=%08X dwBpHandle=%08X\n", b[i].dwAddress, b[i].wBpFlags, b[i].dwBpHandle));
                    }
                }
                else if (b[i].dwBpHandle & 0x80000000)
                {
                    fHALBP = TRUE;
                    bpInfo.nVersion = 1;
                    bpInfo.ulHandle = b[i].dwBpHandle & 0x7FFFFFFF;
                    bpInfo.ulFlags = 0;
                    bpInfo.ulAddress = 0;
                    if (KDIoControl (KD_IOCTL_CLEAR_DBP, &bpInfo, sizeof(KD_BPINFO)))
                    {
                        DEBUGGERMSG(KDZONE_BREAK, (L"  KdpManipulateBreakPoint: Clear Hard DBP Address = %08X wBpFlags=%08X dwBpHandle=%08X\n", b[i].dwAddress, b[i].wBpFlags, b[i].dwBpHandle));
                        fSuccess = TRUE;
                    }
                }
            }
            if (!fHALBP)
            { // SW Data BP
                // TODO: Add support for DATA BP emulation
            }
        }
        else
        { // CODE BP
            DBGKD_CODE_BREAKPOINT_ELEM1 *b = (DBGKD_CODE_BREAKPOINT_ELEM1 *) AdditionalData->Buffer;
            DEBUGGERMSG(KDZONE_BREAK, (L"  KdpManipulateBreakPoint: Address = %08X Flags=%08X dwBpHandle=%08X\n", b[i].dwAddress, b[i].wBpFlags, b[i].dwBpHandle));
            if ((b[i].wBpFlags == DBGKD_BP_FLAG_SOFTWARE) && g_kdKernData.pKDIoControl)
            { // Try to Hardware Code BP
                if (a->dwMBpFlags & DBGKD_MBP_FLAG_SET)
                {
                    bpInfo.nVersion = 1;
                    bpInfo.ulAddress = ZeroPtr (b[i].dwAddress);
                    bpInfo.ulFlags = 0;
                    if (KDIoControl (KD_IOCTL_SET_CBP, &bpInfo, sizeof (KD_BPINFO)))
                    {
                        fSuccess = TRUE;
                        fHALBP = TRUE;
                        b[i].dwBpHandle = bpInfo.ulHandle | 0x80000000;
                        DEBUGGERMSG(KDZONE_BREAK, (L"  KdpManipulateBreakPoint: Set  Hard CBP Address = %08X wBpFlags=%08X dwBpHandle=%08X\n", b[i].dwAddress, b[i].wBpFlags, b[i].dwBpHandle));
                    }
                }
                else if (b[i].dwBpHandle & 0x80000000)
                {
                    fHALBP = TRUE;
                    bpInfo.nVersion = 1;
                    bpInfo.ulHandle = b[i].dwBpHandle & 0x7FFFFFFF;
                    bpInfo.ulFlags = 0;
                    if (KDIoControl (KD_IOCTL_CLEAR_CBP, &bpInfo, sizeof(KD_BPINFO)))
                    {
                        fSuccess = TRUE;
                        DEBUGGERMSG(KDZONE_BREAK, (L"  KdpManipulateBreakPoint: Clear  Hard CBP Address = %08X wBpFlags=%08X dwBpHandle=%08X\n", b[i].dwAddress, b[i].wBpFlags, b[i].dwBpHandle));
                    }
                }
            }
            if (!fHALBP)
            { // SW Data BP
                if (a->dwMBpFlags & DBGKD_MBP_FLAG_SET)
                {
                    b[i].wBpFlags |= DBGKD_BP_FLAG_SOFTWARE;

                    if (Is16BitSupported && (b[i].wBpExecMode == DBGKD_EXECMODE_16BIT)) b[i].dwAddress |= 0x1;

                    if (b[i].dwBpHandle = KdpAddBreakpoint ((PVOID) b[i].dwAddress))
                    {
                        DEBUGGERMSG(KDZONE_BREAK, (L"  KdpManipulateBreakPoint: Set Soft CBP Address = %08X wBpFlags=%08X dwBpHandle=%08X\n", b[i].dwAddress, b[i].wBpFlags, b[i].dwBpHandle));
                        fSuccess = TRUE;
                    }
                }
                else
                {
                    if (KdpDeleteBreakpoint (b[i].dwBpHandle))
                    {
                        DEBUGGERMSG(KDZONE_BREAK, (L"  KdpManipulateBreakPoint: Clear Soft CBP dwBpHandle=%08X\n", b[i].dwBpHandle));
                        fSuccess = TRUE;
                    }
                }
            }
        }
    }

    if (fSuccess)
    {
         pdbgkdCmdPacket->dwReturnStatus = fSuccess ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
    }
    a->NbBpAvail.dwNbHwCodeBpAvail = 0; // TODO: Get this from OAL
    a->NbBpAvail.dwNbSwCodeBpAvail = BREAKPOINT_TABLE_SIZE - g_nTotalNumDistinctSwCodeBps;
    a->NbBpAvail.dwNbHwDataBpAvail = 0; // TODO: Get this from OAL
    a->NbBpAvail.dwNbSwDataBpAvail = 0;
    DEBUGGERMSG (KDZONE_BREAK, (L"--KdpManipulateBreakPoint Status = %ld\n", pdbgkdCmdPacket->dwReturnStatus));
    KdpSendKdApiCmdPacket (&MessageHeader, AdditionalData);
    return;
}

⌨️ 快捷键说明

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