Changeset 86234 in vbox
- Timestamp:
- Sep 23, 2020 12:15:27 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Debugger/DBGCRemoteKd.cpp
r86187 r86234 1124 1124 1125 1125 /** 1126 * KD emulated hardware breakpoint. 1127 */ 1128 typedef 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. */ 1146 typedef KDCTXHWBP *PKDCTXHWBP; 1147 /** Pointer to a const emulated hardware breakpoint. */ 1148 typedef const KDCTXHWBP *PCKDCTXHWBP; 1149 1150 1151 /** 1126 1152 * KD context data. 1127 1153 */ … … 1159 1185 bool fInVBoxDbg; 1160 1186 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 1161 1192 /** Pointer to the OS digger WinNt interface if a matching guest was detected. */ 1162 1193 PDBGFOSIWINNT pIfWinNt; … … 1181 1212 * Internal Functions * 1182 1213 *********************************************************************************************************************************/ 1214 1215 static void dbgcKdCtxMsgSend(PKDCTX pThis, bool fWarning, const char *pszMsg); 1183 1216 1184 1217 … … 1423 1456 1424 1457 /** 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 */ 1463 static 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 */ 1500 static 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 */ 1566 static 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 */ 1596 DECLINLINE(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 */ 1608 static 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 */ 1643 static 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 */ 1659 static 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 /** 1425 1679 * Wrapper for the I/O interface write callback. 1426 1680 * … … 1527 1781 && fCtxFlags & NTCONTEXT_F_DEBUG) 1528 1782 { 1529 /** @todo .*/1783 /** @todo */ 1530 1784 } 1531 1785 … … 1709 1963 1710 1964 if (fCtxFlags & NTCONTEXT_F_DEBUG) 1711 { 1712 /** @todo. */ 1713 } 1965 dbgcKdCtxMsgSend(pThis, true /*fWarning*/, "Setting local DR registers does not work!"); 1714 1966 1715 1967 return DBGFR3RegNmSetBatch(pThis->Dbgc.pUVM, idCpu, &aRegsSet[0], idxReg); … … 1739 1991 if (RT_SUCCESS(rc)) 1740 1992 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);1753 1993 if (RT_SUCCESS(rc)) 1754 1994 rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, idCpu, DBGFREG_GDTR_LIMIT, &pKNtCtx->Gdtr.u16Limit); … … 1765 2005 if (RT_SUCCESS(rc)) 1766 2006 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_MXCSR, &pKNtCtx->u32RegMxCsr); 1767 /** @todo Debug control and stuff. */1768 2007 1769 2008 if (RT_SUCCESS(rc)) … … 1781 2020 /** @todo XCR0 */ 1782 2021 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 1783 2030 if (RT_SUCCESS(rc)) 1784 2031 rc = dbgcKdCtxQueryNtCtx64(pThis, idCpu, &pKNtCtx->Ctx, fCtxFlags); … … 1808 2055 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_CR4, &pKNtCtx->u32RegCr4); 1809 2056 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);1822 2057 if (RT_SUCCESS(rc)) 1823 2058 rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, idCpu, DBGFREG_GDTR_LIMIT, &pKNtCtx->Gdtr.u16Limit); … … 1833 2068 rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, idCpu, DBGFREG_LDTR, &pKNtCtx->u16RegLdtr); 1834 2069 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 1835 2078 return rc; 1836 2079 } … … 1858 2101 KD_REG_INIT_U64("cr4", pKNtCtx->u64RegCr4); 1859 2102 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);1866 2103 1867 2104 KD_REG_INIT_DTR("gdtr", pKNtCtx->Gdtr.u64PtrBase, pKNtCtx->Gdtr.u16Limit); … … 1885 2122 && cbSet > RT_UOFFSETOF(NTKCONTEXT64, Ctx)) /** @todo Probably wrong. */ 1886 2123 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 } 1887 2139 1888 2140 return rc; … … 2250 2502 2251 2503 /** 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 */ 2511 static 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 /** 2252 2556 * Queries some user input from the remotes end. 2253 2557 * … … 2332 2636 case DBGFEVENT_STEPPED: 2333 2637 case DBGFEVENT_STEPPED_HYPER: 2638 pThis->fSingleStepped = true; /* For emulation of DR6. */ 2334 2639 StateChange64.u.Exception.ExcpRec.u32ExcpCode = KD_PACKET_EXCP_CODE_SINGLE_STEP; 2335 2640 break; … … 2560 2865 { 2561 2866 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); 2562 2873 2563 2874 /* Resume if not single stepping, the single step will get a state change when the VM stepped. */ … … 3072 3383 break; 3073 3384 } 3385 case KD_PACKET_MANIPULATE_REQ_REBOOT: 3386 { 3387 rc = VMR3Reset(pThis->Dbgc.pUVM); /* Doesn't expect an answer here. */ 3388 break; 3389 } 3074 3390 default: 3075 3391 KDPACKETMANIPULATEHDR RespHdr; … … 3090 3406 3091 3407 /** 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 */ 3413 static 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 /** 3092 3459 * Processes a fully received packet. 3093 3460 * … … 3123 3490 case KD_PACKET_HDR_SUB_TYPE_RESET: 3124 3491 { 3492 dbgcKdCtxDetectGstOs(pThis); 3493 3125 3494 pThis->idPktNext = 0; 3126 3495 rc = dbgcKdCtxPktSendReset(pThis); … … 3426 3795 } 3427 3796 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 3428 3807 rc = dbgcKdCtxStateChangeSend(pThis, pEvent->enmType); 3429 3808 break; … … 3433 3812 case DBGFEVENT_STEPPED_HYPER: 3434 3813 { 3814 pThis->fSingleStepped = true; /* For emulation of DR6. */ 3435 3815 rc = dbgcKdCtxStateChangeSend(pThis, pEvent->enmType); 3436 3816 break; … … 3757 4137 dbgcKdCtxPktRecvReset(pThis); 3758 4138 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 3759 4147 *ppKdCtx = pThis; 3760 4148 return VINF_SUCCESS; … … 3825 4213 pThis->Dbgc.pUVM = pUVM; 3826 4214 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 else3837 LogRel(("DBGC/Kd: Detected guest OS is not of the Windows NT kind (%s)\n", &szName[0]));3838 }3839 else3840 {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 else3853 {3854 /*3855 * Try to detect bitness based on the current CPU mode which might fool us (32bit process running3856 * 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 else3864 LogRel(("DBGC/Kd: Heh, trying to debug real mode code with WinDbg are we? Good luck with that...\n"));3865 }3866 4215 } 3867 4216 else
Note:
See TracChangeset
for help on using the changeset viewer.