- Timestamp:
- Aug 25, 2010 4:15:25 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/dbg.h
r31927 r31966 36 36 37 37 #include <iprt/stdarg.h> 38 #ifdef IN_RING3 39 # include <iprt/err.h> 40 #endif 38 41 39 42 RT_C_DECLS_BEGIN … … 500 503 DECLCALLBACKMEMBER(int, pfnVarToBool)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, bool *pf); 501 504 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 502 527 } DBGCCMDHLP; 503 528 … … 590 615 591 616 return rc; 617 } 618 619 /** 620 * @copydoc DBGCCMDHLP::pfnVarToDbgfAddr 621 */ 622 DECLINLINE(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 */ 635 DECLINLINE(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 */ 647 DECLINLINE(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 */ 655 DECLINLINE(PCDBGFINFOHLP) DBGCCmdHlpGetDbgfOutputHlp(PDBGCCMDHLP pCmdHlp) 656 { 657 return pCmdHlp->pfnGetDbgfOutputHlp(pCmdHlp); 592 658 } 593 659 -
trunk/include/VBox/dbgf.h
r31948 r31966 918 918 919 919 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 /** @} */ 959 VMMDECL(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 920 963 /** @name DBGFR3SelQueryInfo flags. 921 964 * @{ */ -
trunk/include/VBox/pgm.h
r31948 r31966 565 565 VMMR3DECL(int) PGMR3DbgScanVirtual(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, RTGCPTR cbRange, RTGCPTR GCPtrAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCUINTPTR pGCPhysHit); 566 566 VMMR3DECL(int) PGMR3DumpHierarchyHC(PVM pVM, uint64_t cr3, uint64_t cr4, bool fLongMode, unsigned cMaxDepth, PCDBGFINFOHLP pHlp); 567 VMMR3_INT_DECL(int) PGMR3DumpHierarchyHCEx(PVM pVM, uint64_t cr3, uint32_t fFlags, uint64_t u64FirstAddr, uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp); 567 568 VMMR3DECL(int) PGMR3DumpHierarchyGC(PVM pVM, uint64_t cr3, uint64_t cr4, RTGCPHYS PhysSearch); 569 VMMR3_INT_DECL(int) PGMR3DumpHierarchyGCEx(PVM pVM, uint64_t cr3, uint32_t fFlags, RTGCPTR FirstAddr, RTGCPTR LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp); 568 570 569 571 -
trunk/src/VBox/Debugger/DBGCCmdHlp.cpp
r31530 r31966 792 792 793 793 /** 794 * @interface_method_impl{DBGCCMDHLP,pfnVarGetRange} 795 */ 796 static 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 */ 824 static 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 */ 841 static 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 */ 851 static 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 /** 794 867 * Initializes the Command Helpers for a DBGC instance. 795 868 * … … 798 871 void dbgcInitCmdHlp(PDBGC pDbgc) 799 872 { 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 874 874 875 875 /** 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 /**907 876 * The 'info' command. 908 877 * … … 932 901 * Dump it. 933 902 */ 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)); 941 906 if (RT_FAILURE(rc)) 942 907 return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "DBGFR3Info()\n"); -
trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp
r31769 r31966 58 58 static DECLCALLBACK(int) dbgcCmdDumpPageDir(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 59 59 static DECLCALLBACK(int) dbgcCmdDumpPageDirBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 60 static DECLCALLBACK(int) dbgcCmdDumpPageHierarchy(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 60 61 static DECLCALLBACK(int) dbgcCmdDumpPageTable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 61 62 static DECLCALLBACK(int) dbgcCmdDumpPageTableBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); … … 164 165 /* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */ 165 166 { 0, 1, DBGCVAR_CAT_POINTER, 0, "address", "Address of the page directory entry to start dumping from." }, 167 }; 168 169 170 /** 'dph*' arguments. */ 171 static 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." }, 166 177 }; 167 178 … … 314 325 { "dpdg", 0, 1, &g_aArgDumpPD[0], RT_ELEMENTS(g_aArgDumpPD), NULL, 0, dbgcCmdDumpPageDir, "[addr] [index]", "Dumps page directory entries of the guest." }, 315 326 { "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." }, 316 330 { "dpt", 1, 1, &g_aArgDumpPT[0], RT_ELEMENTS(g_aArgDumpPT), NULL, 0, dbgcCmdDumpPageTable,"<addr>", "Dumps page table entries of the default context." }, 317 331 { "dpta", 1, 1, &g_aArgDumpPTAddr[0],RT_ELEMENTS(g_aArgDumpPTAddr), NULL, 0, dbgcCmdDumpPageTable,"<addr>", "Dumps specified page table." }, … … 979 993 else 980 994 pDbgc->DisasmPos = paArgs[0]; 995 pDbgc->pLastPos = &pDbgc->DisasmPos; 981 996 982 997 /* … … 1137 1152 else 1138 1153 pDbgc->SourcePos = paArgs[0]; 1154 pDbgc->pLastPos = &pDbgc->SourcePos; 1139 1155 1140 1156 /* … … 2377 2393 } 2378 2394 2395 pDbgc->pLastPos = &pDbgc->DumpPos; 2396 2379 2397 /* 2380 2398 * Do the dumping. … … 2850 2868 2851 2869 /** 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 */ 2879 static 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 /** 2852 2988 * The 'dpg*' commands. 2853 2989 * -
trunk/src/VBox/Debugger/DBGCInternal.h
r31530 r31966 145 145 /** Command helpers. */ 146 146 DBGCCMDHLP CmdHlp; 147 /** Wrappers for DBGF output. */ 148 DBGFINFOHLP DbgfOutputHlp; 147 149 /** Pointer to backend callback structure. */ 148 150 PDBGCBACK pBack; … … 176 178 /** Size of the previous dump element. */ 177 179 unsigned cbDumpElement; 180 /** Points to DisasmPos, SourcePos or DumpPos depending on which was 181 * used last. */ 182 PCDBGCVAR pLastPos; 178 183 179 184 /** Number of variables in papVars. */ -
trunk/src/VBox/Debugger/DBGConsole.cpp
r31530 r31966 1966 1966 //pDbgc->SourcePos = {0}; 1967 1967 //pDbgc->DumpPos = {0}; 1968 pDbgc->pLastPos = &pDbgc->DisasmPos; 1968 1969 //pDbgc->cbDumpElement = 0; 1969 1970 //pDbgc->cVars = 0; -
trunk/src/VBox/Debugger/testcase/tstDBGCStubs.cpp
r31530 r31966 185 185 return VERR_INTERNAL_ERROR; 186 186 } 187 VMMDECL(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 } 187 192 VMMR3DECL(int) DBGFR3RegQueryU8( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t *pu8) 188 193 { -
trunk/src/VBox/VMM/DBGFMem.cpp
r30320 r31966 5 5 6 6 /* 7 * Copyright (C) 2007 Oracle Corporation7 * Copyright (C) 2007-2010 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 125 125 const void *pvNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress) 126 126 { 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); 128 129 return VMR3ReqCallWait(pVM, idCpu, (PFNRT)dbgfR3MemScan, 8, 129 130 pVM, idCpu, pAddress, &cbRange, &uAlign, pvNeedle, cbNeedle, pHitAddress); … … 204 205 VMMR3DECL(int) DBGFR3MemRead(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead) 205 206 { 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); 207 209 if ((pAddress->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_RING0) 208 210 { … … 283 285 return VERR_INVALID_PARAMETER; 284 286 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); 286 289 287 290 /* … … 362 365 VMMR3DECL(int) DBGFR3MemWrite(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void const *pvBuf, size_t cbWrite) 363 366 { 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); 365 369 return VMR3ReqCallWaitU(pVM->pUVM, idCpu, (PFNRT)dbgfR3MemWrite, 5, pVM, idCpu, pAddress, pvBuf, cbWrite); 366 370 } … … 454 458 VMMR3DECL(int) DBGFR3SelQueryInfo(PVM pVM, VMCPUID idCpu, RTSEL Sel, uint32_t fFlags, PDBGFSELINFO pSelInfo) 455 459 { 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); 457 462 AssertReturn(!(fFlags & ~(DBGFSELQI_FLAGS_DT_GUEST | DBGFSELQI_FLAGS_DT_SHADOW | DBGFSELQI_FLAGS_DT_ADJ_64BIT_MODE)), VERR_INVALID_PARAMETER); 458 463 AssertReturn( (fFlags & (DBGFSELQI_FLAGS_DT_SHADOW | DBGFSELQI_FLAGS_DT_ADJ_64BIT_MODE)) … … 505 510 } 506 511 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 */ 519 static 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 */ 557 static 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 */ 639 VMMDECL(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 59 59 /** Set if long mode is enabled. */ 60 60 bool fLme; 61 /** Set if nested paging. */ 62 bool fNp; 63 /** Set if EPT. */ 64 bool fEpt; 61 65 /** The number or chars the address needs. */ 62 66 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; 64 72 /** The current address. */ 65 73 uint64_t u64Address; … … 827 835 828 836 /** 837 * Dumps the a shadow page summary or smth. 838 * 839 * @param pState The dumper state. 840 * @param HCPhys The page address. 841 */ 842 static 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 */ 856 static void pgmR3DumpHierarchyHcPageInfo(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, uint32_t cbPage) 857 { 858 /* later */ 859 NOREF(pState); NOREF(HCPhys); NOREF(cbPage); 860 } 861 862 863 /** 829 864 * Dumps a PAE shadow page table. 830 865 * 831 866 * @returns VBox status code (VINF_SUCCESS). 832 * @param p Args Dumper state.833 * @param pPT Pointer to the page table.834 * @param pHlp Pointer to the output functions.835 */ 836 static int 867 * @param pState The dumper state. 868 * @param HCPhys The page table address. 869 * @param fIsMapping Whether it is a mapping. 870 */ 871 static int pgmR3DumpHierarchyHCPaePT(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, bool fIsMapping) 837 872 { 838 873 PPGMSHWPTPAE pPT = NULL; … … 865 900 } 866 901 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) 869 907 { 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)) 897 943 pState->pHlp->pfnPrintf(pState->pHlp, 898 944 pState->fLme 899 945 ? "%016llx 3 | invalid / MMIO optimization\n" 900 946 : "%08llx 2 | invalid / MMIO optimization\n", 901 pState->u64Address + ((uint64_t)i << X86_PT_PAE_SHIFT));947 pState->u64Address); 902 948 else 903 949 pState->pHlp->pfnPrintf(pState->pHlp, … … 905 951 ? "%016llx 3 | invalid: %RX64\n" 906 952 : "%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])); 909 954 pState->cLeaves++; 910 955 } … … 940 985 941 986 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++) 944 991 { 945 992 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) 950 994 { 995 pState->u64Address = u64BaseAddress + ((uint64_t)i << X86_PD_PAE_SHIFT); 951 996 if (Pde.b.u1Size) 952 997 { … … 969 1014 Pde.u & PGM_PDFLAGS_TRACK_DIRTY ? 'd' : '-', 970 1015 Pde.u & X86_PDE2M_PAE_PG_MASK); 1016 if (pState->fDumpPageInfo) 1017 pgmR3DumpHierarchyHcPageInfo(pState, Pde.u & X86_PDE2M_PAE_PG_MASK, _2M); 971 1018 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 ? "" : "!"); 973 1020 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 ? "" : "!"); 975 1022 pState->pHlp->pfnPrintf(pState->pHlp, "\n"); 976 1023 … … 996 1043 Pde.u & PGM_PDFLAGS_TRACK_DIRTY ? 'd' : '-', 997 1044 Pde.u & X86_PDE_PAE_PG_MASK_FULL); 1045 if (pState->fDumpPageInfo) 1046 pgmR3DumpHierarchyHcShwPageInfo(pState, Pde.u & X86_PDE_PAE_PG_MASK_FULL); 998 1047 if ((Pde.u >> 52) & 0x7ff) 999 1048 pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx!", (Pde.u >> 52) & 0x7ff); … … 1029 1078 static int pgmR3DumpHierarchyHCPaePDPT(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth) 1030 1079 { 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 1031 1084 Assert(cMaxDepth > 0); 1032 1085 cMaxDepth--; … … 1042 1095 1043 1096 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++) 1047 1101 { 1048 1102 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) 1053 1104 { 1054 1105 if (pState->fLme) 1055 1106 { 1056 pState->pHlp->pfnPrintf(pState->pHlp, /*P R S A D G WT CD AT NX 4Ma p ? */1107 pState->pHlp->pfnPrintf(pState->pHlp, /*P R S A D G WT CD AT NX .. a p ? */ 1057 1108 "%016llx 1 | P %c %c %c %c %c %s %s %s %s .. %c%c%c %016llx", 1058 1109 pState->u64Address, … … 1070 1121 Pdpe.u & RT_BIT(11) ? '1' : '0', 1071 1122 Pdpe.u & X86_PDPE_PG_MASK_FULL); 1123 if (pState->fDumpPageInfo) 1124 pgmR3DumpHierarchyHcShwPageInfo(pState, Pdpe.u & X86_PDPE_PG_MASK_FULL); 1072 1125 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); 1074 1127 } 1075 1128 else 1076 1129 { 1077 pState->pHlp->pfnPrintf(pState->pHlp,/*P G WT CD AT NX 4Ma p ? */1078 "%08llx 0 | P 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", 1079 1132 pState->u64Address, 1133 Pdpe.n.u2Reserved & 1? '!' : '.', /* mbz */ 1134 Pdpe.n.u2Reserved & 2? '!' : '.', /* mbz */ 1080 1135 Pdpe.n.u4Reserved & 1? '!' : '.', /* mbz */ 1081 Pdpe.n.u4Reserved & 4? '!' : '.', /* mbz */ 1136 Pdpe.n.u4Reserved & 2? '!' : '.', /* mbz */ 1137 Pdpe.n.u4Reserved & 8? '!' : '.', /* mbz */ 1082 1138 Pdpe.n.u1WriteThru ? "WT" : "--", 1083 1139 Pdpe.n.u1CacheDisable? "CD" : "--", 1084 1140 Pdpe.n.u4Reserved & 2? "!" : "..",/* mbz */ 1141 Pdpe.lm.u1NoExecute ? "!!" : "..",/* mbz */ 1085 1142 Pdpe.u & RT_BIT(9) ? '1' : '0', 1086 1143 Pdpe.u & PGM_PLXFLAGS_PERMANENT ? 'p' : '-', 1087 1144 Pdpe.u & RT_BIT(11) ? '1' : '0', 1088 1145 Pdpe.u & X86_PDPE_PG_MASK_FULL); 1146 if (pState->fDumpPageInfo) 1147 pgmR3DumpHierarchyHcShwPageInfo(pState, Pdpe.u & X86_PDPE_PG_MASK_FULL); 1089 1148 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); 1091 1150 } 1092 1151 pState->pHlp->pfnPrintf(pState->pHlp, "\n"); 1152 1093 1153 if (cMaxDepth) 1094 1154 { … … 1115 1175 static int pgmR3DumpHierarchyHcPaePML4(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth) 1116 1176 { 1177 Assert(cMaxDepth); 1178 cMaxDepth--; 1179 1117 1180 PX86PML4 pPML4 = (PX86PML4)MMPagePhys2Page(pState->pVM, HCPhys); 1118 1181 if (!pPML4) … … 1123 1186 1124 1187 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++) 1127 1191 { 1128 1192 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) 1135 1194 { 1195 pState->u64Address = ((uint64_t)i << X86_PML4_SHIFT) 1196 | (i >= RT_ELEMENTS(pPML4->a) / 2 ? UINT64_C(0xffff000000000000) : 0); 1136 1197 pState->pHlp->pfnPrintf(pState->pHlp, /*P R S A D G WT CD AT NX 4M a p ? */ 1137 1198 "%016llx 0 | P %c %c %c %c %c %s %s %s %s .. %c%c%c %016llx", … … 1150 1211 Pml4e.u & RT_BIT(11) ? '1' : '0', 1151 1212 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); 1153 1215 if ((Pml4e.u >> 52) & 0x7ff) 1154 1216 pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx!", (Pml4e.u >> 52) & 0x7ff); 1155 1217 pState->pHlp->pfnPrintf(pState->pHlp, "\n"); 1156 1218 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); 1160 1222 if (rc2 < rc && RT_SUCCESS(rc)) 1161 1223 rc = rc2; … … 1206 1268 1207 1269 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++) 1209 1274 { 1210 1275 X86PTE Pte = pPT->a[i]; 1211 1276 if (Pte.n.u1Present) 1212 1277 { 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); 1217 1279 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, 1220 1282 Pte.n.u1Write ? 'W' : 'R', 1221 1283 Pte.n.u1User ? 'U' : 'S', … … 1230 1292 Pte.u & PGM_PTFLAGS_CSAM_VALIDATED ? 'v' : '-', 1231 1293 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"); 1232 1297 } 1233 1298 } … … 1248 1313 static int pgmR3DumpHierarchyHC32BitPD(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth) 1249 1314 { 1315 if (pState->u64Address >= _4G) 1316 return VINF_SUCCESS; 1317 1250 1318 Assert(cMaxDepth > 0); 1251 1319 cMaxDepth--; … … 1260 1328 1261 1329 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++) 1264 1334 { 1265 1335 X86PDE Pde = pPD->a[i]; … … 1267 1337 { 1268 1338 pState->u64Address = (uint32_t)i << X86_PD_SHIFT; 1269 if ( pState->u64Address < pState->u64FirstAddress1270 && pState->u64Address > pState->u64LastAddress)1271 continue;1272 1273 1339 if (Pde.b.u1Size && pState->fPse) 1274 1340 { 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); 1275 1343 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", 1277 1345 pState->u64Address, 1278 1346 Pde.b.u1Write ? 'W' : 'R', … … 1287 1355 Pde.u & PGM_PDFLAGS_MAPPING ? 'm' : '-', 1288 1356 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"); 1291 1361 pState->cLeaves++; 1292 1362 } … … 1294 1364 { 1295 1365 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", 1297 1367 pState->u64Address, 1298 1368 Pde.n.u1Write ? 'W' : 'R', … … 1307 1377 Pde.u & PGM_PDFLAGS_TRACK_DIRTY ? 'd' : '-', 1308 1378 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 1309 1383 if (cMaxDepth) 1310 1384 { … … 1333 1407 static int pdmR3DumpHierarchyHcDoIt(PPGMR3DUMPHIERARCHYSTATE pState, uint64_t cr3, unsigned cMaxDepth) 1334 1408 { 1409 int rc; 1335 1410 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 */ 1486 VMMR3_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); 1364 1510 } 1365 1511 … … 1387 1533 State.fPae = (cr4 & X86_CR4_PAE) || fLongMode; 1388 1534 State.fLme = fLongMode; 1535 State.fNp = false; 1536 State.fEpt = false; 1389 1537 State.cchAddress = fLongMode ? 16 : 8; 1538 State.fDumpPageInfo = false; 1539 State.fPrintHeader = true; 1390 1540 State.u64Address = 0; 1391 1541 State.u64FirstAddress = 0; … … 1557 1707 } 1558 1708 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 */ 1724 VMMR3_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.