PGMDbg.cpp revision b40179b44fea65b72b2f226f62af1ed7bd3c48fc
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * PGM - Page Manager and Monitor - Debugger & Debugging APIs.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Copyright (C) 2006-2010 Oracle Corporation
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * This file is part of VirtualBox Open Source Edition (OSE), as
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * available from http://www.virtualbox.org. This file is free software;
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * you can redistribute it and/or modify it under the terms of the GNU
ed22c7109fc5dd9e1b7a5d0333bdc7ad2718e2abYuri Pankov * General Public License (GPL) as published by the Free Software
ed22c7109fc5dd9e1b7a5d0333bdc7ad2718e2abYuri Pankov * Foundation, in version 2 as it comes in the "COPYING" file of the
ed22c7109fc5dd9e1b7a5d0333bdc7ad2718e2abYuri Pankov * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe/*******************************************************************************
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe* Header Files *
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe*******************************************************************************/
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe/*******************************************************************************
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe* Defined Constants And Macros *
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe*******************************************************************************/
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe/** The max needle size that we will bother searching for
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * This must not be more than half a page! */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe/*******************************************************************************
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe* Structures and Typedefs *
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe*******************************************************************************/
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * State structure for the paging hierarchy dumpers.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** The VM handle. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** Output helpers. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** Set if PSE, PAE or long mode is enabled. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** Set if PAE or long mode is enabled. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** Set if long mode is enabled. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** Set if nested paging. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** Set if EPT. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** Set if NXE is enabled. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** The number or chars the address needs. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** The last reserved bit. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** Dump the page info as well (shadow page summary / guest physical
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * page summary). */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** Whether or not to print the header. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** Whether to print the CR3 value */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** Padding*/
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** The current address. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** The last address to dump structures for. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** The last address to dump structures for. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** Mask with the high reserved bits set. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /** The number of leaf entries that we've printed. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe/** Pointer to the paging hierarchy dumper state. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowetypedef PGMR3DUMPHIERARCHYSTATE *PPGMR3DUMPHIERARCHYSTATE;
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Converts a R3 pointer to a GC physical address.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Only for the debugger.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @returns VBox status code.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @retval VINF_SUCCESS on success, *pGCPhys is set.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @retval VERR_INVALID_POINTER if the pointer is not within the GC physical memory.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pVM The VM handle.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param R3Ptr The R3 pointer to convert.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pGCPhys Where to store the GC physical address on success.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard LoweVMMR3DECL(int) PGMR3DbgR3Ptr2GCPhys(PVM pVM, RTR3PTR R3Ptr, PRTGCPHYS pGCPhys)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Converts a R3 pointer to a HC physical address.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Only for the debugger.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @returns VBox status code.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @retval VINF_SUCCESS on success, *pHCPhys is set.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid GC physical page but has no physical backing.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @retval VERR_INVALID_POINTER if the pointer is not within the GC physical memory.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pVM The VM handle.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param R3Ptr The R3 pointer to convert.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pHCPhys Where to store the HC physical address on success.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard LoweVMMR3DECL(int) PGMR3DbgR3Ptr2HCPhys(PVM pVM, RTR3PTR R3Ptr, PRTHCPHYS pHCPhys)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Converts a HC physical address to a GC physical address.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Only for the debugger.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @returns VBox status code
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @retval VINF_SUCCESS on success, *pGCPhys is set.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @retval VERR_INVALID_POINTER if the HC physical address is not within the GC physical memory.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pVM The VM handle.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param HCPhys The HC physical address to convert.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pGCPhys Where to store the GC physical address on success.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard LoweVMMR3DECL(int) PGMR3DbgHCPhys2GCPhys(PVM pVM, RTHCPHYS HCPhys, PRTGCPHYS pGCPhys)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Validate and adjust the input a bit.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe while (iPage-- > 0)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if (PGM_PAGE_GET_HCPHYS(&pRam->aPages[iPage]) == HCPhys)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe *pGCPhys = pRam->GCPhys + (iPage << PAGE_SHIFT) + off;
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Read physical memory API for the debugger, similar to
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * PGMPhysSimpleReadGCPhys.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @returns VBox status code.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pVM The VM handle.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pvDst Where to store what's read.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param GCPhysDst Where to start reading from.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param cb The number of bytes to attempt reading.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param fFlags Flags, MBZ.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pcbRead For store the actual number of bytes read, pass NULL if
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * partial reads are unwanted.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @todo Unused?
c10c16dec587a0662068f6e2991c29ed3a9db943Richard LoweVMMR3DECL(int) PGMR3DbgReadGCPhys(PVM pVM, void *pvDst, RTGCPHYS GCPhysSrc, size_t cb, uint32_t fFlags, size_t *pcbRead)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* validate */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* try simple first. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe int rc = PGMPhysSimpleReadGCPhys(pVM, pvDst, GCPhysSrc, cb);
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* partial read that failed, chop it up in pages. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe rc = PGMPhysSimpleReadGCPhys(pVM, pvDst, GCPhysSrc, cbChunk);
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* advance */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Write physical memory API for the debugger, similar to
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * PGMPhysSimpleWriteGCPhys.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @returns VBox status code.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pVM The VM handle.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param GCPhysDst Where to start writing.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pvSrc What to write.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param cb The number of bytes to attempt writing.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param fFlags Flags, MBZ.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pcbWritten For store the actual number of bytes written, pass NULL
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * if partial writes are unwanted.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @todo Unused?
c10c16dec587a0662068f6e2991c29ed3a9db943Richard LoweVMMR3DECL(int) PGMR3DbgWriteGCPhys(PVM pVM, RTGCPHYS GCPhysDst, const void *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* validate */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* try simple first. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe int rc = PGMPhysSimpleWriteGCPhys(pVM, GCPhysDst, pvSrc, cb);
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* partial write that failed, chop it up in pages. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe rc = PGMPhysSimpleWriteGCPhys(pVM, GCPhysDst, pvSrc, cbChunk);
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* advance */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe return *pcbWritten && RT_FAILURE(rc) ? -rc : rc;
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Read virtual memory API for the debugger, similar to PGMPhysSimpleReadGCPtr.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @returns VBox status code.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pVM The VM handle.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pvDst Where to store what's read.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param GCPtrDst Where to start reading from.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param cb The number of bytes to attempt reading.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param fFlags Flags, MBZ.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pcbRead For store the actual number of bytes read, pass NULL if
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * partial reads are unwanted.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @todo Unused?
c10c16dec587a0662068f6e2991c29ed3a9db943Richard LoweVMMR3DECL(int) PGMR3DbgReadGCPtr(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb, uint32_t fFlags, size_t *pcbRead)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* validate */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* @todo SMP support! */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe/** @todo deal with HMA */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* try simple first. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe int rc = PGMPhysSimpleReadGCPtr(pVCpu, pvDst, GCPtrSrc, cb);
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* partial read that failed, chop it up in pages. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe rc = PGMPhysSimpleReadGCPtr(pVCpu, pvDst, GCPtrSrc, cbChunk);
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* advance */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * Write virtual memory API for the debugger, similar to
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * PGMPhysSimpleWriteGCPtr.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @returns VBox status code.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pVM The VM handle.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param GCPtrDst Where to start writing.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pvSrc What to write.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param cb The number of bytes to attempt writing.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param fFlags Flags, MBZ.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pcbWritten For store the actual number of bytes written, pass NULL
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * if partial writes are unwanted.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @todo Unused?
c10c16dec587a0662068f6e2991c29ed3a9db943Richard LoweVMMR3DECL(int) PGMR3DbgWriteGCPtr(PVM pVM, RTGCPTR GCPtrDst, void const *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* validate */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* @todo SMP support! */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe/** @todo deal with HMA */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* try simple first. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe int rc = PGMPhysSimpleWriteGCPtr(pVCpu, GCPtrDst, pvSrc, cb);
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* partial write that failed, chop it up in pages. */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe rc = PGMPhysSimpleWriteGCPtr(pVCpu, GCPtrDst, pvSrc, cbChunk);
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe /* advance */
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe return *pcbWritten && RT_FAILURE(rc) ? -rc : rc;
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * memchr() with alignment considerations.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @returns Pointer to matching byte, NULL if none found.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param pb Where to search. Aligned.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe * @param b What to search for.
static const uint8_t *pgmR3DbgAlignedMemChr(const uint8_t *pb, uint8_t b, size_t cb, uint32_t uAlign)
pbRet++;
if (!cbLeft)
if (cb)
if (*pb == b)
return pbRet;
if (*pcbPrev > 0)
if (!pb)
*pcbPrev = 0;
if (!pb)
VMMR3DECL(int) PGMR3DbgScanPhysical(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cbRange, RTGCPHYS GCPhysAlign,
return VERR_INVALID_POINTER;
return VERR_INVALID_POINTER;
if (!cbNeedle)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
if (!cbRange)
return VERR_DBGF_MEM_NOT_FOUND;
return VERR_DBGF_MEM_NOT_FOUND;
if (!GCPhysAlign)
return VERR_INVALID_PARAMETER;
return VERR_NOT_POWER_OF_TWO;
return VERR_INVALID_PARAMETER;
return VERR_DBGF_MEM_NOT_FOUND;
: ~(RTGCPHYS)0;
pRam;
off = 0;
for (;; offPage = 0)
|| fAllZero)
void const *pvPage;
bool fRc;
if (fRc)
return VINF_SUCCESS;
cbPrev = 0;
return VERR_DBGF_MEM_NOT_FOUND;
return VERR_DBGF_MEM_NOT_FOUND;
VMMR3DECL(int) PGMR3DbgScanVirtual(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, RTGCPTR cbRange, RTGCPTR GCPtrAlign,
return VERR_INVALID_POINTER;
*pGCPtrHit = 0;
return VERR_INVALID_POINTER;
if (!cbNeedle)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
if (!cbRange)
return VERR_DBGF_MEM_NOT_FOUND;
return VERR_DBGF_MEM_NOT_FOUND;
if (!GCPtrAlign)
return VERR_INVALID_PARAMETER;
return VERR_NOT_POWER_OF_TWO;
return VERR_INVALID_PARAMETER;
return VERR_DBGF_MEM_NOT_FOUND;
: GCPtrMask;
for (;; offPage = 0)
if ( pPage
|| fAllZero)
void const *pvPage;
bool fRc;
if (fRc)
return VINF_SUCCESS;
cbPrev = 0;
return VERR_DBGF_MEM_NOT_FOUND;
pState->u64HighReservedBits = pState->uLastRsvdBit == 62 ? UINT64_C(0x7ff) << 52 : UINT64_C(0xfff) << 52;
static uint64_t pgmR3DumpHierarchyCalcRange(PPGMR3DUMPHIERARCHYSTATE pState, uint32_t cShift, uint32_t cEntries,
*piFirst = 0;
*piLast = 0;
static int pgmR3DumpHierarchyShwMapPage(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, const char *pszDesc,
void *pvPage;
if (!fIsMapping)
pState->pHlp->pfnPrintf(pState->pHlp, "%0*llx error! %s at HCPhys=%RHp was not found in the page pool!\n",
return rc;
if (!pvPage)
pState->pHlp->pfnPrintf(pState->pHlp, "%0*llx error! PT mapping %s at HCPhys=%RHp was not found in the page pool!\n",
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
if (pPage)
static void pgmR3DumpHierarchyShwGuestPageInfo(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, uint32_t cbPage)
if (pPage)
static int pgmR3DumpHierarchyShwPaePT(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, bool fIsMapping)
int rc = pgmR3DumpHierarchyShwMapPage(pState, HCPhys, "Page table", fIsMapping, (void const **)&pPT);
return rc;
uint64_t u64BaseAddress = pgmR3DumpHierarchyCalcRange(pState, X86_PT_PAE_SHIFT, X86_PG_PAE_ENTRIES, &iFirst, &iLast);
pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx%s", (Pte.u >> 52) & 0x7ff, pState->fLme ? "" : "!");
else if ( (PGMSHWPTEPAE_GET_U(pPT->a[i]) & (pState->pVM->pgm.s.HCPhysInvMmioPg | X86_PTE_PAE_MBZ_MASK_NO_NX))
return VINF_SUCCESS;
static int pgmR3DumpHierarchyShwPaePD(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth)
int rc = pgmR3DumpHierarchyShwMapPage(pState, HCPhys, "Page directory", false, (void const **)&pPD);
return rc;
cMaxDepth--;
uint64_t u64BaseAddress = pgmR3DumpHierarchyCalcRange(pState, X86_PD_PAE_SHIFT, X86_PG_PAE_ENTRIES, &iFirst, &iLast);
pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx%s", (Pde.u >> 52) & 0x7ff, pState->fLme ? "" : "!");
pState->pHlp->pfnPrintf(pState->pHlp, " 20:13=%02llx%s", (Pde.u >> 13) & 0x0ff, pState->fLme ? "" : "!");
if (cMaxDepth)
int rc2 = pgmR3DumpHierarchyShwPaePT(pState, Pde.u & X86_PDE_PAE_PG_MASK, !!(Pde.u & PGM_PDFLAGS_MAPPING));
return rc;
static int pgmR3DumpHierarchyShwPaePDPT(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth)
return VINF_SUCCESS;
int rc = pgmR3DumpHierarchyShwMapPage(pState, HCPhys, "Page directory pointer table", false, (void const **)&pPDPT);
return rc;
cMaxDepth--;
if (cMaxDepth)
return rc;
static int pgmR3DumpHierarchyShwPaePML4(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth)
int rc = pgmR3DumpHierarchyShwMapPage(pState, HCPhys, "Page map level 4", false, (void const **)&pPML4);
return rc;
cMaxDepth--;
if (cMaxDepth)
return rc;
static int pgmR3DumpHierarchyShw32BitPT(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, bool fMapping)
return rc;
uint64_t u64BaseAddress = pgmR3DumpHierarchyCalcRange(pState, X86_PT_SHIFT, X86_PG_ENTRIES, &iFirst, &iLast);
return VINF_SUCCESS;
static int pgmR3DumpHierarchyShw32BitPD(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth)
return VINF_SUCCESS;
int rc = pgmR3DumpHierarchyShwMapPage(pState, HCPhys, "Page directory", false, (void const **)&pPD);
return rc;
cMaxDepth--;
uint64_t u64BaseAddress = pgmR3DumpHierarchyCalcRange(pState, X86_PD_SHIFT, X86_PG_ENTRIES, &iFirst, &iLast);
u64Phys);
if (cMaxDepth)
int rc2 = pgmR3DumpHierarchyShw32BitPT(pState, Pde.u & X86_PDE_PG_MASK, !!(Pde.u & PGM_PDFLAGS_MAPPING));
return rc;
static int pgmR3DumpHierarchyShwDoIt(PPGMR3DUMPHIERARCHYSTATE pState, uint64_t cr3, unsigned cMaxDepth)
int rc;
return rc;
VMMR3_INT_DECL(int) PGMR3DumpHierarchyShw(PVM pVM, uint64_t cr3, uint32_t fFlags, uint64_t u64FirstAddr, uint64_t u64LastAddr,
AssertReturn(!(fFlags & (DBGFPGDMP_FLAGS_CURRENT_MODE | DBGFPGDMP_FLAGS_CURRENT_CR3)), VERR_INVALID_PARAMETER);
VMMR3DECL(int) PGMR3DumpHierarchyHC(PVM pVM, uint64_t cr3, uint64_t cr4, bool fLongMode, unsigned cMaxDepth, PCDBGFINFOHLP pHlp)
if (!cMaxDepth)
return VINF_SUCCESS;
if (!pVCpu)
uint32_t fFlags = DBGFPGDMP_FLAGS_HEADER | DBGFPGDMP_FLAGS_PRINT_CR3 | DBGFPGDMP_FLAGS_PAGE_INFO | DBGFPGDMP_FLAGS_SHADOW;
if (fLongMode)
return DBGFR3PagingDumpEx(pVM, pVCpu->idCpu, fFlags, cr3, 0, fLongMode ? UINT64_MAX : UINT32_MAX, cMaxDepth, pHlp);
static int pgmR3DumpHierarchyGstMapPage(PPGMR3DUMPHIERARCHYSTATE pState, RTGCPHYS GCPhys, const char *pszDesc,
return rc;
return VINF_SUCCESS;
static void pgmR3DumpHierarchyGstPageInfo(PPGMR3DUMPHIERARCHYSTATE pState, RTGCPHYS GCPhys, uint32_t cbPage)
if (pPage)
static void pgmR3DumpHierarchyGstCheckReservedHighBits(PPGMR3DUMPHIERARCHYSTATE pState, uint64_t u64Entry)
if (uRsvd)
return rc;
uint64_t u64BaseAddress = pgmR3DumpHierarchyCalcRange(pState, X86_PT_PAE_SHIFT, X86_PG_PAE_ENTRIES, &iFirst, &iLast);
return VINF_SUCCESS;
static int pgmR3DumpHierarchyGstPaePD(PPGMR3DUMPHIERARCHYSTATE pState, RTGCPHYS GCPhys, unsigned cMaxDepth)
int rc = pgmR3DumpHierarchyGstMapPage(pState, GCPhys, "Page directory", (void const **)&pPD, &Lock);
return rc;
cMaxDepth--;
uint64_t u64BaseAddress = pgmR3DumpHierarchyCalcRange(pState, X86_PD_PAE_SHIFT, X86_PG_PAE_ENTRIES, &iFirst, &iLast);
pState->pHlp->pfnPrintf(pState->pHlp, " 20:13=%02llx%s", (Pde.u >> 13) & 0x0ff, pState->fLme ? "" : "!");
if (cMaxDepth)
return rc;
static int pgmR3DumpHierarchyGstPaePDPT(PPGMR3DUMPHIERARCHYSTATE pState, RTGCPHYS GCPhys, unsigned cMaxDepth)
return VINF_SUCCESS;
int rc = pgmR3DumpHierarchyGstMapPage(pState, GCPhys, "Page directory pointer table", (void const **)&pPDPT, &Lock);
return rc;
cMaxDepth--;
if (cMaxDepth)
return rc;
static int pgmR3DumpHierarchyGstPaePML4(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS GCPhys, unsigned cMaxDepth)
int rc = pgmR3DumpHierarchyGstMapPage(pState, GCPhys, "Page map level 4", (void const **)&pPML4, &Lock);
return rc;
cMaxDepth--;
if (cMaxDepth)
return rc;
return rc;
uint64_t u64BaseAddress = pgmR3DumpHierarchyCalcRange(pState, X86_PT_SHIFT, X86_PG_ENTRIES, &iFirst, &iLast);
return VINF_SUCCESS;
static int pgmR3DumpHierarchyGst32BitPD(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS GCPhys, unsigned cMaxDepth)
return VINF_SUCCESS;
int rc = pgmR3DumpHierarchyGstMapPage(pState, GCPhys, "Page directory", (void const **)&pPD, &Lock);
return rc;
cMaxDepth--;
uint64_t u64BaseAddress = pgmR3DumpHierarchyCalcRange(pState, X86_PD_SHIFT, X86_PG_ENTRIES, &iFirst, &iLast);
u64Phys);
if (cMaxDepth)
return rc;
static int pgmR3DumpHierarchyGstDoIt(PPGMR3DUMPHIERARCHYSTATE pState, uint64_t cr3, unsigned cMaxDepth)
int rc;
return rc;
VMMR3_INT_DECL(int) PGMR3DumpHierarchyGst(PVM pVM, uint64_t cr3, uint32_t fFlags, RTGCPTR FirstAddr, RTGCPTR LastAddr,