- Timestamp:
- Dec 1, 2016 12:28:44 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/dbgf.h
r64720 r64770 124 124 VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromPhys(PUVM pUVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr); 125 125 VMMR3DECL(bool) DBGFR3AddrIsValid(PUVM pUVM, PCDBGFADDRESS pAddress); 126 VMMR3DECL(int) DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, P DBGFADDRESS pAddress, PRTGCPHYS pGCPhys);126 VMMR3DECL(int) DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, PRTGCPHYS pGCPhys); 127 127 VMMR3DECL(int) DBGFR3AddrToHostPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys); 128 128 VMMR3DECL(int) DBGFR3AddrToVolatileR3Ptr(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr); … … 791 791 uint8_t cb; 792 792 } Reg; 793 /** Recompiler breakpoint data. */ 793 794 /** INT3 breakpoint data. */ 794 795 struct DBGFBPINT3 795 796 { 796 797 /** The flat GC address of the breakpoint. */ 797 798 RTGCUINTPTR GCPtr; 799 /** The physical address of the breakpoint. */ 800 RTGCPHYS PhysAddr; 798 801 /** The byte value we replaced by the INT 3 instruction. */ 799 802 uint8_t bOrg; … … 831 834 832 835 /** Paddind to ensure that the size is identical on win32 and linux. */ 833 uint64_t u64Padding[ 2];836 uint64_t u64Padding[3]; 834 837 } u; 835 838 } DBGFBP; … … 844 847 845 848 #ifdef IN_RING3 /* The breakpoint management API is only available in ring-3. */ 846 VMMR3DECL(int) DBGFR3BpSet (PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp);849 VMMR3DECL(int) DBGFR3BpSetInt3(PUVM pUVM, VMCPUID idSrcCpu, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp); 847 850 VMMR3DECL(int) DBGFR3BpSetReg(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, 848 851 uint8_t fType, uint8_t cb, uint32_t *piBp); … … 879 882 VMM_INT_DECL(bool) DBGFBpIsHwArmed(PVM pVM); 880 883 VMM_INT_DECL(bool) DBGFBpIsHwIoArmed(PVM pVM); 884 VMM_INT_DECL(bool) DBGFBpIsInt3Armed(PVM pVM); 881 885 VMM_INT_DECL(bool) DBGFIsStepping(PVMCPU pVCpu); 882 886 VMM_INT_DECL(VBOXSTRICTRC) DBGFBpCheckIo(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, RTIOPORT uIoPort, uint8_t cbValue); -
trunk/include/VBox/vmm/vm.h
r63648 r64770 1207 1207 /** Enabled software interrupt breakpoints. */ 1208 1208 uint32_t cSoftIntBreakpoints; 1209 /** Number of selected events. */1209 /** The number of selected events. */ 1210 1210 uint32_t cSelectedEvents; 1211 /** The number of enabled hardware breakpoints. */ 1212 uint8_t cEnabledHwBreakpoints; 1213 /** The number of enabled hardware I/O breakpoints. */ 1214 uint8_t cEnabledHwIoBreakpoints; 1215 /** The number of enabled INT3 breakpoints. */ 1216 uint8_t cEnabledInt3Breakpoints; 1217 uint8_t abPadding[1]; /**< Unused padding space up for grabs. */ 1211 1218 } const ro; 1212 1219 #endif -
trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp
r64721 r64770 1085 1085 */ 1086 1086 uint32_t iBp; 1087 rc = DBGFR3BpSet(pUVM, &Address, iHitTrigger, iHitDisable, &iBp); 1087 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp); 1088 rc = DBGFR3BpSetInt3(pUVM, pDbgc->idCpu, &Address, iHitTrigger, iHitDisable, &iBp); 1088 1089 if (RT_SUCCESS(rc)) 1089 1090 { 1090 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);1091 1091 rc = dbgcBpAdd(pDbgc, iBp, pszCmds); 1092 1092 if (RT_SUCCESS(rc)) -
trunk/src/VBox/Debugger/testcase/tstDBGCStubs.cpp
r64721 r64770 42 42 } 43 43 44 VMMR3DECL(int) DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, P DBGFADDRESS pAddress, PRTGCPHYS pGCPhys)44 VMMR3DECL(int) DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, PRTGCPHYS pGCPhys) 45 45 { 46 46 return VERR_INTERNAL_ERROR; … … 68 68 return VERR_INTERNAL_ERROR; 69 69 } 70 VMMR3DECL(int) DBGFR3BpSet (PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, PRTUINT piBp)70 VMMR3DECL(int) DBGFR3BpSetInt3(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, PRTUINT piBp) 71 71 { 72 72 return VERR_INTERNAL_ERROR; -
trunk/src/VBox/VMM/VMMAll/DBGFAll.cpp
r62478 r64770 150 150 { 151 151 return pVM->dbgf.s.cEnabledHwIoBreakpoints > 0; 152 } 153 154 155 /** 156 * Checks if any INT3 breakpoints are armed. 157 * 158 * @returns true if armed, false if not. 159 * @param pVM The cross context VM structure. 160 * @remarks Don't call this from CPUMRecalcHyperDRx! 161 */ 162 VMM_INT_DECL(bool) DBGFBpIsInt3Armed(PVM pVM) 163 { 164 return pVM->dbgf.s.cEnabledInt3Breakpoints > 0; 152 165 } 153 166 -
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r64663 r64770 1670 1670 static int hmR0SvmLoadGuestXcptIntercepts(PVMCPU pVCpu, PSVMVMCB pVmcb, PCPUMCTX pCtx) 1671 1671 { 1672 int rc = VINF_SUCCESS;1673 NOREF(pCtx);1674 1672 if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS)) 1675 1673 { 1676 /* T he remaining intercepts are handled elsewhere, e.g. in hmR0SvmLoadSharedCR0(). */1674 /* Trap #UD for GIM provider (e.g. for hypercalls). */ 1677 1675 if (pVCpu->hm.s.fGIMTrapXcptUD) 1678 1676 hmR0SvmAddXcptIntercept(pVmcb, X86_XCPT_UD); 1679 1677 else 1680 1678 hmR0SvmRemoveXcptIntercept(pVmcb, X86_XCPT_UD); 1679 1680 /* Trap #BP for INT3 debug breakpoints set by the VM debugger. */ 1681 if (pVCpu->CTX_SUFF(pVM)->dbgf.ro.cEnabledInt3Breakpoints) 1682 hmR0SvmAddXcptIntercept(pVmcb, X86_XCPT_BP); 1683 else 1684 hmR0SvmRemoveXcptIntercept(pVmcb, X86_XCPT_BP); 1685 1686 /* The remaining intercepts are handled elsewhere, e.g. in hmR0SvmLoadSharedCR0(). */ 1681 1687 HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS); 1682 1688 } 1683 return rc;1689 return VINF_SUCCESS; 1684 1690 } 1685 1691 -
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r64676 r64770 2650 2650 LogFlowFunc(("pVM=%p pVCpu=%p\n", pVM, pVCpu)); 2651 2651 2652 /** @todo r=ramshankar: Shouldn't setting up \#UD intercepts be handled by 2653 * hmR0VmxLoadGuestXcptIntercepts()? Why do we check it here? */ 2652 2654 uint32_t u32XcptBitmap = pVCpu->hm.s.fGIMTrapXcptUD ? RT_BIT(X86_XCPT_UD) : 0; 2653 2655 … … 9107 9109 /** Stuff we need in VMX_VMCS32_CTRL_PROC_EXEC2. */ 9108 9110 uint32_t fCpe2Extra; 9109 /** Extra stuff we need in 9111 /** Extra stuff we need in VMX_VMCS32_CTRL_EXCEPTION_BITMAP. */ 9110 9112 uint32_t bmXcptExtra; 9111 9113 /** The sequence number of the Dtrace provider settings the state was … … 9305 9307 ASMBitSet(pDbgState->bmExitsToCheck, VMX_EXIT_XCPT_OR_NMI); 9306 9308 } 9309 9310 /* 9311 * INT3 breakpoints - triggered by #BP exceptions. 9312 */ 9313 if (pVM->dbgf.ro.cEnabledInt3Breakpoints > 0) 9314 pDbgState->bmXcptExtra |= RT_BIT_32(X86_XCPT_BP); 9307 9315 9308 9316 /* … … 10406 10414 if ( !pVCpu->hm.s.fUseDebugLoop 10407 10415 && (!VBOXVMM_ANY_PROBES_ENABLED() || !hmR0VmxAnyExpensiveProbesEnabled()) 10408 && !DBGFIsStepping(pVCpu) ) 10416 && !DBGFIsStepping(pVCpu) 10417 && !pVM->dbgf.ro.cEnabledInt3Breakpoints) 10409 10418 rcStrict = hmR0VmxRunGuestCodeNormal(pVM, pVCpu, pCtx); 10410 10419 else -
trunk/src/VBox/VMM/VMMR3/DBGFAddr.cpp
r62478 r64770 237 237 * @param pGCPhys Where to return the physical address. 238 238 */ 239 static DECLCALLBACK(int) dbgfR3AddrToPhysOnVCpu(PVMCPU pVCpu, P DBGFADDRESS pAddress, PRTGCPHYS pGCPhys)239 static DECLCALLBACK(int) dbgfR3AddrToPhysOnVCpu(PVMCPU pVCpu, PCDBGFADDRESS pAddress, PRTGCPHYS pGCPhys) 240 240 { 241 241 VMCPU_ASSERT_EMT(pVCpu); … … 265 265 * @param pGCPhys Where to return the physical address. 266 266 */ 267 VMMR3DECL(int) DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, P DBGFADDRESS pAddress, PRTGCPHYS pGCPhys)267 VMMR3DECL(int) DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, PRTGCPHYS pGCPhys) 268 268 { 269 269 /* -
trunk/src/VBox/VMM/VMMR3/DBGFBp.cpp
r64530 r64770 42 42 43 43 /********************************************************************************************************************************* 44 * Structures and Typedefs * 45 *********************************************************************************************************************************/ 46 /** 47 * DBGF INT3-breakpoint set callback arguments. 48 */ 49 typedef struct DBGFBPINT3ARGS 50 { 51 /** The source virtual CPU ID (used for breakpoint address resolution). */ 52 VMCPUID idSrcCpu; 53 /** The breakpoint address. */ 54 PCDBGFADDRESS pAddress; 55 /** The hit count at which the breakpoint starts triggering. */ 56 uint64_t iHitTrigger; 57 /** The hit count at which disables the breakpoint. */ 58 uint64_t iHitDisable; 59 /** Where to store the breakpoint Id (optional). */ 60 uint32_t *piBp; 61 } DBGFBPINT3ARGS; 62 /** Pointer to a DBGF INT3 breakpoint set callback argument. */ 63 typedef DBGFBPINT3ARGS *PDBGFBPINT3ARGS; 64 65 66 /********************************************************************************************************************************* 44 67 * Internal Functions * 45 68 *********************************************************************************************************************************/ 46 69 RT_C_DECLS_BEGIN 47 70 static int dbgfR3BpRegArm(PVM pVM, PDBGFBP pBp); 48 static int dbgfR3BpInt3Arm(P UVM pUVM, PDBGFBP pBp);71 static int dbgfR3BpInt3Arm(PVM pVM, PDBGFBP pBp); 49 72 RT_C_DECLS_END 50 73 … … 166 189 167 190 /** 168 * Updates IOM on whether we've got any armed I/O port or MMIO breakpoints. 169 * 170 * @returns VINF_SUCCESS 191 * Updates the search optimization structure for enabled breakpoints of the 192 * specified type. 193 * 194 * @returns VINF_SUCCESS. 171 195 * @param pVM The cross context VM structure. 172 196 * @param enmType The breakpoint type. … … 317 341 318 342 /** 319 * Sets a breakpoint (int 3 based). 320 * 321 * @returns VBox status code. 322 * @param pUVM The user mode VM handle. 323 * @param pAddress The address of the breakpoint. 324 * @param piHitTrigger The hit count at which the breakpoint start triggering. 325 * Use 0 (or 1) if it's gonna trigger at once. 326 * @param piHitDisable The hit count which disables the breakpoint. 327 * Use ~(uint64_t) if it's never gonna be disabled. 328 * @param piBp Where to store the breakpoint id. (optional) 329 * @thread Any thread. 330 */ 331 static DECLCALLBACK(int) dbgfR3BpSetInt3(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t *piHitTrigger, 332 uint64_t *piHitDisable, uint32_t *piBp) 343 * @callback_method_impl{FNVMMEMTRENDEZVOUS} 344 */ 345 static DECLCALLBACK(VBOXSTRICTRC) dbgfR3BpEnableInt3OnCpu(PVM pVM, PVMCPU pVCpu, void *pvUser) 333 346 { 334 347 /* 335 348 * Validate input. 336 349 */ 337 PVM pVM = pUVM->pVM; 350 PDBGFBP pBp = (PDBGFBP)pvUser; 351 AssertReturn(pBp, VERR_INVALID_PARAMETER); 352 Assert(pBp->enmType == DBGFBPTYPE_INT3); 353 VMCPU_ASSERT_EMT(pVCpu); RT_NOREF(pVCpu); 338 354 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 339 if (!DBGFR3AddrIsValid(pUVM, pAddress)) 355 356 /* 357 * Arm the breakpoint. 358 */ 359 return dbgfR3BpInt3Arm(pVM, pBp); 360 } 361 362 363 /** 364 * @callback_method_impl{FNVMMEMTRENDEZVOUS} 365 */ 366 static DECLCALLBACK(VBOXSTRICTRC) dbgfR3BpSetInt3OnCpu(PVM pVM, PVMCPU pVCpu, void *pvUser) 367 { 368 /* 369 * Validate input. 370 */ 371 PDBGFBPINT3ARGS pBpArgs = (PDBGFBPINT3ARGS)pvUser; 372 AssertReturn(pBpArgs, VERR_INVALID_PARAMETER); 373 VMCPU_ASSERT_EMT(pVCpu); 374 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 375 376 AssertMsgReturn(!pBpArgs->piBp || VALID_PTR(pBpArgs->piBp), ("piBp=%p\n", pBpArgs->piBp), VERR_INVALID_POINTER); 377 PCDBGFADDRESS pAddress = pBpArgs->pAddress; 378 if (!DBGFR3AddrIsValid(pVM->pUVM, pAddress)) 340 379 return VERR_INVALID_PARAMETER; 341 if (*piHitTrigger > *piHitDisable) 380 381 if (pBpArgs->iHitTrigger > pBpArgs->iHitDisable) 342 382 return VERR_INVALID_PARAMETER; 343 AssertMsgReturn(!piBp || VALID_PTR(piBp), ("piBp=%p\n", piBp), VERR_INVALID_POINTER); 344 if (piBp) 345 *piBp = UINT32_MAX; 346 347 /* 348 * Check if the breakpoint already exists. 349 */ 350 PDBGFBP pBp = dbgfR3BpGetByAddr(pVM, DBGFBPTYPE_INT3, pAddress->FlatPtr); 351 if (pBp) 352 { 353 int rc = VINF_SUCCESS; 354 if (!pBp->fEnabled) 355 rc = dbgfR3BpInt3Arm(pUVM, pBp); 383 384 /* 385 * Check if we're on the source CPU where we can resolve the breakpoint address. 386 */ 387 if (pVCpu->idCpu == pBpArgs->idSrcCpu) 388 { 389 if (pBpArgs->piBp) 390 *pBpArgs->piBp = UINT32_MAX; 391 392 /* 393 * Check if the breakpoint already exists. 394 */ 395 PDBGFBP pBp = dbgfR3BpGetByAddr(pVM, DBGFBPTYPE_INT3, pAddress->FlatPtr); 396 if (pBp) 397 { 398 int rc = VINF_SUCCESS; 399 if (!pBp->fEnabled) 400 rc = dbgfR3BpInt3Arm(pVM, pBp); 401 if (RT_SUCCESS(rc)) 402 { 403 if (pBpArgs->piBp) 404 *pBpArgs->piBp = pBp->iBp; 405 406 /* 407 * Returning VINF_DBGF_BP_ALREADY_EXIST here causes a VBOXSTRICTRC out-of-range assertion 408 * in VMMR3EmtRendezvous(). Re-setting of an existing breakpoint shouldn't cause an assertion 409 * killing the VM (and debugging session), so for now we'll pretend success. 410 */ 411 #if 0 412 rc = VINF_DBGF_BP_ALREADY_EXIST; 413 #endif 414 } 415 else 416 dbgfR3BpFree(pVM, pBp); 417 return rc; 418 } 419 420 /* 421 * Allocate the breakpoint. 422 */ 423 pBp = dbgfR3BpAlloc(pVM, DBGFBPTYPE_INT3); 424 if (!pBp) 425 return VERR_DBGF_NO_MORE_BP_SLOTS; 426 427 /* 428 * Translate & save the breakpoint address into a guest-physical address. 429 */ 430 int rc = DBGFR3AddrToPhys(pVM->pUVM, pBpArgs->idSrcCpu, pAddress, &pBp->u.Int3.PhysAddr); 356 431 if (RT_SUCCESS(rc)) 357 432 { 358 rc = VINF_DBGF_BP_ALREADY_EXIST; 359 if (piBp) 360 *piBp = pBp->iBp; 433 /* The physical address from DBGFR3AddrToPhys() is the start of the page, 434 we need the exact byte offset into the page while writing to it in dbgfR3BpInt3Arm(). */ 435 pBp->u.Int3.PhysAddr |= (pAddress->FlatPtr & X86_PAGE_OFFSET_MASK); 436 pBp->u.Int3.GCPtr = pAddress->FlatPtr; 437 pBp->iHitTrigger = pBpArgs->iHitTrigger; 438 pBp->iHitDisable = pBpArgs->iHitDisable; 439 440 /* 441 * Now set the breakpoint in guest memory. 442 */ 443 rc = dbgfR3BpInt3Arm(pVM, pBp); 444 if (RT_SUCCESS(rc)) 445 { 446 if (pBpArgs->piBp) 447 *pBpArgs->piBp = pBp->iBp; 448 return VINF_SUCCESS; 449 } 361 450 } 451 452 dbgfR3BpFree(pVM, pBp); 362 453 return rc; 363 454 } 364 455 365 /* 366 * Allocate and initialize the bp. 367 */ 368 pBp = dbgfR3BpAlloc(pVM, DBGFBPTYPE_INT3); 369 if (!pBp) 370 return VERR_DBGF_NO_MORE_BP_SLOTS; 371 pBp->u.Int3.GCPtr = pAddress->FlatPtr; 372 pBp->iHitTrigger = *piHitTrigger; 373 pBp->iHitDisable = *piHitDisable; 374 ASMCompilerBarrier(); 375 pBp->fEnabled = true; 376 dbgfR3BpUpdateSearchOptimizations(pVM, DBGFBPTYPE_INT3, &pVM->dbgf.s.Int3); 377 378 /* 379 * Now ask REM to set the breakpoint. 380 */ 381 int rc = dbgfR3BpInt3Arm(pUVM, pBp); 382 if (RT_SUCCESS(rc)) 383 { 384 if (piBp) 385 *piBp = pBp->iBp; 386 } 387 else 388 dbgfR3BpFree(pVM, pBp); 389 390 return rc; 456 return VINF_SUCCESS; 391 457 } 392 458 … … 397 463 * @returns VBox status code. 398 464 * @param pUVM The user mode VM handle. 465 * @param idSrcCpu The ID of the virtual CPU used for the 466 * breakpoint address resolution. 399 467 * @param pAddress The address of the breakpoint. 400 468 * @param iHitTrigger The hit count at which the breakpoint start triggering. … … 405 473 * @thread Any thread. 406 474 */ 407 VMMR3DECL(int) DBGFR3BpSet(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp) 408 { 409 /* 410 * This must be done on EMT. 411 */ 412 int rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)dbgfR3BpSetInt3, 5, 413 pUVM, pAddress, &iHitTrigger, &iHitDisable, piBp); 475 VMMR3DECL(int) DBGFR3BpSetInt3(PUVM pUVM, VMCPUID idSrcCpu, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, 476 uint32_t *piBp) 477 { 478 AssertReturn(idSrcCpu <= pUVM->cCpus, VERR_INVALID_CPU_ID); 479 480 DBGFBPINT3ARGS BpArgs; 481 RT_ZERO(BpArgs); 482 BpArgs.idSrcCpu = idSrcCpu; 483 BpArgs.iHitTrigger = iHitTrigger; 484 BpArgs.iHitDisable = iHitDisable; 485 BpArgs.pAddress = pAddress; 486 BpArgs.piBp = piBp; 487 488 int rc = VMMR3EmtRendezvous(pUVM->pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ALL_AT_ONCE, dbgfR3BpSetInt3OnCpu, &BpArgs); 414 489 LogFlow(("DBGFR3BpSet: returns %Rrc\n", rc)); 415 490 return rc; … … 419 494 /** 420 495 * Arms an int 3 breakpoint. 421 * This is used to implement both DBGFR3BpSetReg() and DBGFR3BpEnable(). 422 * 423 * @returns VBox status code. 424 * @param pUVM The user mode VM handle. 496 * 497 * This is used to implement both DBGFR3BpSetInt3() and 498 * DBGFR3BpEnable(). 499 * 500 * @returns VBox status code. 501 * @param pVM The cross context VM structure. 425 502 * @param pBp The breakpoint. 426 503 */ 427 static int dbgfR3BpInt3Arm(PUVM pUVM, PDBGFBP pBp) 428 { 429 /** @todo should actually use physical address here! */ 430 431 /** @todo SMP support! */ 432 VMCPUID idCpu = 0; 433 434 /* 435 * Save current byte and write int3 instruction. 436 */ 437 DBGFADDRESS Addr; 438 DBGFR3AddrFromFlat(pUVM, &Addr, pBp->u.Int3.GCPtr); 439 int rc = DBGFR3MemRead(pUVM, idCpu, &Addr, &pBp->u.Int3.bOrg, 1); 504 static int dbgfR3BpInt3Arm(PVM pVM, PDBGFBP pBp) 505 { 506 VM_ASSERT_EMT(pVM); 507 508 /* 509 * Save current byte and write the int3 instruction byte. 510 */ 511 int rc = PGMPhysSimpleReadGCPhys(pVM, &pBp->u.Int3.bOrg, pBp->u.Int3.PhysAddr, sizeof(pBp->u.Int3.bOrg)); 440 512 if (RT_SUCCESS(rc)) 441 513 { 442 514 static const uint8_t s_bInt3 = 0xcc; 443 rc = DBGFR3MemWrite(pUVM, idCpu, &Addr, &s_bInt3, 1); 515 rc = PGMPhysSimpleWriteGCPhys(pVM, pBp->u.Int3.PhysAddr, &s_bInt3, sizeof(s_bInt3)); 516 if (RT_SUCCESS(rc)) 517 { 518 pBp->fEnabled = true; 519 dbgfR3BpUpdateSearchOptimizations(pVM, DBGFBPTYPE_INT3, &pVM->dbgf.s.Int3); 520 pVM->dbgf.s.cEnabledInt3Breakpoints = pVM->dbgf.s.Int3.cToSearch; 521 Log(("DBGF: Set breakpoint at %RGv (Phys %RGp) cEnabledInt3Breakpoints=%u\n", pBp->u.Int3.GCPtr, 522 pBp->u.Int3.PhysAddr, pVM->dbgf.s.cEnabledInt3Breakpoints)); 523 } 444 524 } 445 525 return rc; … … 449 529 /** 450 530 * Disarms an int 3 breakpoint. 531 * 451 532 * This is used to implement both DBGFR3BpClear() and DBGFR3BpDisable(). 452 533 * 453 534 * @returns VBox status code. 454 * @param p UVM The user mode VM handle.535 * @param pVM The cross context VM structure. 455 536 * @param pBp The breakpoint. 456 537 */ 457 static int dbgfR3BpInt3Disarm(PUVM pUVM, PDBGFBP pBp) 458 { 459 /** @todo SMP support! */ 460 VMCPUID idCpu = 0; 538 static int dbgfR3BpInt3Disarm(PVM pVM, PDBGFBP pBp) 539 { 540 VM_ASSERT_EMT(pVM); 461 541 462 542 /* … … 464 544 * We currently ignore invalid bytes. 465 545 */ 466 DBGFADDRESS Addr; 467 DBGFR3AddrFromFlat(pUVM, &Addr, pBp->u.Int3.GCPtr); 468 uint8_t bCurrent; 469 int rc = DBGFR3MemRead(pUVM, idCpu, &Addr, &bCurrent, 1); 470 if (bCurrent == 0xcc) 471 rc = DBGFR3MemWrite(pUVM, idCpu, &Addr, &pBp->u.Int3.bOrg, 1); 546 uint8_t bCurrent = 0; 547 int rc = PGMPhysSimpleReadGCPhys(pVM, &bCurrent, pBp->u.Int3.PhysAddr, sizeof(bCurrent)); 548 if ( RT_SUCCESS(rc) 549 && bCurrent == 0xcc) 550 { 551 rc = PGMPhysSimpleWriteGCPhys(pVM, pBp->u.Int3.PhysAddr, &pBp->u.Int3.bOrg, sizeof(pBp->u.Int3.bOrg)); 552 if (RT_SUCCESS(rc)) 553 { 554 pBp->fEnabled = false; 555 dbgfR3BpUpdateSearchOptimizations(pVM, DBGFBPTYPE_INT3, &pVM->dbgf.s.Int3); 556 pVM->dbgf.s.cEnabledInt3Breakpoints = pVM->dbgf.s.Int3.cToSearch; 557 Log(("DBGF: Removed breakpoint at %RGv (Phys %RGp) cEnabledInt3Breakpoints=%u\n", pBp->u.Int3.GCPtr, 558 pBp->u.Int3.PhysAddr, pVM->dbgf.s.cEnabledInt3Breakpoints)); 559 } 560 } 472 561 return rc; 562 } 563 564 565 /** 566 * @callback_method_impl{FNVMMEMTRENDEZVOUS} 567 */ 568 static DECLCALLBACK(VBOXSTRICTRC) dbgfR3BpDisableInt3OnCpu(PVM pVM, PVMCPU pVCpu, void *pvUser) 569 { 570 /* 571 * Validate input. 572 */ 573 PDBGFBP pBp = (PDBGFBP)pvUser; 574 AssertReturn(pBp, VERR_INVALID_PARAMETER); 575 Assert(pBp->enmType == DBGFBPTYPE_INT3); 576 VMCPU_ASSERT_EMT(pVCpu); RT_NOREF(pVCpu); 577 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 578 579 /* 580 * Disarm the breakpoint. 581 */ 582 return dbgfR3BpInt3Disarm(pVM, pBp); 473 583 } 474 584 … … 966 1076 * Allocate and initialize the breakpoint. 967 1077 */ 968 PDBGFBP pBp = dbgfR3BpAlloc(pVM, DBGFBPTYPE_ PORT_IO);1078 PDBGFBP pBp = dbgfR3BpAlloc(pVM, DBGFBPTYPE_MMIO); 969 1079 if (!pBp) 970 1080 return VERR_DBGF_NO_MORE_BP_SLOTS; … … 1041 1151 */ 1042 1152 PVM pVM = pUVM->pVM; 1153 VM_ASSERT_EMT(pVM); 1043 1154 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 1044 1155 PDBGFBP pBp = dbgfR3BpGet(pVM, iBp); … … 1060 1171 1061 1172 case DBGFBPTYPE_INT3: 1062 rc = dbgfR3BpInt3Disarm(pUVM, pBp); 1063 dbgfR3BpUpdateSearchOptimizations(pVM, DBGFBPTYPE_INT3, &pVM->dbgf.s.Int3); 1173 rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, dbgfR3BpDisableInt3OnCpu, pBp); 1064 1174 break; 1065 1175 … … 1137 1247 1138 1248 /* 1139 * Removethe breakpoint.1249 * Arm the breakpoint. 1140 1250 */ 1141 1251 int rc; … … 1148 1258 1149 1259 case DBGFBPTYPE_INT3: 1150 dbgfR3BpUpdateSearchOptimizations(pVM, DBGFBPTYPE_INT3, &pVM->dbgf.s.Int3); 1151 rc = dbgfR3BpInt3Arm(pUVM, pBp); 1260 rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, dbgfR3BpEnableInt3OnCpu, pBp); 1152 1261 break; 1153 1262 … … 1232 1341 1233 1342 case DBGFBPTYPE_INT3: 1234 rc = dbgfR3BpInt3Disarm(pUVM, pBp); 1235 dbgfR3BpUpdateSearchOptimizations(pVM, DBGFBPTYPE_INT3, &pVM->dbgf.s.Int3); 1343 rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, dbgfR3BpDisableInt3OnCpu, pBp); 1236 1344 break; 1237 1345 … … 1337 1445 */ 1338 1446 int rc = VMR3ReqPriorityCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)dbgfR3BpEnum, 3, pUVM, pfnCallback, pvUser); 1339 LogFlow(("DBGFR3Bp Clear: returns %Rrc\n", rc));1447 LogFlow(("DBGFR3BpEnum: returns %Rrc\n", rc)); 1340 1448 return rc; 1341 1449 } -
trunk/src/VBox/VMM/VMMR3/DBGFMem.cpp
r62478 r64770 161 161 162 162 /* 163 * HMA is special 163 * HMA is special. 164 164 */ 165 165 int rc; … … 174 174 { 175 175 /* 176 * Select DBGFworker by addressing mode.176 * Select PGM worker by addressing mode. 177 177 */ 178 178 PVMCPU pVCpu = VMMGetCpuById(pVM, idCpu); -
trunk/src/VBox/VMM/include/DBGFInternal.h
r64720 r64770 209 209 uint32_t cSoftIntBreakpoints; 210 210 211 /** Number of selected events. */211 /** The number of selected events. */ 212 212 uint32_t cSelectedEvents; 213 214 /** The number of enabled hardware breakpoints. */ 215 uint8_t cEnabledHwBreakpoints; 216 /** The number of enabled hardware I/O breakpoints. */ 217 uint8_t cEnabledHwIoBreakpoints; 218 /** The number of enabled INT3 breakpoints. */ 219 uint8_t cEnabledInt3Breakpoints; 220 uint8_t abPadding; /**< Unused padding space up for grabs. */ 221 uint32_t uPadding; 213 222 214 223 /** Debugger Attached flag. … … 276 285 } SteppingFilter; 277 286 278 uint32_t u32Padding; /**< Alignment padding. */ 279 280 /** The number of enabled hardware breakpoints. */ 281 uint8_t cEnabledHwBreakpoints; 282 /** The number of enabled hardware I/O breakpoints. */ 283 uint8_t cEnabledHwIoBreakpoints; 284 uint8_t abPadding[2]; /**< Unused padding space up for grabs. */ 287 uint32_t u32Padding[2]; /**< Alignment padding. */ 285 288 286 289 /** Array of hardware breakpoints. (0..3)
Note:
See TracChangeset
for help on using the changeset viewer.