/** * Converts an address to a host physical address. * * @returns VBox status code. * @retval VINF_SUCCESS * @retval VERR_INVALID_PARAMETER if the address is invalid. * @retval VERR_INVALID_STATE if the VM is being terminated or if the virtual * CPU handle is invalid. * @retval VERR_NOT_SUPPORTED is the type of address cannot be converted. * @retval VERR_PAGE_NOT_PRESENT * @retval VERR_PAGE_TABLE_NOT_PRESENT * @retval VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT * @retval VERR_PAGE_MAP_LEVEL4_NOT_PRESENT * @retval VERR_PGM_PHYS_PAGE_RESERVED * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS * * @param pVM The VM handle. * @param idCpu The ID of the CPU context to convert virtual * addresses. * @param pAddress The address. * @param pHCPhys Where to return the physical address. */ VMMR3DECL(int) DBGFR3AddrToHostPhys(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys) { /* * Parameter validation. */ AssertPtr(pHCPhys); *pHCPhys = NIL_RTHCPHYS; AssertPtr(pAddress); AssertReturn(DBGFADDRESS_IS_VALID(pAddress), VERR_INVALID_PARAMETER); VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_STATE); AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_PARAMETER); /* * Convert it if we can. */ int rc; if (pAddress->fFlags & DBGFADDRESS_FLAGS_HMA) rc = VERR_NOT_SUPPORTED; /** @todo implement this */ else { RTGCPHYS GCPhys; rc = DBGFR3AddrToPhys(pVM, idCpu, pAddress, &GCPhys); if (RT_SUCCESS(rc)) rc = PGMPhysGCPhys2HCPhys(pVM, pAddress->FlatPtr, pHCPhys); } return rc; }
/** * @interface_method_impl{DBGCCMDHLP,pfnVarConvert} */ static DECLCALLBACK(int) dbgcHlpVarConvert(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pInVar, DBGCVARTYPE enmToType, bool fConvSyms, PDBGCVAR pResult) { PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp); DBGCVAR const InVar = *pInVar; /* if pInVar == pResult */ PCDBGCVAR pArg = &InVar; /* lazy bird, clean up later */ DBGFADDRESS Address; int rc; Assert(pDbgc->pUVM); *pResult = InVar; switch (InVar.enmType) { case DBGCVAR_TYPE_GC_FLAT: switch (enmToType) { case DBGCVAR_TYPE_GC_FLAT: return VINF_SUCCESS; case DBGCVAR_TYPE_GC_FAR: return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_GC_PHYS: pResult->enmType = DBGCVAR_TYPE_GC_PHYS; rc = DBGFR3AddrToPhys(pDbgc->pUVM, pDbgc->idCpu, DBGFR3AddrFromFlat(pDbgc->pUVM, &Address, pArg->u.GCFlat), &pResult->u.GCPhys); if (RT_SUCCESS(rc)) return VINF_SUCCESS; return VERR_DBGC_PARSE_CONVERSION_FAILED; case DBGCVAR_TYPE_HC_FLAT: pResult->enmType = DBGCVAR_TYPE_HC_FLAT; rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pUVM, pDbgc->idCpu, DBGFR3AddrFromFlat(pDbgc->pUVM, &Address, pArg->u.GCFlat), false /*fReadOnly */, &pResult->u.pvHCFlat); if (RT_SUCCESS(rc)) return VINF_SUCCESS; return VERR_DBGC_PARSE_CONVERSION_FAILED; case DBGCVAR_TYPE_HC_PHYS: pResult->enmType = DBGCVAR_TYPE_HC_PHYS; rc = DBGFR3AddrToHostPhys(pDbgc->pUVM, pDbgc->idCpu, DBGFR3AddrFromFlat(pDbgc->pUVM, &Address, pArg->u.GCFlat), &pResult->u.GCPhys); if (RT_SUCCESS(rc)) return VINF_SUCCESS; return VERR_DBGC_PARSE_CONVERSION_FAILED; case DBGCVAR_TYPE_NUMBER: pResult->enmType = enmToType; pResult->u.u64Number = InVar.u.GCFlat; return VINF_SUCCESS; case DBGCVAR_TYPE_STRING: case DBGCVAR_TYPE_SYMBOL: return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_UNKNOWN: case DBGCVAR_TYPE_ANY: break; } break; case DBGCVAR_TYPE_GC_FAR: switch (enmToType) { case DBGCVAR_TYPE_GC_FLAT: rc = DBGFR3AddrFromSelOff(pDbgc->pUVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off); if (RT_SUCCESS(rc)) { pResult->enmType = DBGCVAR_TYPE_GC_FLAT; pResult->u.GCFlat = Address.FlatPtr; return VINF_SUCCESS; } return VERR_DBGC_PARSE_CONVERSION_FAILED; case DBGCVAR_TYPE_GC_FAR: return VINF_SUCCESS; case DBGCVAR_TYPE_GC_PHYS: rc = DBGFR3AddrFromSelOff(pDbgc->pUVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off); if (RT_SUCCESS(rc)) { pResult->enmType = DBGCVAR_TYPE_GC_PHYS; rc = DBGFR3AddrToPhys(pDbgc->pUVM, pDbgc->idCpu, &Address, &pResult->u.GCPhys); if (RT_SUCCESS(rc)) return VINF_SUCCESS; } return VERR_DBGC_PARSE_CONVERSION_FAILED; case DBGCVAR_TYPE_HC_FLAT: rc = DBGFR3AddrFromSelOff(pDbgc->pUVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off); if (RT_SUCCESS(rc)) { pResult->enmType = DBGCVAR_TYPE_HC_FLAT; rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pUVM, pDbgc->idCpu, &Address, false /*fReadOnly*/, &pResult->u.pvHCFlat); if (RT_SUCCESS(rc)) return VINF_SUCCESS; } return VERR_DBGC_PARSE_CONVERSION_FAILED; case DBGCVAR_TYPE_HC_PHYS: rc = DBGFR3AddrFromSelOff(pDbgc->pUVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off); if (RT_SUCCESS(rc)) { pResult->enmType = DBGCVAR_TYPE_HC_PHYS; rc = DBGFR3AddrToHostPhys(pDbgc->pUVM, pDbgc->idCpu, &Address, &pResult->u.GCPhys); if (RT_SUCCESS(rc)) return VINF_SUCCESS; } return VERR_DBGC_PARSE_CONVERSION_FAILED; case DBGCVAR_TYPE_NUMBER: pResult->enmType = enmToType; pResult->u.u64Number = InVar.u.GCFar.off; return VINF_SUCCESS; case DBGCVAR_TYPE_STRING: case DBGCVAR_TYPE_SYMBOL: return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_UNKNOWN: case DBGCVAR_TYPE_ANY: break; } break; case DBGCVAR_TYPE_GC_PHYS: switch (enmToType) { case DBGCVAR_TYPE_GC_FLAT: //rc = MMR3PhysGCPhys2GCVirtEx(pDbgc->pVM, pResult->u.GCPhys, ..., &pResult->u.GCFlat); - yea, sure. return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_GC_FAR: return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_GC_PHYS: return VINF_SUCCESS; case DBGCVAR_TYPE_HC_FLAT: pResult->enmType = DBGCVAR_TYPE_HC_FLAT; rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pUVM, pDbgc->idCpu, DBGFR3AddrFromPhys(pDbgc->pUVM, &Address, pArg->u.GCPhys), false /*fReadOnly */, &pResult->u.pvHCFlat); if (RT_SUCCESS(rc)) return VINF_SUCCESS; return VERR_DBGC_PARSE_CONVERSION_FAILED; case DBGCVAR_TYPE_HC_PHYS: pResult->enmType = DBGCVAR_TYPE_HC_PHYS; rc = DBGFR3AddrToHostPhys(pDbgc->pUVM, pDbgc->idCpu, DBGFR3AddrFromPhys(pDbgc->pUVM, &Address, pArg->u.GCPhys), &pResult->u.HCPhys); if (RT_SUCCESS(rc)) return VINF_SUCCESS; return VERR_DBGC_PARSE_CONVERSION_FAILED; case DBGCVAR_TYPE_NUMBER: pResult->enmType = enmToType; pResult->u.u64Number = InVar.u.GCPhys; return VINF_SUCCESS; case DBGCVAR_TYPE_STRING: case DBGCVAR_TYPE_SYMBOL: return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_UNKNOWN: case DBGCVAR_TYPE_ANY: break; } break; case DBGCVAR_TYPE_HC_FLAT: switch (enmToType) { case DBGCVAR_TYPE_GC_FLAT: return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_GC_FAR: return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_GC_PHYS: pResult->enmType = DBGCVAR_TYPE_GC_PHYS; rc = PGMR3DbgR3Ptr2GCPhys(pDbgc->pUVM, pArg->u.pvHCFlat, &pResult->u.GCPhys); if (RT_SUCCESS(rc)) return VINF_SUCCESS; /** @todo more memory types! */ return VERR_DBGC_PARSE_CONVERSION_FAILED; case DBGCVAR_TYPE_HC_FLAT: return VINF_SUCCESS; case DBGCVAR_TYPE_HC_PHYS: pResult->enmType = DBGCVAR_TYPE_HC_PHYS; rc = PGMR3DbgR3Ptr2HCPhys(pDbgc->pUVM, pArg->u.pvHCFlat, &pResult->u.HCPhys); if (RT_SUCCESS(rc)) return VINF_SUCCESS; /** @todo more memory types! */ return VERR_DBGC_PARSE_CONVERSION_FAILED; case DBGCVAR_TYPE_NUMBER: pResult->enmType = enmToType; pResult->u.u64Number = (uintptr_t)InVar.u.pvHCFlat; return VINF_SUCCESS; case DBGCVAR_TYPE_STRING: case DBGCVAR_TYPE_SYMBOL: return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_UNKNOWN: case DBGCVAR_TYPE_ANY: break; } break; case DBGCVAR_TYPE_HC_PHYS: switch (enmToType) { case DBGCVAR_TYPE_GC_FLAT: return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_GC_FAR: return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_GC_PHYS: pResult->enmType = DBGCVAR_TYPE_GC_PHYS; rc = PGMR3DbgHCPhys2GCPhys(pDbgc->pUVM, pArg->u.HCPhys, &pResult->u.GCPhys); if (RT_SUCCESS(rc)) return VINF_SUCCESS; return VERR_DBGC_PARSE_CONVERSION_FAILED; case DBGCVAR_TYPE_HC_FLAT: return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_HC_PHYS: return VINF_SUCCESS; case DBGCVAR_TYPE_NUMBER: pResult->enmType = enmToType; pResult->u.u64Number = InVar.u.HCPhys; return VINF_SUCCESS; case DBGCVAR_TYPE_STRING: case DBGCVAR_TYPE_SYMBOL: return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_UNKNOWN: case DBGCVAR_TYPE_ANY: break; } break; case DBGCVAR_TYPE_NUMBER: switch (enmToType) { case DBGCVAR_TYPE_GC_FLAT: pResult->enmType = DBGCVAR_TYPE_GC_FLAT; pResult->u.GCFlat = (RTGCPTR)InVar.u.u64Number; return VINF_SUCCESS; case DBGCVAR_TYPE_GC_FAR: return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_GC_PHYS: pResult->enmType = DBGCVAR_TYPE_GC_PHYS; pResult->u.GCPhys = (RTGCPHYS)InVar.u.u64Number; return VINF_SUCCESS; case DBGCVAR_TYPE_HC_FLAT: pResult->enmType = DBGCVAR_TYPE_HC_FLAT; pResult->u.pvHCFlat = (void *)(uintptr_t)InVar.u.u64Number; return VINF_SUCCESS; case DBGCVAR_TYPE_HC_PHYS: pResult->enmType = DBGCVAR_TYPE_HC_PHYS; pResult->u.HCPhys = (RTHCPHYS)InVar.u.u64Number; return VINF_SUCCESS; case DBGCVAR_TYPE_NUMBER: return VINF_SUCCESS; case DBGCVAR_TYPE_STRING: case DBGCVAR_TYPE_SYMBOL: return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_UNKNOWN: case DBGCVAR_TYPE_ANY: break; } break; case DBGCVAR_TYPE_SYMBOL: case DBGCVAR_TYPE_STRING: switch (enmToType) { case DBGCVAR_TYPE_GC_FLAT: case DBGCVAR_TYPE_GC_FAR: case DBGCVAR_TYPE_GC_PHYS: case DBGCVAR_TYPE_HC_FLAT: case DBGCVAR_TYPE_HC_PHYS: case DBGCVAR_TYPE_NUMBER: if (fConvSyms) { rc = dbgcSymbolGet(pDbgc, InVar.u.pszString, enmToType, pResult); if (RT_SUCCESS(rc)) return VINF_SUCCESS; } return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; case DBGCVAR_TYPE_STRING: case DBGCVAR_TYPE_SYMBOL: pResult->enmType = enmToType; return VINF_SUCCESS; case DBGCVAR_TYPE_UNKNOWN: case DBGCVAR_TYPE_ANY: break; } break; case DBGCVAR_TYPE_UNKNOWN: case DBGCVAR_TYPE_ANY: break; } AssertMsgFailed(("f=%d t=%d\n", InVar.enmType, enmToType)); return VERR_INVALID_PARAMETER; }