/** * 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; }
/** * EMT worker for DBGFR3BpClear(). * * @returns VBox status code. * @param pVM Pointer to the VM. * @param iBp The id of the breakpoint which should be removed (cleared). * @thread EMT * @internal */ static DECLCALLBACK(int) dbgfR3BpClear(PVM pVM, uint32_t iBp) { /* * Validate input. */ PDBGFBP pBp = dbgfR3BpGet(pVM, iBp); if (!pBp) return VERR_DBGF_BP_NOT_FOUND; /* * Disarm the breakpoint if it's enabled. */ if (pBp->fEnabled) { pBp->fEnabled = false; int rc; switch (pBp->enmType) { case DBGFBPTYPE_REG: rc = dbgfR3BpRegDisarm(pVM, pBp); break; case DBGFBPTYPE_INT3: rc = dbgfR3BpInt3Disarm(pVM, pBp); break; case DBGFBPTYPE_REM: #ifdef VBOX_WITH_REM rc = REMR3BreakpointClear(pVM, pBp->GCPtr); #else rc = IEMBreakpointClear(pVM, pBp->GCPtr); #endif break; default: AssertMsgFailedReturn(("Invalid enmType=%d!\n", pBp->enmType), VERR_IPE_NOT_REACHED_DEFAULT_CASE); } AssertRCReturn(rc, rc); } /* * Free the breakpoint. */ dbgfR3BpFree(pVM, pBp); return VINF_SUCCESS; }
/** * EMT worker for DBGFR3BpDisable(). * * @returns VBox status code. * @param pVM The VM handle. * @param iBp The id of the breakpoint which should be disabled. * @thread EMT * @internal */ static DECLCALLBACK(int) dbgfR3BpDisable(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_DISABLED; /* * Remove the breakpoint. */ pBp->fEnabled = false; int rc; switch (pBp->enmType) { case DBGFBPTYPE_REG: rc = dbgfR3BpRegDisarm(pVM, pBp); break; case DBGFBPTYPE_INT3: rc = dbgfR3BpInt3Disarm(pVM, pBp); break; case DBGFBPTYPE_REM: rc = REMR3BreakpointClear(pVM, pBp->GCPtr); break; default: AssertMsgFailedReturn(("Invalid enmType=%d!\n", pBp->enmType), VERR_IPE_NOT_REACHED_DEFAULT_CASE); } return rc; }