Changeset 58903 in vbox
- Timestamp:
- Nov 27, 2015 3:07:07 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 104399
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/dbgf.h
r58891 r58903 493 493 /** Recompiler. */ 494 494 DBGFBPTYPE_REM, 495 /** Port I/O breakpoint. */ 496 DBGFBPTYPE_PORT_IO, 497 /** Memory mapped I/O breakpoint. */ 498 DBGFBPTYPE_MMIO, 495 499 /** ensure 32-bit size. */ 496 500 DBGFBPTYPE_32BIT_HACK = 0x7fffffff 497 501 } DBGFBPTYPE; 498 502 503 504 /** @name DBGFBPIOACCESS_XXX - I/O (port + mmio) access types. 505 * @{ */ 506 /** Byte sized read accesses. */ 507 #define DBGFBPIOACCESS_READ_BYTE UINT32_C(0x00000001) 508 /** Word sized accesses. */ 509 #define DBGFBPIOACCESS_READ_WORD UINT32_C(0x00000002) 510 /** Double word sized accesses. */ 511 #define DBGFBPIOACCESS_READ_DWORD UINT32_C(0x00000004) 512 /** Quad word sized accesses - not available for I/O ports. */ 513 #define DBGFBPIOACCESS_READ_QWORD UINT32_C(0x00000008) 514 /** Other sized accesses - not available for I/O ports. */ 515 #define DBGFBPIOACCESS_READ_OTHER UINT32_C(0x00000010) 516 /** Read mask. */ 517 #define DBGFBPIOACCESS_READ_MASK UINT32_C(0x0000001f) 518 519 /** Byte sized write accesses. */ 520 #define DBGFBPIOACCESS_WRITE_BYTE UINT32_C(0x00000100) 521 /** Word sized write accesses. */ 522 #define DBGFBPIOACCESS_WRITE_WORD UINT32_C(0x00000200) 523 /** Double word sized write accesses. */ 524 #define DBGFBPIOACCESS_WRITE_DWORD UINT32_C(0x00000400) 525 /** Quad word sized write accesses - not available for I/O ports. */ 526 #define DBGFBPIOACCESS_WRITE_QWORD UINT32_C(0x00000800) 527 /** Other sized write accesses - not available for I/O ports. */ 528 #define DBGFBPIOACCESS_WRITE_OTHER UINT32_C(0x00001000) 529 /** Write mask. */ 530 #define DBGFBPIOACCESS_WRITE_MASK UINT32_C(0x00001f00) 531 532 /** All kind of access (read, write, all sizes). */ 533 #define DBGFBPIOACCESS_ALL UINT32_C(0x00001f1f) 534 535 /** The acceptable mask for I/O ports. */ 536 #define DBGFBPIOACCESS_VALID_MASK_PORT_IO UINT32_C(0x00000303) 537 /** The acceptable mask for MMIO. */ 538 #define DBGFBPIOACCESS_VALID_MASK_MMIO UINT32_C(0x00001f1f) 539 /** @} */ 499 540 500 541 /** … … 510 551 * Use ~(uint64_t)0 if it should never stop. */ 511 552 uint64_t iHitDisable; 512 /** The Flat GC address of the breakpoint.513 * (PC register value if REM type?) */514 RTGCUINTPTR GCPtr;515 553 /** The breakpoint id. */ 516 uint 32_t iBp;554 uint16_t iBp; 517 555 /** The breakpoint status - enabled or disabled. */ 518 556 bool fEnabled; 519 520 557 /** The breakpoint type. */ 521 558 DBGFBPTYPE enmType; 522 523 #if GC_ARCH_BITS == 64524 uint32_t u32Padding;525 #endif526 559 527 560 /** Union of type specific data. */ 528 561 union 529 562 { 563 /** The flat GC address breakpoint address for REG, INT3 and REM breakpoints. */ 564 RTGCUINTPTR GCPtr; 565 530 566 /** Debug register data. */ 531 567 struct DBGFBPREG 532 568 { 569 /** The flat GC address of the breakpoint. */ 570 RTGCUINTPTR GCPtr; 533 571 /** The debug register number. */ 534 uint8_t iReg;572 uint8_t iReg; 535 573 /** The access type (one of the X86_DR7_RW_* value). */ 536 uint8_t fType;574 uint8_t fType; 537 575 /** The access size. */ 538 uint8_t cb;576 uint8_t cb; 539 577 } Reg; 540 578 /** Recompiler breakpoint data. */ 541 579 struct DBGFBPINT3 542 580 { 581 /** The flat GC address of the breakpoint. */ 582 RTGCUINTPTR GCPtr; 543 583 /** The byte value we replaced by the INT 3 instruction. */ 544 uint8_t bOrg;584 uint8_t bOrg; 545 585 } Int3; 546 586 … … 548 588 struct DBGFBPREM 549 589 { 550 /** nothing yet */ 551 uint8_t fDummy; 590 /** The flat GC address of the breakpoint. 591 * (PC register value?) */ 592 RTGCUINTPTR GCPtr; 552 593 } Rem; 594 595 /** I/O port breakpoint data. */ 596 struct DBGFBPPORTIO 597 { 598 /** The first port. */ 599 RTIOPORT uPort; 600 /** The number of ports. */ 601 RTIOPORT cPorts; 602 /** Valid DBGFBPIOACCESS_XXX selection, max DWORD size. */ 603 uint32_t fAccess; 604 } PortIo; 605 606 /** Memory mapped I/O breakpoint data. */ 607 struct DBGFBPMMIO 608 { 609 /** The first MMIO address. */ 610 RTGCPHYS PhysAddr; 611 /** The size of the MMIO range in bytes. */ 612 uint32_t cb; 613 /** Valid DBGFBPIOACCESS_XXX selection, max DWORD size. */ 614 uint32_t fAccess; 615 } Mmio; 616 553 617 /** Paddind to ensure that the size is identical on win32 and linux. */ 554 uint64_t u64Padding ;618 uint64_t u64Padding[2]; 555 619 } u; 556 620 } DBGFBP; 621 AssertCompileMembersAtSameOffset(DBGFBP, u.GCPtr, DBGFBP, u.Reg.GCPtr); 622 AssertCompileMembersAtSameOffset(DBGFBP, u.GCPtr, DBGFBP, u.Int3.GCPtr); 623 AssertCompileMembersAtSameOffset(DBGFBP, u.GCPtr, DBGFBP, u.Rem.GCPtr); 557 624 558 625 /** Pointer to a breakpoint. */ … … 566 633 uint8_t fType, uint8_t cb, uint32_t *piBp); 567 634 VMMR3DECL(int) DBGFR3BpSetREM(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp); 635 VMMR3DECL(int) DBGFR3BpSetPortIo(PUVM pUVM, RTIOPORT uPort, RTIOPORT cPorts, uint32_t fAccess, 636 uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp); 637 VMMR3DECL(int) DBGFR3BpSetMmio(PUVM pUVM, RTGCPHYS GCPhys, uint32_t cb, uint32_t fAccess, 638 uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp); 568 639 VMMR3DECL(int) DBGFR3BpClear(PUVM pUVM, uint32_t iBp); 569 640 VMMR3DECL(int) DBGFR3BpEnable(PUVM pUVM, uint32_t iBp); -
trunk/include/VBox/vmm/iom.h
r58110 r58903 29 29 #include <VBox/types.h> 30 30 #include <VBox/dis.h> 31 #include <VBox/vmm/dbgf.h> 31 32 32 33 RT_C_DECLS_BEGIN … … 338 339 VMMR3_INT_DECL(int) IOMR3MmioDeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange); 339 340 341 VMMR3_INT_DECL(void) IOMR3NotifyBreakpointCountChange(PVM pVM, unsigned cPortIo, unsigned cMmio); 342 VMMR3_INT_DECL(void) IOMR3NotifyDebugEventChange(PVM pVM, DBGFEVENT enmEvent, bool fEnabled); 343 340 344 /** @} */ 341 345 #endif /* IN_RING3 */ -
trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp
r58890 r58903 675 675 * BP type and size. 676 676 */ 677 char chType;678 char cb = 1;677 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%#4x %c ", pBp->iBp, pBp->fEnabled ? 'e' : 'd'); 678 bool fHasAddress = false; 679 679 switch (pBp->enmType) 680 680 { 681 681 case DBGFBPTYPE_INT3: 682 chType = 'p'; 682 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, " p %RGv", pBp->u.Int3.GCPtr); 683 fHasAddress = true; 683 684 break; 684 685 case DBGFBPTYPE_REG: 686 { 687 char chType; 685 688 switch (pBp->u.Reg.fType) 686 689 { … … 692 695 693 696 } 694 cb = pBp->u.Reg.cb; 695 break; 697 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%d %c %RGv", pBp->u.Reg.cb, chType, pBp->u.Reg.GCPtr); 698 fHasAddress = true; 699 break; 700 } 701 696 702 case DBGFBPTYPE_REM: 697 chType = 'r'; 698 break; 703 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, " r %RGv", pBp->u.Rem.GCPtr); 704 fHasAddress = true; 705 break; 706 707 /** @todo realign the list when I/O and MMIO breakpoint command have been added and it's possible to test this code. */ 708 case DBGFBPTYPE_PORT_IO: 709 case DBGFBPTYPE_MMIO: 710 { 711 uint32_t fAccess = pBp->enmType == DBGFBPTYPE_PORT_IO ? pBp->u.PortIo.fAccess : pBp->u.Mmio.fAccess; 712 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, pBp->enmType == DBGFBPTYPE_PORT_IO ? " i" : " m"); 713 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, " %c%c%c%c%c%c", 714 fAccess & DBGFBPIOACCESS_READ_MASK ? 'r' : '-', 715 fAccess & DBGFBPIOACCESS_READ_BYTE ? '1' : '-', 716 fAccess & DBGFBPIOACCESS_READ_WORD ? '2' : '-', 717 fAccess & DBGFBPIOACCESS_READ_DWORD ? '4' : '-', 718 fAccess & DBGFBPIOACCESS_READ_QWORD ? '8' : '-', 719 fAccess & DBGFBPIOACCESS_READ_OTHER ? '+' : '-'); 720 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, " %c%c%c%c%c%c", 721 fAccess & DBGFBPIOACCESS_WRITE_MASK ? 'w' : '-', 722 fAccess & DBGFBPIOACCESS_WRITE_BYTE ? '1' : '-', 723 fAccess & DBGFBPIOACCESS_WRITE_WORD ? '2' : '-', 724 fAccess & DBGFBPIOACCESS_WRITE_DWORD ? '4' : '-', 725 fAccess & DBGFBPIOACCESS_WRITE_QWORD ? '8' : '-', 726 fAccess & DBGFBPIOACCESS_WRITE_OTHER ? '+' : '-'); 727 if (pBp->enmType == DBGFBPTYPE_PORT_IO) 728 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, " %04x-%04x", 729 pBp->u.PortIo.uPort, pBp->u.PortIo.uPort + pBp->u.PortIo.cPorts - 1); 730 else 731 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%RGp LB %03x", pBp->u.Mmio.PhysAddr, pBp->u.Mmio.cb); 732 break; 733 } 734 699 735 default: 700 chType = '?'; 701 break; 702 } 703 704 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%#4x %c %d %c %RGv %04RX64 (%04RX64 to ", 705 pBp->iBp, pBp->fEnabled ? 'e' : 'd', (int)cb, chType, 706 pBp->GCPtr, pBp->cHits, pBp->iHitTrigger); 736 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, " unknown type %d!!", pBp->enmType); 737 AssertFailed(); 738 break; 739 740 } 707 741 if (pBp->iHitDisable == ~(uint64_t)0) 708 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, " ~0) ");742 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, " %04RX64 (%04RX64 to ~0) ", pBp->cHits, pBp->iHitTrigger); 709 743 else 710 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%04RX64)", pBp->iHitDisable); 711 712 /* 713 * Try resolve the address. 714 */ 715 RTDBGSYMBOL Sym; 716 RTINTPTR off; 717 DBGFADDRESS Addr; 718 int rc = DBGFR3AsSymbolByAddr(pUVM, pDbgc->hDbgAs, DBGFR3AddrFromFlat(pDbgc->pUVM, &Addr, pBp->GCPtr), 719 RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL, &off, &Sym, NULL); 720 if (RT_SUCCESS(rc)) 721 { 722 if (!off) 723 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%s", Sym.szName); 724 else if (off > 0) 725 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%s+%RGv", Sym.szName, off); 726 else 727 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%s-%RGv", Sym.szName, -off); 744 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, " %04RX64 (%04RX64 to %04RX64)", pBp->cHits, pBp->iHitTrigger, pBp->iHitDisable); 745 746 /* 747 * Try resolve the address if it has one. 748 */ 749 if (fHasAddress) 750 { 751 RTDBGSYMBOL Sym; 752 RTINTPTR off; 753 DBGFADDRESS Addr; 754 int rc = DBGFR3AsSymbolByAddr(pUVM, pDbgc->hDbgAs, DBGFR3AddrFromFlat(pDbgc->pUVM, &Addr, pBp->u.GCPtr), 755 RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL, &off, &Sym, NULL); 756 if (RT_SUCCESS(rc)) 757 { 758 if (!off) 759 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%s", Sym.szName); 760 else if (off > 0) 761 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%s+%RGv", Sym.szName, off); 762 else 763 DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "%s-%RGv", Sym.szName, -off); 764 } 728 765 } 729 766 -
trunk/src/VBox/VMM/VMMAll/DBGFAll.cpp
r58123 r58903 69 69 PCDBGFBP pBp = &pVM->dbgf.s.aHwBreakpoints[0]; 70 70 Assert(pBp->u.Reg.iReg == 0); 71 return pBp-> GCPtr;71 return pBp->u.Reg.GCPtr; 72 72 } 73 73 … … 83 83 PCDBGFBP pBp = &pVM->dbgf.s.aHwBreakpoints[1]; 84 84 Assert(pBp->u.Reg.iReg == 1); 85 return pBp-> GCPtr;85 return pBp->u.Reg.GCPtr; 86 86 } 87 87 … … 97 97 PCDBGFBP pBp = &pVM->dbgf.s.aHwBreakpoints[2]; 98 98 Assert(pBp->u.Reg.iReg == 2); 99 return pBp-> GCPtr;99 return pBp->u.Reg.GCPtr; 100 100 } 101 101 … … 111 111 PCDBGFBP pBp = &pVM->dbgf.s.aHwBreakpoints[3]; 112 112 Assert(pBp->u.Reg.iReg == 3); 113 return pBp-> GCPtr;113 return pBp->u.Reg.GCPtr; 114 114 } 115 115 … … 192 192 { 193 193 uint8_t cbReg = pVM->dbgf.s.aHwBreakpoints[iBp].u.Reg.cb; Assert(RT_IS_POWER_OF_TWO(cbReg)); 194 uint64_t uDrXFirst = pVM->dbgf.s.aHwBreakpoints[iBp]. GCPtr & ~(uint64_t)(cbReg - 1);194 uint64_t uDrXFirst = pVM->dbgf.s.aHwBreakpoints[iBp].u.Reg.GCPtr & ~(uint64_t)(cbReg - 1); 195 195 uint64_t uDrXLast = uDrXFirst + cbReg - 1; 196 196 if (uDrXFirst <= uIoPortLast && uDrXLast >= uIoPortFirst) -
trunk/src/VBox/VMM/VMMR3/DBGF.cpp
r58170 r58903 668 668 for (size_t i = 0; i < RT_ELEMENTS(pVM->dbgf.s.aBreakpoints); i++) 669 669 if ( pVM->dbgf.s.aBreakpoints[i].enmType == DBGFBPTYPE_REM 670 && pVM->dbgf.s.aBreakpoints[i]. GCPtr == eip)670 && pVM->dbgf.s.aBreakpoints[i].u.Rem.GCPtr == eip) 671 671 { 672 672 pVM->dbgf.s.DbgEvent.u.Bp.iBp = pVM->dbgf.s.aBreakpoints[i].iBp; -
trunk/src/VBox/VMM/VMMR3/DBGFBp.cpp
r58126 r58903 29 29 #endif 30 30 #include <VBox/vmm/mm.h> 31 #include <VBox/vmm/iom.h> 32 #include <VBox/vmm/hm.h> 31 33 #include "DBGFInternal.h" 32 34 #include <VBox/vmm/vm.h> … … 223 225 */ 224 226 for (unsigned iBp = 0; iBp < cBps; iBp++) 225 { 226 if ( paBps[iBp].enmType == enmType 227 && paBps[iBp].GCPtr == GCPtr) 227 if ( paBps[iBp].enmType == enmType 228 && paBps[iBp].u.GCPtr == GCPtr) 228 229 return &paBps[iBp]; 229 }230 230 231 231 return NULL; … … 320 320 if (!pBp) 321 321 return VERR_DBGF_NO_MORE_BP_SLOTS; 322 pBp->GCPtr = pAddress->FlatPtr; 323 pBp->iHitTrigger = *piHitTrigger; 324 pBp->iHitDisable = *piHitDisable; 325 pBp->fEnabled = true; 322 pBp->u.Int3.GCPtr = pAddress->FlatPtr; 323 pBp->iHitTrigger = *piHitTrigger; 324 pBp->iHitDisable = *piHitDisable; 325 ASMCompilerBarrier(); 326 pBp->fEnabled = true; 326 327 327 328 /* … … 386 387 */ 387 388 DBGFADDRESS Addr; 388 DBGFR3AddrFromFlat(pUVM, &Addr, pBp-> GCPtr);389 DBGFR3AddrFromFlat(pUVM, &Addr, pBp->u.Int3.GCPtr); 389 390 int rc = DBGFR3MemRead(pUVM, idCpu, &Addr, &pBp->u.Int3.bOrg, 1); 390 391 if (RT_SUCCESS(rc)) … … 415 416 */ 416 417 DBGFADDRESS Addr; 417 DBGFR3AddrFromFlat(pUVM, &Addr, pBp-> GCPtr);418 DBGFR3AddrFromFlat(pUVM, &Addr, pBp->u.Int3.GCPtr); 418 419 uint8_t bCurrent; 419 420 int rc = DBGFR3MemRead(pUVM, idCpu, &Addr, &bCurrent, 1); … … 508 509 if (!pBp) 509 510 return VERR_DBGF_NO_MORE_BP_SLOTS; 510 pBp->GCPtr = pAddress->FlatPtr;511 511 pBp->iHitTrigger = *piHitTrigger; 512 512 pBp->iHitDisable = *piHitDisable; 513 pBp->fEnabled = true;514 513 Assert(pBp->iBp == pBp->u.Reg.iReg); 514 pBp->u.Reg.GCPtr = pAddress->FlatPtr; 515 515 pBp->u.Reg.fType = fType; 516 516 pBp->u.Reg.cb = cb; 517 ASMCompilerBarrier(); 518 pBp->fEnabled = true; 517 519 518 520 /* … … 642 644 if (!pBp->fEnabled) 643 645 #ifdef VBOX_WITH_REM 644 rc = REMR3BreakpointSet(pVM, pBp-> GCPtr);646 rc = REMR3BreakpointSet(pVM, pBp->u.Rem.GCPtr); 645 647 #else 646 rc = IEMBreakpointSet(pVM, pBp-> GCPtr);648 rc = IEMBreakpointSet(pVM, pBp->u.Rem.GCPtr); 647 649 #endif 648 650 if (RT_SUCCESS(rc)) … … 661 663 if (!pBp) 662 664 return VERR_DBGF_NO_MORE_BP_SLOTS; 663 pBp-> GCPtr= pAddress->FlatPtr;665 pBp->u.Rem.GCPtr = pAddress->FlatPtr; 664 666 pBp->iHitTrigger = *piHitTrigger; 665 667 pBp->iHitDisable = *piHitDisable; 668 ASMCompilerBarrier(); 666 669 pBp->fEnabled = true; 667 670 … … 711 714 712 715 716 717 /** 718 * Updates IOM on whether we've got any armed I/O port or MMIO breakpoints. 719 * 720 * @returns VINF_SUCCESS 721 * @param pVM The cross context VM structure. 722 */ 723 static int dbgfR3BpUpdateIom(PVM pVM) 724 { 725 unsigned cPortIo = 0; 726 unsigned cMmio = 0; 727 for (uint32_t iBp = 0; iBp < RT_ELEMENTS(pVM->dbgf.s.aBreakpoints); iBp++) 728 if (pVM->dbgf.s.aBreakpoints[iBp].fEnabled) 729 { 730 if (pVM->dbgf.s.aBreakpoints[iBp].enmType == DBGFBPTYPE_PORT_IO) 731 cPortIo++; 732 else if (pVM->dbgf.s.aBreakpoints[iBp].enmType == DBGFBPTYPE_MMIO) 733 cMmio++; 734 } 735 736 pVM->dbgf.s.fHasPortIoBps = cPortIo != 0; 737 pVM->dbgf.s.fHasMmioBps = cMmio != 0; 738 739 IOMR3NotifyBreakpointCountChange(pVM, cPortIo, cMmio); 740 return VINF_SUCCESS; 741 } 742 743 744 /** 745 * EMT worker for DBGFR3BpSetPortIo. 746 * 747 * @returns VBox status code. 748 * @param pUVM The user mode VM handle. 749 * @param uPort The first I/O port. 750 * @param cPorts The number of I/O ports. 751 * @param fAccess The access we want to break on. 752 * @param piHitTrigger The hit count at which the breakpoint start triggering. 753 * Use 0 (or 1) if it's gonna trigger at once. 754 * @param piHitDisable The hit count which disables the breakpoint. 755 * Use ~(uint64_t) if it's never gonna be disabled. 756 * @param piBp Where to store the breakpoint ID. 757 */ 758 static DECLCALLBACK(int) dbgfR3BpSetPortIo(PUVM pUVM, RTIOPORT uPort, RTIOPORT cPorts, uint32_t fAccess, 759 uint64_t const *piHitTrigger, uint64_t const *piHitDisable, uint32_t *piBp) 760 { 761 /* 762 * Validate input. 763 */ 764 PVM pVM = pUVM->pVM; 765 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 766 *piBp = ~0; 767 768 /* 769 * Check if the breakpoint already exists. 770 */ 771 for (uint32_t i = 0; i < RT_ELEMENTS(pVM->dbgf.s.aBreakpoints); i++) 772 if ( pVM->dbgf.s.aBreakpoints[i].enmType == DBGFBPTYPE_PORT_IO 773 && pVM->dbgf.s.aBreakpoints[i].u.PortIo.uPort == uPort 774 && pVM->dbgf.s.aBreakpoints[i].u.PortIo.cPorts == cPorts 775 && pVM->dbgf.s.aBreakpoints[i].u.PortIo.fAccess == fAccess) 776 { 777 if (!pVM->dbgf.s.aBreakpoints[i].fEnabled) 778 { 779 pVM->dbgf.s.aBreakpoints[i].fEnabled = true; 780 dbgfR3BpUpdateIom(pVM); 781 } 782 *piBp = pVM->dbgf.s.aBreakpoints[i].iBp; 783 return VINF_DBGF_BP_ALREADY_EXIST; 784 } 785 786 /* 787 * Allocate and initialize the breakpoint. 788 */ 789 PDBGFBP pBp = dbgfR3BpAlloc(pVM, DBGFBPTYPE_PORT_IO); 790 if (!pBp) 791 return VERR_DBGF_NO_MORE_BP_SLOTS; 792 pBp->iHitTrigger = *piHitTrigger; 793 pBp->iHitDisable = *piHitDisable; 794 pBp->u.PortIo.uPort = uPort; 795 pBp->u.PortIo.cPorts = cPorts; 796 pBp->u.PortIo.fAccess = fAccess; 797 ASMCompilerBarrier(); 798 pBp->fEnabled = true; 799 800 /* 801 * Tell IOM. 802 */ 803 dbgfR3BpUpdateIom(pVM); 804 *piBp = pBp->iBp; 805 return VINF_SUCCESS; 806 } 807 808 809 /** 810 * Sets an I/O port breakpoint. 811 * 812 * @returns VBox status code. 813 * @param pUvm The user mode VM handle. 814 * @param uPort The first I/O port. 815 * @param cPorts The number of I/O ports, see DBGFBPIOACCESS_XXX. 816 * @param fAccess The access we want to break on. 817 * @param iHitTrigger The hit count at which the breakpoint start 818 * triggering. Use 0 (or 1) if it's gonna trigger at 819 * once. 820 * @param iHitDisable The hit count which disables the breakpoint. 821 * Use ~(uint64_t) if it's never gonna be disabled. 822 * @param piBp Where to store the breakpoint ID. Optional. 823 */ 824 VMMR3DECL(int) DBGFR3BpSetPortIo(PUVM pUVM, RTIOPORT uPort, RTIOPORT cPorts, uint32_t fAccess, 825 uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp) 826 { 827 AssertReturn(!(fAccess & ~DBGFBPIOACCESS_VALID_MASK_PORT_IO), VERR_INVALID_FLAGS); 828 AssertReturn(fAccess, VERR_INVALID_FLAGS); 829 if (iHitTrigger > iHitDisable) 830 return VERR_INVALID_PARAMETER; 831 AssertPtrNullReturn(piBp, VERR_INVALID_POINTER); 832 AssertReturn(cPorts > 0, VERR_OUT_OF_RANGE); 833 AssertReturn((RTIOPORT)(uPort + cPorts) < uPort, VERR_OUT_OF_RANGE); 834 835 /* 836 * This must be done on EMT. 837 */ 838 uint32_t iBp = -1; 839 int rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)dbgfR3BpSetPortIo, 7, 840 pUVM, uPort, cPorts, fAccess, &iHitTrigger, &iHitDisable, piBp); 841 if (piBp) 842 *piBp = iBp; 843 LogFlow(("DBGFR3BpSetPortIo: returns %Rrc *piBp=%d\n", rc, iBp)); 844 return rc; 845 } 846 847 848 /** 849 * EMT worker for DBGFR3BpSetMmio. 850 * 851 * @returns VBox status code. 852 * @param pUVM The user mode VM handle. 853 * @param pGCPhys The start of the MMIO range to break on. 854 * @param cb The the size of the MMIO range. 855 * @param fAccess The access we want to break on. 856 * @param piHitTrigger The hit count at which the breakpoint start triggering. 857 * Use 0 (or 1) if it's gonna trigger at once. 858 * @param piHitDisable The hit count which disables the breakpoint. 859 * Use ~(uint64_t) if it's never gonna be disabled. 860 * @param piBp Where to store the breakpoint ID. 861 */ 862 static DECLCALLBACK(int) dbgfR3BpSetMmio(PUVM pUVM, PCRTGCPHYS pGCPhys, uint32_t cb, uint32_t fAccess, 863 uint64_t const *piHitTrigger, uint64_t const *piHitDisable, uint32_t *piBp) 864 { 865 RTGCPHYS const GCPhys = *pGCPhys; 866 867 /* 868 * Validate input. 869 */ 870 PVM pVM = pUVM->pVM; 871 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 872 *piBp = ~0; 873 874 /* 875 * Check if the breakpoint already exists. 876 */ 877 for (uint32_t i = 0; i < RT_ELEMENTS(pVM->dbgf.s.aBreakpoints); i++) 878 if ( pVM->dbgf.s.aBreakpoints[i].enmType == DBGFBPTYPE_MMIO 879 && pVM->dbgf.s.aBreakpoints[i].u.Mmio.PhysAddr == GCPhys 880 && pVM->dbgf.s.aBreakpoints[i].u.Mmio.cb == cb 881 && pVM->dbgf.s.aBreakpoints[i].u.Mmio.fAccess == fAccess) 882 { 883 if (!pVM->dbgf.s.aBreakpoints[i].fEnabled) 884 { 885 pVM->dbgf.s.aBreakpoints[i].fEnabled = true; 886 dbgfR3BpUpdateIom(pVM); 887 } 888 *piBp = pVM->dbgf.s.aBreakpoints[i].iBp; 889 return VINF_DBGF_BP_ALREADY_EXIST; 890 } 891 892 /* 893 * Allocate and initialize the breakpoint. 894 */ 895 PDBGFBP pBp = dbgfR3BpAlloc(pVM, DBGFBPTYPE_PORT_IO); 896 if (!pBp) 897 return VERR_DBGF_NO_MORE_BP_SLOTS; 898 pBp->iHitTrigger = *piHitTrigger; 899 pBp->iHitDisable = *piHitDisable; 900 pBp->u.Mmio.PhysAddr = GCPhys; 901 pBp->u.Mmio.cb = cb; 902 pBp->u.Mmio.fAccess = fAccess; 903 ASMCompilerBarrier(); 904 pBp->fEnabled = true; 905 906 /* 907 * Tell IOM. 908 */ 909 dbgfR3BpUpdateIom(pVM); 910 *piBp = pBp->iBp; 911 return VINF_SUCCESS; 912 } 913 914 915 /** 916 * Sets a memory mapped I/O breakpoint. 917 * 918 * @returns VBox status code. 919 * @param pUvm The user mode VM handle. 920 * @param GCPhys The first MMIO address. 921 * @param cb The size of the MMIO range to break on. 922 * @param fAccess The access we want to break on. 923 * @param iHitTrigger The hit count at which the breakpoint start 924 * triggering. Use 0 (or 1) if it's gonna trigger at 925 * once. 926 * @param iHitDisable The hit count which disables the breakpoint. 927 * Use ~(uint64_t) if it's never gonna be disabled. 928 * @param piBp Where to store the breakpoint ID. Optional. 929 */ 930 VMMR3DECL(int) DBGFR3BpSetMmio(PUVM pUVM, RTGCPHYS GCPhys, uint32_t cb, uint32_t fAccess, 931 uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp) 932 { 933 AssertReturn(!(fAccess & ~DBGFBPIOACCESS_VALID_MASK_MMIO), VERR_INVALID_FLAGS); 934 AssertReturn(fAccess, VERR_INVALID_FLAGS); 935 if (iHitTrigger > iHitDisable) 936 return VERR_INVALID_PARAMETER; 937 AssertPtrNullReturn(piBp, VERR_INVALID_POINTER); 938 AssertReturn(cb, VERR_OUT_OF_RANGE); 939 AssertReturn(GCPhys + cb < GCPhys, VERR_OUT_OF_RANGE); 940 941 /* 942 * This must be done on EMT. 943 */ 944 uint32_t iBp = -1; 945 int rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)dbgfR3BpSetMmio, 7, 946 pUVM, &GCPhys, cb, fAccess, &iHitTrigger, &iHitDisable, piBp); 947 if (piBp) 948 *piBp = iBp; 949 LogFlow(("DBGFR3BpSetMmio: returns %Rrc *piBp=%d\n", rc, iBp)); 950 return rc; 951 } 952 953 713 954 /** 714 955 * EMT worker for DBGFR3BpClear(). … … 750 991 case DBGFBPTYPE_REM: 751 992 #ifdef VBOX_WITH_REM 752 rc = REMR3BreakpointClear(pVM, pBp-> GCPtr);993 rc = REMR3BreakpointClear(pVM, pBp->u.Rem.GCPtr); 753 994 #else 754 rc = IEMBreakpointClear(pVM, pBp-> GCPtr);995 rc = IEMBreakpointClear(pVM, pBp->u.Rem.GCPtr); 755 996 #endif 997 break; 998 999 case DBGFBPTYPE_PORT_IO: 1000 case DBGFBPTYPE_MMIO: 1001 rc = dbgfR3BpUpdateIom(pVM); 756 1002 break; 757 1003 … … 832 1078 case DBGFBPTYPE_REM: 833 1079 #ifdef VBOX_WITH_REM 834 rc = REMR3BreakpointSet(pVM, pBp-> GCPtr);1080 rc = REMR3BreakpointSet(pVM, pBp->u.Rem.GCPtr); 835 1081 #else 836 rc = IEMBreakpointSet(pVM, pBp-> GCPtr);1082 rc = IEMBreakpointSet(pVM, pBp->u.Rem.GCPtr); 837 1083 #endif 1084 break; 1085 1086 case DBGFBPTYPE_PORT_IO: 1087 case DBGFBPTYPE_MMIO: 1088 rc = dbgfR3BpUpdateIom(pVM); 838 1089 break; 839 1090 … … 910 1161 case DBGFBPTYPE_REM: 911 1162 #ifdef VBOX_WITH_REM 912 rc = REMR3BreakpointClear(pVM, pBp-> GCPtr);1163 rc = REMR3BreakpointClear(pVM, pBp->u.Rem.GCPtr); 913 1164 #else 914 rc = IEMBreakpointClear(pVM, pBp-> GCPtr);1165 rc = IEMBreakpointClear(pVM, pBp->u.Rem.GCPtr); 915 1166 #endif 1167 break; 1168 1169 case DBGFBPTYPE_PORT_IO: 1170 case DBGFBPTYPE_MMIO: 1171 rc = dbgfR3BpUpdateIom(pVM); 916 1172 break; 917 1173 -
trunk/src/VBox/VMM/VMMR3/IOM.cpp
r58126 r58903 1646 1646 1647 1647 /** 1648 * Notification from DBGF that the number of active I/O port or MMIO 1649 * breakpoints has change. 1650 * 1651 * For performance reasons, IOM will only call DBGF before doing I/O and MMIO 1652 * accesses where there are armed breakpoints. 1653 * 1654 * @param pVM The cross context VM structure. 1655 * @param cPortIo Number of armed I/O port breakpoints. 1656 * @param cMmio Number of armed MMIO breakpoints. 1657 */ 1658 VMMR3_INT_DECL(void) IOMR3NotifyBreakpointCountChange(PVM pVM, unsigned cPortIo, unsigned cMmio) 1659 { 1660 /** @todo I/O breakpoints. */ 1661 } 1662 1663 1664 /** 1665 * Notification from DBGF that an event has been enabled or disabled. 1666 * 1667 * For performance reasons, IOM may cache the state of events it implements. 1668 * 1669 * @param pVM The cross context VM structure. 1670 * @param enmEvent The event. 1671 * @param fEnabled The new state. 1672 */ 1673 VMMR3_INT_DECL(void) IOMR3NotifyDebugEventChange(PVM pVM, DBGFEVENT enmEvent, bool fEnabled) 1674 { 1675 /** @todo IOM debug events. */ 1676 } 1677 1678 1679 /** 1648 1680 * Display a single MMIO range. 1649 1681 * -
trunk/src/VBox/VMM/VMMRZ/DBGFRZ.cpp
r58123 r58903 139 139 for (unsigned iBp = 0; iBp < RT_ELEMENTS(pVM->dbgf.s.aBreakpoints); iBp++) 140 140 { 141 if ( pVM->dbgf.s.aBreakpoints[iBp]. GCPtr == (RTGCUINTPTR)pPc141 if ( pVM->dbgf.s.aBreakpoints[iBp].u.GCPtr == (RTGCUINTPTR)pPc 142 142 && pVM->dbgf.s.aBreakpoints[iBp].enmType == DBGFBPTYPE_INT3) 143 143 { -
trunk/src/VBox/VMM/include/DBGFInternal.h
r56287 r58903 50 50 /** Single step execution - stepping into calls. */ 51 51 DBGFCMD_SINGLE_STEP, 52 /** Set a breakpoint. */53 DBGFCMD_BREAKPOINT_SET,54 /** Set a access breakpoint. */55 DBGFCMD_BREAKPOINT_SET_ACCESS,56 /** Set a REM breakpoint. */57 DBGFCMD_BREAKPOINT_SET_REM,58 /** Clear a breakpoint. */59 DBGFCMD_BREAKPOINT_CLEAR,60 /** Enable a breakpoint. */61 DBGFCMD_BREAKPOINT_ENABLE,62 /** Disable a breakpoint. */63 DBGFCMD_BREAKPOINT_DISABLE,64 /** List breakpoints. */65 DBGFCMD_BREAKPOINT_LIST,66 67 52 /** Detaches the debugger. 68 53 * Disabling all breakpoints, watch points and the like. */ 69 DBGFCMD_DETACH_DEBUGGER = 0x7ffffffe,54 DBGFCMD_DETACH_DEBUGGER, 70 55 /** Detached the debugger. 71 56 * The isn't a command as such, it's just that it's necessary for the 72 57 * detaching protocol to be racefree. */ 73 DBGFCMD_DETACHED_DEBUGGER = 0x7fffffff58 DBGFCMD_DETACHED_DEBUGGER 74 59 } DBGFCMD; 75 60 … … 202 187 int32_t offVM; 203 188 189 /** Set if we've got armed port I/O breakpoints. */ 190 bool fHasPortIoBps : 1; 191 /** Set if we've got armed memory mapped I/O breakpoints. */ 192 bool fHasMmioBps : 1; 193 204 194 /** Debugger Attached flag. 205 195 * Set if a debugger is attached, elsewise it's clear. … … 247 237 * @remark This is currently a fixed size array for reasons of simplicity. */ 248 238 DBGFBP aBreakpoints[32]; 239 249 240 } DBGF; 250 241 /** Pointer to DBGF Data. */
Note:
See TracChangeset
for help on using the changeset viewer.