Changeset 86165 in vbox
- Timestamp:
- Sep 18, 2020 9:54:18 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Debugger/DBGCRemoteKd.cpp
r86160 r86165 59 59 * From: https://www.geoffchappell.com/studies/windows/km/ntoskrnl/structs/kprcb/amd64.htm */ 60 60 #define KD_KPCR_VERSION_BLOCK_ADDR_OFF 0x34 61 61 62 62 63 /********************************************************************************************************************************* … … 249 250 250 251 /** 251 * [GI]DT descriptor.252 * 64bit [GI]DT descriptor. 252 253 */ 253 254 typedef struct NTKCONTEXTDESC64 … … 261 262 } NTKCONTEXTDESC64; 262 263 AssertCompileSize(NTKCONTEXTDESC64, 2 * 8); 263 /** Pointer to a n amd64 NT context. */264 /** Pointer to a 64bit [GI]DT descriptor. */ 264 265 typedef NTKCONTEXTDESC64 *PNTKCONTEXTDESC64; 265 /** Pointer to a const amd64 NT context. */266 /** Pointer to a const 64bit [GI]DT descriptor. */ 266 267 typedef const NTKCONTEXTDESC64 *PCNTKCONTEXTDESC64; 267 268 … … 335 336 336 337 338 /** 339 * 32bit context FPU save area. 340 */ 341 typedef struct NTCONTEXT32_FPU_SAVE_AREA 342 { 343 uint32_t u32CtrlWord; 344 uint32_t u32StatusWord; 345 uint32_t u32TagWord; 346 uint32_t u32ErrorOff; 347 uint32_t u32ErrorSel; 348 uint32_t u32DataOff; 349 uint32_t u32DataSel; 350 uint8_t abRegArea[80]; 351 uint32_t u32Cr0Npx; 352 } NTCONTEXT32_FPU_SAVE_AREA; 353 /** Pointer to an 32bit context FPU save area. */ 354 typedef NTCONTEXT32_FPU_SAVE_AREA *PNTCONTEXT32_FPU_SAVE_AREA; 355 /** Pointer to a const 32bit context FPU save area. */ 356 typedef const NTCONTEXT32_FPU_SAVE_AREA *PCNTCONTEXT32_FPU_SAVE_AREA; 357 358 359 /** 360 * i386 NT context structure. 361 */ 362 typedef struct NTCONTEXT32 363 { 364 /** Context flags indicating the valid bits, see NTCONTEXT_F_XXX. */ 365 uint32_t fContext; 366 /** DR0 register. */ 367 uint32_t u32RegDr0; 368 /** DR1 register. */ 369 uint32_t u32RegDr1; 370 /** DR2 register. */ 371 uint32_t u32RegDr2; 372 /** DR3 register. */ 373 uint32_t u32RegDr3; 374 /** DR6 register. */ 375 uint32_t u32RegDr6; 376 /** DR7 register. */ 377 uint32_t u32RegDr7; 378 /** Floating point save area. */ 379 NTCONTEXT32_FPU_SAVE_AREA FloatSave; 380 /** GS segment. */ 381 uint32_t u32SegGs; 382 /** FS segment. */ 383 uint32_t u32SegFs; 384 /** ES segment. */ 385 uint32_t u32SegEs; 386 /** DS segment. */ 387 uint32_t u32SegDs; 388 /** EDI register. */ 389 uint32_t u32RegEdi; 390 /** ESI register. */ 391 uint32_t u32RegEsi; 392 /** EBX register. */ 393 uint32_t u32RegEbx; 394 /** EDX register. */ 395 uint32_t u32RegEdx; 396 /** ECX register. */ 397 uint32_t u32RegEcx; 398 /** EAX register. */ 399 uint32_t u32RegEax; 400 /** EBP register. */ 401 uint32_t u32RegEbp; 402 /** EIP register. */ 403 uint32_t u32RegEip; 404 /** CS segment. */ 405 uint32_t u32SegCs; 406 /** EFLAGS register. */ 407 uint32_t u32RegEflags; 408 /** ESP register. */ 409 uint32_t u32RegEsp; 410 /** SS segment. */ 411 uint32_t u32SegSs; 412 /** @todo Extended registers */ 413 uint8_t abRegsExtended[512]; 414 } NTCONTEXT32; 415 AssertCompileSize(NTCONTEXT32, 716); 416 /** Pointer to an i386 NT context. */ 417 typedef NTCONTEXT32 *PNTCONTEXT32; 418 /** Pointer to a const i386 NT context. */ 419 typedef const NTCONTEXT32 *PCNTCONTEXT32; 420 421 422 /** 423 * 32bit [GI]DT descriptor. 424 */ 425 typedef struct NTKCONTEXTDESC32 426 { 427 /** Alignment. */ 428 uint16_t u16Alignment; 429 /** Limit. */ 430 uint16_t u16Limit; 431 /** Base address. */ 432 uint32_t u32PtrBase; 433 } NTKCONTEXTDESC32; 434 AssertCompileSize(NTKCONTEXTDESC32, 2 * 4); 435 /** Pointer to an 32bit [GI]DT descriptor. */ 436 typedef NTKCONTEXTDESC32 *PNTKCONTEXTDESC32; 437 /** Pointer to a const 32bit [GI]DT descriptor. */ 438 typedef const NTKCONTEXTDESC32 *PCNTKCONTEXTDESC32; 439 440 441 /** 442 * 32bit Kernel context as queried by KD_PACKET_MANIPULATE_REQ_READ_CTRL_SPACE 443 */ 444 typedef struct NTKCONTEXT32 445 { 446 /** CR0 register. */ 447 uint32_t u32RegCr0; 448 /** CR2 register. */ 449 uint32_t u32RegCr2; 450 /** CR3 register. */ 451 uint32_t u32RegCr3; 452 /** CR4 register. */ 453 uint32_t u32RegCr4; 454 /** DR0 register. */ 455 uint32_t u32RegDr0; 456 /** DR1 register. */ 457 uint32_t u32RegDr1; 458 /** DR2 register. */ 459 uint32_t u32RegDr2; 460 /** DR3 register. */ 461 uint32_t u32RegDr3; 462 /** DR6 register. */ 463 uint32_t u32RegDr6; 464 /** DR7 register. */ 465 uint32_t u32RegDr7; 466 /** GDTR. */ 467 NTKCONTEXTDESC32 Gdtr; 468 /** IDTR. */ 469 NTKCONTEXTDESC32 Idtr; 470 /** TR register. */ 471 uint16_t u16RegTr; 472 /** LDTR register. */ 473 uint16_t u16RegLdtr; 474 /** Padding. */ 475 uint8_t abPad[24]; 476 } NTKCONTEXT32; 477 AssertCompileSize(NTKCONTEXT32, 84); 478 /** Pointer to an i386 NT context. */ 479 typedef NTKCONTEXT32 *PNTKCONTEXT32; 480 /** Pointer to a const i386 NT context. */ 481 typedef const NTKCONTEXT32 *PCNTKCONTEXT32; 482 483 337 484 /** x86 context. */ 338 485 #define NTCONTEXT_F_X86 UINT32_C(0x00010000) … … 905 1052 /** Pointer to the OS digger WinNt interface if a matching guest was detected. */ 906 1053 PDBGFOSIWINNT pIfWinNt; 1054 /** Flag whether the detected guest is 32bit (false if 64bit). */ 1055 bool f32Bit; 907 1056 } KDCTX; 908 1057 /** Pointer to the KD context data. */ … … 912 1061 /** Pointer to a KD context data pointer. */ 913 1062 typedef PKDCTX *PPKDCTX; 1063 1064 1065 /** Creates a possibly sign extended guest context pointer which is required for 32bit targets. */ 1066 #define KD_PTR_CREATE(a_pThis, a_GCPtr) ((a_pThis)->f32Bit && ((a_GCPtr) & RT_BIT_32(31)) ? (a_GCPtr) | UINT64_C(0xffffffff00000000) : (a_GCPtr)) 1067 /** Returns the value of a possibly sign extended guest context pointer received for 32bit targets. */ 1068 #define KD_PTR_GET(a_pThis, a_GCPtr) ((a_pThis)->f32Bit ? (a_GCPtr) & ~UINT64_C(0xffffffff00000000) : (a_GCPtr)) 914 1069 915 1070 … … 1253 1408 1254 1409 1410 /** 1411 * Fills in the given 32bit NT context structure with the requested values. 1412 * 1413 * @returns VBox status code. 1414 * @param pThis The KD context. 1415 * @param idCpu The CPU to query the context for. 1416 * @param pNtCtx The NT context structure to fill in. 1417 * @param fCtxFlags Combination of NTCONTEXT_F_XXX determining what to fill in. 1418 */ 1419 static int dbgcKdCtxQueryNtCtx32(PKDCTX pThis, VMCPUID idCpu, PNTCONTEXT32 pNtCtx, uint32_t fCtxFlags) 1420 { 1421 RT_BZERO(pNtCtx, sizeof(*pNtCtx)); 1422 1423 pNtCtx->fContext = NTCONTEXT_F_X86; 1424 1425 int rc = VINF_SUCCESS; 1426 if (fCtxFlags & NTCONTEXT_F_CONTROL) 1427 { 1428 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_CS, &pNtCtx->u32SegCs); 1429 if (RT_SUCCESS(rc)) 1430 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_SS, &pNtCtx->u32SegSs); 1431 if (RT_SUCCESS(rc)) 1432 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_EIP, &pNtCtx->u32RegEip); 1433 if (RT_SUCCESS(rc)) 1434 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_ESP, &pNtCtx->u32RegEsp); 1435 if (RT_SUCCESS(rc)) 1436 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_EBP, &pNtCtx->u32RegEbp); 1437 if (RT_SUCCESS(rc)) 1438 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_EFLAGS, &pNtCtx->u32RegEflags); 1439 if (RT_SUCCESS(rc)) 1440 pNtCtx->fContext |= NTCONTEXT_F_CONTROL; 1441 } 1442 1443 if ( RT_SUCCESS(rc) 1444 && fCtxFlags & NTCONTEXT_F_INTEGER) 1445 { 1446 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_EAX, &pNtCtx->u32RegEax); 1447 if (RT_SUCCESS(rc)) 1448 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_ECX, &pNtCtx->u32RegEcx); 1449 if (RT_SUCCESS(rc)) 1450 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_EDX, &pNtCtx->u32RegEdx); 1451 if (RT_SUCCESS(rc)) 1452 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_EBX, &pNtCtx->u32RegEbx); 1453 if (RT_SUCCESS(rc)) 1454 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_ESI, &pNtCtx->u32RegEsi); 1455 if (RT_SUCCESS(rc)) 1456 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_EDI, &pNtCtx->u32RegEdi); 1457 if (RT_SUCCESS(rc)) 1458 pNtCtx->fContext |= NTCONTEXT_F_INTEGER; 1459 } 1460 1461 if ( RT_SUCCESS(rc) 1462 && fCtxFlags & NTCONTEXT_F_SEGMENTS) 1463 { 1464 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DS, &pNtCtx->u32SegDs); 1465 if (RT_SUCCESS(rc)) 1466 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_ES, &pNtCtx->u32SegEs); 1467 if (RT_SUCCESS(rc)) 1468 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_FS, &pNtCtx->u32SegFs); 1469 if (RT_SUCCESS(rc)) 1470 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_GS, &pNtCtx->u32SegGs); 1471 if (RT_SUCCESS(rc)) 1472 pNtCtx->fContext |= NTCONTEXT_F_SEGMENTS; 1473 } 1474 1475 if ( RT_SUCCESS(rc) 1476 && fCtxFlags & NTCONTEXT_F_FLOATING_POINT) 1477 { 1478 /** @todo. */ 1479 } 1480 1481 if ( RT_SUCCESS(rc) 1482 && fCtxFlags & NTCONTEXT_F_DEBUG) 1483 { 1484 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR0, &pNtCtx->u32RegDr0); 1485 if (RT_SUCCESS(rc)) 1486 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR1, &pNtCtx->u32RegDr1); 1487 if (RT_SUCCESS(rc)) 1488 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR3, &pNtCtx->u32RegDr3); 1489 if (RT_SUCCESS(rc)) 1490 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR6, &pNtCtx->u32RegDr6); 1491 if (RT_SUCCESS(rc)) 1492 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR7, &pNtCtx->u32RegDr7); 1493 if (RT_SUCCESS(rc)) 1494 pNtCtx->fContext |= NTCONTEXT_F_DEBUG; 1495 } 1496 1497 return rc; 1498 } 1499 1500 1255 1501 #define KD_REG_INIT(a_pszName, a_enmType, a_ValMember, a_Val) \ 1256 1502 do \ … … 1417 1663 1418 1664 /** 1665 * Fills in the given 32bit NT kernel context structure with the requested values. 1666 * 1667 * @returns VBox status code. 1668 * @param pThis The KD context. 1669 * @param idCpu The CPU to query the context for. 1670 * @param pKNtCtx The NT context structure to fill in. 1671 */ 1672 static int dbgcKdCtxQueryNtKCtx32(PKDCTX pThis, VMCPUID idCpu, PNTKCONTEXT32 pKNtCtx) 1673 { 1674 RT_BZERO(pKNtCtx, sizeof(*pKNtCtx)); 1675 1676 int rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_CR0, &pKNtCtx->u32RegCr0); 1677 if (RT_SUCCESS(rc)) 1678 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_CR2, &pKNtCtx->u32RegCr2); 1679 if (RT_SUCCESS(rc)) 1680 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_CR3, &pKNtCtx->u32RegCr3); 1681 if (RT_SUCCESS(rc)) 1682 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_CR4, &pKNtCtx->u32RegCr4); 1683 1684 if (RT_SUCCESS(rc)) 1685 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR0, &pKNtCtx->u32RegDr0); 1686 if (RT_SUCCESS(rc)) 1687 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR1, &pKNtCtx->u32RegDr1); 1688 if (RT_SUCCESS(rc)) 1689 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR2, &pKNtCtx->u32RegDr2); 1690 if (RT_SUCCESS(rc)) 1691 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR3, &pKNtCtx->u32RegDr3); 1692 if (RT_SUCCESS(rc)) 1693 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR6, &pKNtCtx->u32RegDr6); 1694 if (RT_SUCCESS(rc)) 1695 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR7, &pKNtCtx->u32RegDr7); 1696 if (RT_SUCCESS(rc)) 1697 rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, idCpu, DBGFREG_GDTR_LIMIT, &pKNtCtx->Gdtr.u16Limit); 1698 if (RT_SUCCESS(rc)) 1699 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_GDTR_BASE, &pKNtCtx->Gdtr.u32PtrBase); 1700 if (RT_SUCCESS(rc)) 1701 rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, idCpu, DBGFREG_IDTR_LIMIT, &pKNtCtx->Idtr.u16Limit); 1702 if (RT_SUCCESS(rc)) 1703 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_IDTR_BASE, &pKNtCtx->Idtr.u32PtrBase); 1704 if (RT_SUCCESS(rc)) 1705 rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, idCpu, DBGFREG_TR, &pKNtCtx->u16RegTr); 1706 if (RT_SUCCESS(rc)) 1707 rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, idCpu, DBGFREG_LDTR, &pKNtCtx->u16RegLdtr); 1708 1709 return rc; 1710 } 1711 1712 1713 /** 1419 1714 * Fills in the given 64bit NT kernel context structure with the requested values. 1420 1715 * … … 1802 2097 /* Select the record to send based on the CPU mode. */ 1803 2098 int rc = VINF_SUCCESS; 1804 CPUMMODE enmMode = DBGCCmdHlpGetCpuMode(&pThis->Dbgc.CmdHlp); 1805 switch (enmMode) 1806 { 1807 case CPUMMODE_PROTECTED: 1808 { 1809 break; 1810 } 1811 case CPUMMODE_LONG: 1812 { 1813 KDPACKETSTATECHANGE64 StateChange64; 1814 RT_ZERO(StateChange64); 1815 1816 StateChange64.u32StateNew = KD_PACKET_STATE_CHANGE_EXCEPTION; 1817 StateChange64.u16CpuLvl = 0x6; /** @todo Figure this one out. */ 1818 StateChange64.idCpu = pThis->Dbgc.idCpu; 1819 StateChange64.cCpus = (uint16_t)DBGFR3CpuGetCount(pThis->Dbgc.pUVM); 1820 rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_RIP, &StateChange64.u64RipThread); 1821 if (RT_SUCCESS(rc)) 1822 { 1823 /** @todo Properly fill in the exception record. */ 1824 switch (enmType) 1825 { 1826 case DBGFEVENT_HALT_DONE: 1827 case DBGFEVENT_BREAKPOINT: 1828 case DBGFEVENT_BREAKPOINT_IO: 1829 case DBGFEVENT_BREAKPOINT_MMIO: 1830 case DBGFEVENT_BREAKPOINT_HYPER: 1831 StateChange64.u.Exception.ExcpRec.u32ExcpCode = KD_PACKET_EXCP_CODE_BKPT; 1832 break; 1833 case DBGFEVENT_STEPPED: 1834 case DBGFEVENT_STEPPED_HYPER: 1835 StateChange64.u.Exception.ExcpRec.u32ExcpCode = KD_PACKET_EXCP_CODE_SINGLE_STEP; 1836 break; 1837 default: 1838 AssertMsgFailed(("Invalid DBGF event type for state change %d!\n", enmType)); 1839 } 1840 1841 StateChange64.u.Exception.ExcpRec.cExcpParms = 3; 1842 StateChange64.u.Exception.u32FirstChance = 0x1; 1843 1844 /** @todo Properly fill in the control report. */ 1845 rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_DR6, &StateChange64.uCtrlReport.Amd64.u64RegDr6); 1846 if (RT_SUCCESS(rc)) 1847 rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_DR7, &StateChange64.uCtrlReport.Amd64.u64RegDr7); 1848 if (RT_SUCCESS(rc)) 1849 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_RFLAGS, &StateChange64.uCtrlReport.Amd64.u32RegEflags); 1850 if (RT_SUCCESS(rc)) 1851 rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_CS, &StateChange64.uCtrlReport.Amd64.u16SegCs); 1852 if (RT_SUCCESS(rc)) 1853 rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_DS, &StateChange64.uCtrlReport.Amd64.u16SegDs); 1854 if (RT_SUCCESS(rc)) 1855 rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_ES, &StateChange64.uCtrlReport.Amd64.u16SegEs); 1856 if (RT_SUCCESS(rc)) 1857 rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_FS, &StateChange64.uCtrlReport.Amd64.u16SegFs); 1858 1859 /* Read instruction bytes. */ 1860 StateChange64.uCtrlReport.Amd64.cbInsnStream = sizeof(StateChange64.uCtrlReport.Amd64.abInsn); 1861 DBGFADDRESS AddrRip; 1862 DBGFR3AddrFromFlat(pThis->Dbgc.pUVM, &AddrRip, StateChange64.u64RipThread); 1863 rc = DBGFR3MemRead(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, &AddrRip, 1864 &StateChange64.uCtrlReport.Amd64.abInsn[0], StateChange64.uCtrlReport.Amd64.cbInsnStream); 1865 if (RT_SUCCESS(rc)) 1866 { 1867 pThis->idPktNext = KD_PACKET_HDR_ID_INITIAL; 1868 rc = dbgcKdCtxPktSend(pThis, KD_PACKET_HDR_SIGNATURE_DATA, KD_PACKET_HDR_SUB_TYPE_STATE_CHANGE64, 1869 &StateChange64, sizeof(StateChange64), false /*fAck*/); 1870 } 1871 } 1872 break; 1873 } 1874 case CPUMMODE_REAL: 1875 default: 1876 return DBGCCmdHlpPrintf(&pThis->Dbgc.CmdHlp, "error: Invalid CPU mode %d.\n", enmMode); 2099 KDPACKETSTATECHANGE64 StateChange64; 2100 RT_ZERO(StateChange64); 2101 2102 StateChange64.u32StateNew = KD_PACKET_STATE_CHANGE_EXCEPTION; 2103 StateChange64.u16CpuLvl = 0x6; /** @todo Figure this one out. */ 2104 StateChange64.idCpu = pThis->Dbgc.idCpu; 2105 StateChange64.cCpus = (uint16_t)DBGFR3CpuGetCount(pThis->Dbgc.pUVM); 2106 rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_RIP, &StateChange64.u64RipThread); 2107 if (RT_SUCCESS(rc)) 2108 { 2109 DBGFADDRESS AddrRip; 2110 DBGFR3AddrFromFlat(pThis->Dbgc.pUVM, &AddrRip, StateChange64.u64RipThread); 2111 2112 StateChange64.u64RipThread = KD_PTR_CREATE(pThis, StateChange64.u64RipThread); 2113 2114 /** @todo Properly fill in the exception record. */ 2115 switch (enmType) 2116 { 2117 case DBGFEVENT_HALT_DONE: 2118 case DBGFEVENT_BREAKPOINT: 2119 case DBGFEVENT_BREAKPOINT_IO: 2120 case DBGFEVENT_BREAKPOINT_MMIO: 2121 case DBGFEVENT_BREAKPOINT_HYPER: 2122 StateChange64.u.Exception.ExcpRec.u32ExcpCode = KD_PACKET_EXCP_CODE_BKPT; 2123 break; 2124 case DBGFEVENT_STEPPED: 2125 case DBGFEVENT_STEPPED_HYPER: 2126 StateChange64.u.Exception.ExcpRec.u32ExcpCode = KD_PACKET_EXCP_CODE_SINGLE_STEP; 2127 break; 2128 default: 2129 AssertMsgFailed(("Invalid DBGF event type for state change %d!\n", enmType)); 2130 } 2131 2132 StateChange64.u.Exception.ExcpRec.cExcpParms = 3; 2133 StateChange64.u.Exception.u32FirstChance = 0x1; 2134 2135 /** @todo Properly fill in the control report. */ 2136 rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_DR6, &StateChange64.uCtrlReport.Amd64.u64RegDr6); 2137 if (RT_SUCCESS(rc)) 2138 rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_DR7, &StateChange64.uCtrlReport.Amd64.u64RegDr7); 2139 if (RT_SUCCESS(rc)) 2140 rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_RFLAGS, &StateChange64.uCtrlReport.Amd64.u32RegEflags); 2141 if (RT_SUCCESS(rc)) 2142 rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_CS, &StateChange64.uCtrlReport.Amd64.u16SegCs); 2143 if (RT_SUCCESS(rc)) 2144 rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_DS, &StateChange64.uCtrlReport.Amd64.u16SegDs); 2145 if (RT_SUCCESS(rc)) 2146 rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_ES, &StateChange64.uCtrlReport.Amd64.u16SegEs); 2147 if (RT_SUCCESS(rc)) 2148 rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_FS, &StateChange64.uCtrlReport.Amd64.u16SegFs); 2149 2150 /* Read instruction bytes. */ 2151 StateChange64.uCtrlReport.Amd64.cbInsnStream = sizeof(StateChange64.uCtrlReport.Amd64.abInsn); 2152 rc = DBGFR3MemRead(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, &AddrRip, 2153 &StateChange64.uCtrlReport.Amd64.abInsn[0], StateChange64.uCtrlReport.Amd64.cbInsnStream); 2154 if (RT_SUCCESS(rc)) 2155 { 2156 pThis->idPktNext = KD_PACKET_HDR_ID_INITIAL; 2157 rc = dbgcKdCtxPktSend(pThis, KD_PACKET_HDR_SIGNATURE_DATA, KD_PACKET_HDR_SUB_TYPE_STATE_CHANGE64, 2158 &StateChange64, sizeof(StateChange64), false /*fAck*/); 2159 } 1877 2160 } 1878 2161 … … 1917 2200 Resp.u.GetVersion.u16VersMin = NtBuildNumber & UINT32_C(0xffff); 1918 2201 Resp.u.GetVersion.u8VersProtocol = 0x6; /* From a Windows 10 guest. */ 1919 Resp.u.GetVersion.u8VersKdSecondary = 0x2; /* From a Windows 10 guest. */2202 Resp.u.GetVersion.u8VersKdSecondary = pThis->f32Bit ? 0 : 0x2; /* amd64 has a versioned context (0 and 1 are obsolete). */ 1920 2203 Resp.u.GetVersion.fFlags = KD_PACKET_MANIPULATE64_GET_VERSION_F_MP; 1921 2204 Resp.u.GetVersion.u8MaxPktType = KD_PACKET_HDR_SUB_TYPE_MAX; … … 1925 2208 1926 2209 if (f32Bit) 1927 Resp.u.GetVersion.u16MachineType = IMAGE_FILE_MACHINE_I386; 2210 { 2211 Resp.u.GetVersion.u16MachineType = IMAGE_FILE_MACHINE_I386; 2212 Resp.u.GetVersion.u64PtrKernBase = KD_PTR_CREATE(pThis, Resp.u.GetVersion.u64PtrKernBase); 2213 Resp.u.GetVersion.u64PtrPsLoadedModuleList = KD_PTR_CREATE(pThis, Resp.u.GetVersion.u64PtrPsLoadedModuleList); 2214 } 1928 2215 else 1929 2216 { … … 1954 2241 uint32_t cbRead = RT_MIN(sizeof(abMem), pPktManip->u.XferMem.cbXferReq); 1955 2242 if (pPktManip->Hdr.idReq == KD_PACKET_MANIPULATE_REQ_READ_VIRT_MEM) 1956 DBGFR3AddrFromFlat(pThis->Dbgc.pUVM, &AddrRead, pPktManip->u.XferMem.u64PtrTarget);2243 DBGFR3AddrFromFlat(pThis->Dbgc.pUVM, &AddrRead, KD_PTR_GET(pThis, pPktManip->u.XferMem.u64PtrTarget)); 1957 2244 else 1958 DBGFR3AddrFromPhys(pThis->Dbgc.pUVM, &AddrRead, pPktManip->u.XferMem.u64PtrTarget);2245 DBGFR3AddrFromPhys(pThis->Dbgc.pUVM, &AddrRead, KD_PTR_GET(pThis, pPktManip->u.XferMem.u64PtrTarget)); 1959 2246 1960 2247 RTSGSEG aRespSegs[3]; … … 2006 2293 uint32_t cbWrite = RT_MIN(sizeof(pThis->abBody) - sizeof(*pPktManip), pPktManip->u.XferMem.cbXferReq); 2007 2294 if (pPktManip->Hdr.idReq == KD_PACKET_MANIPULATE_REQ_WRITE_VIRT_MEM) 2008 DBGFR3AddrFromFlat(pThis->Dbgc.pUVM, &AddrWrite, pPktManip->u.XferMem.u64PtrTarget);2295 DBGFR3AddrFromFlat(pThis->Dbgc.pUVM, &AddrWrite, KD_PTR_GET(pThis, pPktManip->u.XferMem.u64PtrTarget)); 2009 2296 else 2010 DBGFR3AddrFromPhys(pThis->Dbgc.pUVM, &AddrWrite, pPktManip->u.XferMem.u64PtrTarget);2297 DBGFR3AddrFromPhys(pThis->Dbgc.pUVM, &AddrWrite, KD_PTR_GET(pThis, pPktManip->u.XferMem.u64PtrTarget)); 2011 2298 2012 2299 RTSGSEG aRespSegs[2]; … … 2153 2440 2154 2441 int rc = VINF_SUCCESS; 2155 switch (pPktManip->u.XferCtrlSpace.u64IdXfer) 2156 { 2157 case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KPCR: 2158 { 2159 if (pThis->pIfWinNt) 2442 if (pThis->f32Bit) 2443 { 2444 if (pPktManip->u.XferCtrlSpace.u64IdXfer == sizeof(NTCONTEXT32)) 2445 { 2446 /* Queries the kernel context. */ 2447 rc = dbgcKdCtxQueryNtKCtx32(pThis, RespHdr.idCpu, (PNTKCONTEXT32)&abResp[0]); 2448 if (RT_SUCCESS(rc)) 2449 cbData = sizeof(NTKCONTEXT32); 2450 } 2451 } 2452 else 2453 { 2454 switch (pPktManip->u.XferCtrlSpace.u64IdXfer) 2455 { 2456 case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KPCR: 2160 2457 { 2161 RTGCUINTPTR GCPtrKpcr = 0; 2162 2163 rc = pThis->pIfWinNt->pfnQueryKpcrForVCpu(pThis->pIfWinNt, pThis->Dbgc.pUVM, RespHdr.idCpu, 2164 &GCPtrKpcr, NULL /*pKpcrb*/); 2458 if (pThis->pIfWinNt) 2459 { 2460 RTGCUINTPTR GCPtrKpcr = 0; 2461 2462 rc = pThis->pIfWinNt->pfnQueryKpcrForVCpu(pThis->pIfWinNt, pThis->Dbgc.pUVM, RespHdr.idCpu, 2463 &GCPtrKpcr, NULL /*pKpcrb*/); 2464 if (RT_SUCCESS(rc)) 2465 memcpy(&abResp[0], &GCPtrKpcr, sizeof(GCPtrKpcr)); 2466 } 2467 2468 cbData = sizeof(RTGCUINTPTR); 2469 break; 2470 } 2471 case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KPCRB: 2472 { 2473 if (pThis->pIfWinNt) 2474 { 2475 RTGCUINTPTR GCPtrKpcrb = 0; 2476 2477 rc = pThis->pIfWinNt->pfnQueryKpcrForVCpu(pThis->pIfWinNt, pThis->Dbgc.pUVM, RespHdr.idCpu, 2478 NULL /*pKpcr*/, &GCPtrKpcrb); 2479 if (RT_SUCCESS(rc)) 2480 memcpy(&abResp[0], &GCPtrKpcrb, sizeof(GCPtrKpcrb)); 2481 } 2482 2483 cbData = sizeof(RTGCUINTPTR); 2484 break; 2485 } 2486 case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KCTX: 2487 { 2488 rc = dbgcKdCtxQueryNtKCtx64(pThis, RespHdr.idCpu, (PNTKCONTEXT64)&abResp[0], NTCONTEXT64_F_FULL); 2165 2489 if (RT_SUCCESS(rc)) 2166 memcpy(&abResp[0], &GCPtrKpcr, sizeof(GCPtrKpcr)); 2490 cbData = sizeof(NTKCONTEXT64); 2491 break; 2167 2492 } 2168 2169 cbData = sizeof(RTGCUINTPTR); 2170 break; 2171 } 2172 case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KPCRB: 2173 { 2174 if (pThis->pIfWinNt) 2493 case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KTHRD: 2175 2494 { 2176 RTGCUINTPTR GCPtrKpcrb = 0; 2177 2178 rc = pThis->pIfWinNt->pfnQueryKpcrForVCpu(pThis->pIfWinNt, pThis->Dbgc.pUVM, RespHdr.idCpu, 2179 NULL /*pKpcr*/, &GCPtrKpcrb); 2180 if (RT_SUCCESS(rc)) 2181 memcpy(&abResp[0], &GCPtrKpcrb, sizeof(GCPtrKpcrb)); 2495 if (pThis->pIfWinNt) 2496 { 2497 RTGCUINTPTR GCPtrCurThrd = 0; 2498 2499 rc = pThis->pIfWinNt->pfnQueryCurThrdForVCpu(pThis->pIfWinNt, pThis->Dbgc.pUVM, RespHdr.idCpu, 2500 &GCPtrCurThrd); 2501 if (RT_SUCCESS(rc)) 2502 memcpy(&abResp[0], &GCPtrCurThrd, sizeof(GCPtrCurThrd)); 2503 } 2504 2505 cbData = sizeof(RTGCUINTPTR); 2506 break; 2182 2507 } 2183 2184 cbData = sizeof(RTGCUINTPTR); 2185 break; 2186 } 2187 case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KCTX: 2188 { 2189 rc = dbgcKdCtxQueryNtKCtx64(pThis, RespHdr.idCpu, (PNTKCONTEXT64)&abResp[0], NTCONTEXT64_F_FULL); 2190 if (RT_SUCCESS(rc)) 2191 cbData = sizeof(NTKCONTEXT64); 2192 break; 2193 } 2194 case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KTHRD: 2195 { 2196 if (pThis->pIfWinNt) 2197 { 2198 RTGCUINTPTR GCPtrCurThrd = 0; 2199 2200 rc = pThis->pIfWinNt->pfnQueryCurThrdForVCpu(pThis->pIfWinNt, pThis->Dbgc.pUVM, RespHdr.idCpu, 2201 &GCPtrCurThrd); 2202 if (RT_SUCCESS(rc)) 2203 memcpy(&abResp[0], &GCPtrCurThrd, sizeof(GCPtrCurThrd)); 2204 } 2205 2206 cbData = sizeof(RTGCUINTPTR); 2207 break; 2208 } 2209 default: 2210 rc = VERR_NOT_SUPPORTED; 2211 break; 2508 default: 2509 rc = VERR_NOT_SUPPORTED; 2510 break; 2511 } 2212 2512 } 2213 2513 … … 2371 2671 KDPACKETMANIPULATEHDR RespHdr; 2372 2672 KDPACKETMANIPULATE_CONTEXTEX ContextEx; 2373 NTCONTEXT64 NtCtx; 2374 RT_ZERO(RespHdr); RT_ZERO(ContextEx); 2673 union 2674 { 2675 NTCONTEXT64 v64; 2676 NTCONTEXT32 v32; 2677 } NtCtx; 2678 RT_ZERO(RespHdr); RT_ZERO(ContextEx); RT_ZERO(NtCtx); 2375 2679 2376 2680 RTSGSEG aRespSegs[3]; … … 2390 2694 aRespSegs[1].cbSeg = sizeof(ContextEx); 2391 2695 2392 int rc = dbgcKdCtxQueryNtCtx64(pThis, pPktManip->Hdr.idCpu, &NtCtx, NTCONTEXT64_F_FULL); 2696 int rc = VINF_SUCCESS; 2697 size_t cbCtx = pThis->f32Bit ? sizeof(NtCtx.v32) : sizeof(NtCtx.v64); 2698 if (pThis->f32Bit) 2699 dbgcKdCtxQueryNtCtx32(pThis, pPktManip->Hdr.idCpu, &NtCtx.v32, NTCONTEXT32_F_FULL); 2700 else 2701 dbgcKdCtxQueryNtCtx64(pThis, pPktManip->Hdr.idCpu, &NtCtx.v64, NTCONTEXT64_F_FULL); 2393 2702 if ( RT_SUCCESS(rc) 2394 && pPktManip->u.ContextEx.offStart < sizeof(NtCtx))2703 && pPktManip->u.ContextEx.offStart < cbCtx) 2395 2704 { 2396 2705 RespHdr.u32NtStatus = NTSTATUS_SUCCESS; 2397 ContextEx.cbXfered = RT_MIN( sizeof(NtCtx)- ContextEx.offStart, ContextEx.cbXfer);2706 ContextEx.cbXfered = RT_MIN(cbCtx - ContextEx.offStart, ContextEx.cbXfer); 2398 2707 2399 2708 aRespSegs[2].pvSeg = (uint8_t *)&NtCtx + ContextEx.offStart; … … 2544 2853 case KD_PACKET_HDR_SUB_TYPE_STATE_MANIPULATE: 2545 2854 { 2546 CPUMMODE enmMode = DBGCCmdHlpGetCpuMode(&pThis->Dbgc.CmdHlp); 2547 switch (enmMode) 2548 { 2549 case CPUMMODE_PROTECTED: 2550 { 2551 rc = VERR_NOT_IMPLEMENTED; 2552 break; 2553 } 2554 case CPUMMODE_LONG: 2555 { 2556 pThis->idPktNext = pThis->PktHdr.Fields.idPacket ^ 0x1; 2557 rc = dbgcKdCtxPktManipulate64Process(pThis); 2558 break; 2559 } 2560 case CPUMMODE_REAL: 2561 default: 2562 rc = VERR_NOT_SUPPORTED; 2563 break; 2564 } 2855 pThis->idPktNext = pThis->PktHdr.Fields.idPacket ^ 0x1; 2856 rc = dbgcKdCtxPktManipulate64Process(pThis); 2565 2857 break; 2566 2858 } … … 3098 3390 pThis->idPktNext = KD_PACKET_HDR_ID_INITIAL; 3099 3391 pThis->pIfWinNt = NULL; 3392 pThis->f32Bit = false; 3100 3393 dbgcKdCtxPktRecvReset(pThis); 3101 3394 … … 3185 3478 rc = VINF_SUCCESS; /* Try to continue nevertheless. */ 3186 3479 } 3480 3481 if (pThis->pIfWinNt) 3482 { 3483 rc = pThis->pIfWinNt->pfnQueryVersion(pThis->pIfWinNt, pThis->Dbgc.pUVM, 3484 NULL /*puVersMajor*/, NULL /*puVersMinor*/, 3485 NULL /*puBuildNumber*/, &pThis->f32Bit); 3486 AssertRC(rc); 3487 } 3488 else 3489 { 3490 /* 3491 * Try to detect bitness based on the current CPU mode which might fool us (32bit process running 3492 * inside of 64bit host). 3493 */ 3494 CPUMMODE enmMode = DBGCCmdHlpGetCpuMode(&pThis->Dbgc.CmdHlp); 3495 if (enmMode == CPUMMODE_PROTECTED) 3496 pThis->f32Bit = true; 3497 else if (enmMode == CPUMMODE_LONG) 3498 pThis->f32Bit = false; 3499 else 3500 LogRel(("DBGC/Kd: Heh, trying to debug real mode code with WinDbg are we? Good luck with that...\n")); 3501 } 3187 3502 } 3188 3503 else
Note:
See TracChangeset
for help on using the changeset viewer.