- Add 'simple' implementation of MmDbgCopyMemory to read/write virtual memory in...
authorStefan Ginsberg <stefanginsberg@gmail.com>
Sat, 31 Oct 2009 01:02:35 +0000 (01:02 +0000)
committerStefan Ginsberg <stefanginsberg@gmail.com>
Sat, 31 Oct 2009 01:02:35 +0000 (01:02 +0000)
- Stub out the remaining missing global variables for the debugger data block -- fixes some cases of WinDbg failures and gives it a chance to handle errors instead of failing on a NULL read. Several of these variables are for functionality we don't yet implement, so I tried to put them where they are "least wrong". Everything besides the MmLoadedUserImageList variable is left unitialized -- KD should mostly be able to handle this properly.
- Define correctly sized KDDEBUGGER_DATA64 for our kernel (needs to be done in a better way).

svn path=/trunk/; revision=43863

21 files changed:
reactos/include/psdk/wdbgexts.h
reactos/ntoskrnl/include/internal/io.h
reactos/ntoskrnl/include/internal/kd64.h
reactos/ntoskrnl/include/internal/mm.h
reactos/ntoskrnl/io/iomgr/iomgr.c
reactos/ntoskrnl/kd64/i386/kdsup.c
reactos/ntoskrnl/kd64/kdapi.c
reactos/ntoskrnl/kd64/kdbreak.c
reactos/ntoskrnl/kd64/kddata.c
reactos/ntoskrnl/mm/ARM3/arm/init.c
reactos/ntoskrnl/mm/ARM3/expool.c
reactos/ntoskrnl/mm/ARM3/i386/init.c
reactos/ntoskrnl/mm/ARM3/miarm.h
reactos/ntoskrnl/mm/ARM3/pool.c
reactos/ntoskrnl/mm/freelist.c
reactos/ntoskrnl/mm/mmdbg.c [new file with mode: 0644]
reactos/ntoskrnl/mm/mminit.c
reactos/ntoskrnl/mm/pagefile.c
reactos/ntoskrnl/mm/section.c
reactos/ntoskrnl/mm/sysldr.c
reactos/ntoskrnl/ntoskrnl-generic.rbuild

index af45582..81cc471 100644 (file)
@@ -285,7 +285,11 @@ typedef struct _KDDEBUGGER_DATA64
     USHORT Gdt64R3CmTeb;
     GCC_ULONG64 IopNumTriageDumpDataBlocks;
     GCC_ULONG64 IopTriageDumpDataBlocks;
+#if 0 // Longhorn/Vista and later
     GCC_ULONG64 VfCrashDataBlock;
+    GCC_ULONG64 MmBadPagesDetected;
+    GCC_ULONG64 MmZeroedPageSingleBitErrorsDetected;
+#endif
 } KDDEBUGGER_DATA64, *PKDDEBUGGER_DATA64;
 
 #endif
index 436f4f2..cf45a02 100644 (file)
@@ -1057,6 +1057,8 @@ extern GENERIC_MAPPING IopFileMapping;
 extern POBJECT_TYPE _IoFileObjectType;
 extern HAL_DISPATCH _HalDispatchTable;
 extern LIST_ENTRY IopErrorLogListHead;
+extern ULONG IopNumTriageDumpDataBlocks;
+extern PVOID IopTriageDumpDataBlocks[64];
 
 //
 // Inlined Functions
index a3e9d28..6b22c0b 100644 (file)
@@ -296,6 +296,20 @@ KdpSuspendAllBreakPoints(
     VOID
 );
 
+//
+// Safe memory read & write Support
+//
+NTSTATUS
+NTAPI
+KdpCopyMemoryChunks(
+    IN ULONG64 Address,
+    IN PVOID Buffer,
+    IN ULONG TotalSize,
+    IN ULONG ChunkSize,
+    IN ULONG Flags,
+    OUT PULONG ActualSize OPTIONAL
+);
+
 //
 // Architecture dependent support routines
 //
index 22207df..6c31ac2 100644 (file)
@@ -18,6 +18,7 @@ extern UCHAR MmDisablePagingExecutive;
 extern ULONG MmLowestPhysicalPage;
 extern ULONG MmHighestPhysicalPage;
 extern ULONG MmAvailablePages;
+extern ULONG MmResidentAvailablePages;
 
 extern PVOID MmPagedPoolBase;
 extern ULONG MmPagedPoolSize;
@@ -25,6 +26,25 @@ extern ULONG MmPagedPoolSize;
 extern PMEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptor;
 extern MEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorOrg;
 
+extern LIST_ENTRY MmLoadedUserImageList;
+
+extern ULONG MmNumberOfPagingFiles;
+
+extern PVOID MmUnloadedDrivers;
+extern PVOID MmLastUnloadedDrivers;
+extern PVOID MmTriageActionTaken;
+extern PVOID KernelVerifier;
+extern MM_DRIVER_VERIFIER_DATA MmVerifierData;
+
+extern SIZE_T MmTotalCommitLimit;
+extern SIZE_T MmTotalCommittedPages;
+extern SIZE_T MmSharedCommit;
+extern SIZE_T MmDriverCommit;
+extern SIZE_T MmProcessCommit;
+extern SIZE_T MmPagedPoolCommit;
+extern SIZE_T MmPeakCommitment;
+extern SIZE_T MmtotalCommitLimitMaximum;
+
 struct _KTRAP_FRAME;
 struct _EPROCESS;
 struct _MM_RMAP_ENTRY;
@@ -33,7 +53,7 @@ typedef ULONG SWAPENTRY;
 typedef ULONG PFN_TYPE, *PPFN_TYPE;
 
 //
-//MmDbgCopyMemory Flags
+// MmDbgCopyMemory Flags
 //
 #define MMDBG_COPY_WRITE            0x00000001
 #define MMDBG_COPY_PHYSICAL         0x00000002
@@ -369,6 +389,20 @@ typedef struct _MMPFN
 
 extern PMMPFN MmPfnDatabase;
 
+typedef struct _MMPFNLIST
+{
+    PFN_NUMBER Total;
+    MMLISTS ListName;
+    PFN_NUMBER Flink;
+    PFN_NUMBER Blink;
+} MMPFNLIST, *PMMPFNLIST;
+
+extern MMPFNLIST MmZeroedPageListHead;
+extern MMPFNLIST MmFreePageListHead;
+extern MMPFNLIST MmStandbyPageListHead;
+extern MMPFNLIST MmModifiedPageListHead;
+extern MMPFNLIST MmModifiedNoWritePageListHead;
+
 typedef struct _MM_PAGEOP
 {
   /* Type of operation. */
index 6fad94a..cb32297 100644 (file)
@@ -39,6 +39,8 @@ LARGE_INTEGER IoWriteTransferCount = {{0, 0}};
 ULONG IoOtherOperationCount = 0;
 LARGE_INTEGER IoOtherTransferCount = {{0, 0}};
 KSPIN_LOCK IoStatisticsLock = 0;
+ULONG IopNumTriageDumpDataBlocks;
+PVOID IopTriageDumpDataBlocks[64];
 
 GENERIC_MAPPING IopFileMapping = {
     FILE_GENERIC_READ,
index db2dc8b..8c0f59d 100644 (file)
@@ -160,7 +160,7 @@ KdpSysReadBusData(IN ULONG BusDataType,
                                           Length);
 
     /* Return status */
-    return (*ActualLength != 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
+    return *ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
 }
 
 NTSTATUS
@@ -182,7 +182,7 @@ KdpSysWriteBusData(IN ULONG BusDataType,
                                           Length);
 
     /* Return status */
-    return (*ActualLength != 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
+    return *ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
 }
 
 NTSTATUS
@@ -209,12 +209,13 @@ KdpSysReadControlSpace(IN ULONG Processor,
                                (ULONG_PTR)&KiProcessorBlock[Processor]->
                                            ProcessorState);
 
-        /* Copy the memory */
-        RtlCopyMemory(Buffer, ControlStart, Length);
-
-        /* Finish up */
-        *ActualLength = Length;
-        return STATUS_SUCCESS;
+        /* Read the control state safely */
+        return KdpCopyMemoryChunks((ULONG_PTR)Buffer,
+                                   ControlStart,
+                                   Length,
+                                   0,
+                                   MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
+                                   ActualLength);
     }
     else
     {
@@ -243,12 +244,13 @@ KdpSysWriteControlSpace(IN ULONG Processor,
                                (ULONG_PTR)&KiProcessorBlock[Processor]->
                                            ProcessorState);
 
-        /* Copy the memory */
-        RtlCopyMemory(ControlStart, Buffer, Length);
-
-        /* Finish up */
-        *ActualLength = Length;
-        return STATUS_SUCCESS;
+        /* Write the control state safely */
+        return KdpCopyMemoryChunks((ULONG_PTR)Buffer,
+                                   ControlStart,
+                                   Length,
+                                   0,
+                                   MMDBG_COPY_UNSAFE,
+                                   ActualLength);
     }
     else
     {
index b21a8b0..4754394 100644 (file)
@@ -24,65 +24,72 @@ KdpCopyMemoryChunks(IN ULONG64 Address,
                     IN ULONG Flags,
                     OUT PULONG ActualSize OPTIONAL)
 {
-    ULONG Length;
     NTSTATUS Status;
+    ULONG RemainingLength, CopyChunk;
 
-    /* Check if this is physical or virtual copy */
-    if (Flags & MMDBG_COPY_PHYSICAL)
+    /* Check if we didn't get a chunk size or if it is too big */
+    if (ChunkSize == 0)
     {
-        /* Fail physical memory read/write for now */
-        if (Flags & MMDBG_COPY_WRITE)
-        {
-            KdpDprintf("KdpCopyMemoryChunks: Failing write for Physical Address 0x%I64x Length: %x\n",
-                       Address,
-                       TotalSize);
-        }
-        else
-        {
-            KdpDprintf("KdpCopyMemoryChunks: Failing read for Physical Address 0x%I64x Length: %x\n",
-                       Address,
-                       TotalSize);
-        }
-
-        /* Return an error */
-        Length = 0;
-        Status = STATUS_UNSUCCESSFUL;
+        /* Default to 4 byte chunks */
+        ChunkSize = 4;
     }
-    else
+    else if (ChunkSize > MMDBG_COPY_MAX_SIZE)
+    {
+        /* Normalize to maximum size */
+        ChunkSize = MMDBG_COPY_MAX_SIZE;
+    }
+
+    /* Copy the whole range in page aligned chunks */
+    RemainingLength = TotalSize;
+    CopyChunk = 1;
+    while (RemainingLength > 0)
     {
-        /* Protect against NULL */
-        if (!Address)
+        /*
+         * Determine the best chunk size for this round.
+         * The ideal size is page aligned, isn't larger than the
+         * the remaining length and respects the chunk limit.
+         */
+        while (((CopyChunk * 2) <= RemainingLength) &&
+               (CopyChunk < ChunkSize) &&
+               ((Address & ((CopyChunk * 2) - 1)) == 0))
         {
-            if (ActualSize) *ActualSize = 0;
-            return STATUS_UNSUCCESSFUL;
+            /* Increase it */
+            CopyChunk = CopyChunk * 2;
         }
 
-        /* Check if this is read or write */
-        if (Flags & MMDBG_COPY_WRITE)
+        /*
+         * The chunk size can be larger than the remaining size if this isn't
+         * the first round, so check if we need to shrink it back
+         */
+        while (CopyChunk > RemainingLength)
         {
-            /* Do the write */
-            RtlCopyMemory((PVOID)(ULONG_PTR)Address,
-                          Buffer,
-                          TotalSize);
+            /* Shrink it */
+            CopyChunk /= 2;
         }
-        else
+
+        /* Do the copy */
+        Status = MmDbgCopyMemory(Address,
+                                 Buffer,
+                                 CopyChunk,
+                                 Flags);
+        if (!NT_SUCCESS(Status))
         {
-            /* Do the read */
-            RtlCopyMemory(Buffer,
-                          (PVOID)(ULONG_PTR)Address,
-                          TotalSize);
+            /* Copy failed, break out */
+            break;
         }
 
-        /* Set size and status */
-        Length = TotalSize;
-        Status = STATUS_SUCCESS;
+        /* Update pointers and length for the next run */
+        Address = Address + CopyChunk;
+        Buffer = (PVOID)((ULONG_PTR)Buffer + CopyChunk);
+        RemainingLength = RemainingLength - CopyChunk;
     }
 
-    /* Return the actual length if requested */
-    if (ActualSize) *ActualSize = Length;
-
-    /* Return status */
-    return Status;
+    /*
+     * Return the size we managed to copy
+     * and return success if we could copy the whole range
+     */
+    if (ActualSize) *ActualSize = TotalSize - RemainingLength;
+    return RemainingLength == 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
 }
 
 VOID
@@ -269,7 +276,7 @@ KdpSetCommonState(IN ULONG NewState,
                   IN PCONTEXT Context,
                   IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange)
 {
-    USHORT InstructionCount;
+    ULONG InstructionCount;
     BOOLEAN HadBreakpoints;
 
     /* Setup common stuff available for all CPU architectures */
@@ -285,10 +292,12 @@ KdpSetCommonState(IN ULONG NewState,
                   sizeof(DBGKD_ANY_CONTROL_REPORT));
 
     /* Now copy the instruction stream and set the count */
-    RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0],
-                  (PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter,
-                  DBGKD_MAXSTREAM);
-    InstructionCount = DBGKD_MAXSTREAM;
+    KdpCopyMemoryChunks((ULONG_PTR)WaitStateChange->ProgramCounter,
+                        &WaitStateChange->ControlReport.InstructionStream[0],
+                        DBGKD_MAXSTREAM,
+                        0,
+                        MMDBG_COPY_UNSAFE,
+                        &InstructionCount);
     WaitStateChange->ControlReport.InstructionCount = InstructionCount;
 
     /* Clear all the breakpoints in this region */
@@ -299,9 +308,12 @@ KdpSetCommonState(IN ULONG NewState,
     if (HadBreakpoints)
     {
         /* Copy the instruction stream again, this time without breakpoints */
-        RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0],
-                      (PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter,
-                      WaitStateChange->ControlReport.InstructionCount);
+        KdpCopyMemoryChunks((ULONG_PTR)WaitStateChange->ProgramCounter,
+                            &WaitStateChange->ControlReport.InstructionStream[0],
+                            InstructionCount,
+                            0,
+                            MMDBG_COPY_UNSAFE,
+                            NULL);
     }
 }
 
@@ -1297,6 +1309,7 @@ KdpReportLoadSymbolsStateChange(IN PSTRING PathName,
     PSTRING ExtraData;
     STRING Data, Header;
     DBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange;
+    ULONG PathNameLength;
     KCONTINUE_STATUS Status;
 
     /* Start wait loop */
@@ -1317,14 +1330,27 @@ KdpReportLoadSymbolsStateChange(IN PSTRING PathName,
         WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum;
         WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage;
 
-        /* Check if we have a symbol name */
+        /* Check if we have a path name */
         if (PathName)
         {
-            /* Setup the information */
-            WaitStateChange.u.LoadSymbols.PathNameLength = PathName->Length;
-            RtlCopyMemory(KdpPathBuffer, PathName->Buffer, PathName->Length);
+            /* Copy it to the path buffer */
+            KdpCopyMemoryChunks((ULONG_PTR)PathName->Buffer,
+                                KdpPathBuffer,
+                                PathName->Length,
+                                0,
+                                MMDBG_COPY_UNSAFE,
+                                &PathNameLength);
+
+            /* Null terminate */
+            KdpPathBuffer[PathNameLength] = ANSI_NULL;
+            PathNameLength++;
+
+            /* Set the path length */
+            WaitStateChange.u.LoadSymbols.PathNameLength = PathNameLength;
+
+            /* Set up the data */
             Data.Buffer = KdpPathBuffer;
-            Data.Length = WaitStateChange.u.LoadSymbols.PathNameLength;
+            Data.Length = PathNameLength;
             ExtraData = &Data;
         }
         else
index 48c2cca..6b3aa54 100644 (file)
@@ -21,6 +21,7 @@ KdpAddBreakpoint(IN PVOID Address)
 {
     KD_BREAKPOINT_TYPE Content;
     ULONG i;
+    NTSTATUS Status;
 
     /* Loop current breakpoints */
     for (i = 0; i < KD_BREAKPOINT_MAX; i++)
@@ -51,15 +52,39 @@ KdpAddBreakpoint(IN PVOID Address)
     if (i == KD_BREAKPOINT_MAX) return 0;
 
     /* Save the old instruction */
-    RtlCopyMemory(&Content, Address, KD_BREAKPOINT_SIZE);
+    Status = KdpCopyMemoryChunks((ULONG_PTR)Address,
+                                 &Content,
+                                 KD_BREAKPOINT_SIZE,
+                                 0,
+                                 MMDBG_COPY_UNSAFE,
+                                 NULL);
+
+    if (!NT_SUCCESS(Status))
+    {
+        /* TODO: Set it as a owed breakpoint */
+        KdpDprintf("Failed to set breakpoint at address 0x%p\n", Address);
+        return 0;
+    }
 
     /* Write the entry */
     KdpBreakpointTable[i].Address = Address;
     KdpBreakpointTable[i].Content = Content;
     KdpBreakpointTable[i].Flags = KdpBreakpointActive;
 
-    /* Write the breakpoint and return the handle */
-    RtlCopyMemory(Address, &KdpBreakpointInstruction, KD_BREAKPOINT_SIZE);
+    /* Write the breakpoint */
+    Status = KdpCopyMemoryChunks((ULONG_PTR)Address,
+                                 &KdpBreakpointInstruction,
+                                 KD_BREAKPOINT_SIZE,
+                                 0,
+                                 MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
+                                 NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        /* This should never happen */
+        KdpDprintf("Unable to write breakpoint to address 0x%p\n", Address);
+    }
+
+    /* Return the breakpoint handle */
     return i + 1;
 }
 
@@ -67,6 +92,8 @@ BOOLEAN
 NTAPI
 KdpLowWriteContent(IN ULONG BpIndex)
 {
+    NTSTATUS Status;
+
     /* Make sure that the breakpoint is actually active */
     if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointPending)
     {
@@ -83,9 +110,20 @@ KdpLowWriteContent(IN ULONG BpIndex)
     }
 
     /* We have an active breakpoint with an instruction to bring back. Do it. */
-    RtlCopyMemory(KdpBreakpointTable[BpIndex].Address,
-                  &KdpBreakpointTable[BpIndex].Content,
-                  KD_BREAKPOINT_SIZE);
+    Status = KdpCopyMemoryChunks((ULONG_PTR)KdpBreakpointTable[BpIndex].
+                                 Address,
+                                 &KdpBreakpointTable[BpIndex].Content,
+                                 KD_BREAKPOINT_SIZE,
+                                 0,
+                                 MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
+                                 NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        /* TODO: Set it as a owed breakpoint */
+        KdpDprintf("Failed to delete breakpoint at address 0x%p\n",
+                   KdpBreakpointTable[BpIndex].Address);
+        return FALSE;
+    }
 
     /* Everything went fine, return */
     return TRUE;
@@ -95,6 +133,8 @@ BOOLEAN
 NTAPI
 KdpLowRestoreBreakpoint(IN ULONG BpIndex)
 {
+    NTSTATUS Status;
+
     /* Were we not able to remove it earlier? */
     if (KdpBreakpointTable[BpIndex].Flags & KdpBreakpointExpired)
     {
@@ -111,9 +151,20 @@ KdpLowRestoreBreakpoint(IN ULONG BpIndex)
     }
 
     /* Ok, we actually have to overwrite the instruction now */
-    RtlCopyMemory(KdpBreakpointTable[BpIndex].Address,
-                  &KdpBreakpointInstruction,
-                  KD_BREAKPOINT_SIZE);
+    Status = KdpCopyMemoryChunks((ULONG_PTR)KdpBreakpointTable[BpIndex].
+                                 Address,
+                                 &KdpBreakpointInstruction,
+                                 KD_BREAKPOINT_SIZE,
+                                 0,
+                                 MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
+                                 NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        /* FIXME: Set it as a owed breakpoint */
+        KdpDprintf("Failed to restore breakpoint at address 0x%p\n",
+                   KdpBreakpointTable[BpIndex].Address);
+        return FALSE;
+    }
 
     /* Clear any possible previous pending flag and return success */
     KdpBreakpointTable[BpIndex].Flags &= ~KdpBreakpointPending;
index c911037..512725d 100644 (file)
@@ -391,22 +391,22 @@ KDDEBUGGER_DATA64 KdDebuggerDataBlock =
     {(ULONG_PTR)&PsActiveProcessHead},
     {(ULONG_PTR)&PspCidTable},
     {(ULONG_PTR)&ExpSystemResourcesList},
-    {0},                                                        // ExpPagedPoolDescriptor
-    {0},                                                        // ExpNumberOfPagedPools
+    {(ULONG_PTR)ExpPagedPoolDescriptor},
+    {(ULONG_PTR)&ExpNumberOfPagedPools},
     {(ULONG_PTR)&KeTimeIncrement},
     {(ULONG_PTR)&KeBugcheckCallbackListHead},
     {(ULONG_PTR)KiBugCheckData},
     {(ULONG_PTR)&IopErrorLogListHead},
     {(ULONG_PTR)&ObpRootDirectoryObject},
     {(ULONG_PTR)&ObpTypeObjectType},
-    {0},                                                        // MmSystemCacheStart
-    {0},                                                        // MmSystemCacheEnd
-    {0},                                                        // MmSystemCacheWs
+    {(ULONG_PTR)&MmSystemCacheStart},
+    {(ULONG_PTR)&MmSystemCacheEnd},
+    {(ULONG_PTR)&MmSystemCacheWs},
     {(ULONG_PTR)&MmPfnDatabase},
     {(ULONG_PTR)MmSystemPtesStart},
     {(ULONG_PTR)MmSystemPtesEnd},
-    {0},                                                        // MmSubsectionBase
-    {0},                                                        // MmNumberOfPagingFiles
+    {(ULONG_PTR)&MmSubsectionBase},
+    {(ULONG_PTR)&MmNumberOfPagingFiles},
     {(ULONG_PTR)&MmLowestPhysicalPage},
     {(ULONG_PTR)&MmHighestPhysicalPage},
     {(ULONG_PTR)&MmNumberOfPhysicalPages},
@@ -419,21 +419,21 @@ KDDEBUGGER_DATA64 KdDebuggerDataBlock =
     {(ULONG_PTR)&MmPagedPoolInfo},
     PAGE_SIZE,
     {(ULONG_PTR)&MmSizeOfPagedPoolInBytes},
-    {0},                                                        // MmTotalCommitLimit
-    {0},                                                        // MmTotalCommittedPages
-    {0},                                                        // MmSharedCommit
-    {0},                                                        // MmDriverCommit
-    {0},                                                        // MmProcessCommit
-    {0},                                                        // MmPagedPoolCommit
+    {(ULONG_PTR)&MmTotalCommitLimit},
+    {(ULONG_PTR)&MmTotalCommittedPages},
+    {(ULONG_PTR)&MmSharedCommit},
+    {(ULONG_PTR)&MmDriverCommit},
+    {(ULONG_PTR)&MmProcessCommit},
+    {(ULONG_PTR)&MmPagedPoolCommit},
     {0},
-    {0},                                                        // MmZeroedPageListHead
-    {0},                                                        // MmFreePageListHead
-    {0},                                                        // MmStandbyPageListHead
-    {0},                                                        // MmModifiedPageListHead
-    {0},                                                        // MmModifiedNoWritePageListHead
-    {0},                                                        // MmAvailablePages
-    {0},                                                        // MmResidentAvailablePages
-    {0},                                                        // PoolTrackTable
+    {(ULONG_PTR)&MmZeroedPageListHead},
+    {(ULONG_PTR)&MmFreePageListHead},
+    {(ULONG_PTR)&MmStandbyPageListHead},
+    {(ULONG_PTR)&MmModifiedPageListHead},
+    {(ULONG_PTR)&MmModifiedNoWritePageListHead},
+    {(ULONG_PTR)&MmAvailablePages},
+    {(ULONG_PTR)&MmResidentAvailablePages},
+    {(ULONG_PTR)&PoolTrackTable},
     {(ULONG_PTR)&NonPagedPoolDescriptor},
     {(ULONG_PTR)&MmHighestUserAddress},
     {(ULONG_PTR)&MmSystemRangeStart},
@@ -442,19 +442,19 @@ KDDEBUGGER_DATA64 KdDebuggerDataBlock =
     {(ULONG_PTR)KdPrintDefaultCircularBuffer + 1},
     {(ULONG_PTR)&KdPrintWritePointer},
     {(ULONG_PTR)&KdPrintRolloverCount},
-    {0},                                                        // MmLoadedUserImageList
+    {(ULONG_PTR)&MmLoadedUserImageList},
     {(ULONG_PTR)&NtBuildLab},
     {0},
     {(ULONG_PTR)KiProcessorBlock},
-    {0},                                                        // MmUnloadedDrivers
-    {0},                                                        // MmLastUnloadedDrivers
-    {0},                                                        // MmTriageActionTaken
-    {0},                                                        // MmSpecialPoolTag
-    {0},                                                        // KernelVerifier
-    {0},                                                        // MmVerifierData
-    {0},                                                        // MmAllocatedNonPagedPool
-    {0},                                                        // MmPeakCommitment
-    {0},                                                        // MmtotalCommitLimitMaximum
+    {(ULONG_PTR)&MmUnloadedDrivers},
+    {(ULONG_PTR)&MmLastUnloadedDrivers},
+    {(ULONG_PTR)&MmTriageActionTaken},
+    {(ULONG_PTR)&MmSpecialPoolTag},
+    {(ULONG_PTR)&KernelVerifier},
+    {(ULONG_PTR)&MmVerifierData},
+    {(ULONG_PTR)&MmAllocatedNonPagedPool},
+    {(ULONG_PTR)&MmPeakCommitment},
+    {(ULONG_PTR)&MmtotalCommitLimitMaximum},
     {(ULONG_PTR)&CmNtCSDVersion},
     {(ULONG_PTR)&MmPhysicalMemoryBlock},
     {(ULONG_PTR)&MmSessionBase},
@@ -539,6 +539,6 @@ KDDEBUGGER_DATA64 KdDebuggerDataBlock =
     0,
     0,
 #endif
-    {0},                                                        // IopNumTriageDumpDataBlocks
-    {0},                                                        // IopTriageDumpDataBlocks
+    {(ULONG_PTR)&IopNumTriageDumpDataBlocks},
+    {(ULONG_PTR)IopTriageDumpDataBlocks},
 };
index 3d91ed6..9b98ea9 100644 (file)
@@ -54,6 +54,9 @@ ULONG MmBootImageSize;
 ULONG MmUserProbeAddress;
 PVOID MmHighestUserAddress;
 PVOID MmSystemRangeStart;
+PVOID MmSystemCacheStart;
+PVOID MmSystemCacheEnd;
+MMSUPPORT MmSystemCacheWs;
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
index d6274e1..a8fe5f3 100644 (file)
 
 /* GLOBALS ********************************************************************/
 
+ULONG ExpNumberOfPagedPools;
 POOL_DESCRIPTOR NonPagedPoolDescriptor;
+PPOOL_DESCRIPTOR ExpPagedPoolDescriptor[16 + 1];
 PPOOL_DESCRIPTOR PoolVector[2];
+PVOID PoolTrackTable;
 PKGUARDED_MUTEX ExpPagedPoolMutex;
 
 /* PRIVATE FUNCTIONS **********************************************************/
index aae42aa..f8a12f0 100644 (file)
@@ -217,6 +217,12 @@ ULONG MmUserProbeAddress;
 PVOID MmHighestUserAddress;
 PVOID MmSystemRangeStart;
 
+
+
+PVOID MmSystemCacheStart;
+PVOID MmSystemCacheEnd;
+MMSUPPORT MmSystemCacheWs;
+
 /* PRIVATE FUNCTIONS **********************************************************/
 
 //
index 41823f9..9051252 100644 (file)
@@ -87,7 +87,10 @@ typedef struct _POOL_HEADER
 C_ASSERT(sizeof(POOL_HEADER) == 8);
 C_ASSERT(sizeof(POOL_HEADER) == sizeof(LIST_ENTRY));
 
+extern ULONG ExpNumberOfPagedPools;
 extern POOL_DESCRIPTOR NonPagedPoolDescriptor;
+extern PPOOL_DESCRIPTOR ExpPagedPoolDescriptor[16 + 1];
+extern PVOID PoolTrackTable;
 
 //
 // END FIXFIX
@@ -156,6 +159,12 @@ extern PVOID MmSessionBase;
 extern PVOID MiSessionSpaceEnd;
 extern ULONG MmSizeOfPagedPoolInBytes;
 extern PMMPTE MmSystemPagePtes;
+extern PVOID MmSystemCacheStart;
+extern PVOID MmSystemCacheEnd;
+extern MMSUPPORT MmSystemCacheWs;
+extern SIZE_T MmAllocatedNonPagedPool;
+extern ULONG_PTR MmSubsectionBase;
+extern ULONG MmSpecialPoolTag;
 
 NTSTATUS
 NTAPI
index 889ed0a..7fddd38 100644 (file)
@@ -24,6 +24,8 @@ PVOID MmNonPagedPoolEnd0;
 PFN_NUMBER MiStartOfInitialPoolFrame, MiEndOfInitialPoolFrame;
 KGUARDED_MUTEX MmPagedPoolMutex;
 MM_PAGED_POOL_INFO MmPagedPoolInfo;
+SIZE_T MmAllocatedNonPagedPool;
+ULONG MmSpecialPoolTag;
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
index f42e139..7d7293f 100644 (file)
 PPHYSICAL_PAGE MmPfnDatabase;
 
 ULONG MmAvailablePages;
+ULONG MmResidentAvailablePages;
+
+SIZE_T MmTotalCommitLimit;
+SIZE_T MmTotalCommittedPages;
+SIZE_T MmSharedCommit;
+SIZE_T MmDriverCommit;
+SIZE_T MmProcessCommit;
+SIZE_T MmPagedPoolCommit;
+SIZE_T MmPeakCommitment;
+SIZE_T MmtotalCommitLimitMaximum;
+
+MMPFNLIST MmZeroedPageListHead;
+MMPFNLIST MmFreePageListHead;
+MMPFNLIST MmStandbyPageListHead;
+MMPFNLIST MmModifiedPageListHead;
+MMPFNLIST MmModifiedNoWritePageListHead;
 
 /* List of pages allocated to the MC_USER Consumer */
 static LIST_ENTRY UserPageListHead;
diff --git a/reactos/ntoskrnl/mm/mmdbg.c b/reactos/ntoskrnl/mm/mmdbg.c
new file mode 100644 (file)
index 0000000..bf846ca
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            ntoskrnl/mm/mmdbg.c
+ * PURPOSE:         Memory Manager support routines for the Kernel Debugger
+ * PROGRAMMERS:     Stefan Ginsberg (stefan.ginsberg@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+NTSTATUS
+NTAPI
+MmDbgCopyMemory(IN ULONG64 Address,
+                IN PVOID Buffer,
+                IN ULONG Size,
+                IN ULONG Flags)
+{
+    NTSTATUS Status;
+
+    /* For now, this must be a "unsafe" copy */
+    ASSERT(Flags & MMDBG_COPY_UNSAFE);
+
+    /* We only handle 1, 2, 4 and 8 byte requests */
+    if ((Size != 1) &&
+        (Size != 2) &&
+        (Size != 4) &&
+        (Size != MMDBG_COPY_MAX_SIZE))
+    {
+        /* Invalid size, fail */
+        return STATUS_INVALID_PARAMETER_3;
+    }
+
+    /* The copy must be aligned too */
+    if ((Address & (Size - 1)) != 0)
+    {
+        /* Fail */
+        return STATUS_INVALID_PARAMETER_3;
+    }
+
+    /* No physical memory support yet */
+    if (Flags & MMDBG_COPY_PHYSICAL)
+    {
+        /* Fail */
+        KdpDprintf("MmDbgCopyMemory: Failing %s for Physical Address 0x%I64x\n",
+                   Flags & MMDBG_COPY_WRITE ? "write" : "read",
+                   Address);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* Simple check for invalid address */
+    if ((MiAddressToPde((ULONG_PTR)Address)->u.Hard.Valid == 0) ||
+        (MiAddressToPte((ULONG_PTR)Address)->u.Hard.Valid == 0))
+    {
+        /* Fail */
+        KdpDprintf("MmDbgCopyMemory: Failing %s for invalid Address 0x%p\n",
+                   Flags & MMDBG_COPY_WRITE ? "write" : "read",
+                   (PVOID)(ULONG_PTR)Address);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* If we are going to write to it then make sure it is writeable too */
+    if ((Flags & MMDBG_COPY_WRITE) &&
+        (!MI_IS_PAGE_WRITEABLE(MiAddressToPte((ULONG_PTR)Address))))
+    {
+        /* Fail */
+        KdpDprintf("MmDbgCopyMemory: Failing write for Address 0x%p\n",
+                   (PVOID)(ULONG_PTR)Address);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* Use SEH to try to catch anything else somewhat cleanly */
+    _SEH2_TRY
+    {
+        /* Check if this is read or write */
+        if (Flags & MMDBG_COPY_WRITE)
+        {
+            /* Do the write */
+            RtlCopyMemory((PVOID)(ULONG_PTR)Address,
+                          Buffer,
+                          Size);
+        }
+        else
+        {
+            /* Do the read */
+            RtlCopyMemory(Buffer,
+                          (PVOID)(ULONG_PTR)Address,
+                          Size);
+        }
+
+        /* Copy succeeded */
+        Status = STATUS_SUCCESS;
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* Get the exception code */
+        Status = _SEH2_GetExceptionCode();
+    }
+    _SEH2_END;
+
+    /* Return status */
+    return Status;
+}
index 1900cbb..ff8a740 100644 (file)
@@ -424,6 +424,9 @@ MmInitSystem(IN ULONG Phase,
         /* Initialize working sets */
         MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
 
+        /* Initialize the user mode image list */
+        InitializeListHead(&MmLoadedUserImageList);
+
         /* Initialize the Loader Lock */
         KeInitializeMutant(&MmSystemLoadLock, FALSE);
 
index 9dfcf7e..1af2fac 100644 (file)
@@ -78,6 +78,7 @@ static KSPIN_LOCK PagingFileListLock;
 
 /* Number of paging files */
 static ULONG MiPagingFileCount;
+ULONG MmNumberOfPagingFiles;
 
 /* Number of pages that are available for swapping */
 ULONG MiFreeSwapPages;
index 10f72f3..d49cb09 100644 (file)
@@ -71,6 +71,8 @@ MM_SECTION_PAGEOUT_CONTEXT;
 
 POBJECT_TYPE MmSectionObjectType = NULL;
 
+ULONG_PTR MmSubsectionBase;
+
 static GENERIC_MAPPING MmpSectionMapping = {
          STANDARD_RIGHTS_READ | SECTION_MAP_READ | SECTION_QUERY,
          STANDARD_RIGHTS_WRITE | SECTION_MAP_WRITE,
index 23cb5fe..cbabd8d 100644 (file)
@@ -28,11 +28,18 @@ sprintf_nt(IN PCHAR Buffer,
 /* GLOBALS *******************************************************************/
 
 LIST_ENTRY PsLoadedModuleList;
+LIST_ENTRY MmLoadedUserImageList;
 KSPIN_LOCK PsLoadedModuleSpinLock;
 ULONG_PTR PsNtosImageBase;
 KMUTANT MmSystemLoadLock;
 extern ULONG NtGlobalFlag;
 
+PVOID MmUnloadedDrivers;
+PVOID MmLastUnloadedDrivers;
+PVOID MmTriageActionTaken;
+PVOID KernelVerifier;
+MM_DRIVER_VERIFIER_DATA MmVerifierData;
+
 /* FUNCTIONS *****************************************************************/
 
 PVOID
index d34f964..efe8e01 100644 (file)
                <file>dbgpool.c</file>
                <file>freelist.c</file>
                <file>marea.c</file>
+               <file>mmdbg.c</file>
                <file>mmfault.c</file>
                <file>mminit.c</file>
                <file>mpw.c</file>