/*++ Copyright (c) 1992 Microsoft Corporation Module Name: ptov.c Abstract: Kernel debugger extension for dumping all physical to virtual translations for a given process. Author: John Vert (jvert) 25-Jul-1995 Revision History: --*/ #include "precomp.h" BOOL ReadPhysicalPage( IN ULONG64 PageNumber, OUT PVOID Buffer ); DECLARE_API( ptov ) /*++ Routine Description: Dumps all physical to virtual translations for a given process Arguments: args - supplies physical address of PDE Return Value: None. --*/ { ULONG64 PdeAddress=0; ULONG ActualRead; PCHAR PageDirectory; PCHAR PageTable; ULONG i,j; ULONG64 VirtualPage=0; ULONG SizeOfHwPte; ULONG ValidOff, ValidSize, PfnOff, PfnSz; if (!sscanf(args, "%I64lx", &PdeAddress)) { dprintf("usage: ptov PFNOfPDE\n"); return E_INVALIDARG; } PageDirectory = LocalAlloc(LMEM_FIXED, PageSize); if (PageDirectory == NULL) { dprintf("Couldn't allocate %d bytes for page directory\n",PageSize); return E_INVALIDARG; } PageTable = LocalAlloc(LMEM_FIXED, PageSize); if (PageTable == NULL) { dprintf("Couldn't allocate %d bytes for page table\n",PageSize); LocalFree(PageDirectory); } SizeOfHwPte = GetTypeSize("nt!HARDWARE_PTE"); GetBitFieldOffset("nt!HARDWARE_PTE", "Valid", &ValidOff, &ValidSize); GetBitFieldOffset("nt!HARDWARE_PTE", "PageFrameNumber", &PfnOff, &PfnSz); __try { if (ReadPhysicalPage(PdeAddress,PageDirectory)) { for (i=0;i> ValidOff) & 1) { ULONG64 PageFrameNumber; PageFrameNumber = GetBits(thisPageDir, PfnOff, PfnSz); if (!ReadPhysicalPage(PageFrameNumber,PageTable)) { break; } for (j=0;j> ValidOff) & 1) { dprintf("%I64lx %I64lx\n",GetBits(thisPageTable, PfnOff, PfnSz)*PageSize,VirtualPage); } VirtualPage+=PageSize; } } else { VirtualPage += PageSize * (PageSize/SizeOfHwPte); } } } } __finally { LocalFree(PageDirectory); LocalFree(PageTable); } return S_OK; } ULONG DBG_GET_PAGE_SHIFT ( VOID ); BOOL ReadPhysicalPage( IN ULONG64 PageNumber, OUT PVOID Buffer ) { ULONG i; ULONG64 Address; // // do the read 1k at a time to avoid overflowing the packet maximum. // Address = PageNumber << DBG_GET_PAGE_SHIFT(); if (!IsPtr64()) { Address = (ULONG64) (LONG64) (LONG) Address; } // dprintf("Pg no %I64lx shft by %d, PhyAddr %I64lx\n", PageNumber, DBG_GET_PAGE_SHIFT(), Address); for (i=0; i>= PageShift; } PageDirectory = LocalAlloc(LMEM_FIXED, PageSize); if (PageDirectory == NULL) { dprintf("Couldn't allocate %d bytes for page directory\n",PageSize); return E_INVALIDARG; } PageTable = LocalAlloc(LMEM_FIXED, PageSize); if (PageTable == NULL) { dprintf("Couldn't allocate %d bytes for page table\n",PageSize); LocalFree(PageDirectory); return E_INVALIDARG; } __try { if (!(SizeOfHwPte = GetTypeSize("nt!HARDWARE_PTE")) ) { dprintf("Cannot find HARDWARE_PTE\n"); return E_INVALIDARG; } i =(ULONG) ( VirtualPage / (PageSize*(PageSize/ SizeOfHwPte))); j = (ULONG) ((VirtualPage % (PageSize*(PageSize/ SizeOfHwPte))) / PageSize); dprintf("Pdi %x Pti %x\n",i,j); GetBitFieldOffset("nt!_MMPTE", "u.Soft.Transition", &TransOff, &TransSize); GetBitFieldOffset("nt!HARDWARE_PTE", "Valid", &ValidOff, &ValidSize); GetBitFieldOffset("nt!HARDWARE_PTE", "PageFrameNumber", &PfnOff, &PfnSz); if (ReadPhysicalPage(PdeAddress,PageDirectory)) { ULONG64 thisPageDir = *((PULONG64) (PageDirectory + i*SizeOfHwPte)); if (CheckControlC()) { return E_INVALIDARG; } if ((thisPageDir >> ValidOff) & 1) { ULONG64 PageFrameNumber; ULONG64 thisPageTable; PageFrameNumber = GetBits(thisPageDir, PfnOff, PfnSz); if (!ReadPhysicalPage(PageFrameNumber,PageTable)) { return E_INVALIDARG; } thisPageTable = *((PULONG64) PageTable + j*SizeOfHwPte); if ((thisPageTable >> ValidOff) & 1) { dprintf("%08I64lx %08I64lx pfn(%05I64lx)\n", VirtualPage, GetBits(thisPageTable, PfnOff, PfnSz)*PageSize, GetBits(thisPageTable, PfnOff, PfnSz) ); } else { if ((thisPageTable >> TransOff) & 1) { dprintf("%08I64lx Transition %08I64lx (%05I64lx)\n", VirtualPage, GetBits(thisPageTable, PfnOff, PfnSz)*PageSize, GetBits(thisPageTable, PfnOff, PfnSz) ); } else { dprintf("%08I64lx Not present (%p)\n",VirtualPage,thisPageTable); } } } else { dprintf("PageDirectory Entry %u not valid, try another process\n",i); } } } __finally { LocalFree(PageDirectory); LocalFree(PageTable); } return S_OK; }