- Timestamp:
- Aug 26, 2010 12:33:45 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/dbgf.h
r31966 r31987 942 942 * Same value as MSR_K6_EFER_NXE. */ 943 943 #define DBGFPGDMP_FLAGS_NXE RT_BIT_32(11) 944 /** Whether to print the CR3. */ 945 #define DBGFPGDMP_FLAGS_PRINT_CR3 RT_BIT_32(27) 944 946 /** Whether to print the header. */ 945 947 #define DBGFPGDMP_FLAGS_HEADER RT_BIT_32(28) … … 953 955 #define DBGFPGDMP_FLAGS_GUEST RT_BIT_32(31) 954 956 /** Mask of valid bits. */ 955 #define DBGFPGDMP_FLAGS_VALID_MASK UINT32_C(0xf 0000f33)957 #define DBGFPGDMP_FLAGS_VALID_MASK UINT32_C(0xf8000f33) 956 958 /** The mask of bits controlling the paging mode. */ 957 959 #define DBGFPGDMP_FLAGS_MODE_MASK UINT32_C(0x00000f32) -
trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp
r31978 r31987 2868 2868 2869 2869 /** 2870 * The 'dph*' commands .2870 * The 'dph*' commands and main part of 'm'. 2871 2871 * 2872 2872 * @returns VBox status. … … 2884 2884 2885 2885 /* 2886 * Figure the context. 2887 */ 2888 uint32_t fFlags = DBGFPGDMP_FLAGS_PAGE_INFO | DBGFPGDMP_FLAGS_HEADER; 2889 if (pCmd->pszCmd[3] == '\0') 2886 * Figure the context and base flags. 2887 */ 2888 uint32_t fFlags = DBGFPGDMP_FLAGS_PAGE_INFO | DBGFPGDMP_FLAGS_PRINT_CR3; 2889 if (pCmd->pszCmd[0] == 'm') 2890 fFlags |= DBGFPGDMP_FLAGS_GUEST | DBGFPGDMP_FLAGS_SHADOW; 2891 else if (pCmd->pszCmd[3] == '\0') 2890 2892 fFlags |= pDbgc->fRegCtxGuest ? DBGFPGDMP_FLAGS_GUEST : DBGFPGDMP_FLAGS_SHADOW; 2891 2893 else if (pCmd->pszCmd[3] == 'g') … … 2894 2896 fFlags |= DBGFPGDMP_FLAGS_SHADOW; 2895 2897 else 2896 fFlags |= DBGFPGDMP_FLAGS_GUEST | DBGFPGDMP_FLAGS_SHADOW; 2898 AssertFailed(); 2899 2900 if (pDbgc->cPagingHierarchyDumps == 0) 2901 fFlags |= DBGFPGDMP_FLAGS_HEADER; 2902 pDbgc->cPagingHierarchyDumps = (pDbgc->cPagingHierarchyDumps + 1) % 42; 2897 2903 2898 2904 /* … … 3586 3592 if (!pVM) 3587 3593 return DBGCCmdHlpFail(pCmdHlp, pCmd, "No VM.\n"); 3588 3589 DBGCCmdHlpPrintf(pCmdHlp, "guest pd (dpdg %DV):\n", &paArgs[0]); 3590 int rc1 = pCmdHlp->pfnExec(pCmdHlp, "dpdg %DV", &paArgs[0]); 3591 DBGCCmdHlpPrintf(pCmdHlp, "hyper pd (dpdh %DV):\n", &paArgs[0]); 3592 int rc2 = pCmdHlp->pfnExec(pCmdHlp, "dpdh %DV", &paArgs[0]); 3593 DBGCCmdHlpPrintf(pCmdHlp, "guest pt (dptg %DV):\n", &paArgs[0]); 3594 int rc3 = pCmdHlp->pfnExec(pCmdHlp, "dptg %DV", &paArgs[0]); 3595 DBGCCmdHlpPrintf(pCmdHlp, "hyper pt (dpth %DV):\n", &paArgs[0]); 3596 int rc4 = pCmdHlp->pfnExec(pCmdHlp, "dpth %DV", &paArgs[0]); 3597 if (RT_FAILURE(rc1)) 3598 return rc1; 3599 if (RT_FAILURE(rc2)) 3600 return rc2; 3601 if (RT_FAILURE(rc3)) 3602 return rc3; 3603 NOREF(pCmd); NOREF(cArgs); NOREF(pResult); 3604 return rc4; 3594 return dbgcCmdDumpPageHierarchy(pCmd, pCmdHlp, pVM, paArgs, cArgs, pResult); 3605 3595 } 3606 3596 -
trunk/src/VBox/Debugger/DBGCInternal.h
r31966 r31987 169 169 /** Indicates whether the register are terse or sparse. */ 170 170 bool fRegTerse; 171 /** Counter use to suppress the printing of the headers. */ 172 uint8_t cPagingHierarchyDumps; 171 173 172 174 /** Current dissassembler position. */ -
trunk/src/VBox/Debugger/DBGConsole.cpp
r31966 r31987 1963 1963 pDbgc->fRegCtxGuest = true; 1964 1964 pDbgc->fRegTerse = true; 1965 //pDbgc->cPagingHierarchyDumps = 0; 1965 1966 //pDbgc->DisasmPos = {0}; 1966 1967 //pDbgc->SourcePos = {0}; -
trunk/src/VBox/VMM/DBGFMem.cpp
r31966 r31987 602 602 fFlags |= CPUMGetGuestCR4(pVCpu) & (X86_CR4_PSE | X86_CR4_PAE); 603 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);604 fFlags |= CPUMGetGuestEFER(pVCpu) & (MSR_K6_EFER_LME | MSR_K6_EFER_NXE); 605 605 } 606 606 } -
trunk/src/VBox/VMM/PGMDbg.cpp
r31978 r31987 63 63 /** Set if EPT. */ 64 64 bool fEpt; 65 /** Set if NXE is enabled. */ 66 bool fNxe; 65 67 /** The number or chars the address needs. */ 66 68 uint8_t cchAddress; 69 /** The last reserved bit. */ 70 uint8_t uLastRsvdBit; 67 71 /** Dump the page info as well (shadow page summary / guest physical 68 72 * page summary). */ … … 70 74 /** Whether or not to print the header. */ 71 75 bool fPrintHeader; 76 /** Whether to print the CR3 value */ 77 bool fPrintCr3; 78 /** Padding*/ 79 bool afReserved[5]; 72 80 /** The current address. */ 73 81 uint64_t u64Address; … … 76 84 /** The last address to dump structures for. */ 77 85 uint64_t u64LastAddress; 86 /** Mask with the high reserved bits set. */ 87 uint64_t u64HighReservedBits; 78 88 /** The number of leaf entries that we've printed. */ 79 89 uint64_t cLeaves; … … 835 845 836 846 /** 847 * Initializes the dumper state. 848 * 849 * @param pState The state to initialize. 850 * @param pVM The VM handle. 851 * @param fFlags The flags. 852 * @param u64FirstAddr The first address. 853 * @param u64LastAddr The last address. 854 * @param pHlp The output helpers. 855 */ 856 static void pgmR3DumpHierarchyInitState(PPGMR3DUMPHIERARCHYSTATE pState, PVM pVM, uint32_t fFlags, 857 uint64_t u64FirstAddr, uint64_t u64LastAddr, PCDBGFINFOHLP pHlp) 858 { 859 pState->pVM = pVM; 860 pState->pHlp = pHlp ? pHlp : DBGFR3InfoLogHlp(); 861 pState->fPse = !!(fFlags & (DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME)); 862 pState->fPae = !!(fFlags & (DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME)); 863 pState->fLme = !!(fFlags & DBGFPGDMP_FLAGS_LME); 864 pState->fNp = !!(fFlags & DBGFPGDMP_FLAGS_NP); 865 pState->fEpt = !!(fFlags & DBGFPGDMP_FLAGS_EPT); 866 pState->fNxe = !!(fFlags & DBGFPGDMP_FLAGS_NXE); 867 pState->cchAddress = pState->fLme ? 16 : 8; 868 pState->uLastRsvdBit = pState->fNxe ? 62 : 63; 869 pState->fDumpPageInfo = !!(fFlags & DBGFPGDMP_FLAGS_PAGE_INFO); 870 pState->fPrintHeader = !!(fFlags & DBGFPGDMP_FLAGS_HEADER); 871 pState->fPrintCr3 = !!(fFlags & DBGFPGDMP_FLAGS_PRINT_CR3); 872 pState->afReserved[0] = false; 873 pState->afReserved[1] = false; 874 pState->afReserved[2] = false; 875 pState->afReserved[3] = false; 876 pState->afReserved[4] = false; 877 pState->u64Address = u64FirstAddr; 878 pState->u64FirstAddress = u64FirstAddr; 879 pState->u64LastAddress = u64LastAddr; 880 pState->u64HighReservedBits = pState->uLastRsvdBit == 62 ? UINT64_C(0x7ff) << 52 : UINT64_C(0xfff) << 52; 881 pState->cLeaves = 0; 882 } 883 884 885 /** 837 886 * The simple way out, too tired to think of a more elegant solution. 838 887 * … … 892 941 * @param ppv Where to return the pointer. 893 942 */ 894 static int pgmR3DumpHierarchy HcMapPage(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, const char *pszDesc,895 bool fIsMapping, void**ppv)943 static int pgmR3DumpHierarchyShwMapPage(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, const char *pszDesc, 944 bool fIsMapping, void const **ppv) 896 945 { 897 946 void *pvPage; … … 943 992 * @param HCPhys The page address. 944 993 */ 945 static void pgmR3DumpHierarchy HcShwPageInfo(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys)994 static void pgmR3DumpHierarchyShwTablePageInfo(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys) 946 995 { 947 996 pgmLock(pState->pVM); … … 984 1033 * @param cbPage The page size. 985 1034 */ 986 static void pgmR3DumpHierarchy HcPageInfo(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, uint32_t cbPage)1035 static void pgmR3DumpHierarchyShwGuestPageInfo(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, uint32_t cbPage) 987 1036 { 988 1037 char szPage[80]; … … 1021 1070 * @param fIsMapping Whether it is a mapping. 1022 1071 */ 1023 static int pgmR3DumpHierarchy HcPaePT(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, bool fIsMapping)1024 { 1025 P PGMSHWPTPAE pPT;1026 int rc = pgmR3DumpHierarchy HcMapPage(pState, HCPhys, "Page table", fIsMapping, (void**)&pPT);1072 static int pgmR3DumpHierarchyShwPaePT(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, bool fIsMapping) 1073 { 1074 PCPGMSHWPTPAE pPT; 1075 int rc = pgmR3DumpHierarchyShwMapPage(pState, HCPhys, "Page table", fIsMapping, (void const **)&pPT); 1027 1076 if (RT_FAILURE(rc)) 1028 1077 return rc; … … 1057 1106 Pte.u & X86_PTE_PAE_PG_MASK); 1058 1107 if (pState->fDumpPageInfo) 1059 pgmR3DumpHierarchy HcPageInfo(pState, Pte.u & X86_PTE_PAE_PG_MASK, _4K);1108 pgmR3DumpHierarchyShwGuestPageInfo(pState, Pte.u & X86_PTE_PAE_PG_MASK, _4K); 1060 1109 if ((Pte.u >> 52) & 0x7ff) 1061 1110 pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx%s", (Pte.u >> 52) & 0x7ff, pState->fLme ? "" : "!"); … … 1085 1134 * 1086 1135 * @returns VBox status code (VINF_SUCCESS). 1087 * @param p VM The VM handle.1136 * @param pState The dumper state. 1088 1137 * @param HCPhys The physical address of the page directory table. 1089 * @param u64Address The virtual address of the page table starts.1090 * @param cr4 The CR4, PSE is currently used.1091 * @param fLongMode Set if this a long mode table; clear if it's a legacy mode table.1092 1138 * @param cMaxDepth The maxium depth. 1093 * @param pHlp Pointer to the output functions. 1094 */ 1095 static int pgmR3DumpHierarchyHcPaePD(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth) 1096 { 1097 PX86PDPAE pPD; 1098 int rc = pgmR3DumpHierarchyHcMapPage(pState, HCPhys, "Page directory", false, (void **)&pPD); 1139 */ 1140 static int pgmR3DumpHierarchyShwPaePD(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth) 1141 { 1142 PCX86PDPAE pPD; 1143 int rc = pgmR3DumpHierarchyShwMapPage(pState, HCPhys, "Page directory", false, (void const **)&pPD); 1099 1144 if (RT_FAILURE(rc)) 1100 1145 return rc; … … 1132 1177 Pde.u & X86_PDE2M_PAE_PG_MASK); 1133 1178 if (pState->fDumpPageInfo) 1134 pgmR3DumpHierarchy HcPageInfo(pState, Pde.u & X86_PDE2M_PAE_PG_MASK, _2M);1179 pgmR3DumpHierarchyShwGuestPageInfo(pState, Pde.u & X86_PDE2M_PAE_PG_MASK, _2M); 1135 1180 if ((Pde.u >> 52) & 0x7ff) 1136 1181 pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx%s", (Pde.u >> 52) & 0x7ff, pState->fLme ? "" : "!"); … … 1161 1206 Pde.u & X86_PDE_PAE_PG_MASK_FULL); 1162 1207 if (pState->fDumpPageInfo) 1163 pgmR3DumpHierarchy HcShwPageInfo(pState, Pde.u & X86_PDE_PAE_PG_MASK_FULL);1208 pgmR3DumpHierarchyShwTablePageInfo(pState, Pde.u & X86_PDE_PAE_PG_MASK_FULL); 1164 1209 if ((Pde.u >> 52) & 0x7ff) 1165 1210 pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx!", (Pde.u >> 52) & 0x7ff); … … 1168 1213 if (cMaxDepth) 1169 1214 { 1170 int rc2 = pgmR3DumpHierarchy HcPaePT(pState, Pde.u & X86_PDE_PAE_PG_MASK_FULL, !!(Pde.u & PGM_PDFLAGS_MAPPING));1215 int rc2 = pgmR3DumpHierarchyShwPaePT(pState, Pde.u & X86_PDE_PAE_PG_MASK_FULL, !!(Pde.u & PGM_PDFLAGS_MAPPING)); 1171 1216 if (rc2 < rc && RT_SUCCESS(rc)) 1172 1217 rc = rc2; … … 1185 1230 * 1186 1231 * @returns VBox status code (VINF_SUCCESS). 1187 * @param p VM The VM handle.1232 * @param pState The dumper state. 1188 1233 * @param HCPhys The physical address of the page directory pointer table. 1189 * @param u64Address The virtual address of the page table starts.1190 * @param cr4 The CR4, PSE is currently used.1191 * @param fLongMode Set if this a long mode table; clear if it's a legacy mode table.1192 1234 * @param cMaxDepth The maxium depth. 1193 * @param pHlp Pointer to the output functions. 1194 */ 1195 static int pgmR3DumpHierarchyHcPaePDPT(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth) 1235 */ 1236 static int pgmR3DumpHierarchyShwPaePDPT(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth) 1196 1237 { 1197 1238 /* Fend of addresses that are out of range in PAE mode - simplifies the code below. */ … … 1199 1240 return VINF_SUCCESS; 1200 1241 1201 P X86PDPT pPDPT;1202 int rc = pgmR3DumpHierarchy HcMapPage(pState, HCPhys, "Page directory pointer table", false, (void**)&pPDPT);1242 PCX86PDPT pPDPT; 1243 int rc = pgmR3DumpHierarchyShwMapPage(pState, HCPhys, "Page directory pointer table", false, (void const **)&pPDPT); 1203 1244 if (RT_FAILURE(rc)) 1204 1245 return rc; … … 1236 1277 Pdpe.u & X86_PDPE_PG_MASK_FULL); 1237 1278 if (pState->fDumpPageInfo) 1238 pgmR3DumpHierarchy HcShwPageInfo(pState, Pdpe.u & X86_PDPE_PG_MASK_FULL);1279 pgmR3DumpHierarchyShwTablePageInfo(pState, Pdpe.u & X86_PDPE_PG_MASK_FULL); 1239 1280 if ((Pdpe.u >> 52) & 0x7ff) 1240 1281 pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx", (Pdpe.u >> 52) & 0x7ff); … … 1259 1300 Pdpe.u & X86_PDPE_PG_MASK_FULL); 1260 1301 if (pState->fDumpPageInfo) 1261 pgmR3DumpHierarchy HcShwPageInfo(pState, Pdpe.u & X86_PDPE_PG_MASK_FULL);1302 pgmR3DumpHierarchyShwTablePageInfo(pState, Pdpe.u & X86_PDPE_PG_MASK_FULL); 1262 1303 if ((Pdpe.u >> 52) & 0xfff) 1263 1304 pState->pHlp->pfnPrintf(pState->pHlp, " 63:52=%03llx!", (Pdpe.u >> 52) & 0xfff); … … 1267 1308 if (cMaxDepth) 1268 1309 { 1269 int rc2 = pgmR3DumpHierarchy HcPaePD(pState, Pdpe.u & X86_PDPE_PG_MASK_FULL, cMaxDepth);1310 int rc2 = pgmR3DumpHierarchyShwPaePD(pState, Pdpe.u & X86_PDPE_PG_MASK_FULL, cMaxDepth); 1270 1311 if (rc2 < rc && RT_SUCCESS(rc)) 1271 1312 rc = rc2; … … 1287 1328 * @param cMaxDepth The maxium depth. 1288 1329 */ 1289 static int pgmR3DumpHierarchy HcPaePML4(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth)1290 { 1291 P X86PML4 pPML4;1292 int rc = pgmR3DumpHierarchy HcMapPage(pState, HCPhys, "Page map level 4", false, (void**)&pPML4);1330 static int pgmR3DumpHierarchyShwPaePML4(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth) 1331 { 1332 PCX86PML4 pPML4; 1333 int rc = pgmR3DumpHierarchyShwMapPage(pState, HCPhys, "Page map level 4", false, (void const **)&pPML4); 1293 1334 if (RT_FAILURE(rc)) 1294 1335 return rc; … … 1337 1378 Pml4e.u & X86_PML4E_PG_MASK); 1338 1379 if (pState->fDumpPageInfo) 1339 pgmR3DumpHierarchy HcShwPageInfo(pState, Pml4e.u & X86_PML4E_PG_MASK);1380 pgmR3DumpHierarchyShwTablePageInfo(pState, Pml4e.u & X86_PML4E_PG_MASK); 1340 1381 if ((Pml4e.u >> 52) & 0x7ff) 1341 1382 pState->pHlp->pfnPrintf(pState->pHlp, " 62:52=%03llx!", (Pml4e.u >> 52) & 0x7ff); … … 1344 1385 if (cMaxDepth) 1345 1386 { 1346 int rc2 = pgmR3DumpHierarchy HcPaePDPT(pState, Pml4e.u & X86_PML4E_PG_MASK, cMaxDepth);1387 int rc2 = pgmR3DumpHierarchyShwPaePDPT(pState, Pml4e.u & X86_PML4E_PG_MASK, cMaxDepth); 1347 1388 if (rc2 < rc && RT_SUCCESS(rc)) 1348 1389 rc = rc2; … … 1362 1403 * @param pVM The VM handle. 1363 1404 * @param pPT Pointer to the page table. 1364 * @param u32Address The virtual address this table starts at. 1365 * @param pHlp Pointer to the output functions. 1366 */ 1367 static int pgmR3DumpHierarchyHc32BitPT(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, bool fMapping) 1368 { 1369 PX86PT pPT; 1370 int rc = pgmR3DumpHierarchyHcMapPage(pState, HCPhys, "Page table", fMapping, (void **)&pPT); 1405 * @param fMapping Set if it's a guest mapping. 1406 */ 1407 static int pgmR3DumpHierarchyShw32BitPT(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, bool fMapping) 1408 { 1409 PCX86PT pPT; 1410 int rc = pgmR3DumpHierarchyShwMapPage(pState, HCPhys, "Page table", fMapping, (void const **)&pPT); 1371 1411 if (RT_FAILURE(rc)) 1372 1412 return rc; … … 1396 1436 Pte.u & X86_PDE_PG_MASK); 1397 1437 if (pState->fDumpPageInfo) 1398 pgmR3DumpHierarchy HcPageInfo(pState, Pte.u & X86_PDE_PG_MASK, _4K);1438 pgmR3DumpHierarchyShwGuestPageInfo(pState, Pte.u & X86_PDE_PG_MASK, _4K); 1399 1439 pState->pHlp->pfnPrintf(pState->pHlp, "\n"); 1400 1440 } … … 1408 1448 * 1409 1449 * @returns VBox status code (VINF_SUCCESS). 1410 * @param pVM The VM handle. 1411 * @param cr3 The root of the hierarchy. 1412 * @param cr4 The CR4, PSE is currently used. 1413 * @param cMaxDepth How deep into the hierarchy the dumper should go. 1414 * @param pHlp Pointer to the output functions. 1415 */ 1416 static int pgmR3DumpHierarchyHc32BitPD(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth) 1450 * @param pState The dumper state. 1451 * @param HCPhys The physical address of the table. 1452 * @param cMaxDepth The maxium depth. 1453 */ 1454 static int pgmR3DumpHierarchyShw32BitPD(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS HCPhys, unsigned cMaxDepth) 1417 1455 { 1418 1456 if (pState->u64Address >= _4G) 1419 1457 return VINF_SUCCESS; 1420 1458 1421 P X86PD pPD;1422 int rc = pgmR3DumpHierarchy HcMapPage(pState, HCPhys, "Page directory", false, (void**)&pPD);1459 PCX86PD pPD; 1460 int rc = pgmR3DumpHierarchyShwMapPage(pState, HCPhys, "Page directory", false, (void const **)&pPD); 1423 1461 if (RT_FAILURE(rc)) 1424 1462 return rc; … … 1455 1493 u64Phys); 1456 1494 if (pState->fDumpPageInfo) 1457 pgmR3DumpHierarchy HcPageInfo(pState, u64Phys, _4M);1495 pgmR3DumpHierarchyShwGuestPageInfo(pState, u64Phys, _4M); 1458 1496 pState->pHlp->pfnPrintf(pState->pHlp, "\n"); 1459 1497 pState->cLeaves++; … … 1476 1514 Pde.u & X86_PDE_PG_MASK); 1477 1515 if (pState->fDumpPageInfo) 1478 pgmR3DumpHierarchy HcShwPageInfo(pState, Pde.u & X86_PDE_PG_MASK);1516 pgmR3DumpHierarchyShwTablePageInfo(pState, Pde.u & X86_PDE_PG_MASK); 1479 1517 pState->pHlp->pfnPrintf(pState->pHlp, "\n"); 1480 1518 1481 1519 if (cMaxDepth) 1482 1520 { 1483 int rc2 = pgmR3DumpHierarchy Hc32BitPT(pState, Pde.u & X86_PDE_PG_MASK, !!(Pde.u & PGM_PDFLAGS_MAPPING));1521 int rc2 = pgmR3DumpHierarchyShw32BitPT(pState, Pde.u & X86_PDE_PG_MASK, !!(Pde.u & PGM_PDFLAGS_MAPPING)); 1484 1522 if (rc2 < rc && RT_SUCCESS(rc)) 1485 1523 rc = rc2; … … 1503 1541 * @param cMaxDepth The max depth. 1504 1542 */ 1505 static int pdmR3DumpHierarchyHcDoIt(PPGMR3DUMPHIERARCHYSTATE pState, uint64_t cr3, unsigned cMaxDepth) 1506 { 1507 int rc; 1508 const unsigned cch = pState->cchAddress; 1543 static int pgmR3DumpHierarchyShwDoIt(PPGMR3DUMPHIERARCHYSTATE pState, uint64_t cr3, unsigned cMaxDepth) 1544 { 1545 int rc; 1546 unsigned const cch = pState->cchAddress; 1547 uint64_t const cr3Mask = pState->fEpt ? X86_CR3_AMD64_PAGE_MASK 1548 : pState->fLme ? X86_CR3_AMD64_PAGE_MASK 1549 : pState->fPae ? X86_CR3_PAE_PAGE_MASK 1550 : X86_CR3_PAGE_MASK; 1551 if (pState->fPrintCr3) 1552 { 1553 const char * const pszMode = pState->fEpt ? "Extended Page Tables" 1554 : pState->fLme ? "Long Mode" 1555 : pState->fPae ? "PAE Mode" 1556 : pState->fPse ? "32-bit w/ PSE" 1557 : "32-bit"; 1558 pState->pHlp->pfnPrintf(pState->pHlp, "cr3=%0*llx", cch, cr3); 1559 if (pState->fDumpPageInfo) 1560 pgmR3DumpHierarchyShwTablePageInfo(pState, cr3 & X86_CR3_AMD64_PAGE_MASK); 1561 pState->pHlp->pfnPrintf(pState->pHlp, " %s%s\n", 1562 pszMode, 1563 pState->fNp ? " + Nested Paging" : "", 1564 pState->fNxe ? " + NX" : ""); 1565 } 1566 1567 1509 1568 if (pState->fEpt) 1510 1569 { 1511 1570 if (pState->fPrintHeader) 1512 1571 pState->pHlp->pfnPrintf(pState->pHlp, 1513 "cr3=%0*llx Extended Page Tables\n"1514 1572 "%-*s R - Readable\n" 1515 1573 "%-*s | W - Writeable\n" … … 1523 1581 R W X 7 0 f fff 0123456701234567 */ 1524 1582 , 1525 cch, cr3,1526 1583 cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", cch, "Address"); 1527 1584 … … 1534 1591 if (pState->fPrintHeader) 1535 1592 pState->pHlp->pfnPrintf(pState->pHlp, 1536 "cr3=%0*llx %s%s\n"1537 1593 "%-*s P - Present\n" 1538 1594 "%-*s | R/W - Read (0) / Write (1)\n" … … 1552 1608 - W U - - - -- -- -- -- -- 010 */ 1553 1609 , 1554 cch, cr3,1555 pState->fLme ? "Long Mode" : pState->fPae ? "PAE" : pState->fPse ? "32-bit w/ PSE" : "32-bit",1556 pState->fNp ? " Nested Paging" : "",1557 1610 cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", 1558 1611 cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", cch, "Address"); 1559 1612 if (pState->fLme) 1560 rc = pgmR3DumpHierarchy HcPaePML4(pState, cr3 & X86_CR3_PAGE_MASK,cMaxDepth);1613 rc = pgmR3DumpHierarchyShwPaePML4(pState, cr3 & cr3Mask, cMaxDepth); 1561 1614 else if (pState->fPae) 1562 rc = pgmR3DumpHierarchy HcPaePDPT(pState, cr3 & X86_CR3_PAE_PAGE_MASK, cMaxDepth);1615 rc = pgmR3DumpHierarchyShwPaePDPT(pState, cr3 & cr3Mask, cMaxDepth); 1563 1616 else 1564 rc = pgmR3DumpHierarchyHc32BitPD(pState, cr3 & X86_CR3_PAGE_MASK, cMaxDepth); 1565 } 1617 rc = pgmR3DumpHierarchyShw32BitPD(pState, cr3 & cr3Mask, cMaxDepth); 1618 } 1619 1620 if (!pState->cLeaves) 1621 pState->pHlp->pfnPrintf(pState->pHlp, "not present\n"); 1566 1622 return rc; 1567 1623 } … … 1591 1647 1592 1648 PGMR3DUMPHIERARCHYSTATE State; 1593 State.pVM = pVM; 1594 State.pHlp = pHlp ? pHlp : DBGFR3InfoLogHlp(); 1595 State.fPse = !!(fFlags & (DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME)); 1596 State.fPae = !!(fFlags & (DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME)); 1597 State.fLme = !!(fFlags & DBGFPGDMP_FLAGS_LME); 1598 State.fNp = !!(fFlags & DBGFPGDMP_FLAGS_NP); 1599 State.fEpt = !!(fFlags & DBGFPGDMP_FLAGS_EPT); 1600 State.cchAddress = State.fLme ? 16 : 8; 1601 State.fDumpPageInfo = !!(fFlags & DBGFPGDMP_FLAGS_PAGE_INFO); 1602 State.fPrintHeader = !!(fFlags & DBGFPGDMP_FLAGS_HEADER); 1603 State.u64Address = u64FirstAddr; 1604 State.u64FirstAddress = u64FirstAddr; 1605 State.u64LastAddress = u64LastAddr; 1606 State.cLeaves = 0; 1607 return pdmR3DumpHierarchyHcDoIt(&State, cr3, cMaxDepth); 1649 pgmR3DumpHierarchyInitState(&State, pVM, fFlags, u64FirstAddr, u64LastAddr, pHlp); 1650 return pgmR3DumpHierarchyShwDoIt(&State, cr3, cMaxDepth); 1608 1651 } 1609 1652 … … 1619 1662 * @param cMaxDepth Number of levels to dump. 1620 1663 * @param pHlp Pointer to the output functions. 1664 * 1665 * @deprecated Use DBGFR3PagingDumpEx. 1621 1666 */ 1622 1667 VMMR3DECL(int) PGMR3DumpHierarchyHC(PVM pVM, uint64_t cr3, uint64_t cr4, bool fLongMode, unsigned cMaxDepth, PCDBGFINFOHLP pHlp) … … 1625 1670 return VINF_SUCCESS; 1626 1671 1627 PGMR3DUMPHIERARCHYSTATE State; 1628 State.pVM = pVM; 1629 State.pHlp = pHlp ? pHlp : DBGFR3InfoLogHlp(); 1630 State.fPse = (cr4 & X86_CR4_PSE) || (cr4 & X86_CR4_PAE) || fLongMode; 1631 State.fPae = (cr4 & X86_CR4_PAE) || fLongMode; 1632 State.fLme = fLongMode; 1633 State.fNp = false; 1634 State.fEpt = false; 1635 State.cchAddress = fLongMode ? 16 : 8; 1636 State.fDumpPageInfo = false; 1637 State.fPrintHeader = true; 1638 State.u64Address = 0; 1639 State.u64FirstAddress = 0; 1640 State.u64LastAddress = fLongMode ? UINT64_MAX : UINT32_MAX; 1641 State.cLeaves = 0; 1642 return pdmR3DumpHierarchyHcDoIt(&State, cr3, cMaxDepth); 1643 } 1644 1645 1672 PVMCPU pVCpu = VMMGetCpu(pVM); 1673 if (!pVCpu) 1674 pVCpu = &pVM->aCpus[0]; 1675 1676 uint32_t fFlags = DBGFPGDMP_FLAGS_HEADER | DBGFPGDMP_FLAGS_PRINT_CR3 | DBGFPGDMP_FLAGS_PAGE_INFO | DBGFPGDMP_FLAGS_SHADOW; 1677 fFlags |= cr4 & (X86_CR4_PAE | X86_CR4_PSE); 1678 if (fLongMode) 1679 fFlags |= DBGFPGDMP_FLAGS_LME; 1680 1681 return DBGFR3PagingDumpEx(pVM, pVCpu->idCpu, fFlags, cr3, 0, fLongMode ? UINT64_MAX : UINT32_MAX, cMaxDepth, pHlp); 1682 } 1683 1684 1685 ////// kill this code ////// 1646 1686 1647 1687 /** … … 1700 1740 * @param cr4 The CR4, PSE is currently used. 1701 1741 * @param PhysSearch Address to search for. 1742 * @deprecated Use DBGFR3PagingDumpEx. 1702 1743 */ 1703 1744 VMMR3DECL(int) PGMR3DumpHierarchyGC(PVM pVM, uint64_t cr3, uint64_t cr4, RTGCPHYS PhysSearch) … … 1805 1846 } 1806 1847 1848 /////// end of to-be-killed code. /////// 1849 1850 1851 /** 1852 * Maps the guest page. 1853 * 1854 * @returns VBox status code. 1855 * @param pState The dumper state. 1856 * @param GCPhys The physical address of the guest page. 1857 * @param pszDesc The description. 1858 * @param ppv Where to return the pointer. 1859 * @param pLock Where to return the mapping lock. Hand this to 1860 * PGMPhysReleasePageMappingLock when done. 1861 */ 1862 static int pgmR3DumpHierarchyGstMapPage(PPGMR3DUMPHIERARCHYSTATE pState, RTGCPHYS GCPhys, const char *pszDesc, 1863 void const **ppv, PPGMPAGEMAPLOCK pLock) 1864 { 1865 int rc = PGMPhysGCPhys2CCPtrReadOnly(pState->pVM, GCPhys, ppv, pLock); 1866 if (RT_FAILURE(rc)) 1867 { 1868 pState->pHlp->pfnPrintf(pState->pHlp, "%0*llx error! Failed to map %s at GCPhys=%RGp: %Rrc!\n", 1869 pState->cchAddress, pState->u64Address, pszDesc, GCPhys, rc); 1870 return rc; 1871 } 1872 return VINF_SUCCESS; 1873 } 1874 1875 1876 /** 1877 * Figures out which guest page this is and dumps a summary. 1878 * 1879 * @param pState The dumper state. 1880 * @param GCPhys The page address. 1881 * @param cbPage The page size. 1882 */ 1883 static void pgmR3DumpHierarchyGstPageInfo(PPGMR3DUMPHIERARCHYSTATE pState, RTGCPHYS GCPhys, uint32_t cbPage) 1884 { 1885 char szPage[80]; 1886 pgmLock(pState->pVM); 1887 PCPGMPAGE pPage = pgmPhysGetPage(&pState->pVM->pgm.s, GCPhys); 1888 if (pPage) 1889 RTStrPrintf(szPage, sizeof(szPage), " %R[pgmpage]", pPage); 1890 else 1891 strcpy(szPage, " not found"); 1892 pgmUnlock(pState->pVM); 1893 pState->pHlp->pfnPrintf(pState->pHlp, "%s", szPage); 1894 } 1895 1896 1897 /** 1898 * Checks the entry for reserved bits. 1899 * 1900 * @param pState The dumper state. 1901 * @param u64Entry The entry to check. 1902 */ 1903 static void pgmR3DumpHierarchyGstCheckReservedHighBits(PPGMR3DUMPHIERARCHYSTATE pState, uint64_t u64Entry) 1904 { 1905 uint32_t uRsvd = (u64Entry & pState->u64HighReservedBits) >> 52; 1906 if (uRsvd) 1907 pState->pHlp->pfnPrintf(pState->pHlp, " %u:52=%03llx%s", 1908 pState->uLastRsvdBit, uRsvd, pState->fLme ? "" : "!"); 1909 /** @todo check the valid physical bits as well. */ 1910 } 1911 1912 1913 /** 1914 * Dumps a PAE shadow page table. 1915 * 1916 * @returns VBox status code (VINF_SUCCESS). 1917 * @param pState The dumper state. 1918 * @param GCPhys The page table address. 1919 */ 1920 static int pgmR3DumpHierarchyGstPaePT(PPGMR3DUMPHIERARCHYSTATE pState, RTGCPHYS GCPhys) 1921 { 1922 PCX86PTPAE pPT; 1923 PGMPAGEMAPLOCK Lock; 1924 int rc = pgmR3DumpHierarchyGstMapPage(pState, GCPhys, "Page table", (void const **)&pPT, &Lock); 1925 if (RT_FAILURE(rc)) 1926 return rc; 1927 1928 uint32_t iFirst, iLast; 1929 uint64_t u64BaseAddress = pgmR3DumpHierarchyCalcRange(pState, X86_PT_PAE_SHIFT, X86_PG_PAE_ENTRIES, &iFirst, &iLast); 1930 for (uint32_t i = iFirst; i <= iLast; i++) 1931 { 1932 X86PTEPAE Pte = pPT->a[i]; 1933 if (Pte.n.u1Present) 1934 { 1935 pState->u64Address = u64BaseAddress + ((uint64_t)i << X86_PT_PAE_SHIFT); 1936 pState->pHlp->pfnPrintf(pState->pHlp, 1937 pState->fLme /*P R S A D G WT CD AT NX 4M a p ? */ 1938 ? "%016llx 3 | P %c %c %c %c %c %s %s %s %s 4K %c%c%c %016llx" 1939 : "%08llx 2 | P %c %c %c %c %c %s %s %s %s 4K %c%c%c %016llx", 1940 pState->u64Address, 1941 Pte.n.u1Write ? 'W' : 'R', 1942 Pte.n.u1User ? 'U' : 'S', 1943 Pte.n.u1Accessed ? 'A' : '-', 1944 Pte.n.u1Dirty ? 'D' : '-', 1945 Pte.n.u1Global ? 'G' : '-', 1946 Pte.n.u1WriteThru ? "WT" : "--", 1947 Pte.n.u1CacheDisable? "CD" : "--", 1948 Pte.n.u1PAT ? "AT" : "--", 1949 Pte.n.u1NoExecute ? "NX" : "--", 1950 Pte.u & RT_BIT(9) ? '1' : '0', 1951 Pte.u & RT_BIT(10) ? '1' : '0', 1952 Pte.u & RT_BIT(11) ? '1' : '0', 1953 Pte.u & X86_PTE_PAE_PG_MASK); 1954 if (pState->fDumpPageInfo) 1955 pgmR3DumpHierarchyGstPageInfo(pState, Pte.u & X86_PTE_PAE_PG_MASK, _4K); 1956 pgmR3DumpHierarchyGstCheckReservedHighBits(pState, Pte.u); 1957 pState->pHlp->pfnPrintf(pState->pHlp, "\n"); 1958 pState->cLeaves++; 1959 } 1960 } 1961 1962 PGMPhysReleasePageMappingLock(pState->pVM, &Lock); 1963 return VINF_SUCCESS; 1964 } 1965 1966 1967 /** 1968 * Dumps a PAE shadow page directory table. 1969 * 1970 * @returns VBox status code (VINF_SUCCESS). 1971 * @param pState The dumper state. 1972 * @param GCPhys The physical address of the table. 1973 * @param cMaxDepth The maxium depth. 1974 */ 1975 static int pgmR3DumpHierarchyGstPaePD(PPGMR3DUMPHIERARCHYSTATE pState, RTGCPHYS GCPhys, unsigned cMaxDepth) 1976 { 1977 PCX86PDPAE pPD; 1978 PGMPAGEMAPLOCK Lock; 1979 int rc = pgmR3DumpHierarchyGstMapPage(pState, GCPhys, "Page directory", (void const **)&pPD, &Lock); 1980 if (RT_FAILURE(rc)) 1981 return rc; 1982 1983 Assert(cMaxDepth > 0); 1984 cMaxDepth--; 1985 1986 uint32_t iFirst, iLast; 1987 uint64_t u64BaseAddress = pgmR3DumpHierarchyCalcRange(pState, X86_PD_PAE_SHIFT, X86_PG_PAE_ENTRIES, &iFirst, &iLast); 1988 for (uint32_t i = iFirst; i <= iLast; i++) 1989 { 1990 X86PDEPAE Pde = pPD->a[i]; 1991 if (Pde.n.u1Present) 1992 { 1993 pState->u64Address = u64BaseAddress + ((uint64_t)i << X86_PD_PAE_SHIFT); 1994 if (Pde.b.u1Size) 1995 { 1996 pState->pHlp->pfnPrintf(pState->pHlp, 1997 pState->fLme /*P R S A D G WT CD AT NX 2M a p ? phys*/ 1998 ? "%016llx 2 | P %c %c %c %c %c %s %s %s %s 2M %c%c%c %016llx" 1999 : "%08llx 1 | P %c %c %c %c %c %s %s %s %s 2M %c%c%c %016llx", 2000 pState->u64Address, 2001 Pde.b.u1Write ? 'W' : 'R', 2002 Pde.b.u1User ? 'U' : 'S', 2003 Pde.b.u1Accessed ? 'A' : '-', 2004 Pde.b.u1Dirty ? 'D' : '-', 2005 Pde.b.u1Global ? 'G' : '-', 2006 Pde.b.u1WriteThru ? "WT" : "--", 2007 Pde.b.u1CacheDisable ? "CD" : "--", 2008 Pde.b.u1PAT ? "AT" : "--", 2009 Pde.b.u1NoExecute ? "NX" : "--", 2010 Pde.u & RT_BIT_64(9) ? '1' : '0', 2011 Pde.u & RT_BIT_64(10) ? '1' : '0', 2012 Pde.u & RT_BIT_64(11) ? '1' : '0', 2013 Pde.u & X86_PDE2M_PAE_PG_MASK); 2014 if (pState->fDumpPageInfo) 2015 pgmR3DumpHierarchyGstPageInfo(pState, Pde.u & X86_PDE2M_PAE_PG_MASK, _2M); 2016 pgmR3DumpHierarchyGstCheckReservedHighBits(pState, Pde.u); 2017 if ((Pde.u >> 13) & 0xff) 2018 pState->pHlp->pfnPrintf(pState->pHlp, " 20:13=%02llx%s", (Pde.u >> 13) & 0x0ff, pState->fLme ? "" : "!"); 2019 pState->pHlp->pfnPrintf(pState->pHlp, "\n"); 2020 2021 pState->cLeaves++; 2022 } 2023 else 2024 { 2025 pState->pHlp->pfnPrintf(pState->pHlp, 2026 pState->fLme /*P R S A D G WT CD AT NX 4M a p ? phys */ 2027 ? "%016llx 2 | P %c %c %c %c %c %s %s .. %s .. %c%c%c %016llx" 2028 : "%08llx 1 | P %c %c %c %c %c %s %s .. %s .. %c%c%c %016llx", 2029 pState->u64Address, 2030 Pde.n.u1Write ? 'W' : 'R', 2031 Pde.n.u1User ? 'U' : 'S', 2032 Pde.n.u1Accessed ? 'A' : '-', 2033 Pde.n.u1Reserved0 ? '?' : '.', /* ignored */ 2034 Pde.n.u1Reserved1 ? '?' : '.', /* ignored */ 2035 Pde.n.u1WriteThru ? "WT" : "--", 2036 Pde.n.u1CacheDisable ? "CD" : "--", 2037 Pde.n.u1NoExecute ? "NX" : "--", 2038 Pde.u & RT_BIT_64(9) ? '1' : '0', 2039 Pde.u & RT_BIT_64(10) ? '1' : '0', 2040 Pde.u & RT_BIT_64(11) ? '1' : '0', 2041 Pde.u & X86_PDE_PAE_PG_MASK_FULL); 2042 if (pState->fDumpPageInfo) 2043 pgmR3DumpHierarchyGstPageInfo(pState, Pde.u & X86_PDE_PAE_PG_MASK_FULL, _4K); 2044 pgmR3DumpHierarchyGstCheckReservedHighBits(pState, Pde.u); 2045 pState->pHlp->pfnPrintf(pState->pHlp, "\n"); 2046 2047 if (cMaxDepth) 2048 { 2049 int rc2 = pgmR3DumpHierarchyGstPaePT(pState, Pde.u & X86_PDE_PAE_PG_MASK_FULL); 2050 if (rc2 < rc && RT_SUCCESS(rc)) 2051 rc = rc2; 2052 } 2053 else 2054 pState->cLeaves++; 2055 } 2056 } 2057 } 2058 2059 PGMPhysReleasePageMappingLock(pState->pVM, &Lock); 2060 return rc; 2061 } 2062 2063 2064 /** 2065 * Dumps a PAE shadow page directory pointer table. 2066 * 2067 * @returns VBox status code (VINF_SUCCESS). 2068 * @param pState The dumper state. 2069 * @param GCPhys The physical address of the table. 2070 * @param cMaxDepth The maxium depth. 2071 */ 2072 static int pgmR3DumpHierarchyGstPaePDPT(PPGMR3DUMPHIERARCHYSTATE pState, RTGCPHYS GCPhys, unsigned cMaxDepth) 2073 { 2074 /* Fend of addresses that are out of range in PAE mode - simplifies the code below. */ 2075 if (!pState->fLme && pState->u64Address >= _4G) 2076 return VINF_SUCCESS; 2077 2078 PCX86PDPT pPDPT; 2079 PGMPAGEMAPLOCK Lock; 2080 int rc = pgmR3DumpHierarchyGstMapPage(pState, GCPhys, "Page directory pointer table", (void const **)&pPDPT, &Lock); 2081 if (RT_FAILURE(rc)) 2082 return rc; 2083 2084 Assert(cMaxDepth > 0); 2085 cMaxDepth--; 2086 2087 uint32_t iFirst, iLast; 2088 uint64_t u64BaseAddress = pgmR3DumpHierarchyCalcRange(pState, X86_PDPT_SHIFT, 2089 pState->fLme ? X86_PG_AMD64_PDPE_ENTRIES : X86_PG_PAE_PDPE_ENTRIES, 2090 &iFirst, &iLast); 2091 for (uint32_t i = iFirst; i <= iLast; i++) 2092 { 2093 X86PDPE Pdpe = pPDPT->a[i]; 2094 if (Pdpe.n.u1Present) 2095 { 2096 pState->u64Address = u64BaseAddress + ((uint64_t)i << X86_PDPT_SHIFT); 2097 if (pState->fLme) 2098 { 2099 /** @todo Do 1G pages. */ 2100 pState->pHlp->pfnPrintf(pState->pHlp, /*P R S A D G WT CD AT NX .. a p ? */ 2101 "%016llx 1 | P %c %c %c %c %c %s %s %s %s .. %c%c%c %016llx", 2102 pState->u64Address, 2103 Pdpe.lm.u1Write ? 'W' : 'R', 2104 Pdpe.lm.u1User ? 'U' : 'S', 2105 Pdpe.lm.u1Accessed ? 'A' : '-', 2106 Pdpe.lm.u3Reserved & 1 ? '?' : '.', /* ignored */ 2107 Pdpe.lm.u3Reserved & 4 ? '!' : '.', /* mbz */ 2108 Pdpe.lm.u1WriteThru ? "WT" : "--", 2109 Pdpe.lm.u1CacheDisable ? "CD" : "--", 2110 Pdpe.lm.u3Reserved & 2 ? "!" : "..",/* mbz */ 2111 Pdpe.lm.u1NoExecute ? "NX" : "--", 2112 Pdpe.u & RT_BIT_64(9) ? '1' : '0', 2113 Pdpe.u & RT_BIT_64(10) ? '1' : '0', 2114 Pdpe.u & RT_BIT_64(11) ? '1' : '0', 2115 Pdpe.u & X86_PDPE_PG_MASK_FULL); 2116 if (pState->fDumpPageInfo) 2117 pgmR3DumpHierarchyGstPageInfo(pState, Pdpe.u & X86_PDPE_PG_MASK_FULL, _4K); 2118 pgmR3DumpHierarchyGstCheckReservedHighBits(pState, Pdpe.u); 2119 } 2120 else 2121 { 2122 pState->pHlp->pfnPrintf(pState->pHlp,/*P R S A D G WT CD AT NX .. a p ? */ 2123 "%08llx 0 | P %c %c %c %c %c %s %s %s %s .. %c%c%c %016llx", 2124 pState->u64Address, 2125 Pdpe.n.u2Reserved & 1 ? '!' : '.', /* mbz */ 2126 Pdpe.n.u2Reserved & 2 ? '!' : '.', /* mbz */ 2127 Pdpe.n.u4Reserved & 1 ? '!' : '.', /* mbz */ 2128 Pdpe.n.u4Reserved & 2 ? '!' : '.', /* mbz */ 2129 Pdpe.n.u4Reserved & 8 ? '!' : '.', /* mbz */ 2130 Pdpe.n.u1WriteThru ? "WT" : "--", 2131 Pdpe.n.u1CacheDisable ? "CD" : "--", 2132 Pdpe.n.u4Reserved & 2 ? "!" : "..", /* mbz */ 2133 Pdpe.lm.u1NoExecute ? "!!" : "..",/* mbz */ 2134 Pdpe.u & RT_BIT_64(9) ? '1' : '0', 2135 Pdpe.u & RT_BIT_64(10) ? '1' : '0', 2136 Pdpe.u & RT_BIT_64(11) ? '1' : '0', 2137 Pdpe.u & X86_PDPE_PG_MASK_FULL); 2138 if (pState->fDumpPageInfo) 2139 pgmR3DumpHierarchyGstPageInfo(pState, Pdpe.u & X86_PDPE_PG_MASK_FULL, _4K); 2140 pgmR3DumpHierarchyGstCheckReservedHighBits(pState, Pdpe.u); 2141 } 2142 pState->pHlp->pfnPrintf(pState->pHlp, "\n"); 2143 2144 if (cMaxDepth) 2145 { 2146 int rc2 = pgmR3DumpHierarchyGstPaePD(pState, Pdpe.u & X86_PDPE_PG_MASK_FULL, cMaxDepth); 2147 if (rc2 < rc && RT_SUCCESS(rc)) 2148 rc = rc2; 2149 } 2150 else 2151 pState->cLeaves++; 2152 } 2153 } 2154 2155 PGMPhysReleasePageMappingLock(pState->pVM, &Lock); 2156 return rc; 2157 } 2158 2159 2160 /** 2161 * Dumps a 32-bit shadow page table. 2162 * 2163 * @returns VBox status code (VINF_SUCCESS). 2164 * @param pVM The VM handle. 2165 * @param GCPhys The physical address of the table. 2166 * @param cMaxDepth The maxium depth. 2167 */ 2168 static int pgmR3DumpHierarchyGstPaePML4(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS GCPhys, unsigned cMaxDepth) 2169 { 2170 PCX86PML4 pPML4; 2171 PGMPAGEMAPLOCK Lock; 2172 int rc = pgmR3DumpHierarchyGstMapPage(pState, GCPhys, "Page map level 4", (void const **)&pPML4, &Lock); 2173 if (RT_FAILURE(rc)) 2174 return rc; 2175 2176 Assert(cMaxDepth); 2177 cMaxDepth--; 2178 2179 /* 2180 * This is a bit tricky as we're working on unsigned addresses while the 2181 * AMD64 spec uses signed tricks. 2182 */ 2183 uint32_t iFirst = (pState->u64FirstAddress >> X86_PML4_SHIFT) & X86_PML4_MASK; 2184 uint32_t iLast = (pState->u64LastAddress >> X86_PML4_SHIFT) & X86_PML4_MASK; 2185 if ( pState->u64LastAddress <= UINT64_C(0x00007fffffffffff) 2186 || pState->u64FirstAddress >= UINT64_C(0xffff800000000000)) 2187 { /* Simple, nothing to adjust */ } 2188 else if (pState->u64FirstAddress <= UINT64_C(0x00007fffffffffff)) 2189 iLast = X86_PG_AMD64_ENTRIES / 2 - 1; 2190 else if (pState->u64LastAddress >= UINT64_C(0xffff800000000000)) 2191 iFirst = X86_PG_AMD64_ENTRIES / 2; 2192 else 2193 iFirst = X86_PG_AMD64_ENTRIES; /* neither address is canonical */ 2194 2195 for (uint32_t i = iFirst; i <= iLast; i++) 2196 { 2197 X86PML4E Pml4e = pPML4->a[i]; 2198 if (Pml4e.n.u1Present) 2199 { 2200 pState->u64Address = ((uint64_t)i << X86_PML4_SHIFT) 2201 | (i >= RT_ELEMENTS(pPML4->a) / 2 ? UINT64_C(0xffff000000000000) : 0); 2202 pState->pHlp->pfnPrintf(pState->pHlp, /*P R S A D G WT CD AT NX 4M a p ? */ 2203 "%016llx 0 | P %c %c %c %c %c %s %s %s %s .. %c%c%c %016llx", 2204 pState->u64Address, 2205 Pml4e.n.u1Write ? 'W' : 'R', 2206 Pml4e.n.u1User ? 'U' : 'S', 2207 Pml4e.n.u1Accessed ? 'A' : '-', 2208 Pml4e.n.u3Reserved & 1 ? '?' : '.', /* ignored */ 2209 Pml4e.n.u3Reserved & 4 ? '!' : '.', /* mbz */ 2210 Pml4e.n.u1WriteThru ? "WT" : "--", 2211 Pml4e.n.u1CacheDisable ? "CD" : "--", 2212 Pml4e.n.u3Reserved & 2 ? "!" : "..",/* mbz */ 2213 Pml4e.n.u1NoExecute ? "NX" : "--", 2214 Pml4e.u & RT_BIT_64(9) ? '1' : '0', 2215 Pml4e.u & RT_BIT_64(10) ? '1' : '0', 2216 Pml4e.u & RT_BIT_64(11) ? '1' : '0', 2217 Pml4e.u & X86_PML4E_PG_MASK); 2218 if (pState->fDumpPageInfo) 2219 pgmR3DumpHierarchyGstPageInfo(pState, Pml4e.u & X86_PML4E_PG_MASK, _4K); 2220 pgmR3DumpHierarchyGstCheckReservedHighBits(pState, Pml4e.u); 2221 pState->pHlp->pfnPrintf(pState->pHlp, "\n"); 2222 2223 if (cMaxDepth) 2224 { 2225 int rc2 = pgmR3DumpHierarchyGstPaePDPT(pState, Pml4e.u & X86_PML4E_PG_MASK, cMaxDepth); 2226 if (rc2 < rc && RT_SUCCESS(rc)) 2227 rc = rc2; 2228 } 2229 else 2230 pState->cLeaves++; 2231 } 2232 } 2233 2234 PGMPhysReleasePageMappingLock(pState->pVM, &Lock); 2235 return rc; 2236 } 2237 2238 2239 /** 2240 * Dumps a 32-bit shadow page table. 2241 * 2242 * @returns VBox status code (VINF_SUCCESS). 2243 * @param pState The dumper state. 2244 * @param GCPhys The physical address of the table. 2245 */ 2246 static int pgmR3DumpHierarchyGst32BitPT(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS GCPhys) 2247 { 2248 PCX86PT pPT; 2249 PGMPAGEMAPLOCK Lock; 2250 int rc = pgmR3DumpHierarchyGstMapPage(pState, GCPhys, "Page table", (void const **)&pPT, &Lock); 2251 if (RT_FAILURE(rc)) 2252 return rc; 2253 2254 uint32_t iFirst, iLast; 2255 uint64_t u64BaseAddress = pgmR3DumpHierarchyCalcRange(pState, X86_PT_SHIFT, X86_PG_ENTRIES, &iFirst, &iLast); 2256 for (uint32_t i = iFirst; i <= iLast; i++) 2257 { 2258 X86PTE Pte = pPT->a[i]; 2259 if (Pte.n.u1Present) 2260 { 2261 pState->u64Address = u64BaseAddress + (i << X86_PT_SHIFT); 2262 pState->pHlp->pfnPrintf(pState->pHlp,/*P R S A D G WT CD AT NX 4M a m d */ 2263 "%08llx 1 | P %c %c %c %c %c %s %s %s .. 4K %c%c%c %08x", 2264 pState->u64Address, 2265 Pte.n.u1Write ? 'W' : 'R', 2266 Pte.n.u1User ? 'U' : 'S', 2267 Pte.n.u1Accessed ? 'A' : '-', 2268 Pte.n.u1Dirty ? 'D' : '-', 2269 Pte.n.u1Global ? 'G' : '-', 2270 Pte.n.u1WriteThru ? "WT" : "--", 2271 Pte.n.u1CacheDisable ? "CD" : "--", 2272 Pte.n.u1PAT ? "AT" : "--", 2273 Pte.u & RT_BIT_32(9) ? '1' : '0', 2274 Pte.u & RT_BIT_32(10) ? '1' : '0', 2275 Pte.u & RT_BIT_32(11) ? '1' : '0', 2276 Pte.u & X86_PDE_PG_MASK); 2277 if (pState->fDumpPageInfo) 2278 pgmR3DumpHierarchyGstPageInfo(pState, Pte.u & X86_PDE_PG_MASK, _4K); 2279 pState->pHlp->pfnPrintf(pState->pHlp, "\n"); 2280 } 2281 } 2282 2283 PGMPhysReleasePageMappingLock(pState->pVM, &Lock); 2284 return VINF_SUCCESS; 2285 } 2286 2287 2288 /** 2289 * Dumps a 32-bit shadow page directory and page tables. 2290 * 2291 * @returns VBox status code (VINF_SUCCESS). 2292 * @param pState The dumper state. 2293 * @param GCPhys The physical address of the table. 2294 * @param cMaxDepth The maxium depth. 2295 */ 2296 static int pgmR3DumpHierarchyGst32BitPD(PPGMR3DUMPHIERARCHYSTATE pState, RTHCPHYS GCPhys, unsigned cMaxDepth) 2297 { 2298 if (pState->u64Address >= _4G) 2299 return VINF_SUCCESS; 2300 2301 PCX86PD pPD; 2302 PGMPAGEMAPLOCK Lock; 2303 int rc = pgmR3DumpHierarchyGstMapPage(pState, GCPhys, "Page directory", (void const **)&pPD, &Lock); 2304 if (RT_FAILURE(rc)) 2305 return rc; 2306 2307 Assert(cMaxDepth > 0); 2308 cMaxDepth--; 2309 2310 uint32_t iFirst, iLast; 2311 uint64_t u64BaseAddress = pgmR3DumpHierarchyCalcRange(pState, X86_PD_SHIFT, X86_PG_ENTRIES, &iFirst, &iLast); 2312 for (uint32_t i = iFirst; i <= iLast; i++) 2313 { 2314 X86PDE Pde = pPD->a[i]; 2315 if (Pde.n.u1Present) 2316 { 2317 pState->u64Address = (uint32_t)i << X86_PD_SHIFT; 2318 if (Pde.b.u1Size && pState->fPse) 2319 { 2320 uint64_t u64Phys = ((uint64_t)(Pde.u & X86_PDE4M_PG_HIGH_MASK) << X86_PDE4M_PG_HIGH_SHIFT) 2321 | (Pde.u & X86_PDE4M_PG_MASK); 2322 pState->pHlp->pfnPrintf(pState->pHlp,/*P R S A D G WT CD AT NX 4M a m d phys */ 2323 "%08llx 0 | P %c %c %c %c %c %s %s %s .. 4M %c%c%c %08llx", 2324 pState->u64Address, 2325 Pde.b.u1Write ? 'W' : 'R', 2326 Pde.b.u1User ? 'U' : 'S', 2327 Pde.b.u1Accessed ? 'A' : '-', 2328 Pde.b.u1Dirty ? 'D' : '-', 2329 Pde.b.u1Global ? 'G' : '-', 2330 Pde.b.u1WriteThru ? "WT" : "--", 2331 Pde.b.u1CacheDisable ? "CD" : "--", 2332 Pde.b.u1PAT ? "AT" : "--", 2333 Pde.u & RT_BIT_32(9) ? '1' : '0', 2334 Pde.u & RT_BIT_32(10) ? '1' : '0', 2335 Pde.u & RT_BIT_32(11) ? '1' : '0', 2336 u64Phys); 2337 if (pState->fDumpPageInfo) 2338 pgmR3DumpHierarchyGstPageInfo(pState, u64Phys, _4M); 2339 pState->pHlp->pfnPrintf(pState->pHlp, "\n"); 2340 pState->cLeaves++; 2341 } 2342 else 2343 { 2344 pState->pHlp->pfnPrintf(pState->pHlp,/*P R S A D G WT CD AT NX 4M a m d phys */ 2345 "%08llx 0 | P %c %c %c %c %c %s %s .. .. .. %c%c%c %08x", 2346 pState->u64Address, 2347 Pde.n.u1Write ? 'W' : 'R', 2348 Pde.n.u1User ? 'U' : 'S', 2349 Pde.n.u1Accessed ? 'A' : '-', 2350 Pde.n.u1Reserved0 ? '?' : '.', /* ignored */ 2351 Pde.n.u1Reserved1 ? '?' : '.', /* ignored */ 2352 Pde.n.u1WriteThru ? "WT" : "--", 2353 Pde.n.u1CacheDisable ? "CD" : "--", 2354 Pde.u & RT_BIT_32(9) ? '1' : '0', 2355 Pde.u & RT_BIT_32(10) ? '1' : '0', 2356 Pde.u & RT_BIT_32(11) ? '1' : '0', 2357 Pde.u & X86_PDE_PG_MASK); 2358 if (pState->fDumpPageInfo) 2359 pgmR3DumpHierarchyGstPageInfo(pState, Pde.u & X86_PDE_PG_MASK, _4K); 2360 pState->pHlp->pfnPrintf(pState->pHlp, "\n"); 2361 2362 if (cMaxDepth) 2363 { 2364 int rc2 = pgmR3DumpHierarchyGst32BitPT(pState, Pde.u & X86_PDE_PG_MASK); 2365 if (rc2 < rc && RT_SUCCESS(rc)) 2366 rc = rc2; 2367 } 2368 else 2369 pState->cLeaves++; 2370 } 2371 } 2372 } 2373 2374 PGMPhysReleasePageMappingLock(pState->pVM, &Lock); 2375 return rc; 2376 } 2377 2378 2379 /** 2380 * Internal worker that initiates the actual dump. 2381 * 2382 * @returns VBox status code. 2383 * @param pState The dumper state. 2384 * @param cr3 The CR3 value. 2385 * @param cMaxDepth The max depth. 2386 */ 2387 static int pgmR3DumpHierarchyGstDoIt(PPGMR3DUMPHIERARCHYSTATE pState, uint64_t cr3, unsigned cMaxDepth) 2388 { 2389 int rc; 2390 unsigned const cch = pState->cchAddress; 2391 uint64_t const cr3Mask = pState->fEpt ? X86_CR3_AMD64_PAGE_MASK 2392 : pState->fLme ? X86_CR3_AMD64_PAGE_MASK 2393 : pState->fPae ? X86_CR3_PAE_PAGE_MASK 2394 : X86_CR3_PAGE_MASK; 2395 if (pState->fPrintCr3) 2396 { 2397 const char * const pszMode = pState->fEpt ? "Extended Page Tables" 2398 : pState->fLme ? "Long Mode" 2399 : pState->fPae ? "PAE Mode" 2400 : pState->fPse ? "32-bit w/ PSE" 2401 : "32-bit"; 2402 pState->pHlp->pfnPrintf(pState->pHlp, "cr3=%0*llx", cch, cr3); 2403 if (pState->fDumpPageInfo) 2404 pgmR3DumpHierarchyGstPageInfo(pState, cr3 & X86_CR3_AMD64_PAGE_MASK, _4K); 2405 pState->pHlp->pfnPrintf(pState->pHlp, " %s%s%s\n", 2406 pszMode, 2407 pState->fNp ? " + Nested Paging" : "", 2408 pState->fNxe ? " + NX" : ""); 2409 } 2410 2411 2412 if (pState->fEpt) 2413 { 2414 if (pState->fPrintHeader) 2415 pState->pHlp->pfnPrintf(pState->pHlp, 2416 "%-*s R - Readable\n" 2417 "%-*s | W - Writeable\n" 2418 "%-*s | | X - Executable\n" 2419 "%-*s | | | EMT - EPT memory type\n" 2420 "%-*s | | | | PAT - Ignored PAT?\n" 2421 "%-*s | | | | | AVL1 - 4 available bits\n" 2422 "%-*s | | | | | | AVL2 - 12 available bits\n" 2423 "%-*s Level | | | | | | | page \n" 2424 /* xxxx n **** R W X EMT PAT AVL1 AVL2 xxxxxxxxxxxxx 2425 R W X 7 0 f fff 0123456701234567 */ 2426 , 2427 cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", cch, "Address"); 2428 2429 pState->pHlp->pfnPrintf(pState->pHlp, "EPT dumping is not yet implemented, sorry.\n"); 2430 /** @todo implemented EPT dumping. */ 2431 rc = VERR_NOT_IMPLEMENTED; 2432 } 2433 else 2434 { 2435 if (pState->fPrintHeader) 2436 pState->pHlp->pfnPrintf(pState->pHlp, 2437 "%-*s P - Present\n" 2438 "%-*s | R/W - Read (0) / Write (1)\n" 2439 "%-*s | | U/S - User (1) / Supervisor (0)\n" 2440 "%-*s | | | A - Accessed\n" 2441 "%-*s | | | | D - Dirty\n" 2442 "%-*s | | | | | G - Global\n" 2443 "%-*s | | | | | | WT - Write thru\n" 2444 "%-*s | | | | | | | CD - Cache disable\n" 2445 "%-*s | | | | | | | | AT - Attribute table (PAT)\n" 2446 "%-*s | | | | | | | | | NX - No execute (K8)\n" 2447 "%-*s | | | | | | | | | | 4K/4M/2M - Page size.\n" 2448 "%-*s | | | | | | | | | | | AVL - 3 available bits.\n" 2449 "%-*s Level | | | | | | | | | | | | Page\n" 2450 /* xxxx n **** P R S A D G WT CD AT NX 4M AVL xxxxxxxxxxxxx 2451 - W U - - - -- -- -- -- -- 010 */ 2452 , 2453 cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", 2454 cch, "", cch, "", cch, "", cch, "", cch, "", cch, "", cch, "Address"); 2455 if (pState->fLme) 2456 rc = pgmR3DumpHierarchyGstPaePML4(pState, cr3 & cr3Mask, cMaxDepth); 2457 else if (pState->fPae) 2458 rc = pgmR3DumpHierarchyGstPaePDPT(pState, cr3 & cr3Mask, cMaxDepth); 2459 else 2460 rc = pgmR3DumpHierarchyGst32BitPD(pState, cr3 & cr3Mask, cMaxDepth); 2461 } 2462 2463 if (!pState->cLeaves) 2464 pState->pHlp->pfnPrintf(pState->pHlp, "not present\n"); 2465 return rc; 2466 } 2467 1807 2468 1808 2469 /** … … 1829 2490 1830 2491 PGMR3DUMPHIERARCHYSTATE State; 1831 State.pVM = pVM; 1832 State.pHlp = pHlp ? pHlp : DBGFR3InfoLogHlp(); 1833 State.fPse = !!(fFlags & (DBGFPGDMP_FLAGS_PSE | DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME)); 1834 State.fPae = !!(fFlags & (DBGFPGDMP_FLAGS_PAE | DBGFPGDMP_FLAGS_LME)); 1835 State.fLme = !!(fFlags & DBGFPGDMP_FLAGS_LME); 1836 State.fNp = !!(fFlags & DBGFPGDMP_FLAGS_NP); 1837 State.fEpt = !!(fFlags & DBGFPGDMP_FLAGS_EPT); 1838 State.cchAddress = State.fLme ? 16 : 8; 1839 State.fDumpPageInfo = !!(fFlags & DBGFPGDMP_FLAGS_PAGE_INFO); 1840 State.fPrintHeader = !!(fFlags & DBGFPGDMP_FLAGS_HEADER); 1841 State.u64Address = FirstAddr; 1842 State.u64FirstAddress = FirstAddr; 1843 State.u64LastAddress = LastAddr; 1844 State.cLeaves = 0; 1845 //return pdmR3DumpHierarchyGcDoIt(&State, cr3, cMaxDepth); 1846 return VERR_NOT_IMPLEMENTED; 1847 } 1848 2492 pgmR3DumpHierarchyInitState(&State, pVM, fFlags, FirstAddr, LastAddr, pHlp); 2493 return pgmR3DumpHierarchyGstDoIt(&State, cr3, cMaxDepth); 2494 } 2495
Note:
See TracChangeset
for help on using the changeset viewer.