@@ -353,6 +353,7 @@ static const struct
353353#endif // _M_IX86
354354 { "x" , "x [address] [L count]" , "Display count dwords, starting at address." , KdbpCmdDisassembleX },
355355 { "regs" , "regs" , "Display general purpose registers." , KdbpCmdRegs },
356+ { "cregs" , "cregs" , "Display control, descriptor table and task segment registers." , KdbpCmdRegs },
356357 { "sregs" , "sregs" , "Display status registers." , KdbpCmdRegs },
357358 { "dregs" , "dregs" , "Display debug registers." , KdbpCmdRegs },
358359 { "bt" , "bt [*frameaddr|thread id]" , "Prints current backtrace or from given frame address." , KdbpCmdBackTrace },
@@ -984,6 +985,84 @@ KdbpCmdRegs(
984985 }
985986 KdbpPrint ("\n" );
986987 }
988+ else if (Argv [0 ][0 ] == 'c' ) /* cregs */
989+ {
990+ ULONG Cr0 , Cr2 , Cr3 , Cr4 ;
991+ KDESCRIPTOR Gdtr = {0 , 0 , 0 }, Idtr = {0 , 0 , 0 };
992+ USHORT Ldtr , Tr ;
993+ static const PCHAR Cr0Bits [32 ] = { " PE" , " MP" , " EM" , " TS" , " ET" , " NE" , NULL , NULL ,
994+ NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL ,
995+ " WP" , NULL , " AM" , NULL , NULL , NULL , NULL , NULL ,
996+ NULL , NULL , NULL , NULL , NULL , " NW" , " CD" , " PG" };
997+ static const PCHAR Cr4Bits [32 ] = { " VME" , " PVI" , " TSD" , " DE" , " PSE" , " PAE" , " MCE" , " PGE" ,
998+ " PCE" , " OSFXSR" , " OSXMMEXCPT" , NULL , NULL , NULL , NULL , NULL ,
999+ NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL ,
1000+ NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL };
1001+ SYSDBG_CONTROL_SPACE Input ;
1002+ KSPECIAL_REGISTERS SpecialRegisters ;
1003+ NTSTATUS Status = STATUS_NOT_IMPLEMENTED ;
1004+
1005+ /* Retrieve the control registers */
1006+ RtlZeroMemory (& Input , sizeof (Input ));
1007+ Input .Buffer = & SpecialRegisters ;
1008+ Input .Request = sizeof (SpecialRegisters );
1009+ #ifdef _M_IX86
1010+ Input .Address = sizeof (CONTEXT );
1011+ #else
1012+ Input .Address = AMD64_DEBUG_CONTROL_SPACE_KSPECIAL ;
1013+ #endif
1014+ Status = KdSystemDebugControl (SysDbgReadControlSpace ,
1015+ & Input , sizeof (Input ),
1016+ NULL , 0 ,
1017+ NULL , KernelMode );
1018+ if (!NT_SUCCESS (Status ))
1019+ {
1020+ KdbpPrint ("Failed to get registers: status 0x%08x\n" , Status );
1021+ return TRUE;
1022+ }
1023+ Cr0 = SpecialRegisters .Cr0 ;
1024+ Cr2 = SpecialRegisters .Cr2 ;
1025+ Cr3 = SpecialRegisters .Cr3 ;
1026+ Cr4 = SpecialRegisters .Cr4 ;
1027+
1028+ /* Retrieve the descriptor table and task segment registers */
1029+ Gdtr = SpecialRegisters .Gdtr ;
1030+ Ldtr = SpecialRegisters .Ldtr ;
1031+ Idtr = SpecialRegisters .Idtr ;
1032+ Tr = SpecialRegisters .Tr ;
1033+
1034+ /* Display the control registers */
1035+ KdbpPrint ("CR0 0x%08x " , Cr0 );
1036+ for (i = 0 ; i < 32 ; i ++ )
1037+ {
1038+ if (!Cr0Bits [i ])
1039+ continue ;
1040+
1041+ if ((Cr0 & (1 << i )) != 0 )
1042+ KdbpPrint (Cr0Bits [i ]);
1043+ }
1044+ KdbpPrint ("\n" );
1045+
1046+ KdbpPrint ("CR2 0x%08x\n" , Cr2 );
1047+ KdbpPrint ("CR3 0x%08x Pagedir-Base 0x%08x %s%s\n" , Cr3 , (Cr3 & 0xfffff000 ),
1048+ (Cr3 & (1 << 3 )) ? " PWT" : "" , (Cr3 & (1 << 4 )) ? " PCD" : "" );
1049+ KdbpPrint ("CR4 0x%08x " , Cr4 );
1050+ for (i = 0 ; i < 32 ; i ++ )
1051+ {
1052+ if (!Cr4Bits [i ])
1053+ continue ;
1054+
1055+ if ((Cr4 & (1 << i )) != 0 )
1056+ KdbpPrint (Cr4Bits [i ]);
1057+ }
1058+ KdbpPrint ("\n" );
1059+
1060+ /* Display the descriptor table and task segment registers */
1061+ KdbpPrint ("GDTR Base 0x%08x Size 0x%04x\n" , Gdtr .Base , Gdtr .Limit );
1062+ KdbpPrint ("LDTR 0x%04x\n" , Ldtr );
1063+ KdbpPrint ("IDTR Base 0x%08x Size 0x%04x\n" , Idtr .Base , Idtr .Limit );
1064+ KdbpPrint ("TR 0x%04x\n" , Tr );
1065+ }
9871066 else if (Argv [0 ][0 ] == 's' ) /* sregs */
9881067 {
9891068 KdbpPrint ("CS 0x%04x Index 0x%04x %cDT RPL%d\n" ,
0 commit comments