Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

276 lines
7.5 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. ptov.c
  5. Abstract:
  6. Kernel debugger extension for dumping all physical to
  7. virtual translations for a given process.
  8. Author:
  9. John Vert (jvert) 25-Jul-1995
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. BOOL
  14. ReadPhysicalPage(
  15. IN ULONG64 PageNumber,
  16. OUT PVOID Buffer
  17. );
  18. DECLARE_API( ptov )
  19. /*++
  20. Routine Description:
  21. Dumps all physical to virtual translations for a given process
  22. Arguments:
  23. args - supplies physical address of PDE
  24. Return Value:
  25. None.
  26. --*/
  27. {
  28. ULONG64 PdeAddress=0;
  29. ULONG ActualRead;
  30. PCHAR PageDirectory;
  31. PCHAR PageTable;
  32. ULONG i,j;
  33. ULONG64 VirtualPage=0;
  34. ULONG SizeOfHwPte;
  35. ULONG ValidOff, ValidSize, PfnOff, PfnSz;
  36. if (!sscanf(args, "%I64lx", &PdeAddress)) {
  37. dprintf("usage: ptov PFNOfPDE\n");
  38. return E_INVALIDARG;
  39. }
  40. PageDirectory = LocalAlloc(LMEM_FIXED, PageSize);
  41. if (PageDirectory == NULL) {
  42. dprintf("Couldn't allocate %d bytes for page directory\n",PageSize);
  43. return E_INVALIDARG;
  44. }
  45. PageTable = LocalAlloc(LMEM_FIXED, PageSize);
  46. if (PageTable == NULL) {
  47. dprintf("Couldn't allocate %d bytes for page table\n",PageSize);
  48. LocalFree(PageDirectory);
  49. }
  50. SizeOfHwPte = GetTypeSize("nt!HARDWARE_PTE");
  51. GetBitFieldOffset("nt!HARDWARE_PTE", "Valid", &ValidOff, &ValidSize);
  52. GetBitFieldOffset("nt!HARDWARE_PTE", "PageFrameNumber", &PfnOff, &PfnSz);
  53. __try {
  54. if (ReadPhysicalPage(PdeAddress,PageDirectory)) {
  55. for (i=0;i<PageSize/SizeOfHwPte;i++) {
  56. ULONG64 thisPageDir = *((PULONG64) (PageDirectory + i*SizeOfHwPte));
  57. if (CheckControlC()) {
  58. return E_INVALIDARG;
  59. }
  60. if ((thisPageDir >> ValidOff) & 1) {
  61. ULONG64 PageFrameNumber;
  62. PageFrameNumber = GetBits(thisPageDir, PfnOff, PfnSz);
  63. if (!ReadPhysicalPage(PageFrameNumber,PageTable)) {
  64. break;
  65. }
  66. for (j=0;j<PageSize/SizeOfHwPte;j++) {
  67. ULONG64 thisPageTable = *((PULONG64) (PageTable + j*SizeOfHwPte));
  68. if ( CheckControlC() ) {
  69. return E_INVALIDARG;
  70. }
  71. if ((thisPageTable >> ValidOff) & 1) {
  72. dprintf("%I64lx %I64lx\n",GetBits(thisPageTable, PfnOff, PfnSz)*PageSize,VirtualPage);
  73. }
  74. VirtualPage+=PageSize;
  75. }
  76. } else {
  77. VirtualPage += PageSize * (PageSize/SizeOfHwPte);
  78. }
  79. }
  80. }
  81. } __finally {
  82. LocalFree(PageDirectory);
  83. LocalFree(PageTable);
  84. }
  85. return S_OK;
  86. }
  87. ULONG
  88. DBG_GET_PAGE_SHIFT (
  89. VOID
  90. );
  91. BOOL
  92. ReadPhysicalPage(
  93. IN ULONG64 PageNumber,
  94. OUT PVOID Buffer
  95. )
  96. {
  97. ULONG i;
  98. ULONG64 Address;
  99. //
  100. // do the read 1k at a time to avoid overflowing the packet maximum.
  101. //
  102. Address = PageNumber << DBG_GET_PAGE_SHIFT();
  103. if (!IsPtr64()) {
  104. Address = (ULONG64) (LONG64) (LONG) Address;
  105. }
  106. // dprintf("Pg no %I64lx shft by %d, PhyAddr %I64lx\n", PageNumber, DBG_GET_PAGE_SHIFT(), Address);
  107. for (i=0; i<PageSize/1024; i++) {
  108. ULONG ActualRead = 0;
  109. ReadPhysical(Address, Buffer, 1024, &ActualRead);
  110. if (ActualRead != 1024) {
  111. dprintf("physical read at %p failed\n",Address);
  112. return(FALSE);
  113. }
  114. Address += 1024;
  115. Buffer = (PVOID)((PUCHAR)Buffer + 1024);
  116. }
  117. return(TRUE);
  118. }
  119. ULONG64
  120. DBG_GET_MM_SESSION_SPACE_DEFAULT (
  121. VOID
  122. );
  123. DECLARE_API( vtop )
  124. /*++
  125. Routine Description:
  126. Dumps the virtual to physical translation for a page
  127. Arguments:
  128. args - supplies physical address of PDE
  129. Return Value:
  130. None.
  131. --*/
  132. {
  133. ULONG ActualRead;
  134. ULONG i,j;
  135. PUCHAR PageDirectory;
  136. PUCHAR PageTable;
  137. ULONG64 PdeAddress = 0;
  138. ULONG64 VirtualPage=DBG_GET_MM_SESSION_SPACE_DEFAULT();
  139. ULONG PageShift,SizeOfHwPte;
  140. ULONG ValidOff, ValidSize, PfnOff, PfnSz, TransOff, TransSize;
  141. if (!sscanf(args,"%I64lx %I64lx", &PdeAddress,&VirtualPage)) {
  142. // Do not use GetExpression - physical addresses
  143. // VirtualPage = GetExpression(args);
  144. PdeAddress = 0;
  145. }
  146. PageShift = DBG_GET_PAGE_SHIFT();
  147. if (PdeAddress == 0) {
  148. dprintf("usage: vtop PFNOfPDE VA\n");
  149. return E_INVALIDARG;
  150. }
  151. // Common mistake, typed in full 32 bit address, not pfn
  152. if( PdeAddress & ~((1 << (32-PageShift)) - 1) ) {
  153. PdeAddress >>= PageShift;
  154. }
  155. PageDirectory = LocalAlloc(LMEM_FIXED, PageSize);
  156. if (PageDirectory == NULL) {
  157. dprintf("Couldn't allocate %d bytes for page directory\n",PageSize);
  158. return E_INVALIDARG;
  159. }
  160. PageTable = LocalAlloc(LMEM_FIXED, PageSize);
  161. if (PageTable == NULL) {
  162. dprintf("Couldn't allocate %d bytes for page table\n",PageSize);
  163. LocalFree(PageDirectory);
  164. return E_INVALIDARG;
  165. }
  166. __try {
  167. if (!(SizeOfHwPte = GetTypeSize("nt!HARDWARE_PTE")) ) {
  168. dprintf("Cannot find HARDWARE_PTE\n");
  169. return E_INVALIDARG;
  170. }
  171. i =(ULONG) ( VirtualPage / (PageSize*(PageSize/ SizeOfHwPte)));
  172. j = (ULONG) ((VirtualPage % (PageSize*(PageSize/ SizeOfHwPte))) / PageSize);
  173. dprintf("Pdi %x Pti %x\n",i,j);
  174. GetBitFieldOffset("nt!_MMPTE", "u.Soft.Transition", &TransOff, &TransSize);
  175. GetBitFieldOffset("nt!HARDWARE_PTE", "Valid", &ValidOff, &ValidSize);
  176. GetBitFieldOffset("nt!HARDWARE_PTE", "PageFrameNumber", &PfnOff, &PfnSz);
  177. if (ReadPhysicalPage(PdeAddress,PageDirectory)) {
  178. ULONG64 thisPageDir = *((PULONG64) (PageDirectory + i*SizeOfHwPte));
  179. if (CheckControlC()) {
  180. return E_INVALIDARG;
  181. }
  182. if ((thisPageDir >> ValidOff) & 1) {
  183. ULONG64 PageFrameNumber;
  184. ULONG64 thisPageTable;
  185. PageFrameNumber = GetBits(thisPageDir, PfnOff, PfnSz);
  186. if (!ReadPhysicalPage(PageFrameNumber,PageTable)) {
  187. return E_INVALIDARG;
  188. }
  189. thisPageTable = *((PULONG64) PageTable + j*SizeOfHwPte);
  190. if ((thisPageTable >> ValidOff) & 1) {
  191. dprintf("%08I64lx %08I64lx pfn(%05I64lx)\n",
  192. VirtualPage,
  193. GetBits(thisPageTable, PfnOff, PfnSz)*PageSize,
  194. GetBits(thisPageTable, PfnOff, PfnSz)
  195. );
  196. }
  197. else {
  198. if ((thisPageTable >> TransOff) & 1) {
  199. dprintf("%08I64lx Transition %08I64lx (%05I64lx)\n",
  200. VirtualPage,
  201. GetBits(thisPageTable, PfnOff, PfnSz)*PageSize,
  202. GetBits(thisPageTable, PfnOff, PfnSz)
  203. );
  204. }
  205. else {
  206. dprintf("%08I64lx Not present (%p)\n",VirtualPage,thisPageTable);
  207. }
  208. }
  209. }
  210. else {
  211. dprintf("PageDirectory Entry %u not valid, try another process\n",i);
  212. }
  213. }
  214. } __finally {
  215. LocalFree(PageDirectory);
  216. LocalFree(PageTable);
  217. }
  218. return S_OK;
  219. }