https://git.reactos.org/?p=reactos.git;a=commitdiff;h=70bf3bb8fa7ed1eefde808efb3b43e85040b24bf

commit 70bf3bb8fa7ed1eefde808efb3b43e85040b24bf
Author:     Hervé Poussineau <hpous...@reactos.org>
AuthorDate: Sat Oct 12 07:46:41 2024 +0200
Commit:     Hervé Poussineau <hpous...@reactos.org>
CommitDate: Wed Jan 29 18:25:24 2025 +0100

    [NTOS:KDBG] Add back 'cregs' command
    
    This command was removed in commit baa47fa5e06948b7e76ba820f7a342547eaf0cde
    because there was no way to get the CRx registers from a CONTEXT structure.
    Previous code was also displaying current GDTR/LDTR and IDT.
    
    Rewrite the code to use KdSystemDebugControl(SysDbgReadControlSpace, ...)
    to get CRx, GDTR/LDTR and IDT values just before entering debugger.
---
 ntoskrnl/kdbg/kdb_cli.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/ntoskrnl/kdbg/kdb_cli.c b/ntoskrnl/kdbg/kdb_cli.c
index b4794dca739..c86b770c81d 100644
--- a/ntoskrnl/kdbg/kdb_cli.c
+++ b/ntoskrnl/kdbg/kdb_cli.c
@@ -353,6 +353,7 @@ static const struct
 #endif // _M_IX86
     { "x", "x [address] [L count]", "Display count dwords, starting at 
address.", KdbpCmdDisassembleX },
     { "regs", "regs", "Display general purpose registers.", KdbpCmdRegs },
+    { "cregs", "cregs", "Display control, descriptor table and task segment 
registers.", KdbpCmdRegs },
     { "sregs", "sregs", "Display status registers.", KdbpCmdRegs },
     { "dregs", "dregs", "Display debug registers.", KdbpCmdRegs },
     { "bt", "bt [*frameaddr|thread id]", "Prints current backtrace or from 
given frame address.", KdbpCmdBackTrace },
@@ -984,6 +985,84 @@ KdbpCmdRegs(
         }
         KdbpPrint("\n");
     }
+    else if (Argv[0][0] == 'c') /* cregs */
+    {
+        ULONG Cr0, Cr2, Cr3, Cr4;
+        KDESCRIPTOR Gdtr = {0, 0, 0}, Idtr = {0, 0, 0};
+        USHORT Ldtr, Tr;
+        static const PCHAR Cr0Bits[32] = { " PE", " MP", " EM", " TS", " ET", 
" NE", NULL, NULL,
+                                           NULL, NULL, NULL, NULL, NULL, NULL, 
NULL, NULL,
+                                           " WP", NULL, " AM", NULL, NULL, 
NULL, NULL, NULL,
+                                           NULL, NULL, NULL, NULL, NULL, " 
NW", " CD", " PG" };
+        static const PCHAR Cr4Bits[32] = { " VME", " PVI", " TSD", " DE", " 
PSE", " PAE", " MCE", " PGE",
+                                           " PCE", " OSFXSR", " OSXMMEXCPT", 
NULL, NULL, NULL, NULL, NULL,
+                                           NULL, NULL, NULL, NULL, NULL, NULL, 
NULL, NULL,
+                                           NULL, NULL, NULL, NULL, NULL, NULL, 
NULL, NULL };
+        SYSDBG_CONTROL_SPACE Input;
+        KSPECIAL_REGISTERS SpecialRegisters;
+        NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
+
+        /* Retrieve the control registers */
+        RtlZeroMemory(&Input, sizeof(Input));
+        Input.Buffer = &SpecialRegisters;
+        Input.Request = sizeof(SpecialRegisters);
+#ifdef _M_IX86
+        Input.Address = sizeof(CONTEXT);
+#else
+        Input.Address = AMD64_DEBUG_CONTROL_SPACE_KSPECIAL;
+#endif
+        Status = KdSystemDebugControl(SysDbgReadControlSpace,
+                                      &Input, sizeof(Input),
+                                      NULL, 0,
+                                      NULL, KernelMode);
+        if (!NT_SUCCESS(Status))
+        {
+            KdbpPrint("Failed to get registers: status 0x%08x\n", Status);
+            return TRUE;
+        }
+        Cr0 = SpecialRegisters.Cr0;
+        Cr2 = SpecialRegisters.Cr2;
+        Cr3 = SpecialRegisters.Cr3;
+        Cr4 = SpecialRegisters.Cr4;
+
+        /* Retrieve the descriptor table and task segment registers */
+        Gdtr = SpecialRegisters.Gdtr;
+        Ldtr = SpecialRegisters.Ldtr;
+        Idtr = SpecialRegisters.Idtr;
+        Tr = SpecialRegisters.Tr;
+
+        /* Display the control registers */
+        KdbpPrint("CR0  0x%08x ", Cr0);
+        for (i = 0; i < 32; i++)
+        {
+            if (!Cr0Bits[i])
+                continue;
+
+            if ((Cr0 & (1 << i)) != 0)
+                KdbpPrint(Cr0Bits[i]);
+        }
+        KdbpPrint("\n");
+
+        KdbpPrint("CR2  0x%08x\n", Cr2);
+        KdbpPrint("CR3  0x%08x  Pagedir-Base 0x%08x %s%s\n", Cr3, (Cr3 & 
0xfffff000),
+                  (Cr3 & (1 << 3)) ? " PWT" : "", (Cr3 & (1 << 4)) ? " PCD" : 
"" );
+        KdbpPrint("CR4  0x%08x ", Cr4);
+        for (i = 0; i < 32; i++)
+        {
+            if (!Cr4Bits[i])
+                continue;
+
+            if ((Cr4 & (1 << i)) != 0)
+                KdbpPrint(Cr4Bits[i]);
+        }
+        KdbpPrint("\n");
+
+        /* Display the descriptor table and task segment registers */
+        KdbpPrint("GDTR Base 0x%08x  Size 0x%04x\n", Gdtr.Base, Gdtr.Limit);
+        KdbpPrint("LDTR 0x%04x\n", Ldtr);
+        KdbpPrint("IDTR Base 0x%08x  Size 0x%04x\n", Idtr.Base, Idtr.Limit);
+        KdbpPrint("TR   0x%04x\n", Tr);
+    }
     else if (Argv[0][0] == 's') /* sregs */
     {
         KdbpPrint("CS  0x%04x  Index 0x%04x  %cDT RPL%d\n",

Reply via email to