/** * Called on the EMT for the VCpu. * * @returns VBox status code. * * @param pVM The VM handle. * @param idCpu The ID of the CPU context. * @param pAddress The address. * @param fReadOnly Whether returning a read-only page is fine or not. * @param ppvR3Ptr Where to return the address. */ static DECLCALLBACK(int) dbgfR3AddrToVolatileR3PtrOnVCpu(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr) { Assert(idCpu == VMMGetCpuId(pVM)); int rc; if (pAddress->fFlags & DBGFADDRESS_FLAGS_HMA) { rc = VERR_NOT_SUPPORTED; /** @todo create some dedicated errors for this stuff. */ /** @todo this may assert, create a debug version of this which doesn't. */ if (MMHyperIsInsideArea(pVM, pAddress->FlatPtr)) { void *pv = MMHyperRCToCC(pVM, (RTRCPTR)pAddress->FlatPtr); if (pv) { *ppvR3Ptr = pv; rc = VINF_SUCCESS; } } } else { /* * This is a tad ugly, but it gets the job done. */ PGMPAGEMAPLOCK Lock; if (pAddress->fFlags & DBGFADDRESS_FLAGS_PHYS) { if (fReadOnly) rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, pAddress->FlatPtr, (void const **)ppvR3Ptr, &Lock); else rc = PGMPhysGCPhys2CCPtr(pVM, pAddress->FlatPtr, ppvR3Ptr, &Lock); } else { PVMCPU pVCpu = VMMGetCpuById(pVM, idCpu); if (fReadOnly) rc = PGMPhysGCPtr2CCPtrReadOnly(pVCpu, pAddress->FlatPtr, (void const **)ppvR3Ptr, &Lock); else rc = PGMPhysGCPtr2CCPtr(pVCpu, pAddress->FlatPtr, ppvR3Ptr, &Lock); } if (RT_SUCCESS(rc)) PGMPhysReleasePageMappingLock(pVM, &Lock); } return rc; }
/** * Checks if an address is in the HMA or not. * @returns true if it's inside the HMA. * @returns flase if it's not inside the HMA. * @param pVM The VM handle. * @param FlatPtr The address in question. */ DECLINLINE(bool) dbgfR3IsHMA(PVM pVM, RTGCUINTPTR FlatPtr) { return MMHyperIsInsideArea(pVM, FlatPtr); }
/** * Find symbol by address (nearest). * * @returns VBox status. * @param pVM VM handle. * @param Address Address. * @param poffDisplacement Where to store the symbol displacement from Address. * @param pSymbol Where to store the symbol info. */ VMMR3DECL(int) DBGFR3SymbolByAddr(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement, PDBGFSYMBOL pSymbol) { /* * Lazy init. */ if (!pVM->dbgf.s.fSymInited) { int rc = dbgfR3SymLazyInit(pVM); if (RT_FAILURE(rc)) return rc; } /* * Look it up. */ #ifdef HAVE_DBGHELP char achBuffer[sizeof(IMAGEHLP_SYMBOL64) + DBGF_SYMBOL_NAME_LENGTH * sizeof(TCHAR) + sizeof(ULONG64)]; PIMAGEHLP_SYMBOL64 pSym = (PIMAGEHLP_SYMBOL64)&achBuffer[0]; pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); pSym->MaxNameLength = DBGF_SYMBOL_NAME_LENGTH; if (SymGetSymFromAddr64(pVM, Address, (PDWORD64)poffDisplacement, pSym)) { pSymbol->Value = (RTGCUINTPTR)pSym->Address; pSymbol->cb = pSym->Size; pSymbol->fFlags = pSym->Flags; strcpy(pSymbol->szName, pSym->Name); return VINF_SUCCESS; } //return win32Error(pVM); #else PDBGFSYM pSym = dbgfR3SymbolGetAddr(pVM, Address); if (pSym) { pSymbol->Value = pSym->Core.Key; pSymbol->cb = pSym->Core.KeyLast - pSym->Core.Key + 1; pSymbol->fFlags = 0; pSymbol->szName[0] = '\0'; strncat(pSymbol->szName, pSym->szName, sizeof(pSymbol->szName) - 1); if (poffDisplacement) *poffDisplacement = Address - pSymbol->Value; return VINF_SUCCESS; } #endif /* * Try PDM. */ if (MMHyperIsInsideArea(pVM, Address)) { char szModName[64]; RTRCPTR RCPtrMod; char szNearSym1[260]; RTRCPTR RCPtrNearSym1; char szNearSym2[260]; RTRCPTR RCPtrNearSym2; int rc = PDMR3LdrQueryRCModFromPC(pVM, Address, &szModName[0], sizeof(szModName), &RCPtrMod, &szNearSym1[0], sizeof(szNearSym1), &RCPtrNearSym1, &szNearSym2[0], sizeof(szNearSym2), &RCPtrNearSym2); if (RT_SUCCESS(rc) && szNearSym1[0]) { pSymbol->Value = RCPtrNearSym1; pSymbol->cb = RCPtrNearSym2 > RCPtrNearSym1 ? RCPtrNearSym2 - RCPtrNearSym1 : 0; pSymbol->fFlags = 0; pSymbol->szName[0] = '\0'; strncat(pSymbol->szName, szNearSym1, sizeof(pSymbol->szName) - 1); if (poffDisplacement) *poffDisplacement = Address - pSymbol->Value; return VINF_SUCCESS; } } return VERR_SYMBOL_NOT_FOUND; }