/** * EMT worker for DBGFR3BpSetREM(). * * @returns VBox status code. * @param pVM The VM handle. * @param pAddress The address of the breakpoint. * @param piHitTrigger The hit count at which the breakpoint start triggering. * Use 0 (or 1) if it's gonna trigger at once. * @param piHitDisable The hit count which disables the breakpoint. * Use ~(uint64_t) if it's never gonna be disabled. * @param piBp Where to store the breakpoint id. (optional) * @thread EMT * @internal */ static DECLCALLBACK(int) dbgfR3BpSetREM(PVM pVM, PCDBGFADDRESS pAddress, uint64_t *piHitTrigger, uint64_t *piHitDisable, uint32_t *piBp) { /* * Validate input. */ if (!DBGFR3AddrIsValid(pVM, pAddress)) return VERR_INVALID_PARAMETER; if (*piHitTrigger > *piHitDisable) return VERR_INVALID_PARAMETER; AssertMsgReturn(!piBp || VALID_PTR(piBp), ("piBp=%p\n", piBp), VERR_INVALID_POINTER); if (piBp) *piBp = ~0; /* * Check if the breakpoint already exists. */ PDBGFBP pBp = dbgfR3BpGetByAddr(pVM, DBGFBPTYPE_REM, pAddress->FlatPtr); if (pBp) { int rc = VINF_SUCCESS; if (!pBp->fEnabled) rc = REMR3BreakpointSet(pVM, pBp->GCPtr); if (RT_SUCCESS(rc)) { rc = VINF_DBGF_BP_ALREADY_EXIST; if (piBp) *piBp = pBp->iBp; } return rc; } /* * Allocate and initialize the bp. */ pBp = dbgfR3BpAlloc(pVM, DBGFBPTYPE_REM); if (!pBp) return VERR_DBGF_NO_MORE_BP_SLOTS; pBp->GCPtr = pAddress->FlatPtr; pBp->iHitTrigger = *piHitTrigger; pBp->iHitDisable = *piHitDisable; pBp->fEnabled = true; /* * Now ask REM to set the breakpoint. */ int rc = REMR3BreakpointSet(pVM, pAddress->FlatPtr); if (RT_SUCCESS(rc)) { if (piBp) *piBp = pBp->iBp; } else dbgfR3BpFree(pVM, pBp); return rc; }
/** * EMT worker for DBGFR3BpEnable(). * * @returns VBox status code. * @param pVM Pointer to the VM. * @param iBp The id of the breakpoint which should be enabled. * @thread EMT * @internal */ static DECLCALLBACK(int) dbgfR3BpEnable(PVM pVM, uint32_t iBp) { /* * Validate input. */ PDBGFBP pBp = dbgfR3BpGet(pVM, iBp); if (!pBp) return VERR_DBGF_BP_NOT_FOUND; /* * Already enabled? */ if (pBp->fEnabled) return VINF_DBGF_BP_ALREADY_ENABLED; /* * Remove the breakpoint. */ int rc; pBp->fEnabled = true; switch (pBp->enmType) { case DBGFBPTYPE_REG: rc = dbgfR3BpRegArm(pVM, pBp); break; case DBGFBPTYPE_INT3: rc = dbgfR3BpInt3Arm(pVM, pBp); break; case DBGFBPTYPE_REM: #ifdef VBOX_WITH_REM rc = REMR3BreakpointSet(pVM, pBp->GCPtr); #else rc = IEMBreakpointSet(pVM, pBp->GCPtr); #endif break; default: AssertMsgFailedReturn(("Invalid enmType=%d!\n", pBp->enmType), VERR_IPE_NOT_REACHED_DEFAULT_CASE); } if (RT_FAILURE(rc)) pBp->fEnabled = false; return rc; }