VirtualBox

Changeset 31966 in vbox for trunk


Ignore:
Timestamp:
Aug 25, 2010 4:15:25 PM (14 years ago)
Author:
vboxsync
Message:

DBGF,PGM,DBGC: dumping page tables - hacking still in progress (sigh, this takes for ever).

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/dbg.h

    r31927 r31966  
    3636
    3737#include <iprt/stdarg.h>
     38#ifdef IN_RING3
     39# include <iprt/err.h>
     40#endif
    3841
    3942RT_C_DECLS_BEGIN
     
    500503    DECLCALLBACKMEMBER(int, pfnVarToBool)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, bool *pf);
    501504
     505    /**
     506     * Get the range of a variable in bytes, resolving symbols if necessary.
     507     *
     508     * @returns VBox status code.
     509     * @param   pCmdHlp     Pointer to the command callback structure.
     510     * @param   pVar        The variable to convert.
     511     * @param   cbElement   Conversion factor for element ranges.
     512     * @param   cbDefault   The default range.
     513     * @param   pcbRange    The length of the range.
     514     */
     515    DECLCALLBACKMEMBER(int, pfnVarGetRange)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t cbElement, uint64_t cbDefault,
     516                                            uint64_t *pcbRange);
     517
     518    /**
     519     * Gets a DBGF output helper that directs the output to the debugger
     520     * console.
     521     *
     522     * @returns Pointer to the helper structure.
     523     * @param   pCmdHlp     Pointer to the command callback structure.
     524     */
     525    DECLCALLBACKMEMBER(PCDBGFINFOHLP, pfnGetDbgfOutputHlp)(PDBGCCMDHLP pCmdHlp);
     526
    502527} DBGCCMDHLP;
    503528
     
    590615
    591616    return rc;
     617}
     618
     619/**
     620 * @copydoc DBGCCMDHLP::pfnVarToDbgfAddr
     621 */
     622DECLINLINE(int) DBGCCmdHlpVarToDbgfAddr(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PDBGFADDRESS pAddress)
     623{
     624    return pCmdHlp->pfnVarToDbgfAddr(pCmdHlp, pVar, pAddress);
     625}
     626
     627/**
     628 * Converts an variable to a flat address.
     629 *
     630 * @returns VBox status code.
     631 * @param   pCmdHlp     Pointer to the command callback structure.
     632 * @param   pVar        The variable to convert.
     633 * @param   pFlatPtr    Where to store the flat address.
     634 */
     635DECLINLINE(int) DBGCCmdHlpVarToFlatAddr(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PRTGCPTR pFlatPtr)
     636{
     637    DBGFADDRESS Addr;
     638    int rc = pCmdHlp->pfnVarToDbgfAddr(pCmdHlp, pVar, &Addr);
     639    if (RT_SUCCESS(rc))
     640        *pFlatPtr = Addr.FlatPtr;
     641    return rc;
     642}
     643
     644/**
     645 * @copydoc DBGCCMDHLP::pfnVarGetRange
     646 */
     647DECLINLINE(int) DBGCCmdHlpVarGetRange(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t cbElement, uint64_t cbDefault, uint64_t *pcbRange)
     648{
     649    return pCmdHlp->pfnVarGetRange(pCmdHlp, pVar, cbElement, cbDefault, pcbRange);
     650}
     651
     652/**
     653 * @copydoc DBGCCMDHLP::pfnGetDbgfOutputHlp
     654 */
     655DECLINLINE(PCDBGFINFOHLP) DBGCCmdHlpGetDbgfOutputHlp(PDBGCCMDHLP pCmdHlp)
     656{
     657    return pCmdHlp->pfnGetDbgfOutputHlp(pCmdHlp);
    592658}
    593659
  • trunk/include/VBox/dbgf.h

    r31948 r31966  
    918918
    919919
     920/** @name Flags for DBGFR3PagingDumpEx, PGMR3DumpHierarchyHCEx and
     921 * PGMR3DumpHierarchyGCEx
     922 * @{ */
     923/** The CR3 from the current CPU state. */
     924#define DBGFPGDMP_FLAGS_CURRENT_CR3     RT_BIT_32(0)
     925/** The current CPU paging mode (PSE, PAE, LM, EPT, NX). */
     926#define DBGFPGDMP_FLAGS_CURRENT_MODE    RT_BIT_32(1)
     927/** Whether PSE is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
     928 * Same value as X86_CR4_PSE. */
     929#define DBGFPGDMP_FLAGS_PSE             RT_BIT_32(4) /*  */
     930/** Whether PAE is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
     931 * Same value as X86_CR4_PAE. */
     932#define DBGFPGDMP_FLAGS_PAE             RT_BIT_32(5) /*  */
     933/** Whether LME is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
     934 * Same value as MSR_K6_EFER_LME. */
     935#define DBGFPGDMP_FLAGS_LME             RT_BIT_32(8)
     936/** Whether nested paging is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE). */
     937#define DBGFPGDMP_FLAGS_NP              RT_BIT_32(9)
     938/** Whether extended nested page tables are enabled
     939 * (!DBGFPGDMP_FLAGS_CURRENT_STATE). */
     940#define DBGFPGDMP_FLAGS_EPT             RT_BIT_32(10)
     941/** Whether no-execution is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
     942 * Same value as MSR_K6_EFER_NXE. */
     943#define DBGFPGDMP_FLAGS_NXE             RT_BIT_32(11)
     944/** Whether to print the header. */
     945#define DBGFPGDMP_FLAGS_HEADER          RT_BIT_32(28)
     946/** Whether to dump additional page information. */
     947#define DBGFPGDMP_FLAGS_PAGE_INFO       RT_BIT_32(29)
     948/** Dump the shadow tables if set.
     949 * Cannot be used together with DBGFPGDMP_FLAGS_GUEST. */
     950#define DBGFPGDMP_FLAGS_SHADOW          RT_BIT_32(30)
     951/** Dump the guest tables if set.
     952 * Cannot be used together with DBGFPGDMP_FLAGS_SHADOW. */
     953#define DBGFPGDMP_FLAGS_GUEST           RT_BIT_32(31)
     954/** Mask of valid bits. */
     955#define DBGFPGDMP_FLAGS_VALID_MASK      UINT32_C(0xf0000f33)
     956/** The mask of bits controlling the paging mode. */
     957#define DBGFPGDMP_FLAGS_MODE_MASK       UINT32_C(0x00000f32)
     958/** @}  */
     959VMMDECL(int) DBGFR3PagingDumpEx(PVM pVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr,
     960                                uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp);
     961
     962
    920963/** @name DBGFR3SelQueryInfo flags.
    921964 * @{ */
  • trunk/include/VBox/pgm.h

    r31948 r31966  
    565565VMMR3DECL(int)      PGMR3DbgScanVirtual(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, RTGCPTR cbRange, RTGCPTR GCPtrAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCUINTPTR pGCPhysHit);
    566566VMMR3DECL(int)      PGMR3DumpHierarchyHC(PVM pVM, uint64_t cr3, uint64_t cr4, bool fLongMode, unsigned cMaxDepth, PCDBGFINFOHLP pHlp);
     567VMMR3_INT_DECL(int) PGMR3DumpHierarchyHCEx(PVM pVM, uint64_t cr3, uint32_t fFlags, uint64_t u64FirstAddr, uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp);
    567568VMMR3DECL(int)      PGMR3DumpHierarchyGC(PVM pVM, uint64_t cr3, uint64_t cr4, RTGCPHYS PhysSearch);
     569VMMR3_INT_DECL(int) PGMR3DumpHierarchyGCEx(PVM pVM, uint64_t cr3, uint32_t fFlags, RTGCPTR FirstAddr, RTGCPTR LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp);
    568570
    569571
  • trunk/src/VBox/Debugger/DBGCCmdHlp.cpp

    r31530 r31966  
    792792
    793793/**
     794 * @interface_method_impl{DBGCCMDHLP,pfnVarGetRange}
     795 */
     796static DECLCALLBACK(int) dbgcHlpVarGetRange(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t cbElement, uint64_t cbDefault,
     797                                            uint64_t *pcbRange)
     798{
     799/** @todo implement this properly, strings/symbols are not resolved now. */
     800    switch (pVar->enmRangeType)
     801    {
     802        default:
     803        case DBGCVAR_RANGE_NONE:
     804            *pcbRange = cbDefault;
     805            break;
     806        case DBGCVAR_RANGE_BYTES:
     807            *pcbRange = pVar->u64Range;
     808            break;
     809        case DBGCVAR_RANGE_ELEMENTS:
     810            *pcbRange = pVar->u64Range * cbElement;
     811            break;
     812    }
     813    return VINF_SUCCESS;
     814}
     815
     816
     817/**
     818 * Info helper callback wrapper - print formatted string.
     819 *
     820 * @param   pHlp        Pointer to this structure.
     821 * @param   pszFormat   The format string.
     822 * @param   ...         Arguments.
     823 */
     824static DECLCALLBACK(void) dbgcHlpGetDbgfOutputHlp_Printf(PCDBGFINFOHLP pHlp, const char *pszFormat, ...)
     825{
     826    PDBGC pDbgc = RT_FROM_MEMBER(pHlp, DBGC, DbgfOutputHlp);
     827    va_list va;
     828    va_start(va, pszFormat);
     829    pDbgc->CmdHlp.pfnPrintfV(&pDbgc->CmdHlp, NULL, pszFormat, va);
     830    va_end(va);
     831}
     832
     833
     834/**
     835 * Info helper callback wrapper - print formatted string.
     836 *
     837 * @param   pHlp        Pointer to this structure.
     838 * @param   pszFormat   The format string.
     839 * @param   args        Argument list.
     840 */
     841static DECLCALLBACK(void) dbgcHlpGetDbgfOutputHlp_PrintfV(PCDBGFINFOHLP pHlp, const char *pszFormat, va_list args)
     842{
     843    PDBGC pDbgc = RT_FROM_MEMBER(pHlp, DBGC, DbgfOutputHlp);
     844    pDbgc->CmdHlp.pfnPrintfV(&pDbgc->CmdHlp, NULL, pszFormat, args);
     845}
     846
     847
     848/**
     849 * @interface_method_impl{DBGCCMDHLP,pfnGetDbgfOutputHlp}
     850 */
     851static DECLCALLBACK(PCDBGFINFOHLP) dbgcHlpGetDbgfOutputHlp(PDBGCCMDHLP pCmdHlp)
     852{
     853    PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
     854
     855    /* Lazy init */
     856    if (!pDbgc->DbgfOutputHlp.pfnPrintf)
     857    {
     858        pDbgc->DbgfOutputHlp.pfnPrintf  = dbgcHlpGetDbgfOutputHlp_Printf;
     859        pDbgc->DbgfOutputHlp.pfnPrintfV = dbgcHlpGetDbgfOutputHlp_PrintfV;
     860    }
     861
     862    return &pDbgc->DbgfOutputHlp;
     863}
     864
     865
     866/**
    794867 * Initializes the Command Helpers for a DBGC instance.
    795868 *
     
    798871void dbgcInitCmdHlp(PDBGC pDbgc)
    799872{
    800     pDbgc->CmdHlp.pfnWrite      = dbgcHlpWrite;
    801     pDbgc->CmdHlp.pfnPrintfV    = dbgcHlpPrintfV;
    802     pDbgc->CmdHlp.pfnPrintf     = dbgcHlpPrintf;
    803     pDbgc->CmdHlp.pfnVBoxErrorV = dbgcHlpVBoxErrorV;
    804     pDbgc->CmdHlp.pfnVBoxError  = dbgcHlpVBoxError;
    805     pDbgc->CmdHlp.pfnMemRead    = dbgcHlpMemRead;
    806     pDbgc->CmdHlp.pfnMemWrite   = dbgcHlpMemWrite;
    807     pDbgc->CmdHlp.pfnEvalV      = dbgcHlpEvalV;
    808     pDbgc->CmdHlp.pfnExec       = dbgcHlpExec;
    809     pDbgc->CmdHlp.pfnFailV      = dbgcHlpFailV;
    810     pDbgc->CmdHlp.pfnVarToDbgfAddr = dbgcHlpVarToDbgfAddr;
    811     pDbgc->CmdHlp.pfnVarToBool = dbgcHlpVarToBool;
    812 }
    813 
     873    pDbgc->CmdHlp.pfnWrite              = dbgcHlpWrite;
     874    pDbgc->CmdHlp.pfnPrintfV            = dbgcHlpPrintfV;
     875    pDbgc->CmdHlp.pfnPrintf             = dbgcHlpPrintf;
     876    pDbgc->CmdHlp.pfnVBoxErrorV         = dbgcHlpVBoxErrorV;
     877    pDbgc->CmdHlp.pfnVBoxError          = dbgcHlpVBoxError;
     878    pDbgc->CmdHlp.pfnMemRead            = dbgcHlpMemRead;
     879    pDbgc->CmdHlp.pfnMemWrite           = dbgcHlpMemWrite;
     880    pDbgc->CmdHlp.pfnEvalV              = dbgcHlpEvalV;
     881    pDbgc->CmdHlp.pfnExec               = dbgcHlpExec;
     882    pDbgc->CmdHlp.pfnFailV              = dbgcHlpFailV;
     883    pDbgc->CmdHlp.pfnVarToDbgfAddr      = dbgcHlpVarToDbgfAddr;
     884    pDbgc->CmdHlp.pfnVarToBool          = dbgcHlpVarToBool;
     885    pDbgc->CmdHlp.pfnVarGetRange        = dbgcHlpVarGetRange;
     886    pDbgc->CmdHlp.pfnGetDbgfOutputHlp   = dbgcHlpGetDbgfOutputHlp;
     887}
     888
  • trunk/src/VBox/Debugger/DBGCCommands.cpp

    r31530 r31966  
    874874
    875875/**
    876  * Print formatted string.
    877  *
    878  * @param   pHlp        Pointer to this structure.
    879  * @param   pszFormat   The format string.
    880  * @param   ...         Arguments.
    881  */
    882 static DECLCALLBACK(void) dbgcCmdInfo_Printf(PCDBGFINFOHLP pHlp, const char *pszFormat, ...)
    883 {
    884     PDBGCCMDHLP pCmdHlp = *(PDBGCCMDHLP *)(pHlp + 1);
    885     va_list args;
    886     va_start(args,  pszFormat);
    887     pCmdHlp->pfnPrintfV(pCmdHlp, NULL, pszFormat, args);
    888     va_end(args);
    889 }
    890 
    891 
    892 /**
    893  * Print formatted string.
    894  *
    895  * @param   pHlp        Pointer to this structure.
    896  * @param   pszFormat   The format string.
    897  * @param   args        Argument list.
    898  */
    899 static DECLCALLBACK(void) dbgcCmdInfo_PrintfV(PCDBGFINFOHLP pHlp, const char *pszFormat, va_list args)
    900 {
    901     PDBGCCMDHLP pCmdHlp = *(PDBGCCMDHLP *)(pHlp + 1);
    902     pCmdHlp->pfnPrintfV(pCmdHlp, NULL, pszFormat, args);
    903 }
    904 
    905 
    906 /**
    907876 * The 'info' command.
    908877 *
     
    932901     * Dump it.
    933902     */
    934     struct
    935     {
    936         DBGFINFOHLP Hlp;
    937         DBGCCMDHLP *pCmdHlp; /* XXX gcc warns when using PDBGCCMDHLP here */
    938     } Hlp = { { dbgcCmdInfo_Printf, dbgcCmdInfo_PrintfV }, pCmdHlp };
    939     int rc = VMR3ReqCallWait(pVM, pDbgc->idCpu,
    940                              (PFNRT)DBGFR3Info, 4, pVM, paArgs[0].u.pszString, cArgs == 2 ? paArgs[1].u.pszString : NULL, &Hlp.Hlp);
     903    int rc = VMR3ReqCallWait(pVM, pDbgc->idCpu, (PFNRT)DBGFR3Info, 4,
     904                             pVM, paArgs[0].u.pszString, cArgs == 2 ? paArgs[1].u.pszString : NULL,
     905                             DBGCCmdHlpGetDbgfOutputHlp(pCmdHlp));
    941906    if (RT_FAILURE(rc))
    942907        return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGFR3Info()\n");
  • trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp

    r31769 r31966  
    5858static DECLCALLBACK(int) dbgcCmdDumpPageDir(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
    5959static DECLCALLBACK(int) dbgcCmdDumpPageDirBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
     60static DECLCALLBACK(int) dbgcCmdDumpPageHierarchy(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
    6061static DECLCALLBACK(int) dbgcCmdDumpPageTable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
    6162static DECLCALLBACK(int) dbgcCmdDumpPageTableBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
     
    164165    /* cTimesMin,   cTimesMax,  enmCategory,            fFlags,                         pszName,        pszDescription */
    165166    {  0,           1,          DBGCVAR_CAT_POINTER,    0,                              "address",      "Address of the page directory entry to start dumping from." },
     167};
     168
     169
     170/** 'dph*' arguments. */
     171static const DBGCVARDESC    g_aArgDumpPH[] =
     172{
     173    /* cTimesMin,   cTimesMax,  enmCategory,            fFlags,                         pszName,        pszDescription */
     174    {  0,           1,          DBGCVAR_CAT_GC_POINTER, 0,                              "address",      "Where in the address space to start dumping and for how long (range).  The default address/range will be used if omitted." },
     175    {  0,           1,          DBGCVAR_CAT_NUMBER,     DBGCVD_FLAGS_DEP_PREV,          "cr3",          "The CR3 value to use.  The current CR3 of the context will be used if omitted." },
     176    {  0,           1,          DBGCVAR_CAT_STRING,     DBGCVD_FLAGS_DEP_PREV,          "mode",         "The paging mode: legacy, pse, pae, long, ept. Append '-np' for nested paging and '-nx' for no-execute.  The current mode will be used if omitted." },
    166177};
    167178
     
    314325    { "dpdg",       0,        1,        &g_aArgDumpPD[0],   RT_ELEMENTS(g_aArgDumpPD),     NULL,               0,       dbgcCmdDumpPageDir, "[addr] [index]",       "Dumps page directory entries of the guest." },
    315326    { "dpdh",       0,        1,        &g_aArgDumpPD[0],   RT_ELEMENTS(g_aArgDumpPD),     NULL,               0,       dbgcCmdDumpPageDir, "[addr] [index]",       "Dumps page directory entries of the hypervisor. " },
     327    { "dph",        0,        3,        &g_aArgDumpPH[0],   RT_ELEMENTS(g_aArgDumpPH),     NULL,               0, dbgcCmdDumpPageHierarchy, "[addr [cr3 [mode]]",   "Dumps the paging hierarchy at for specfied address range. Default context." },
     328    { "dphg",       0,        3,        &g_aArgDumpPH[0],   RT_ELEMENTS(g_aArgDumpPH),     NULL,               0, dbgcCmdDumpPageHierarchy, "[addr [cr3 [mode]]",   "Dumps the paging hierarchy at for specfied address range. Guest context." },
     329    { "dphh",       0,        3,        &g_aArgDumpPH[0],   RT_ELEMENTS(g_aArgDumpPH),     NULL,               0, dbgcCmdDumpPageHierarchy, "[addr [cr3 [mode]]",   "Dumps the paging hierarchy at for specfied address range. Hypervisor context." },
    316330    { "dpt",        1,        1,        &g_aArgDumpPT[0],   RT_ELEMENTS(g_aArgDumpPT),     NULL,               0,       dbgcCmdDumpPageTable,"<addr>",              "Dumps page table entries of the default context." },
    317331    { "dpta",       1,        1,        &g_aArgDumpPTAddr[0],RT_ELEMENTS(g_aArgDumpPTAddr), NULL,              0,       dbgcCmdDumpPageTable,"<addr>",              "Dumps specified page table." },
     
    979993    else
    980994        pDbgc->DisasmPos = paArgs[0];
     995    pDbgc->pLastPos = &pDbgc->DisasmPos;
    981996
    982997    /*
     
    11371152    else
    11381153        pDbgc->SourcePos = paArgs[0];
     1154    pDbgc->pLastPos = &pDbgc->SourcePos;
    11391155
    11401156    /*
     
    23772393    }
    23782394
     2395    pDbgc->pLastPos = &pDbgc->DumpPos;
     2396
    23792397    /*
    23802398     * Do the dumping.
     
    28502868
    28512869/**
     2870 * The 'dph*' commands.
     2871 *
     2872 * @returns VBox status.
     2873 * @param   pCmd        Pointer to the command descriptor (as registered).
     2874 * @param   pCmdHlp     Pointer to command helper functions.
     2875 * @param   pVM         Pointer to the current VM (if any).
     2876 * @param   paArgs      Pointer to (readonly) array of arguments.
     2877 * @param   cArgs       Number of arguments in the array.
     2878 */
     2879static DECLCALLBACK(int) dbgcCmdDumpPageHierarchy(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
     2880{
     2881    PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
     2882    if (!pVM)
     2883        return DBGCCmdHlpFail(pCmdHlp, pCmd, "No VM.\n");
     2884
     2885    /*
     2886     * Figure the context.
     2887     */
     2888    uint32_t fFlags = 0;
     2889    if (pCmd->pszCmd[3] == '\0')
     2890        fFlags |= pDbgc->fRegCtxGuest ? DBGFPGDMP_FLAGS_GUEST : DBGFPGDMP_FLAGS_SHADOW;
     2891    else if (pCmd->pszCmd[3] == 'g')
     2892        fFlags |= DBGFPGDMP_FLAGS_GUEST;
     2893    else if (pCmd->pszCmd[3] == 'h')
     2894        fFlags |= DBGFPGDMP_FLAGS_SHADOW;
     2895    else
     2896        fFlags |= DBGFPGDMP_FLAGS_GUEST | DBGFPGDMP_FLAGS_SHADOW;
     2897
     2898    /*
     2899     * Get the range.
     2900     */
     2901    PCDBGCVAR   pRange = cArgs > 0 ? &paArgs[0] : pDbgc->pLastPos;
     2902    RTGCPTR     GCPtrFirst;
     2903    int rc = DBGCCmdHlpVarToFlatAddr(pCmdHlp, pRange, &GCPtrFirst);
     2904    if (RT_FAILURE(rc))
     2905        return DBGCCmdHlpFail(pCmdHlp, pCmd, "Failed to convert %DV to a flat address: %Rrc", pRange, rc);
     2906
     2907    uint64_t cbRange;
     2908    rc = DBGCCmdHlpVarGetRange(pCmdHlp, pRange, 1, PAGE_SIZE * 8, &cbRange);
     2909    if (RT_FAILURE(rc))
     2910        return DBGCCmdHlpFail(pCmdHlp, pCmd, "Failed to obtain the range of %DV: %Rrc", pRange, rc);
     2911
     2912    RTGCPTR GCPtrLast = RTGCPTR_MAX - GCPtrFirst;
     2913    if (cbRange >= GCPtrLast)
     2914        GCPtrLast = RTGCPTR_MAX;
     2915    else if (!cbRange)
     2916        GCPtrLast = GCPtrFirst;
     2917    else
     2918        GCPtrLast = GCPtrFirst + cbRange - 1;
     2919
     2920    /*
     2921     * Do we have a CR3?
     2922     */
     2923    uint64_t cr3 = 0;
     2924    if (cArgs > 1)
     2925    {
     2926        if ((fFlags & (DBGFPGDMP_FLAGS_GUEST | DBGFPGDMP_FLAGS_SHADOW)) == (DBGFPGDMP_FLAGS_GUEST | DBGFPGDMP_FLAGS_SHADOW))
     2927            return DBGCCmdHlpFail(pCmdHlp, pCmd, "No CR3 or mode arguments when dumping both context, please.");
     2928        if (paArgs[1].enmType != DBGCVAR_TYPE_NUMBER)
     2929            return DBGCCmdHlpFail(pCmdHlp, pCmd, "The CR3 argument is not a number: %DV", &paArgs[1]);
     2930        cr3 = paArgs[1].u.u64Number;
     2931    }
     2932    else
     2933        fFlags |= DBGFPGDMP_FLAGS_CURRENT_CR3;
     2934
     2935    /*
     2936     * Do we have a mode?
     2937     */
     2938    if (cArgs > 2)
     2939    {
     2940        if (paArgs[2].enmType != DBGCVAR_TYPE_STRING)
     2941            return DBGCCmdHlpFail(pCmdHlp, pCmd, "The mode argument is not a string: %DV", &paArgs[2]);
     2942        static const struct MODETOFLAGS
     2943        {
     2944            const char *pszName;
     2945            uint32_t    fFlags;
     2946        } s_aModeToFlags[] =
     2947        {
     2948            { "ept",        DBGFPGDMP_FLAGS_EPT },
     2949            { "legacy",     0 },
     2950            { "legacy-np",  DBGFPGDMP_FLAGS_NP },
     2951            { "pse",        DBGFPGDMP_FLAGS_PSE },
     2952            { "pse-np",     DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_NP },
     2953            { "pae",        DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE },
     2954            { "pae-np",     DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_NP },
     2955            { "pae-nx",     DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_NXE },
     2956            { "pae-nx-np",  DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_NXE | DBGFPGDMP_FLAGS_NP },
     2957            { "long",       DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME },
     2958            { "long-np",    DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME | DBGFPGDMP_FLAGS_NP },
     2959            { "long-nx",    DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME | DBGFPGDMP_FLAGS_NXE },
     2960            { "long-nx-np", DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME | DBGFPGDMP_FLAGS_NXE | DBGFPGDMP_FLAGS_NP }
     2961        };
     2962        int i = RT_ELEMENTS(s_aModeToFlags);
     2963        while (i-- > 0)
     2964            if (!strcmp(s_aModeToFlags[i].pszName, paArgs[2].u.pszString))
     2965            {
     2966                fFlags |= s_aModeToFlags[i].fFlags;
     2967                break;
     2968            }
     2969        if (i < 0)
     2970            return DBGCCmdHlpFail(pCmdHlp, pCmd, "Unknown mode: \"%s\"", paArgs[2].u.pszString);
     2971    }
     2972    else
     2973        fFlags |= DBGFPGDMP_FLAGS_CURRENT_MODE;
     2974
     2975    /*
     2976     * Call the worker.
     2977     */
     2978    rc = DBGFR3PagingDumpEx(pVM, pDbgc->idCpu, fFlags, cr3, GCPtrFirst, GCPtrLast, 99 /*cMaxDepth*/,
     2979                            DBGCCmdHlpGetDbgfOutputHlp(pCmdHlp));
     2980    if (RT_FAILURE(rc))
     2981        return DBGCCmdHlpFail(pCmdHlp, pCmd, "DBGFR3PagingDumpEx: %Rrc\n", rc);
     2982    return VINF_SUCCESS;
     2983}
     2984
     2985
     2986
     2987/**
    28522988 * The 'dpg*' commands.
    28532989 *
  • trunk/src/VBox/Debugger/DBGCInternal.h

    r31530 r31966  
    145145    /** Command helpers. */
    146146    DBGCCMDHLP          CmdHlp;
     147    /** Wrappers for DBGF output. */
     148    DBGFINFOHLP         DbgfOutputHlp;
    147149    /** Pointer to backend callback structure. */
    148150    PDBGCBACK           pBack;
     
    176178    /** Size of the previous dump element. */
    177179    unsigned            cbDumpElement;
     180    /** Points to DisasmPos, SourcePos or DumpPos depending on which was
     181     *  used last. */
     182    PCDBGCVAR           pLastPos;
    178183
    179184    /** Number of variables in papVars. */
  • trunk/src/VBox/Debugger/DBGConsole.cpp

    r31530 r31966  
    19661966    //pDbgc->SourcePos        = {0};
    19671967    //pDbgc->DumpPos          = {0};
     1968    pDbgc->pLastPos          = &pDbgc->DisasmPos;
    19681969    //pDbgc->cbDumpElement    = 0;
    19691970    //pDbgc->cVars            = 0;
  • trunk/src/VBox/Debugger/testcase/tstDBGCStubs.cpp

    r31530 r31966  
    185185    return VERR_INTERNAL_ERROR;
    186186}
     187VMMDECL(int) DBGFR3PagingDumpEx(PVM pVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr,
     188                                uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp)
     189{
     190    return VERR_INTERNAL_ERROR;
     191}
    187192VMMR3DECL(int) DBGFR3RegQueryU8(  PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t     *pu8)
    188193{
  • trunk/src/VBox/VMM/DBGFMem.cpp

    r30320 r31966  
    55
    66/*
    7  * Copyright (C) 2007 Oracle Corporation
     7 * Copyright (C) 2007-2010 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    125125                             const void *pvNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress)
    126126{
    127     AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_PARAMETER);
     127    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     128    AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
    128129    return VMR3ReqCallWait(pVM, idCpu, (PFNRT)dbgfR3MemScan, 8,
    129130                           pVM, idCpu, pAddress, &cbRange, &uAlign, pvNeedle, cbNeedle, pHitAddress);
     
    204205VMMR3DECL(int) DBGFR3MemRead(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead)
    205206{
    206     AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_PARAMETER);
     207    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     208    AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
    207209    if ((pAddress->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_RING0)
    208210    {
     
    283285        return VERR_INVALID_PARAMETER;
    284286    memset(pszBuf, 0, cchBuf);
    285     AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_PARAMETER);
     287    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     288    AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
    286289
    287290    /*
     
    362365VMMR3DECL(int) DBGFR3MemWrite(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void const *pvBuf, size_t cbWrite)
    363366{
    364     AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_PARAMETER);
     367    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     368    AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
    365369    return VMR3ReqCallWaitU(pVM->pUVM, idCpu, (PFNRT)dbgfR3MemWrite, 5, pVM, idCpu, pAddress, pvBuf, cbWrite);
    366370}
     
    454458VMMR3DECL(int) DBGFR3SelQueryInfo(PVM pVM, VMCPUID idCpu, RTSEL Sel, uint32_t fFlags, PDBGFSELINFO pSelInfo)
    455459{
    456     AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_PARAMETER);
     460    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     461    AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
    457462    AssertReturn(!(fFlags & ~(DBGFSELQI_FLAGS_DT_GUEST | DBGFSELQI_FLAGS_DT_SHADOW | DBGFSELQI_FLAGS_DT_ADJ_64BIT_MODE)), VERR_INVALID_PARAMETER);
    458463    AssertReturn(    (fFlags & (DBGFSELQI_FLAGS_DT_SHADOW | DBGFSELQI_FLAGS_DT_ADJ_64BIT_MODE))
     
    505510}
    506511
     512
     513/**
     514 * Convers a PGM paging mode to a set of DBGFPGDMP_XXX flags.
     515 *
     516 * @returns Flags. UINT32_MAX if the mode is invalid (asserted).
     517 * @param   enmMode             The mode.
     518 */
     519static uint32_t dbgfR3PagingDumpModeToFlags(PGMMODE enmMode)
     520{
     521    switch (enmMode)
     522    {
     523        case PGMMODE_32_BIT:
     524            return DBGFPGDMP_FLAGS_PSE;
     525        case PGMMODE_PAE:
     526            return DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE;
     527        case PGMMODE_PAE_NX:
     528            return DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_NXE;
     529        case PGMMODE_AMD64:
     530            return DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME;
     531        case PGMMODE_AMD64_NX:
     532            return DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME | DBGFPGDMP_FLAGS_NXE;
     533        case PGMMODE_NESTED:
     534            return DBGFPGDMP_FLAGS_NP;
     535        case PGMMODE_EPT:
     536            return DBGFPGDMP_FLAGS_EPT;
     537        default:
     538            AssertFailedReturn(UINT32_MAX);
     539    }
     540}
     541
     542
     543/**
     544 * EMT worker for DBGFR3PagingDumpEx.
     545 *
     546 * @returns VBox status code.
     547 * @param   pVM             The VM handle.
     548 * @param   idCpu           The current CPU ID.
     549 * @param   fFlags          The flags, DBGFPGDMP_FLAGS_XXX.  Valid.
     550 * @param   pcr3            The CR3 to use (unless we're getting the current
     551 *                          state, see @a fFlags).
     552 * @param   pu64FirstAddr   The first address.
     553 * @param   pu64LastAddr    The last address.
     554 * @param   cMaxDepth       The depth.
     555 * @param   pHlp            The output callbacks.
     556 */
     557static DECLCALLBACK(int) dbgfR3PagingDumpEx(PVM pVM, VMCPUID idCpu, uint32_t fFlags, uint64_t *pcr3,
     558                                            uint64_t *pu64FirstAddr, uint64_t *pu64LastAddr,
     559                                            uint32_t cMaxDepth, PCDBGFINFOHLP pHlp)
     560{
     561    /*
     562     * Implement dumping both context by means of recursion.
     563     */
     564    if ((fFlags & (DBGFPGDMP_FLAGS_GUEST | DBGFPGDMP_FLAGS_SHADOW)) == (DBGFPGDMP_FLAGS_GUEST | DBGFPGDMP_FLAGS_SHADOW))
     565    {
     566        int rc1 = dbgfR3PagingDumpEx(pVM, idCpu, fFlags & ~DBGFPGDMP_FLAGS_GUEST,
     567                                     pcr3, pu64FirstAddr, pu64LastAddr, cMaxDepth, pHlp);
     568        int rc2 = dbgfR3PagingDumpEx(pVM, idCpu, fFlags & ~DBGFPGDMP_FLAGS_SHADOW,
     569                                     pcr3, pu64FirstAddr, pu64LastAddr, cMaxDepth, pHlp);
     570        return RT_FAILURE(rc1) ? rc1 : rc2;
     571    }
     572
     573    /*
     574     * Get the current CR3/mode if required.
     575     */
     576    uint64_t cr3 = *pcr3;
     577    if (fFlags & (DBGFPGDMP_FLAGS_CURRENT_CR3 | DBGFPGDMP_FLAGS_CURRENT_MODE))
     578    {
     579        PVMCPU pVCpu = &pVM->aCpus[idCpu];
     580        if (fFlags & DBGFPGDMP_FLAGS_SHADOW)
     581        {
     582            if (fFlags & DBGFPGDMP_FLAGS_CURRENT_CR3)
     583                cr3 = PGMGetHyperCR3(pVCpu);
     584            if (fFlags & DBGFPGDMP_FLAGS_CURRENT_MODE)
     585            {
     586                fFlags |= dbgfR3PagingDumpModeToFlags(PGMGetShadowMode(pVCpu));
     587                if (fFlags & DBGFPGDMP_FLAGS_NP)
     588                {
     589                    fFlags |= dbgfR3PagingDumpModeToFlags(PGMGetHostMode(pVM));
     590                    if (HC_ARCH_BITS == 32 && CPUMIsGuestInLongMode(pVCpu))
     591                        fFlags |= DBGFPGDMP_FLAGS_LME;
     592                }
     593            }
     594        }
     595        else
     596        {
     597            if (fFlags & DBGFPGDMP_FLAGS_CURRENT_CR3)
     598                cr3 = CPUMGetGuestCR3(pVCpu);
     599            if (fFlags & DBGFPGDMP_FLAGS_CURRENT_MODE)
     600            {
     601                AssertCompile(DBGFPGDMP_FLAGS_PSE == X86_CR4_PSE);      AssertCompile(DBGFPGDMP_FLAGS_PAE == X86_CR4_PAE);
     602                fFlags |= CPUMGetGuestCR4(pVCpu)  & (X86_CR4_PSE | X86_CR4_PAE);
     603                AssertCompile(DBGFPGDMP_FLAGS_LME == MSR_K6_EFER_LME);  AssertCompile(DBGFPGDMP_FLAGS_NXE == MSR_K6_EFER_NXE);
     604                fFlags |= CPUMGetGuestEFER(pVCpu) & (MSR_K6_EFER_LME & MSR_K6_EFER_NXE);
     605            }
     606        }
     607    }
     608    fFlags &= ~(DBGFPGDMP_FLAGS_CURRENT_MODE | DBGFPGDMP_FLAGS_CURRENT_CR3);
     609
     610    /*
     611     * Call PGM to do the real work.
     612     */
     613    int rc;
     614    if (fFlags & DBGFPGDMP_FLAGS_SHADOW)
     615        rc = PGMR3DumpHierarchyHCEx(pVM, cr3, fFlags, *pu64FirstAddr, *pu64LastAddr, cMaxDepth, pHlp);
     616    else
     617        rc = PGMR3DumpHierarchyGCEx(pVM, cr3, fFlags, *pu64FirstAddr, *pu64LastAddr, cMaxDepth, pHlp);
     618    return rc;
     619}
     620
     621
     622/**
     623 * Dump paging structures.
     624 *
     625 * This API can be used to dump both guest and shadow structures.
     626 *
     627 * @returns VBox status code.
     628 * @param   pVM             The VM handle.
     629 * @param   idCpu           The current CPU ID.
     630 * @param   fFlags          The flags, DBGFPGDMP_FLAGS_XXX.
     631 * @param   cr3             The CR3 to use (unless we're getting the current
     632 *                          state, see @a fFlags).
     633 * @param   u64FirstAddr    The address to start dumping at.
     634 * @param   u64LastAddr     The address to end dumping after.
     635 * @param   cMaxDepth       The depth.
     636 * @param   pHlp            The output callbacks.  Defaults to the debug log if
     637 *                          NULL.
     638 */
     639VMMDECL(int) DBGFR3PagingDumpEx(PVM pVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr,
     640                                uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp)
     641{
     642    /*
     643     * Input validation.
     644     */
     645    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     646    AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
     647    AssertReturn(!(fFlags & ~DBGFPGDMP_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
     648    AssertReturn(fFlags & (DBGFPGDMP_FLAGS_SHADOW | DBGFPGDMP_FLAGS_GUEST), VERR_INVALID_PARAMETER);
     649    AssertReturn((fFlags & DBGFPGDMP_FLAGS_CURRENT_MODE) || !(fFlags & DBGFPGDMP_FLAGS_MODE_MASK), VERR_INVALID_PARAMETER);
     650    AssertReturn(   !(fFlags & DBGFPGDMP_FLAGS_EPT)
     651                 || !(fFlags & (DBGFPGDMP_FLAGS_LME | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_NXE))
     652                 , VERR_INVALID_PARAMETER);
     653    AssertPtrReturn(pHlp, VERR_INVALID_POINTER);
     654    AssertReturn(cMaxDepth, VERR_INVALID_PARAMETER);
     655
     656    /*
     657     * Forward the request to the target CPU.
     658     */
     659    return VMR3ReqCallWaitU(pVM->pUVM, idCpu, (PFNRT)dbgfR3PagingDumpEx, 8,
     660                            pVM, idCpu, fFlags, &cr3, &u64FirstAddr, &u64LastAddr, cMaxDepth, pHlp);
     661}
     662
  • trunk/src/VBox/VMM/PGMDbg.cpp

    r31949 r31966  
    5959    /** Set if long mode is enabled. */
    6060    bool            fLme;
     61    /** Set if nested paging. */
     62    bool            fNp;
     63    /** Set if EPT. */
     64    bool            fEpt;
    6165    /** The number or chars the address needs. */
    6266    uint8_t         cchAddress;
    63     bool            afReserved[4];
     67    /** Dump the page info as well (shadow page summary / guest physical
     68     *  page summary). */
     69    bool            fDumpPageInfo;
     70    /** Whether or not to print the header. */
     71    bool            fPrintHeader;
    6472    /** The current address.  */
    6573    uint64_t        u64Address;
     
    827835
    828836/**
     837 * Dumps the a shadow page summary or smth.
     838 *
     839 * @param   pState              The dumper state.
     840 * @param   HCPhys              The page address.
     841 */
     842static void pgmR3DumpHierarchyHcShwPageInfo(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys)
     843{
     844    /* later */
     845    NOREF(pState); NOREF(HCPhys);
     846}
     847
     848
     849/**
     850 * Figures out which guest page this is and dumps a summary.
     851 *
     852 * @param   pState              The dumper state.
     853 * @param   HCPhys              The page address.
     854 * @param   cbPage              The page size.
     855 */
     856static void pgmR3DumpHierarchyHcPageInfo(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, uint32_t cbPage)
     857{
     858    /* later */
     859    NOREF(pState); NOREF(HCPhys); NOREF(cbPage);
     860}
     861
     862
     863/**
    829864 * Dumps a PAE shadow page table.
    830865 *
    831866 * @returns VBox status code (VINF_SUCCESS).
    832  * @param   pArgs       Dumper state.
    833  * @param   pPT         Pointer to the page table.
    834  * @param   pHlp        Pointer to the output functions.
    835  */
    836 static int  pgmR3DumpHierarchyHCPaePT(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, bool fIsMapping)
     867 * @param   pState              The dumper state.
     868 * @param   HCPhys              The page table address.
     869 * @param   fIsMapping          Whether it is a mapping.
     870 */
     871static int pgmR3DumpHierarchyHCPaePT(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, bool fIsMapping)
    837872{
    838873    PPGMSHWPTPAE pPT = NULL;
     
    865900    }
    866901
    867     for (unsigned i = 0; i < RT_ELEMENTS(pPT->a); i++)
    868         if (PGMSHWPTEPAE_IS_P(pPT->a[i]))
     902    const uint64_t  u64BaseAddress  = pState->u64Address & ~(RT_BIT_64(X86_PT_PAE_SHIFT) - 1);
     903    uint32_t        iFirst          = (pState->u64FirstAddress >> X86_PT_PAE_SHIFT) & X86_PT_PAE_MASK;
     904    uint32_t        iLast           = (pState->u64LastAddress  >> X86_PT_PAE_SHIFT) & X86_PT_PAE_MASK;
     905    for (uint32_t i = iFirst; i <= iLast; i++)
     906        if (PGMSHWPTEPAE_GET_U(pPT->a[i]) & X86_PTE_P)
    869907        {
    870             X86PTEPAE Pte;
    871             Pte.u = PGMSHWPTEPAE_GET_U(pPT->a[i]);
    872             pState->pHlp->pfnPrintf(pState->pHlp,
    873                                     pState->fLme  /*P R  S  A  D  G  WT CD AT NX 4M a p ?  */
    874                                     ? "%016llx 3    | P %c %c %c %c %c %s %s %s %s 4K %c%c%c  %016llx\n"
    875                                     :  "%08llx 2   |  P %c %c %c %c %c %s %s %s %s 4K %c%c%c  %016llx\n",
    876                                     pState->u64Address + ((uint64_t)i << X86_PT_PAE_SHIFT),
    877                                     Pte.n.u1Write       ? 'W'  : 'R',
    878                                     Pte.n.u1User        ? 'U'  : 'S',
    879                                     Pte.n.u1Accessed    ? 'A'  : '-',
    880                                     Pte.n.u1Dirty       ? 'D'  : '-',
    881                                     Pte.n.u1Global      ? 'G'  : '-',
    882                                     Pte.n.u1WriteThru   ? "WT" : "--",
    883                                     Pte.n.u1CacheDisable? "CD" : "--",
    884                                     Pte.n.u1PAT         ? "AT" : "--",
    885                                     Pte.n.u1NoExecute   ? "NX" : "--",
    886                                     Pte.u & PGM_PTFLAGS_TRACK_DIRTY   ? 'd' : '-',
    887                                     Pte.u & RT_BIT(10)                ? '1' : '0',
    888                                     Pte.u & PGM_PTFLAGS_CSAM_VALIDATED? 'v' : '-',
    889                                     Pte.u & X86_PTE_PAE_PG_MASK);
    890 
    891             pState->cLeaves++;
    892         }
    893         else if (PGMSHWPTEPAE_GET_U(pPT->a[i]) & X86_PTE_P)
    894         {
    895             if (   (PGMSHWPTEPAE_GET_U(pPT->a[i]) & (pState->pVM->pgm.s.HCPhysInvMmioPg | X86_PTE_PAE_MBZ_MASK_NO_NX))
    896                 ==                                  (pState->pVM->pgm.s.HCPhysInvMmioPg | X86_PTE_PAE_MBZ_MASK_NO_NX))
     908            pState->u64Address = u64BaseAddress + ((uint64_t)i << X86_PT_PAE_SHIFT);
     909            if (   pState->u64Address < pState->u64FirstAddress
     910                || pState->u64Address > pState->u64LastAddress)
     911                continue;
     912
     913            if (PGMSHWPTEPAE_IS_P(pPT->a[i]))
     914            {
     915                X86PTEPAE Pte;
     916                Pte.u = PGMSHWPTEPAE_GET_U(pPT->a[i]);
     917                pState->pHlp->pfnPrintf(pState->pHlp,
     918                                        pState->fLme  /*P R  S  A  D  G  WT CD AT NX 4M a p ?  */
     919                                        ? "%016llx 3    | P %c %c %c %c %c %s %s %s %s 4K %c%c%c  %016llx"
     920                                        :  "%08llx 2   |  P %c %c %c %c %c %s %s %s %s 4K %c%c%c  %016llx",
     921                                        pState->u64Address,
     922                                        Pte.n.u1Write       ? 'W'  : 'R',
     923                                        Pte.n.u1User        ? 'U'  : 'S',
     924                                        Pte.n.u1Accessed    ? 'A'  : '-',
     925                                        Pte.n.u1Dirty       ? 'D'  : '-',
     926                                        Pte.n.u1Global      ? 'G'  : '-',
     927                                        Pte.n.u1WriteThru   ? "WT" : "--",
     928                                        Pte.n.u1CacheDisable? "CD" : "--",
     929                                        Pte.n.u1PAT         ? "AT" : "--",
     930                                        Pte.n.u1NoExecute   ? "NX" : "--",
     931                                        Pte.u & PGM_PTFLAGS_TRACK_DIRTY   ? 'd' : '-',
     932                                        Pte.u & RT_BIT(10)                ? '1' : '0',
     933                                        Pte.u & PGM_PTFLAGS_CSAM_VALIDATED? 'v' : '-',
     934                                        Pte.u & X86_PTE_PAE_PG_MASK);
     935                if (pState->fDumpPageInfo)
     936                    pgmR3DumpHierarchyHcPageInfo(pState, Pte.u & X86_PTE_PAE_PG_MASK, _4K);
     937                if ((Pte.u >> 52) & 0x7ff)
     938                    pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx%s", (Pte.u >> 52) & 0x7ff, pState->fLme ? "" : "!");
     939                pState->pHlp->pfnPrintf(pState->pHlp, "\n");
     940            }
     941            else if (   (PGMSHWPTEPAE_GET_U(pPT->a[i]) & (pState->pVM->pgm.s.HCPhysInvMmioPg | X86_PTE_PAE_MBZ_MASK_NO_NX))
     942                     ==                                  (pState->pVM->pgm.s.HCPhysInvMmioPg | X86_PTE_PAE_MBZ_MASK_NO_NX))
    897943                pState->pHlp->pfnPrintf(pState->pHlp,
    898944                                        pState->fLme
    899945                                        ? "%016llx 3    | invalid / MMIO optimization\n"
    900946                                        :  "%08llx 2   |  invalid / MMIO optimization\n",
    901                                         pState->u64Address + ((uint64_t)i << X86_PT_PAE_SHIFT));
     947                                        pState->u64Address);
    902948            else
    903949                pState->pHlp->pfnPrintf(pState->pHlp,
     
    905951                                        ? "%016llx 3    | invalid: %RX64\n"
    906952                                        :  "%08llx 2   |  invalid: %RX64\n",
    907                                         pState->u64Address + ((uint64_t)i << X86_PT_PAE_SHIFT),
    908                                         PGMSHWPTEPAE_GET_U(pPT->a[i]));
     953                                        pState->u64Address, PGMSHWPTEPAE_GET_U(pPT->a[i]));
    909954            pState->cLeaves++;
    910955        }
     
    940985
    941986    int             rc              = VINF_SUCCESS;
    942     const uint64_t  u64BaseAddress  = pState->u64Address;
    943     for (unsigned i = 0; i < RT_ELEMENTS(pPD->a); i++)
     987    const uint64_t  u64BaseAddress  = pState->u64Address & ~(RT_BIT_64(X86_PD_PAE_SHIFT) - 1);
     988    uint32_t        iFirst          = (pState->u64FirstAddress >> X86_PD_PAE_SHIFT) & X86_PD_PAE_MASK;
     989    uint32_t        iLast           = (pState->u64LastAddress  >> X86_PD_PAE_SHIFT) & X86_PD_PAE_MASK;
     990    for (uint32_t i = iFirst; i <= iLast; i++)
    944991    {
    945992        X86PDEPAE Pde = pPD->a[i];
    946         pState->u64Address = u64BaseAddress + ((uint64_t)i << X86_PD_PAE_SHIFT);
    947         if (    Pde.n.u1Present
    948             &&  pState->u64Address >= pState->u64FirstAddress
    949             &&  pState->u64Address <= pState->u64LastAddress)
     993        if (Pde.n.u1Present)
    950994        {
     995            pState->u64Address = u64BaseAddress + ((uint64_t)i << X86_PD_PAE_SHIFT);
    951996            if (Pde.b.u1Size)
    952997            {
     
    9691014                                        Pde.u & PGM_PDFLAGS_TRACK_DIRTY ? 'd' : '-',
    9701015                                        Pde.u & X86_PDE2M_PAE_PG_MASK);
     1016                if (pState->fDumpPageInfo)
     1017                    pgmR3DumpHierarchyHcPageInfo(pState, Pde.u & X86_PDE2M_PAE_PG_MASK, _2M);
    9711018                if ((Pde.u >> 52) & 0x7ff)
    972                     pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx!", (Pde.u >> 52) & 0x7ff);
     1019                    pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx%s", (Pde.u >> 52) & 0x7ff, pState->fLme ? "" : "!");
    9731020                if ((Pde.u >> 13) & 0xff)
    974                     pState->pHlp->pfnPrintf(pState->pHlp, " 20:13=%02llx!", (Pde.u >> 13) & 0xff);
     1021                    pState->pHlp->pfnPrintf(pState->pHlp, " 20:13=%02llx%s", (Pde.u >> 13) & 0x0ff, pState->fLme ? "" : "!");
    9751022                pState->pHlp->pfnPrintf(pState->pHlp, "\n");
    9761023
     
    9961043                                        Pde.u & PGM_PDFLAGS_TRACK_DIRTY ? 'd' : '-',
    9971044                                        Pde.u & X86_PDE_PAE_PG_MASK_FULL);
     1045                if (pState->fDumpPageInfo)
     1046                    pgmR3DumpHierarchyHcShwPageInfo(pState, Pde.u & X86_PDE_PAE_PG_MASK_FULL);
    9981047                if ((Pde.u >> 52) & 0x7ff)
    9991048                    pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx!", (Pde.u >> 52) & 0x7ff);
     
    10291078static int  pgmR3DumpHierarchyHCPaePDPT(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth)
    10301079{
     1080    /* Fend of addresses that are out of range in PAE mode - simplifies the code below. */
     1081    if (!pState->fLme && pState->u64Address >= _4G)
     1082        return VINF_SUCCESS;
     1083
    10311084    Assert(cMaxDepth > 0);
    10321085    cMaxDepth--;
     
    10421095
    10431096    int             rc              = VINF_SUCCESS;
    1044     const uint64_t  u64BaseAddress  = pState->u64Address;
    1045     const unsigned  c               = pState->fLme ? RT_ELEMENTS(pPDPT->a) : X86_PG_PAE_PDPE_ENTRIES;
    1046     for (unsigned i = 0; i < c; i++)
     1097    const uint64_t  u64BaseAddress  = pState->u64Address & ~(RT_BIT_64(X86_PDPT_SHIFT) - 1);
     1098    uint32_t        iFirst          = (pState->u64FirstAddress >> X86_PDPT_SHIFT) & X86_PDPT_MASK_AMD64;
     1099    uint32_t        iLast           = (pState->u64LastAddress  >> X86_PDPT_SHIFT) & X86_PDPT_MASK_AMD64;
     1100    for (uint32_t i = iFirst; i <= iLast; i++)
    10471101    {
    10481102        X86PDPE Pdpe = pPDPT->a[i];
    1049         pState->u64Address = u64BaseAddress + ((uint64_t)i << X86_PDPT_SHIFT);
    1050         if (    Pdpe.n.u1Present
    1051             &&  pState->u64Address >= pState->u64FirstAddress
    1052             &&  pState->u64Address <= pState->u64LastAddress)
     1103        if (Pdpe.n.u1Present)
    10531104        {
    10541105            if (pState->fLme)
    10551106            {
    1056                 pState->pHlp->pfnPrintf(pState->pHlp, /*P R  S  A  D  G  WT CD AT NX 4M a p ?  */
     1107                pState->pHlp->pfnPrintf(pState->pHlp, /*P R  S  A  D  G  WT CD AT NX .. a p ?  */
    10571108                                        "%016llx 1  |   P %c %c %c %c %c %s %s %s %s .. %c%c%c  %016llx",
    10581109                                        pState->u64Address,
     
    10701121                                        Pdpe.u & RT_BIT(11)               ? '1' : '0',
    10711122                                        Pdpe.u & X86_PDPE_PG_MASK_FULL);
     1123                if (pState->fDumpPageInfo)
     1124                    pgmR3DumpHierarchyHcShwPageInfo(pState, Pdpe.u & X86_PDPE_PG_MASK_FULL);
    10721125                if ((Pdpe.u >> 52) & 0x7ff)
    1073                     pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx\n", (Pdpe.u >> 52) & 0x7ff);
     1126                    pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx", (Pdpe.u >> 52) & 0x7ff);
    10741127            }
    10751128            else
    10761129            {
    1077                 pState->pHlp->pfnPrintf(pState->pHlp,/*P             G  WT CD AT NX 4M a p ?  */
    1078                                         "%08llx 0 |    P             %c %s %s %s %s .. %c%c%c  %016llx",
     1130                pState->pHlp->pfnPrintf(pState->pHlp,/*P R  S  A  D  G  WT CD AT NX .. a p ?  */
     1131                                        "%08llx 0 |    P %c %c %c %c %c %s %s %s %s .. %c%c%c  %016llx",
    10791132                                        pState->u64Address,
     1133                                        Pdpe.n.u2Reserved & 1? '!'  : '.', /* mbz */
     1134                                        Pdpe.n.u2Reserved & 2? '!'  : '.', /* mbz */
    10801135                                        Pdpe.n.u4Reserved & 1? '!'  : '.', /* mbz */
    1081                                         Pdpe.n.u4Reserved & 4? '!'  : '.', /* mbz */
     1136                                        Pdpe.n.u4Reserved & 2? '!'  : '.', /* mbz */
     1137                                        Pdpe.n.u4Reserved & 8? '!'  : '.', /* mbz */
    10821138                                        Pdpe.n.u1WriteThru   ? "WT" : "--",
    10831139                                        Pdpe.n.u1CacheDisable? "CD" : "--",
    10841140                                        Pdpe.n.u4Reserved & 2? "!"  : "..",/* mbz */
     1141                                        Pdpe.lm.u1NoExecute  ? "!!"  : "..",/* mbz */
    10851142                                        Pdpe.u & RT_BIT(9)                ? '1' : '0',
    10861143                                        Pdpe.u & PGM_PLXFLAGS_PERMANENT   ? 'p' : '-',
    10871144                                        Pdpe.u & RT_BIT(11)               ? '1' : '0',
    10881145                                        Pdpe.u & X86_PDPE_PG_MASK_FULL);
     1146                if (pState->fDumpPageInfo)
     1147                    pgmR3DumpHierarchyHcShwPageInfo(pState, Pdpe.u & X86_PDPE_PG_MASK_FULL);
    10891148                if ((Pdpe.u >> 52) & 0xfff)
    1090                     pState->pHlp->pfnPrintf(pState->pHlp, " 63:52=%03llx\n", (Pdpe.u >> 52) & 0xfff);
     1149                    pState->pHlp->pfnPrintf(pState->pHlp, " 63:52=%03llx!", (Pdpe.u >> 52) & 0xfff);
    10911150            }
    10921151            pState->pHlp->pfnPrintf(pState->pHlp, "\n");
     1152
    10931153            if (cMaxDepth)
    10941154            {
     
    11151175static int pgmR3DumpHierarchyHcPaePML4(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth)
    11161176{
     1177    Assert(cMaxDepth);
     1178    cMaxDepth--;
     1179
    11171180    PX86PML4 pPML4 = (PX86PML4)MMPagePhys2Page(pState->pVM, HCPhys);
    11181181    if (!pPML4)
     
    11231186
    11241187    int         rc      = VINF_SUCCESS;
    1125     uint32_t    cFound  = 0;
    1126     for (uint32_t i = (pState->u64LastAddress >> X86_PML4_SHIFT) & X86_PML4_MASK; i < RT_ELEMENTS(pPML4->a); i++)
     1188    uint32_t    iFirst  = (pState->u64FirstAddress >> X86_PML4_SHIFT) & X86_PML4_MASK;
     1189    uint32_t    iLast   = (pState->u64LastAddress  >> X86_PML4_SHIFT) & X86_PML4_MASK;
     1190    for (uint32_t i = iFirst; i <= iLast; i++)
    11271191    {
    11281192        X86PML4E Pml4e = pPML4->a[i];
    1129         pState->u64Address = ((uint64_t)i << X86_PML4_SHIFT)
    1130                            | (((uint64_t)i >> (X86_PML4_SHIFT - X86_PDPT_SHIFT - 1)) * UINT64_C(0xffff000000000000));
    1131         if (    Pml4e.n.u1Present
    1132             &&  pState->u64Address >= pState->u64FirstAddress
    1133             &&  pState->u64Address <= pState->u64LastAddress
    1134            )
     1193        if (Pml4e.n.u1Present)
    11351194        {
     1195            pState->u64Address = ((uint64_t)i << X86_PML4_SHIFT)
     1196                               | (i >= RT_ELEMENTS(pPML4->a) / 2 ? UINT64_C(0xffff000000000000) : 0);
    11361197            pState->pHlp->pfnPrintf(pState->pHlp, /*P R  S  A  D  G  WT CD AT NX 4M a p ?  */
    11371198                                    "%016llx 0 |    P %c %c %c %c %c %s %s %s %s .. %c%c%c  %016llx",
     
    11501211                                    Pml4e.u & RT_BIT(11)               ? '1' : '0',
    11511212                                    Pml4e.u & X86_PML4E_PG_MASK);
    1152             /** @todo Dump the shadow page referenced? */
     1213            if (pState->fDumpPageInfo)
     1214                pgmR3DumpHierarchyHcShwPageInfo(pState, Pml4e.u & X86_PML4E_PG_MASK);
    11531215            if ((Pml4e.u >> 52) & 0x7ff)
    11541216                pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx!", (Pml4e.u >> 52) & 0x7ff);
    11551217            pState->pHlp->pfnPrintf(pState->pHlp, "\n");
    11561218
    1157             if (cMaxDepth >= 1)
    1158             {
    1159                 int rc2 = pgmR3DumpHierarchyHCPaePDPT(pState, Pml4e.u & X86_PML4E_PG_MASK, cMaxDepth - 1);
     1219            if (cMaxDepth)
     1220            {
     1221                int rc2 = pgmR3DumpHierarchyHCPaePDPT(pState, Pml4e.u & X86_PML4E_PG_MASK, cMaxDepth);
    11601222                if (rc2 < rc && RT_SUCCESS(rc))
    11611223                    rc = rc2;
     
    12061268
    12071269
    1208     for (unsigned i = 0; i < RT_ELEMENTS(pPT->a); i++)
     1270    const uint64_t  u64BaseAddress  = pState->u64Address & ~(RT_BIT_64(X86_PT_SHIFT) - 1);
     1271    uint32_t        iFirst          = RT_MIN(pState->u64FirstAddress >> X86_PT_SHIFT, X86_PG_ENTRIES);
     1272    uint32_t        iLast           = RT_MIN(pState->u64LastAddress  >> X86_PT_SHIFT, X86_PG_ENTRIES - 1);
     1273    for (uint32_t i = iFirst; i <= iLast; i++)
    12091274    {
    12101275        X86PTE Pte = pPT->a[i];
    12111276        if (Pte.n.u1Present)
    12121277        {
    1213             uint64_t u64Address = pState->u64Address + (i << X86_PT_SHIFT);
    1214             if (   u64Address < pState->u64FirstAddress
    1215                 || u64Address < pState->u64LastAddress)
    1216                 continue;
     1278            pState->u64Address = u64BaseAddress + (i << X86_PT_SHIFT);
    12171279            pState->pHlp->pfnPrintf(pState->pHlp,/*P R  S  A  D  G  WT CD AT NX 4M a m d  */
    1218                                     "%08llx 1  |   P %c %c %c %c %c %s %s %s .. 4K %c%c%c  %08x\n",
    1219                                     u64Address,
     1280                                    "%08llx 1  |   P %c %c %c %c %c %s %s %s .. 4K %c%c%c  %08x",
     1281                                    pState->u64Address,
    12201282                                    Pte.n.u1Write       ? 'W'  : 'R',
    12211283                                    Pte.n.u1User        ? 'U'  : 'S',
     
    12301292                                    Pte.u & PGM_PTFLAGS_CSAM_VALIDATED  ? 'v' : '-',
    12311293                                    Pte.u & X86_PDE_PG_MASK);
     1294            if (pState->fDumpPageInfo)
     1295                pgmR3DumpHierarchyHcPageInfo(pState, Pte.u & X86_PDE_PG_MASK, _4K);
     1296            pState->pHlp->pfnPrintf(pState->pHlp, "\n");
    12321297        }
    12331298    }
     
    12481313static int pgmR3DumpHierarchyHC32BitPD(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth)
    12491314{
     1315    if (pState->u64Address >= _4G)
     1316        return VINF_SUCCESS;
     1317
    12501318    Assert(cMaxDepth > 0);
    12511319    cMaxDepth--;
     
    12601328
    12611329    int             rc              = VINF_SUCCESS;
    1262     const uint64_t  u64BaseAddress  = pState->u64Address;
    1263     for (unsigned i = 0; i < RT_ELEMENTS(pPD->a); i++)
     1330    const uint64_t  u64BaseAddress  = pState->u64Address & ~(RT_BIT_64(X86_PD_SHIFT) - 1);
     1331    uint32_t        iFirst          = RT_MIN(pState->u64FirstAddress >> X86_PD_SHIFT, X86_PG_ENTRIES);
     1332    uint32_t        iLast           = RT_MIN(pState->u64LastAddress  >> X86_PD_SHIFT, X86_PG_ENTRIES - 1);
     1333    for (uint32_t i = iFirst; i <= iLast; i++)
    12641334    {
    12651335        X86PDE Pde = pPD->a[i];
     
    12671337        {
    12681338            pState->u64Address = (uint32_t)i << X86_PD_SHIFT;
    1269             if (   pState->u64Address < pState->u64FirstAddress
    1270                 && pState->u64Address > pState->u64LastAddress)
    1271                 continue;
    1272 
    12731339            if (Pde.b.u1Size && pState->fPse)
    12741340            {
     1341                uint64_t u64Phys = ((uint64_t)(Pde.u & X86_PDE4M_PG_HIGH_MASK) << X86_PDE4M_PG_HIGH_SHIFT)
     1342                                 | (Pde.u & X86_PDE4M_PG_MASK);
    12751343                pState->pHlp->pfnPrintf(pState->pHlp,/*P R  S  A  D  G  WT CD AT NX 4M a m d   phys */
    1276                                         "%08llx 0 |    P %c %c %c %c %c %s %s %s .. 4M %c%c%c  %08llx\n",
     1344                                        "%08llx 0 |    P %c %c %c %c %c %s %s %s .. 4M %c%c%c  %08llx",
    12771345                                        pState->u64Address,
    12781346                                        Pde.b.u1Write       ? 'W'  : 'R',
     
    12871355                                        Pde.u & PGM_PDFLAGS_MAPPING     ? 'm' : '-',
    12881356                                        Pde.u & PGM_PDFLAGS_TRACK_DIRTY ? 'd' : '-',
    1289                                           ((Pde.u & X86_PDE4M_PG_HIGH_MASK) << X86_PDE4M_PG_HIGH_SHIFT)
    1290                                         | (Pde.u & X86_PDE4M_PG_MASK) );
     1357                                        u64Phys);
     1358                if (pState->fDumpPageInfo)
     1359                    pgmR3DumpHierarchyHcPageInfo(pState, u64Phys, _4M);
     1360                pState->pHlp->pfnPrintf(pState->pHlp, "\n");
    12911361                pState->cLeaves++;
    12921362            }
     
    12941364            {
    12951365                pState->pHlp->pfnPrintf(pState->pHlp,/*P R  S  A  D  G  WT CD AT NX 4M a m d   phys */
    1296                                         "%08llx 0 |    P %c %c %c %c %c %s %s .. .. 4K %c%c%c  %08x\n",
     1366                                        "%08llx 0 |    P %c %c %c %c %c %s %s .. .. 4K %c%c%c  %08x",
    12971367                                        pState->u64Address,
    12981368                                        Pde.n.u1Write       ? 'W'  : 'R',
     
    13071377                                        Pde.u & PGM_PDFLAGS_TRACK_DIRTY ? 'd' : '-',
    13081378                                        Pde.u & X86_PDE_PG_MASK);
     1379                if (pState->fDumpPageInfo)
     1380                    pgmR3DumpHierarchyHcShwPageInfo(pState, Pde.u & X86_PDE_PG_MASK);
     1381                pState->pHlp->pfnPrintf(pState->pHlp, "\n");
     1382
    13091383                if (cMaxDepth)
    13101384                {
     
    13331407static int pdmR3DumpHierarchyHcDoIt(PPGMR3DUMPHIERARCHYSTATE pState, uint64_t cr3, unsigned cMaxDepth)
    13341408{
     1409    int rc;
    13351410    const unsigned cch = pState->cchAddress;
    1336     pState->pHlp->pfnPrintf(pState->pHlp,
    1337                             "cr3=%0*llx %s\n"
    1338                             "%-*s        P - Present\n"
    1339                             "%-*s        | R/W - Read (0) / Write (1)\n"
    1340                             "%-*s        | | U/S - User (1) / Supervisor (0)\n"
    1341                             "%-*s        | | | A - Accessed\n"
    1342                             "%-*s        | | | | D - Dirty\n"
    1343                             "%-*s        | | | | | G - Global\n"
    1344                             "%-*s        | | | | | | WT - Write thru\n"
    1345                             "%-*s        | | | | | | |  CD - Cache disable\n"
    1346                             "%-*s        | | | | | | |  |  AT - Attribute table (PAT)\n"
    1347                             "%-*s        | | | | | | |  |  |  NX - No execute (K8)\n"
    1348                             "%-*s        | | | | | | |  |  |  |  4K/4M/2M - Page size.\n"
    1349                             "%-*s        | | | | | | |  |  |  |  |  AVL - a=allocated; m=mapping; d=track dirty;\n"
    1350                             "%-*s        | | | | | | |  |  |  |  |  |     p=permanent; v=validated;\n"
    1351                             "%-*s Level  | | | | | | |  |  |  |  |  |    Page\n"
    1352                           /* xxxx n **** P R S A D G WT CD AT NX 4M AVL xxxxxxxxxxxxx
    1353                                          - W U - - - -- -- -- -- -- 010 */
    1354                             ,
    1355                             cch, cr3,
    1356                             pState->fLme ? "Long Mode" : pState->fPae ? "PAE" : pState->fPse ? "32-bit w/ PSE" : "32-bit",
    1357                             cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", cch, "",
    1358                             cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", cch, "Address");
    1359     if (pState->fLme)
    1360         return pgmR3DumpHierarchyHcPaePML4(pState, cr3 & X86_CR3_PAGE_MASK,     cMaxDepth);
    1361     if (pState->fPae)
    1362         return pgmR3DumpHierarchyHCPaePDPT(pState, cr3 & X86_CR3_PAE_PAGE_MASK, cMaxDepth);
    1363     return     pgmR3DumpHierarchyHC32BitPD(pState, cr3 & X86_CR3_PAGE_MASK,     cMaxDepth);
     1411    if (pState->fEpt)
     1412    {
     1413        if (pState->fPrintHeader)
     1414            pState->pHlp->pfnPrintf(pState->pHlp,
     1415                                    "cr3=%0*llx Extended Page Tables\n"
     1416                                    "%-*s        R - Readable\n"
     1417                                    "%-*s        | W - Writeable\n"
     1418                                    "%-*s        | | X - Executable\n"
     1419                                    "%-*s        | | | EMT - EPT memory type\n"
     1420                                    "%-*s        | | | |   PAT - Ignored PAT?\n"
     1421                                    "%-*s        | | | |   |    AVL1 - 4 available bits\n"
     1422                                    "%-*s        | | | |   |    |   AVL2 - 12 available bits\n"
     1423                                    "%-*s Level  | | | |   |    |    |     page  \n"
     1424                                  /* xxxx n **** R W X EMT PAT AVL1 AVL2   xxxxxxxxxxxxx
     1425                                                 R W X  7   0   f   fff    0123456701234567 */
     1426                                    ,
     1427                                    cch, cr3,
     1428                                    cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", cch, "Address");
     1429
     1430        pState->pHlp->pfnPrintf(pState->pHlp, "EPT dumping is not yet implemented, sorry.\n");
     1431        /** @todo implemented EPT dumping. */
     1432        rc = VERR_NOT_IMPLEMENTED;
     1433    }
     1434    else
     1435    {
     1436        if (pState->fPrintHeader)
     1437            pState->pHlp->pfnPrintf(pState->pHlp,
     1438                                    "cr3=%0*llx %s%s\n"
     1439                                    "%-*s        P - Present\n"
     1440                                    "%-*s        | R/W - Read (0) / Write (1)\n"
     1441                                    "%-*s        | | U/S - User (1) / Supervisor (0)\n"
     1442                                    "%-*s        | | | A - Accessed\n"
     1443                                    "%-*s        | | | | D - Dirty\n"
     1444                                    "%-*s        | | | | | G - Global\n"
     1445                                    "%-*s        | | | | | | WT - Write thru\n"
     1446                                    "%-*s        | | | | | | |  CD - Cache disable\n"
     1447                                    "%-*s        | | | | | | |  |  AT - Attribute table (PAT)\n"
     1448                                    "%-*s        | | | | | | |  |  |  NX - No execute (K8)\n"
     1449                                    "%-*s        | | | | | | |  |  |  |  4K/4M/2M - Page size.\n"
     1450                                    "%-*s        | | | | | | |  |  |  |  |  AVL - a=allocated; m=mapping; d=track dirty;\n"
     1451                                    "%-*s        | | | | | | |  |  |  |  |  |     p=permanent; v=validated;\n"
     1452                                    "%-*s Level  | | | | | | |  |  |  |  |  |    Page\n"
     1453                                  /* xxxx n **** P R S A D G WT CD AT NX 4M AVL xxxxxxxxxxxxx
     1454                                                 - W U - - - -- -- -- -- -- 010 */
     1455                                    ,
     1456                                    cch, cr3,
     1457                                    pState->fLme ? "Long Mode" : pState->fPae ? "PAE" : pState->fPse ? "32-bit w/ PSE" : "32-bit",
     1458                                    pState->fNp ? " Nested Paging" : "",
     1459                                    cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", cch, "",
     1460                                    cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", cch, "Address");
     1461        if (pState->fLme)
     1462            rc = pgmR3DumpHierarchyHcPaePML4(pState, cr3 & X86_CR3_PAGE_MASK,     cMaxDepth);
     1463        else if (pState->fPae)
     1464            rc = pgmR3DumpHierarchyHCPaePDPT(pState, cr3 & X86_CR3_PAE_PAGE_MASK, cMaxDepth);
     1465        else
     1466            rc = pgmR3DumpHierarchyHC32BitPD(pState, cr3 & X86_CR3_PAGE_MASK,     cMaxDepth);
     1467    }
     1468    return rc;
     1469}
     1470
     1471
     1472/**
     1473 * dbgfR3PagingDumpEx worker.
     1474 *
     1475 * @returns VBox status code.
     1476 * @param   pVM             The VM handle.
     1477 * @param   cr3             The CR3 register value.
     1478 * @param   fFlags          The flags, DBGFPGDMP_FLAGS_XXX.
     1479 * @param   u64FirstAddr    The start address.
     1480 * @param   u64LastAddr     The address to stop after.
     1481 * @param   cMaxDepth       The max depth.
     1482 * @param   pHlp            The output callbacks.  Defaults to log if NULL.
     1483 *
     1484 * @internal
     1485 */
     1486VMMR3_INT_DECL(int) PGMR3DumpHierarchyHCEx(PVM pVM, uint64_t cr3, uint32_t fFlags, uint64_t u64FirstAddr, uint64_t u64LastAddr,
     1487                                           uint32_t cMaxDepth, PCDBGFINFOHLP pHlp)
     1488{
     1489    /* Minimal validation as we're only supposed to service DBGF. */
     1490    AssertReturn(~(fFlags & ~DBGFPGDMP_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
     1491    AssertReturn(!(fFlags & (DBGFPGDMP_FLAGS_CURRENT_MODE | DBGFPGDMP_FLAGS_CURRENT_CR3)), VERR_INVALID_PARAMETER);
     1492    AssertReturn(fFlags & DBGFPGDMP_FLAGS_SHADOW, VERR_INVALID_PARAMETER);
     1493
     1494    PGMR3DUMPHIERARCHYSTATE State;
     1495    State.pVM               = pVM;
     1496    State.pHlp              = pHlp ? pHlp : DBGFR3InfoLogHlp();
     1497    State.fPse              = !!(fFlags & (DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME));
     1498    State.fPae              = !!(fFlags & (DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME));
     1499    State.fLme              = !!(fFlags & DBGFPGDMP_FLAGS_LME);
     1500    State.fNp               = !!(fFlags & DBGFPGDMP_FLAGS_NP);
     1501    State.fEpt              = !!(fFlags & DBGFPGDMP_FLAGS_EPT);
     1502    State.cchAddress        = State.fLme ? 16 : 8;
     1503    State.fDumpPageInfo     = !!(fFlags & DBGFPGDMP_FLAGS_PAGE_INFO);
     1504    State.fPrintHeader      = !!(fFlags & DBGFPGDMP_FLAGS_HEADER);
     1505    State.u64Address        = u64FirstAddr;
     1506    State.u64FirstAddress   = u64FirstAddr;
     1507    State.u64LastAddress    = u64LastAddr;
     1508    State.cLeaves           = 0;
     1509    return pdmR3DumpHierarchyHcDoIt(&State, cr3, cMaxDepth);
    13641510}
    13651511
     
    13871533    State.fPae              = (cr4 & X86_CR4_PAE) || fLongMode;
    13881534    State.fLme              = fLongMode;
     1535    State.fNp               = false;
     1536    State.fEpt              = false;
    13891537    State.cchAddress        = fLongMode ? 16 : 8;
     1538    State.fDumpPageInfo     = false;
     1539    State.fPrintHeader      = true;
    13901540    State.u64Address        = 0;
    13911541    State.u64FirstAddress   = 0;
     
    15571707}
    15581708
     1709
     1710/**
     1711 * dbgfR3PagingDumpEx worker.
     1712 *
     1713 * @returns VBox status code.
     1714 * @param   pVM             The VM handle.
     1715 * @param   cr3             The CR3 register value.
     1716 * @param   fFlags          The flags, DBGFPGDMP_FLAGS_XXX.
     1717 * @param   FirstAddr       The start address.
     1718 * @param   LastAddr        The address to stop after.
     1719 * @param   cMaxDepth       The max depth.
     1720 * @param   pHlp            The output callbacks.  Defaults to log if NULL.
     1721 *
     1722 * @internal
     1723 */
     1724VMMR3_INT_DECL(int) PGMR3DumpHierarchyGCEx(PVM pVM, uint64_t cr3, uint32_t fFlags, RTGCPTR FirstAddr, RTGCPTR LastAddr,
     1725                                           uint32_t cMaxDepth, PCDBGFINFOHLP pHlp)
     1726{
     1727    /* Minimal validation as we're only supposed to service DBGF. */
     1728    AssertReturn(~(fFlags & ~DBGFPGDMP_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
     1729    AssertReturn(!(fFlags & (DBGFPGDMP_FLAGS_CURRENT_MODE | DBGFPGDMP_FLAGS_CURRENT_CR3)), VERR_INVALID_PARAMETER);
     1730    AssertReturn(fFlags & DBGFPGDMP_FLAGS_GUEST, VERR_INVALID_PARAMETER);
     1731
     1732    PGMR3DUMPHIERARCHYSTATE State;
     1733    State.pVM               = pVM;
     1734    State.pHlp              = pHlp ? pHlp : DBGFR3InfoLogHlp();
     1735    State.fPse              = !!(fFlags & (DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME));
     1736    State.fPae              = !!(fFlags & (DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME));
     1737    State.fLme              = !!(fFlags & DBGFPGDMP_FLAGS_LME);
     1738    State.fNp               = !!(fFlags & DBGFPGDMP_FLAGS_NP);
     1739    State.fEpt              = !!(fFlags & DBGFPGDMP_FLAGS_EPT);
     1740    State.cchAddress        = State.fLme ? 16 : 8;
     1741    State.fDumpPageInfo     = !!(fFlags & DBGFPGDMP_FLAGS_PAGE_INFO);
     1742    State.fPrintHeader      = !!(fFlags & DBGFPGDMP_FLAGS_HEADER);
     1743    State.u64Address        = FirstAddr;
     1744    State.u64FirstAddress   = FirstAddr;
     1745    State.u64LastAddress    = LastAddr;
     1746    State.cLeaves           = 0;
     1747    //return pdmR3DumpHierarchyGcDoIt(&State, cr3, cMaxDepth);
     1748    return VERR_NOT_IMPLEMENTED;
     1749}
     1750
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette