VirtualBox

Changeset 86234 in vbox


Ignore:
Timestamp:
Sep 23, 2020 12:15:27 PM (4 years ago)
Author:
vboxsync
Message:

Debugger/DBGCRemoteKd: Emulate DR<n> registers in order to transparently support hardware breakpoints from WinDbg (lightly tested)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Debugger/DBGCRemoteKd.cpp

    r86187 r86234  
    11241124
    11251125/**
     1126 * KD emulated hardware breakpoint.
     1127 */
     1128typedef struct KDCTXHWBP
     1129{
     1130    /** The DBGF breakpoint handle if active, UINT32_MAX if not active. */
     1131    uint32_t                    iDbgfBp;
     1132    /** The linear address of the breakpoint if active. */
     1133    RTGCPTR                     GCPtrBp;
     1134    /** Access type of the breakpoint, see X86_DR7_RW_*. */
     1135    uint8_t                     fAcc;
     1136    /** Length flags of the breakpoint. */
     1137    uint8_t                     fLen;
     1138    /** Flag whether it is a local breakpoint. */
     1139    bool                        fLocal;
     1140    /** Flag whether it is a global breakpoint. */
     1141    bool                        fGlobal;
     1142    /** Flag whether the breakpoint has triggered since the last time of the reset. */
     1143    bool                        fTriggered;
     1144} KDCTXHWBP;
     1145/** Pointer to an emulated hardware breakpoint. */
     1146typedef KDCTXHWBP *PKDCTXHWBP;
     1147/** Pointer to a const emulated hardware breakpoint. */
     1148typedef const KDCTXHWBP *PCKDCTXHWBP;
     1149
     1150
     1151/**
    11261152 * KD context data.
    11271153 */
     
    11591185    bool                        fInVBoxDbg;
    11601186
     1187    /** Emulated hardware breakpoint handling. */
     1188    KDCTXHWBP                   aHwBp[4];
     1189    /** Flag whether a single step completed since last time this was cleared. */
     1190    bool                        fSingleStepped;
     1191
    11611192    /** Pointer to the OS digger WinNt interface if a matching guest was detected. */
    11621193    PDBGFOSIWINNT               pIfWinNt;
     
    11811212*   Internal Functions                                                                                                           *
    11821213*********************************************************************************************************************************/
     1214
     1215static void dbgcKdCtxMsgSend(PKDCTX pThis, bool fWarning, const char *pszMsg);
    11831216
    11841217
     
    14231456
    14241457/**
     1458 * Resets the emulated hardware breakpoint state to a state similar after a reboot.
     1459 *
     1460 * @returns nothing.
     1461 * @param   pThis               The KD context.
     1462 */
     1463static void dbgcKdCtxHwBpReset(PKDCTX pThis)
     1464{
     1465    pThis->fSingleStepped = false;
     1466
     1467    for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aHwBp); i++)
     1468    {
     1469        PKDCTXHWBP pBp = &pThis->aHwBp[i];
     1470
     1471        if (pBp->iDbgfBp != UINT32_MAX)
     1472        {
     1473            int rc = DBGFR3BpClear(pThis->Dbgc.pUVM, pBp->iDbgfBp);
     1474            AssertRC(rc);
     1475        }
     1476
     1477        pBp->iDbgfBp    = UINT32_MAX;
     1478        pBp->GCPtrBp    = 0;
     1479        pBp->fAcc       = 0;
     1480        pBp->fLen       = 0;
     1481        pBp->fLocal     = false;
     1482        pBp->fGlobal    = false;
     1483        pBp->fTriggered = false;
     1484    }
     1485}
     1486
     1487
     1488/**
     1489 * Updates the given breakpoint with the given properties.
     1490 *
     1491 * @returns VBox status code.
     1492 * @param   pThis               The KD context.
     1493 * @param   pBp                 The breakpoint to update.
     1494 * @param   fAcc                Access mode.
     1495 * @param   fLen                Access length.
     1496 * @param   fGlobal             Global breakpoint.
     1497 * @param   fLocal              Local breakpoint.
     1498 * @param   GCPtrBp             Linear address of the breakpoint.
     1499 */
     1500static int dbgcKdCtxHwBpUpdate(PKDCTX pThis, PKDCTXHWBP pBp, uint8_t fAcc, uint8_t fLen,
     1501                               bool fGlobal, bool fLocal, RTGCPTR GCPtrBp)
     1502{
     1503    int rc = VINF_SUCCESS;
     1504
     1505    /* Did anything actually change?. */
     1506    if (   pBp->fAcc != fAcc
     1507        || pBp->fLen != fLen
     1508        || pBp->fGlobal != fGlobal
     1509        || pBp->fLocal != fLocal
     1510        || pBp->GCPtrBp != GCPtrBp)
     1511    {
     1512        /* Clear the old breakpoint. */
     1513        if (pBp->iDbgfBp != UINT32_MAX)
     1514        {
     1515            rc = DBGFR3BpClear(pThis->Dbgc.pUVM, pBp->iDbgfBp);
     1516            AssertRC(rc);
     1517            pBp->iDbgfBp = UINT32_MAX;
     1518        }
     1519
     1520        pBp->fAcc    = fAcc;
     1521        pBp->fLen    = fLen;
     1522        pBp->fGlobal = fGlobal;
     1523        pBp->fLocal  = fLocal;
     1524        pBp->GCPtrBp = GCPtrBp;
     1525        if (pBp->fGlobal || pBp->fLocal)
     1526        {
     1527            DBGFADDRESS AddrBp;
     1528            DBGFR3AddrFromFlat(pThis->Dbgc.pUVM, &AddrBp, GCPtrBp);
     1529
     1530            uint8_t cb = 0;
     1531            switch (pBp->fLen)
     1532            {
     1533                case X86_DR7_LEN_BYTE:
     1534                    cb = 1;
     1535                    break;
     1536                case X86_DR7_LEN_WORD:
     1537                    cb = 2;
     1538                    break;
     1539                case X86_DR7_LEN_DWORD:
     1540                    cb = 4;
     1541                    break;
     1542                case X86_DR7_LEN_QWORD:
     1543                    cb = 8;
     1544                    break;
     1545                default:
     1546                    AssertFailed();
     1547                    return VERR_NET_PROTOCOL_ERROR;
     1548            }
     1549
     1550            rc = DBGFR3BpSetReg(pThis->Dbgc.pUVM, &AddrBp, 0 /*iHitTrigger*/, UINT64_MAX /*iHitDisable*/,
     1551                                pBp->fAcc, cb, &pBp->iDbgfBp);
     1552        }
     1553    }
     1554
     1555    return rc;
     1556}
     1557
     1558
     1559/**
     1560 * Updates emulated hardware breakpoints based on the written DR7 value.
     1561 *
     1562 * @returns VBox status code.
     1563 * @param   pThis               The KD context.
     1564 * @param   uDr7                The DR7 value which is written.
     1565 */
     1566static int dbgcKdCtxHwBpDr7Update(PKDCTX pThis, uint32_t uDr7)
     1567{
     1568    int rc = VINF_SUCCESS;
     1569
     1570    for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aHwBp); i++)
     1571    {
     1572        PKDCTXHWBP pBp = &pThis->aHwBp[i];
     1573        uint8_t fAcc = X86_DR7_GET_RW(uDr7, i);
     1574        uint8_t fLen = X86_DR7_GET_LEN(uDr7, i);
     1575        bool fGlobal = (uDr7 & RT_BIT_32(1 + i * 2)) ? true : false;
     1576        bool fLocal = (uDr7 & RT_BIT_32(i * 2)) ? true : false;
     1577
     1578        int rc2 = dbgcKdCtxHwBpUpdate(pThis, pBp, fAcc, fLen, fGlobal, fLocal, pThis->aHwBp[i].GCPtrBp);
     1579        if (   RT_FAILURE(rc2)
     1580            && RT_SUCCESS(rc))
     1581            rc = rc2;
     1582    }
     1583
     1584    return rc;
     1585}
     1586
     1587
     1588/**
     1589 * Updates the linear guest pointer for the given hardware breakpoint.
     1590 *
     1591 * @returns VBox status code.
     1592 * @param   pThis               The KD context.
     1593 * @param   pBp                 The breakpoint to update.
     1594 * @param   GCPtrBp             The linear breakpoint address.
     1595 */
     1596DECLINLINE(int) dbgcKdCtxHwBpGCPtrUpdate(PKDCTX pThis, PKDCTXHWBP pBp, RTGCPTR GCPtrBp)
     1597{
     1598    return dbgcKdCtxHwBpUpdate(pThis, pBp, pBp->fAcc, pBp->fLen, pBp->fGlobal, pBp->fLocal, GCPtrBp);
     1599}
     1600
     1601
     1602/**
     1603 * Calculates the DR7 value based on the emulated hardware breakpoint state and returns it.
     1604 *
     1605 * @returns The emulated DR7 value.
     1606 * @param   pThis               The KD context.
     1607 */
     1608static uint32_t dbgcKdCtxHwBpDr7Get(PKDCTX pThis)
     1609{
     1610    uint32_t uDr7 = 0;
     1611
     1612    uDr7 |= X86_DR7_RW(0, pThis->aHwBp[0].fAcc);
     1613    uDr7 |= X86_DR7_RW(1, pThis->aHwBp[1].fAcc);
     1614    uDr7 |= X86_DR7_RW(2, pThis->aHwBp[2].fAcc);
     1615    uDr7 |= X86_DR7_RW(3, pThis->aHwBp[3].fAcc);
     1616
     1617    uDr7 |= X86_DR7_LEN(0, pThis->aHwBp[0].fLen);
     1618    uDr7 |= X86_DR7_LEN(1, pThis->aHwBp[1].fLen);
     1619    uDr7 |= X86_DR7_LEN(2, pThis->aHwBp[2].fLen);
     1620    uDr7 |= X86_DR7_LEN(3, pThis->aHwBp[3].fLen);
     1621
     1622    uDr7 |= pThis->aHwBp[0].fGlobal ? X86_DR7_G(0) : 0;
     1623    uDr7 |= pThis->aHwBp[1].fGlobal ? X86_DR7_G(1) : 0;
     1624    uDr7 |= pThis->aHwBp[2].fGlobal ? X86_DR7_G(2) : 0;
     1625    uDr7 |= pThis->aHwBp[3].fGlobal ? X86_DR7_G(3) : 0;
     1626
     1627    uDr7 |= pThis->aHwBp[0].fLocal ? X86_DR7_L(0) : 0;
     1628    uDr7 |= pThis->aHwBp[1].fLocal ? X86_DR7_L(1) : 0;
     1629    uDr7 |= pThis->aHwBp[2].fLocal ? X86_DR7_L(2) : 0;
     1630    uDr7 |= pThis->aHwBp[3].fLocal ? X86_DR7_L(3) : 0;
     1631
     1632    return uDr7;
     1633}
     1634
     1635
     1636/**
     1637 * Updates emulated hardware breakpoints based on the written DR6 value.
     1638 *
     1639 * @returns nothing.
     1640 * @param   pThis               The KD context.
     1641 * @param   uDr6                The DR7 value which is written.
     1642 */
     1643static void dbgcKdCtxHwBpDr6Update(PKDCTX pThis, uint32_t uDr6)
     1644{
     1645    pThis->aHwBp[0].fTriggered = (uDr6 & X86_DR6_B0) ? true : false;
     1646    pThis->aHwBp[1].fTriggered = (uDr6 & X86_DR6_B1) ? true : false;
     1647    pThis->aHwBp[2].fTriggered = (uDr6 & X86_DR6_B2) ? true : false;
     1648    pThis->aHwBp[3].fTriggered = (uDr6 & X86_DR6_B3) ? true : false;
     1649    pThis->fSingleStepped = (uDr6 & X86_DR6_BS) ? true : false;
     1650}
     1651
     1652
     1653/**
     1654 * Calculates the DR6 value based on the emulated hardware breakpoint state and returns it.
     1655 *
     1656 * @returns The emulated DR6 value.
     1657 * @param   pThis               The KD context.
     1658 */
     1659static uint32_t dbgcKdCtxHwBpDr6Get(PKDCTX pThis)
     1660{
     1661    uint32_t uDr6 = 0;
     1662
     1663    if (pThis->aHwBp[0].fTriggered)
     1664        uDr6 |= X86_DR6_B0;
     1665    if (pThis->aHwBp[1].fTriggered)
     1666        uDr6 |= X86_DR6_B1;
     1667    if (pThis->aHwBp[2].fTriggered)
     1668        uDr6 |= X86_DR6_B2;
     1669    if (pThis->aHwBp[3].fTriggered)
     1670        uDr6 |= X86_DR6_B3;
     1671    if (pThis->fSingleStepped)
     1672        uDr6 |= X86_DR6_BS;
     1673
     1674    return uDr6;
     1675}
     1676
     1677
     1678/**
    14251679 * Wrapper for the I/O interface write callback.
    14261680 *
     
    15271781        && fCtxFlags & NTCONTEXT_F_DEBUG)
    15281782    {
    1529         /** @todo. */
     1783        /** @todo */
    15301784    }
    15311785
     
    17091963
    17101964    if (fCtxFlags & NTCONTEXT_F_DEBUG)
    1711     {
    1712         /** @todo. */
    1713     }
     1965        dbgcKdCtxMsgSend(pThis, true /*fWarning*/, "Setting local DR registers does not work!");
    17141966
    17151967    return DBGFR3RegNmSetBatch(pThis->Dbgc.pUVM, idCpu, &aRegsSet[0], idxReg);
     
    17391991    if (RT_SUCCESS(rc))
    17401992        rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, idCpu, DBGFREG_CR8, &pKNtCtx->u64RegCr8);
    1741     if (RT_SUCCESS(rc))
    1742         rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR0, &pKNtCtx->u64RegDr0);
    1743     if (RT_SUCCESS(rc))
    1744         rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR1, &pKNtCtx->u64RegDr1);
    1745     if (RT_SUCCESS(rc))
    1746         rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR2, &pKNtCtx->u64RegDr2);
    1747     if (RT_SUCCESS(rc))
    1748         rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR3, &pKNtCtx->u64RegDr3);
    1749     if (RT_SUCCESS(rc))
    1750         rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR6, &pKNtCtx->u64RegDr6);
    1751     if (RT_SUCCESS(rc))
    1752         rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR7, &pKNtCtx->u64RegDr7);
    17531993    if (RT_SUCCESS(rc))
    17541994        rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, idCpu, DBGFREG_GDTR_LIMIT, &pKNtCtx->Gdtr.u16Limit);
     
    17652005    if (RT_SUCCESS(rc))
    17662006        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_MXCSR, &pKNtCtx->u32RegMxCsr);
    1767     /** @todo Debug control and stuff. */
    17682007
    17692008    if (RT_SUCCESS(rc))
     
    17812020    /** @todo XCR0 */
    17822021
     2022    /* Get the emulated DR register state. */
     2023    pKNtCtx->u64RegDr0 = pThis->aHwBp[0].GCPtrBp;
     2024    pKNtCtx->u64RegDr1 = pThis->aHwBp[1].GCPtrBp;
     2025    pKNtCtx->u64RegDr2 = pThis->aHwBp[2].GCPtrBp;
     2026    pKNtCtx->u64RegDr3 = pThis->aHwBp[3].GCPtrBp;
     2027    pKNtCtx->u64RegDr6 = dbgcKdCtxHwBpDr6Get(pThis);
     2028    pKNtCtx->u64RegDr7 = dbgcKdCtxHwBpDr7Get(pThis);
     2029
    17832030    if (RT_SUCCESS(rc))
    17842031        rc = dbgcKdCtxQueryNtCtx64(pThis, idCpu, &pKNtCtx->Ctx, fCtxFlags);
     
    18082055        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_CR4, &pKNtCtx->u32RegCr4);
    18092056
    1810     if (RT_SUCCESS(rc))
    1811         rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR0, &pKNtCtx->u32RegDr0);
    1812     if (RT_SUCCESS(rc))
    1813         rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR1, &pKNtCtx->u32RegDr1);
    1814     if (RT_SUCCESS(rc))
    1815         rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR2, &pKNtCtx->u32RegDr2);
    1816     if (RT_SUCCESS(rc))
    1817         rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR3, &pKNtCtx->u32RegDr3);
    1818     if (RT_SUCCESS(rc))
    1819         rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR6, &pKNtCtx->u32RegDr6);
    1820     if (RT_SUCCESS(rc))
    1821         rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR7, &pKNtCtx->u32RegDr7);
    18222057    if (RT_SUCCESS(rc))
    18232058        rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, idCpu, DBGFREG_GDTR_LIMIT, &pKNtCtx->Gdtr.u16Limit);
     
    18332068        rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, idCpu, DBGFREG_LDTR, &pKNtCtx->u16RegLdtr);
    18342069
     2070    /* Get the emulated DR register state. */
     2071    pKNtCtx->u32RegDr0 = (uint32_t)pThis->aHwBp[0].GCPtrBp;
     2072    pKNtCtx->u32RegDr1 = (uint32_t)pThis->aHwBp[1].GCPtrBp;
     2073    pKNtCtx->u32RegDr2 = (uint32_t)pThis->aHwBp[2].GCPtrBp;
     2074    pKNtCtx->u32RegDr3 = (uint32_t)pThis->aHwBp[3].GCPtrBp;
     2075    pKNtCtx->u32RegDr6 = dbgcKdCtxHwBpDr6Get(pThis);
     2076    pKNtCtx->u32RegDr7 = dbgcKdCtxHwBpDr7Get(pThis);
     2077
    18352078    return rc;
    18362079}
     
    18582101    KD_REG_INIT_U64("cr4", pKNtCtx->u64RegCr4);
    18592102    KD_REG_INIT_U64("cr8", pKNtCtx->u64RegCr8);
    1860     KD_REG_INIT_U64("dr0", pKNtCtx->u64RegDr0);
    1861     KD_REG_INIT_U64("dr1", pKNtCtx->u64RegDr1);
    1862     KD_REG_INIT_U64("dr2", pKNtCtx->u64RegDr2);
    1863     KD_REG_INIT_U64("dr3", pKNtCtx->u64RegDr3);
    1864     KD_REG_INIT_U64("dr6", pKNtCtx->u64RegDr6);
    1865     KD_REG_INIT_U64("dr7", pKNtCtx->u64RegDr7);
    18662103
    18672104    KD_REG_INIT_DTR("gdtr", pKNtCtx->Gdtr.u64PtrBase, pKNtCtx->Gdtr.u16Limit);
     
    18852122        && cbSet > RT_UOFFSETOF(NTKCONTEXT64, Ctx)) /** @todo Probably wrong. */
    18862123        rc = dbgcKdCtxSetNtCtx64(pThis, idCpu, &pKNtCtx->Ctx, pKNtCtx->Ctx.fContext);
     2124
     2125    if (RT_SUCCESS(rc))
     2126    {
     2127        /* Update emulated hardware breakpoint state. */
     2128        dbgcKdCtxHwBpDr6Update(pThis, (uint32_t)pKNtCtx->u64RegDr6);
     2129        rc = dbgcKdCtxHwBpDr7Update(pThis, (uint32_t)pKNtCtx->u64RegDr7);
     2130        if (RT_SUCCESS(rc))
     2131            rc = dbgcKdCtxHwBpGCPtrUpdate(pThis, &pThis->aHwBp[0], pKNtCtx->u64RegDr0);
     2132        if (RT_SUCCESS(rc))
     2133            rc = dbgcKdCtxHwBpGCPtrUpdate(pThis, &pThis->aHwBp[1], pKNtCtx->u64RegDr1);
     2134        if (RT_SUCCESS(rc))
     2135            rc = dbgcKdCtxHwBpGCPtrUpdate(pThis, &pThis->aHwBp[2], pKNtCtx->u64RegDr2);
     2136        if (RT_SUCCESS(rc))
     2137            rc = dbgcKdCtxHwBpGCPtrUpdate(pThis, &pThis->aHwBp[3], pKNtCtx->u64RegDr3);
     2138    }
    18872139
    18882140    return rc;
     
    22502502
    22512503/**
     2504 * Sends a message to the remotes end.
     2505 *
     2506 * @returns nothing.
     2507 * @param   pThis               The KD context data.
     2508 * @param   fWarning            Flag whether this is a warning or an informational message.
     2509 * @param   pszMsg              The message to send.
     2510 */
     2511static void dbgcKdCtxMsgSend(PKDCTX pThis, bool fWarning, const char *pszMsg)
     2512{
     2513    size_t cchMsg = strlen(pszMsg);
     2514
     2515    KDPACKETDEBUGIO DebugIo;
     2516    RT_ZERO(DebugIo);
     2517
     2518    DebugIo.u32Type     = KD_PACKET_DEBUG_IO_STRING;
     2519    DebugIo.u16CpuLvl   = 0x6;
     2520    DebugIo.idCpu       = 0;
     2521
     2522    RTSGSEG aRespSegs[5];
     2523
     2524    aRespSegs[0].pvSeg = &DebugIo;
     2525    aRespSegs[0].cbSeg = sizeof(DebugIo);
     2526    aRespSegs[1].pvSeg = (void *)"VBoxDbg ";
     2527    aRespSegs[1].cbSeg = sizeof("VBoxDbg ") - 1;
     2528    if (fWarning)
     2529    {
     2530        aRespSegs[2].pvSeg = (void *)"WARNING ";
     2531        aRespSegs[2].cbSeg = sizeof("WARNING ") - 1;
     2532    }
     2533    else
     2534    {
     2535        aRespSegs[2].pvSeg = (void *)"INFO ";
     2536        aRespSegs[2].cbSeg = sizeof("INFO ") - 1;
     2537    }
     2538    aRespSegs[3].pvSeg = (void *)pszMsg;
     2539    aRespSegs[3].cbSeg = cchMsg;
     2540    aRespSegs[4].pvSeg = (void *)"\r\n";
     2541    aRespSegs[4].cbSeg = 2;
     2542
     2543    DebugIo.u.Str.cbStr =   aRespSegs[1].cbSeg
     2544                          + aRespSegs[2].cbSeg
     2545                          + aRespSegs[3].cbSeg
     2546                          + aRespSegs[4].cbSeg;
     2547
     2548    int rc = dbgcKdCtxPktSendSg(pThis, KD_PACKET_HDR_SIGNATURE_DATA, KD_PACKET_HDR_SUB_TYPE_DEBUG_IO,
     2549                                &aRespSegs[0], RT_ELEMENTS(aRespSegs), true /*fAck*/);
     2550    if (RT_SUCCESS(rc))
     2551        pThis->idPktNext ^= 0x1;
     2552}
     2553
     2554
     2555/**
    22522556 * Queries some user input from the remotes end.
    22532557 *
     
    23322636            case DBGFEVENT_STEPPED:
    23332637            case DBGFEVENT_STEPPED_HYPER:
     2638                pThis->fSingleStepped = true; /* For emulation of DR6. */
    23342639                StateChange64.u.Exception.ExcpRec.u32ExcpCode = KD_PACKET_EXCP_CODE_SINGLE_STEP;
    23352640                break;
     
    25602865{
    25612866    int rc = VINF_SUCCESS;
     2867
     2868    /* Update DR7. */
     2869    if (pThis->f32Bit)
     2870        rc = dbgcKdCtxHwBpDr7Update(pThis, pPktManip->u.Continue2.u.x86.u32RegDr7);
     2871    else
     2872        rc = dbgcKdCtxHwBpDr7Update(pThis, (uint32_t)pPktManip->u.Continue2.u.amd64.u64RegDr7);
    25622873
    25632874    /* Resume if not single stepping, the single step will get a state change when the VM stepped. */
     
    30723383            break;
    30733384        }
     3385        case KD_PACKET_MANIPULATE_REQ_REBOOT:
     3386        {
     3387            rc = VMR3Reset(pThis->Dbgc.pUVM); /* Doesn't expect an answer here. */
     3388            break;
     3389        }
    30743390        default:
    30753391            KDPACKETMANIPULATEHDR RespHdr;
     
    30903406
    30913407/**
     3408 * Tries to detect the guest OS running in the VM looking specifically for the Windows NT kind.
     3409 *
     3410 * @returns Nothing.
     3411 * @param   pThis               The KD context.
     3412 */
     3413static void dbgcKdCtxDetectGstOs(PKDCTX pThis)
     3414{
     3415    pThis->pIfWinNt = NULL;
     3416
     3417    /* Try detecting a Windows NT guest. */
     3418    char szName[64];
     3419    int rc = DBGFR3OSDetect(pThis->Dbgc.pUVM, szName, sizeof(szName));
     3420    if (RT_SUCCESS(rc))
     3421    {
     3422        pThis->pIfWinNt = (PDBGFOSIWINNT)DBGFR3OSQueryInterface(pThis->Dbgc.pUVM, DBGFOSINTERFACE_WINNT);
     3423        if (pThis->pIfWinNt)
     3424            LogRel(("DBGC/Kd: Detected Windows NT guest OS (%s)\n", &szName[0]));
     3425        else
     3426            LogRel(("DBGC/Kd: Detected guest OS is not of the Windows NT kind (%s)\n", &szName[0]));
     3427    }
     3428    else
     3429    {
     3430        LogRel(("DBGC/Kd: Unable to detect any guest operating system type, rc=%Rrc\n", rc));
     3431        rc = VINF_SUCCESS; /* Try to continue nevertheless. */
     3432    }
     3433
     3434    if (pThis->pIfWinNt)
     3435    {
     3436        rc = pThis->pIfWinNt->pfnQueryVersion(pThis->pIfWinNt, pThis->Dbgc.pUVM,
     3437                                              NULL /*puVersMajor*/, NULL /*puVersMinor*/,
     3438                                              NULL /*puBuildNumber*/, &pThis->f32Bit);
     3439        AssertRC(rc);
     3440    }
     3441    else
     3442    {
     3443        /*
     3444         * Try to detect bitness based on the current CPU mode which might fool us (32bit process running
     3445         * inside of 64bit host).
     3446         */
     3447        CPUMMODE enmMode = DBGCCmdHlpGetCpuMode(&pThis->Dbgc.CmdHlp);
     3448        if (enmMode == CPUMMODE_PROTECTED)
     3449            pThis->f32Bit = true;
     3450        else if (enmMode == CPUMMODE_LONG)
     3451            pThis->f32Bit = false;
     3452        else
     3453            LogRel(("DBGC/Kd: Heh, trying to debug real mode code with WinDbg are we? Good luck with that...\n"));
     3454    }
     3455}
     3456
     3457
     3458/**
    30923459 * Processes a fully received packet.
    30933460 *
     
    31233490                case KD_PACKET_HDR_SUB_TYPE_RESET:
    31243491                {
     3492                    dbgcKdCtxDetectGstOs(pThis);
     3493
    31253494                    pThis->idPktNext = 0;
    31263495                    rc = dbgcKdCtxPktSendReset(pThis);
     
    34263795            }
    34273796
     3797            /* Figure out the breakpoint and set the triggered flag for emulation of DR6. */
     3798            for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aHwBp); i++)
     3799            {
     3800                if (pThis->aHwBp[i].iDbgfBp == pEvent->u.Bp.iBp)
     3801                {
     3802                    pThis->aHwBp[i].fTriggered = true;
     3803                    break;
     3804                }
     3805            }
     3806
    34283807            rc = dbgcKdCtxStateChangeSend(pThis, pEvent->enmType);
    34293808            break;
     
    34333812        case DBGFEVENT_STEPPED_HYPER:
    34343813        {
     3814            pThis->fSingleStepped = true; /* For emulation of DR6. */
    34353815            rc = dbgcKdCtxStateChangeSend(pThis, pEvent->enmType);
    34363816            break;
     
    37574137    dbgcKdCtxPktRecvReset(pThis);
    37584138
     4139    for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aHwBp); i++)
     4140    {
     4141        PKDCTXHWBP pBp = &pThis->aHwBp[i];
     4142        pBp->iDbgfBp = UINT32_MAX;
     4143    }
     4144
     4145    dbgcKdCtxHwBpReset(pThis);
     4146
    37594147    *ppKdCtx = pThis;
    37604148    return VINF_SUCCESS;
     
    38254213            pThis->Dbgc.pUVM  = pUVM;
    38264214            pThis->Dbgc.idCpu = 0;
    3827 
    3828             /* Try detecting a Windows NT guest. */
    3829             char szName[64];
    3830             rc = DBGFR3OSDetect(pUVM, szName, sizeof(szName));
    3831             if (RT_SUCCESS(rc))
    3832             {
    3833                 pThis->pIfWinNt = (PDBGFOSIWINNT)DBGFR3OSQueryInterface(pUVM, DBGFOSINTERFACE_WINNT);
    3834                 if (pThis->pIfWinNt)
    3835                     LogRel(("DBGC/Kd: Detected Windows NT guest OS (%s)\n", &szName[0]));
    3836                 else
    3837                     LogRel(("DBGC/Kd: Detected guest OS is not of the Windows NT kind (%s)\n", &szName[0]));
    3838             }
    3839             else
    3840             {
    3841                 LogRel(("DBGC/Kd: Unable to detect any guest operating system type, rc=%Rrc\n", rc));
    3842                 rc = VINF_SUCCESS; /* Try to continue nevertheless. */
    3843             }
    3844 
    3845             if (pThis->pIfWinNt)
    3846             {
    3847                 rc = pThis->pIfWinNt->pfnQueryVersion(pThis->pIfWinNt, pThis->Dbgc.pUVM,
    3848                                                       NULL /*puVersMajor*/, NULL /*puVersMinor*/,
    3849                                                       NULL /*puBuildNumber*/, &pThis->f32Bit);
    3850                 AssertRC(rc);
    3851             }
    3852             else
    3853             {
    3854                 /*
    3855                  * Try to detect bitness based on the current CPU mode which might fool us (32bit process running
    3856                  * inside of 64bit host).
    3857                  */
    3858                 CPUMMODE enmMode = DBGCCmdHlpGetCpuMode(&pThis->Dbgc.CmdHlp);
    3859                 if (enmMode == CPUMMODE_PROTECTED)
    3860                     pThis->f32Bit = true;
    3861                 else if (enmMode == CPUMMODE_LONG)
    3862                     pThis->f32Bit = false;
    3863                 else
    3864                     LogRel(("DBGC/Kd: Heh, trying to debug real mode code with WinDbg are we? Good luck with that...\n"));
    3865             }
    38664215        }
    38674216        else
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette