[NTOS:KD][KDBG] Get rid of kdmemsup.c as its functionality has been superseded by...
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 3 Nov 2019 22:36:40 +0000 (23:36 +0100)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 3 Nov 2019 22:46:52 +0000 (23:46 +0100)
- Import KdpCopyMemoryChunks() from kd64/kdapi.c, and re-implement
  KdbpSafeReadMemory() and KdbpSafeWriteMemory() around it.
  Note that these functions read virtual memory and are equivalent of
  the kd64 KdpReadVirtualMemory() and KdpWriteVirtualMemory()
  respectively.

- Get rid of the KdpEnableSafeMem() call in KdInitSystem().
- Adjust kd gdbstub.c wrapper in accordance.

ntoskrnl/kd/amd64/kdmemsup.c [deleted file]
ntoskrnl/kd/i386/kdmemsup.c
ntoskrnl/kd/kdinit.c
ntoskrnl/kd/wrappers/gdbstub.c
ntoskrnl/kdbg/kdb.c
ntoskrnl/ntos.cmake

diff --git a/ntoskrnl/kd/amd64/kdmemsup.c b/ntoskrnl/kd/amd64/kdmemsup.c
deleted file mode 100644 (file)
index 75f19a1..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS Kernel
- * FILE:            ntoskrnl/kd/amd64/kdmemsup.c
- * PURPOSE:         Kernel Debugger Safe Memory Support
- *
- * PROGRAMMERS:     arty
- */
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <debug.h>
-
-#define HIGH_PHYS_MASK 0x80000000
-#define PAGE_TABLE_MASK 0x3ff
-#define BIG_PAGE_SIZE (1<<22)
-#define CR4_PAGE_SIZE_BIT 0x10
-#define PDE_PRESENT_BIT 0x01
-#define PDE_W_BIT 0x02
-#define PDE_PWT_BIT 0x08
-#define PDE_PCD_BIT 0x10
-#define PDE_ACCESSED_BIT 0x20
-#define PDE_DIRTY_BIT 0x40
-#define PDE_PS_BIT 0x80
-
-#define MI_KDBG_TMP_PAGE_1 (HYPER_SPACE + 0x400000 - PAGE_SIZE)
-#define MI_KDBG_TMP_PAGE_0 (MI_KDBG_TMP_PAGE_1 - PAGE_SIZE)
-
-/* VARIABLES ***************************************************************/
-
-static BOOLEAN KdpPhysAccess = FALSE;
-
-static
-ULONG_PTR
-KdpPhysMap(ULONG_PTR PhysAddr, LONG Len)
-{
-    MMPTE TempPte;
-    PMMPTE PointerPte;
-    ULONG_PTR VirtAddr;
-
-    TempPte.u.Long = PDE_PRESENT_BIT | PDE_W_BIT | PDE_PWT_BIT |
-                     PDE_PCD_BIT | PDE_ACCESSED_BIT | PDE_DIRTY_BIT;
-
-    if ((PhysAddr & (PAGE_SIZE - 1)) + Len > PAGE_SIZE)
-    {
-        TempPte.u.Hard.PageFrameNumber = (PhysAddr >> PAGE_SHIFT) + 1;
-        PointerPte = MiAddressToPte((PVOID)MI_KDBG_TMP_PAGE_1);
-        *PointerPte = TempPte;
-        VirtAddr = (ULONG_PTR)PointerPte << 10;
-        KeInvalidateTlbEntry((PVOID)VirtAddr);
-    }
-
-    TempPte.u.Hard.PageFrameNumber = PhysAddr >> PAGE_SHIFT;
-    PointerPte = MiAddressToPte((PVOID)MI_KDBG_TMP_PAGE_0);
-    *PointerPte = TempPte;
-    VirtAddr = (ULONG_PTR)PointerPte << 10;
-    KeInvalidateTlbEntry((PVOID)VirtAddr);
-
-    return VirtAddr + (PhysAddr & (PAGE_SIZE - 1));
-}
-
-static
-ULONGLONG
-KdpPhysRead(ULONG_PTR PhysAddr, LONG Len)
-{
-    ULONG_PTR Addr;
-    ULONGLONG Result = 0;
-
-    Addr = KdpPhysMap(PhysAddr, Len);
-
-    switch (Len)
-    {
-    case 8:
-        Result = *((PULONGLONG)Addr);
-        break;
-    case 4:
-        Result = *((PULONG)Addr);
-        break;
-    case 2:
-        Result = *((PUSHORT)Addr);
-        break;
-    case 1:
-        Result = *((PUCHAR)Addr);
-        break;
-    }
-
-    return Result;
-}
-
-static
-VOID
-KdpPhysWrite(ULONG_PTR PhysAddr, LONG Len, ULONGLONG Value)
-{
-    ULONG_PTR Addr;
-
-    Addr = KdpPhysMap(PhysAddr, Len);
-
-    switch (Len)
-    {
-    case 8:
-        *((PULONGLONG)Addr) = Value;
-        break;
-    case 4:
-        *((PULONG)Addr) = Value;
-        break;
-    case 2:
-        *((PUSHORT)Addr) = Value;
-        break;
-    case 1:
-        *((PUCHAR)Addr) = Value;
-        break;
-    }
-}
-
-BOOLEAN
-NTAPI
-KdpTranslateAddress(ULONG_PTR Addr, PULONG_PTR ResultAddr)
-{
-    ULONG_PTR CR3Value = __readcr3();
-    ULONG_PTR CR4Value = __readcr4();
-    ULONG_PTR PageDirectory = (CR3Value & ~(PAGE_SIZE-1)) +
-        ((Addr >> 22) * sizeof(ULONG));
-    ULONG_PTR PageDirectoryEntry = KdpPhysRead(PageDirectory, sizeof(ULONG));
-
-    /* Not present -> fail */
-    if (!(PageDirectoryEntry & PDE_PRESENT_BIT))
-    {
-        return FALSE;
-    }
-
-    /* Big Page? */
-    if ((PageDirectoryEntry & PDE_PS_BIT) && (CR4Value & CR4_PAGE_SIZE_BIT))
-    {
-        *ResultAddr = (PageDirectoryEntry & ~(BIG_PAGE_SIZE-1)) +
-            (Addr & (BIG_PAGE_SIZE-1));
-        return TRUE;
-    }
-    else
-    {
-        ULONG_PTR PageTableAddr =
-            (PageDirectoryEntry & ~(PAGE_SIZE-1)) +
-            ((Addr >> PAGE_SHIFT) & PAGE_TABLE_MASK) * sizeof(ULONG);
-        ULONG_PTR PageTableEntry = KdpPhysRead(PageTableAddr, sizeof(ULONG));
-        if (PageTableEntry & PDE_PRESENT_BIT)
-        {
-            *ResultAddr = (PageTableEntry & ~(PAGE_SIZE-1)) +
-                (Addr & (PAGE_SIZE-1));
-            return TRUE;
-        }
-    }
-
-    return FALSE;
-}
-
-BOOLEAN
-NTAPI
-KdpSafeReadMemory(ULONG_PTR Addr, LONG Len, PVOID Value)
-{
-    ULONG_PTR ResultPhysAddr;
-
-    if (!KdpPhysAccess)
-    {
-        memcpy(Value, (PVOID)Addr, Len);
-        return TRUE;
-    }
-
-    memset(Value, 0, Len);
-
-    if (!KdpTranslateAddress(Addr, &ResultPhysAddr))
-        return FALSE;
-
-    switch (Len)
-    {
-    case 8:
-        *((PULONGLONG)Value) = KdpPhysRead(ResultPhysAddr, Len);
-        break;
-    case 4:
-        *((PULONG)Value) = KdpPhysRead(ResultPhysAddr, Len);
-        break;
-    case 2:
-        *((PUSHORT)Value) = KdpPhysRead(ResultPhysAddr, Len);
-        break;
-    case 1:
-        *((PUCHAR)Value) = KdpPhysRead(ResultPhysAddr, Len);
-        break;
-    }
-
-    return TRUE;
-}
-
-BOOLEAN
-NTAPI
-KdpSafeWriteMemory(ULONG_PTR Addr, LONG Len, ULONGLONG Value)
-{
-    ULONG_PTR ResultPhysAddr;
-
-    if (!KdpPhysAccess)
-    {
-        memcpy((PVOID)Addr, &Value, Len);
-        return TRUE;
-    }
-
-    if (!KdpTranslateAddress(Addr, &ResultPhysAddr))
-        return FALSE;
-
-    KdpPhysWrite(ResultPhysAddr, Len, Value);
-    return TRUE;
-}
-
-VOID
-NTAPI
-KdpEnableSafeMem(VOID)
-{
-    KdpPhysAccess = TRUE;
-}
-
-/* EOF */
index 7616734..20a5824 100644 (file)
@@ -1,3 +1,11 @@
+/*****************************************************************************\
+ *                                                                           *
+ *     This file is current kept ONLY for DOCUMENTATION purposes, until      *
+ *  we are sure that all the functionality (e.g. regarding the "big pages")  *
+ * are fully present in Mm and in mm/ARM3/mmdbg.c that supersedes this file. *
+ *                                                                           *
+\*****************************************************************************/
+
 /*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS Kernel
@@ -44,14 +52,14 @@ KdpPhysMap(ULONG_PTR PhysAddr, LONG Len)
     if ((PhysAddr & (PAGE_SIZE - 1)) + Len > PAGE_SIZE)
     {
         TempPte.u.Hard.PageFrameNumber = (PhysAddr >> PAGE_SHIFT) + 1;
-        PointerPte = MiAddressToPte(MI_KDBG_TMP_PAGE_1);
+        PointerPte = MiAddressToPte((PVOID)MI_KDBG_TMP_PAGE_1);
         *PointerPte = TempPte;
         VirtAddr = (ULONG_PTR)PointerPte << 10;
         KeInvalidateTlbEntry((PVOID)VirtAddr);
     }
 
     TempPte.u.Hard.PageFrameNumber = PhysAddr >> PAGE_SHIFT;
-    PointerPte = MiAddressToPte(MI_KDBG_TMP_PAGE_0);
+    PointerPte = MiAddressToPte((PVOID)MI_KDBG_TMP_PAGE_0);
     *PointerPte = TempPte;
     VirtAddr = (ULONG_PTR)PointerPte << 10;
     KeInvalidateTlbEntry((PVOID)VirtAddr);
@@ -112,8 +120,8 @@ KdpPhysWrite(ULONG_PTR PhysAddr, LONG Len, ULONGLONG Value)
     }
 }
 
+static
 BOOLEAN
-NTAPI
 KdpTranslateAddress(ULONG_PTR Addr, PULONG_PTR ResultAddr)
 {
     ULONG_PTR CR3Value = __readcr3();
index f5e1c48..3e32b16 100644 (file)
@@ -287,9 +287,6 @@ KdInitSystem(ULONG BootPhase,
     }
     else /* BootPhase > 0 */
     {
-#ifdef _M_IX86
-        KdpEnableSafeMem();
-#endif
     }
 
     /* Call the Initialization Routines of the Registered Providers */
index 6ca6893..5249777 100644 (file)
@@ -246,19 +246,35 @@ static volatile BOOLEAN GspMemoryError = FALSE;
 static CHAR
 GspReadMemSafe(PCHAR Address)
 {
-    CHAR ch = 0;
-
-    if (!KdpSafeReadMemory((ULONG_PTR)Address, 1, &ch))
+    CHAR Ch = 0;
+
+#if 0
+    if (!NT_SUCCESS(KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Address, &Ch, 1,
+                                        0, MMDBG_COPY_UNSAFE, NULL)))
+#else
+    if (!NT_SUCCESS(MmDbgCopyMemory((ULONG64)(ULONG_PTR)Address, &Ch, 1,
+                                    MMDBG_COPY_UNSAFE)))
+#endif
+    {
         GspMemoryError = TRUE;
+    }
 
-    return ch;
+    return Ch;
 }
 
 static void
 GspWriteMemSafe(PCHAR Address, CHAR Ch)
 {
-    if (!KdpSafeWriteMemory((ULONG_PTR)Address, 1, Ch))
+#if 0
+    if (!NT_SUCCESS(KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Address, &Ch, 1,
+                                        0, MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE, NULL)))
+#else
+    if (!NT_SUCCESS(MmDbgCopyMemory((ULONG64)(ULONG_PTR)Address, &Ch, 1,
+                                    MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE)))
+#endif
+    {
         GspMemoryError = TRUE;
+    }
 }
 
 /* Convert the memory pointed to by Address into hex, placing result in Buffer
index 6b9d469..d75ab13 100644 (file)
@@ -1730,40 +1730,101 @@ KdbpGetCommandLineSettings(
     }
 }
 
+/*
+ * Copied from ntoskrnl/kd64/kdapi.c
+ */
 NTSTATUS
-KdbpSafeReadMemory(
-    OUT PVOID Dest,
-    IN PVOID Src,
-    IN ULONG Bytes)
+NTAPI
+KdpCopyMemoryChunks(IN ULONG64 Address,
+                    IN PVOID Buffer,
+                    IN ULONG TotalSize,
+                    IN ULONG ChunkSize,
+                    IN ULONG Flags,
+                    OUT PULONG ActualSize OPTIONAL)
 {
-    BOOLEAN Result = TRUE;
+    NTSTATUS Status;
+    ULONG RemainingLength, CopyChunk;
 
-    switch (Bytes)
+    /* Check if we didn't get a chunk size or if it is too big */
+    if (ChunkSize == 0)
     {
-        case 1:
-        case 2:
-        case 4:
-        case 8:
-            Result = KdpSafeReadMemory((ULONG_PTR)Src, Bytes, Dest);
-            break;
+        /* Default to 4 byte chunks */
+        ChunkSize = 4;
+    }
+    else if (ChunkSize > MMDBG_COPY_MAX_SIZE)
+    {
+        /* Normalize to maximum size */
+        ChunkSize = MMDBG_COPY_MAX_SIZE;
+    }
 
-        default:
+    /* Copy the whole range in aligned chunks */
+    RemainingLength = TotalSize;
+    CopyChunk = 1;
+    while (RemainingLength > 0)
+    {
+        /*
+         * Determine the best chunk size for this round.
+         * The ideal size is 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))
         {
-            ULONG_PTR Start, End, Write;
+            /* Increase it */
+            CopyChunk *= 2;
+        }
 
-            for (Start = (ULONG_PTR)Src,
-                    End = Start + Bytes,
-                    Write = (ULONG_PTR)Dest;
-                 Result && (Start < End);
-                 Start++, Write++)
-                if (!KdpSafeReadMemory(Start, 1, (PVOID)Write))
-                    Result = FALSE;
+        /*
+         * 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)
+        {
+            /* Shrink it */
+            CopyChunk /= 2;
+        }
 
+        /* Do the copy */
+        Status = MmDbgCopyMemory(Address,
+                                 Buffer,
+                                 CopyChunk,
+                                 Flags);
+        if (!NT_SUCCESS(Status))
+        {
+            /* Copy failed, break out */
             break;
         }
+
+        /* Update pointers and length for the next run */
+        Address = Address + CopyChunk;
+        Buffer = (PVOID)((ULONG_PTR)Buffer + CopyChunk);
+        RemainingLength = RemainingLength - CopyChunk;
     }
 
-    return Result ? STATUS_SUCCESS : STATUS_ACCESS_VIOLATION;
+    /* We may have modified executable code, flush the instruction cache */
+    KeSweepICache((PVOID)(ULONG_PTR)Address, TotalSize);
+
+    /*
+     * 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;
+}
+
+NTSTATUS
+KdbpSafeReadMemory(
+    OUT PVOID Dest,
+    IN PVOID Src,
+    IN ULONG Bytes)
+{
+    return KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Src,
+                               Dest,
+                               Bytes,
+                               0,
+                               MMDBG_COPY_UNSAFE,
+                               NULL);
 }
 
 NTSTATUS
@@ -1772,16 +1833,10 @@ KdbpSafeWriteMemory(
     IN PVOID Src,
     IN ULONG Bytes)
 {
-    BOOLEAN Result = TRUE;
-    ULONG_PTR Start, End, Write;
-
-    for (Start = (ULONG_PTR)Src,
-            End = Start + Bytes,
-            Write = (ULONG_PTR)Dest;
-         Result && (Start < End);
-         Start++, Write++)
-        if (!KdpSafeWriteMemory(Write, 1, *((PCHAR)Start)))
-            Result = FALSE;
-
-    return Result ? STATUS_SUCCESS : STATUS_ACCESS_VIOLATION;
+    return KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Dest,
+                               Src,
+                               Bytes,
+                               0,
+                               MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
+                               NULL);
 }
index 38dc52a..9d4d668 100644 (file)
@@ -369,7 +369,6 @@ if(NOT _WINKD_)
     if(ARCH STREQUAL "i386")
         list(APPEND SOURCE
             ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/i386/kdbg.c
-            ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/i386/kdmemsup.c
             ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/wrappers/gdbstub.c)
         if(KDBG)
             list(APPEND ASM_SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/i386/kdb_help.S)
@@ -377,9 +376,8 @@ if(NOT _WINKD_)
         endif()
     elseif(ARCH STREQUAL "amd64")
         list(APPEND SOURCE
-            ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/amd64/kd.c
             ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/i386/kdbg.c  # Use the x86 file
-            ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/amd64/kdmemsup.c)
+            ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/amd64/kd.c)
         if(KDBG)
             list(APPEND ASM_SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/amd64/kdb_help.S)
             list(APPEND SOURCE