00001 /*****************************************************************/ 00004 /*****************************************************************/ 00005 00006 #include <stdio.h> 00007 #include <process.h> 00008 #include <setjmp.h> 00009 00010 #include <time.h> 00011 00012 #include <nt.h> 00013 #include <ntrtl.h> 00014 #include <nturtl.h> 00015 #include <windows.h> 00016 00017 // declare a BSS value - see what the assemble looks like 00018 00019 CONTEXT RegContext; 00020 ULONG DefaultValue; 00021 ULONG TestCount; 00022 ULONG ExpectedException; 00023 00024 extern ULONG DivOperand; 00025 extern ULONG DivRegPointer; 00026 extern LONG DivRegScaler; 00027 extern ULONG ExceptEip; 00028 extern ULONG ExceptEsp; 00029 extern ULONG TestTable[]; 00030 extern ULONG TestTableCenter[]; 00031 #define TESTTABLESIZE (128*sizeof(ULONG)) 00032 00033 extern TestDiv(); 00034 00035 BOOLEAN vInitialized; 00036 ULONG vZero = 0; 00037 ULONG vTwo = 0; 00038 ULONG vDivOk = 0x7f7f7f7f; 00039 00040 00041 VOID __cdecl 00042 main (argc, argv) 00043 int argc; 00044 char *argv[]; 00045 { 00046 00047 /*** 00048 * This program tests the kernel's MOD/RM & SIB decoding of 00049 * a processor trap 0. The kernel needs to crack the MOD/RM & SIB 00050 * on a div to determine if the exception is a divide_by_zero 00051 * or an overflow execption. 00052 */ 00053 00054 try { 00055 // 00056 // Setup for divide by zero test 00057 // 00058 00059 DivOperand = 0; 00060 DivRegScaler = 0; 00061 DivRegPointer = TestTableCenter; 00062 DefaultValue = 0x01010101; 00063 ExpectedException = STATUS_INTEGER_DIVIDE_BY_ZERO; 00064 00065 printf ("Begin divide by zero test\n"); 00066 00067 for (DivRegScaler = -7; DivRegScaler < 7; DivRegScaler++) { 00068 vInitialized = FALSE; 00069 TestDiv (); 00070 } 00071 00072 printf ("End divide by zero test\n\n"); 00073 00074 // 00075 // Setup for divide overflow test 00076 // 00077 00078 DivOperand = 2; 00079 DivRegPointer = TestTableCenter; 00080 DefaultValue = 0; 00081 ExpectedException = STATUS_INTEGER_OVERFLOW; 00082 00083 printf ("Begin divide overflow test\n"); 00084 00085 for (DivRegScaler = -7; DivRegScaler < 7; DivRegScaler++) { 00086 vInitialized = FALSE; 00087 TestDiv (); 00088 } 00089 printf ("End divide overflow test\n\n"); 00090 00091 } except (HandleException(GetExceptionInformation())) { 00092 printf ("FAIL: in divide by zero exception handler"); 00093 } 00094 00095 printf ("%ld varations run ", TestCount); 00096 } 00097 00098 HandleException ( 00099 IN PEXCEPTION_POINTERS ExceptionPointers 00100 ) 00101 { 00102 ULONG i; 00103 PUCHAR p; 00104 PCONTEXT Context; 00105 ULONG def; 00106 00107 switch (i = ExceptionPointers->ExceptionRecord->ExceptionCode) { 00108 case 1: 00109 Context = ExceptionPointers->ContextRecord; 00110 Context->Eip = ExceptEip; 00111 Context->Esp = ExceptEsp; 00112 00113 if (vInitialized) { 00114 printf ("Divide failed - div instruction completed\n"); 00115 return EXCEPTION_CONTINUE_SEARCH; // to debugger 00116 } 00117 vInitialized = TRUE; 00118 TestCount--; 00119 // fall through... 00120 00121 case STATUS_INTEGER_OVERFLOW: 00122 case STATUS_INTEGER_DIVIDE_BY_ZERO: 00123 if (i != ExpectedException && i != 1) { 00124 break; 00125 } 00126 00127 TestCount++; 00128 00129 // set context 00130 def = DefaultValue; 00131 Context = ExceptionPointers->ContextRecord; 00132 Context->Eax = def; 00133 Context->Ebx = def; 00134 Context->Ecx = def; 00135 Context->Edx = def; 00136 Context->Esi = def; 00137 Context->Edi = def; 00138 Context->Ebp = def; 00139 00140 // find next test 00141 for (p = (PUCHAR) Context->Eip; ((PULONG) p)[0] != 0xCCCCCCCC; p++) ; 00142 Context->Eip = (ULONG) (p + 4); 00143 00144 // clear global testable 00145 RtlFillMemoryUlong (TestTable, TESTTABLESIZE, def); 00146 return EXCEPTION_CONTINUE_EXECUTION; 00147 } 00148 00149 printf ("\nFailed - unexpected exception code %lx (expected %lx)\n", 00150 ExceptionPointers->ExceptionRecord->ExceptionCode, 00151 ExpectedException 00152 ); 00153 00154 return EXCEPTION_CONTINUE_SEARCH; 00155 } 00156 00157 00158 00159 00160 DivMarker() 00161 { 00162 EXCEPTION_RECORD ExceptionRecord; 00163 00164 // 00165 // Construct an exception record. 00166 // 00167 00168 ExceptionRecord.ExceptionCode = 1; 00169 ExceptionRecord.ExceptionRecord = (PEXCEPTION_RECORD)NULL; 00170 ExceptionRecord.NumberParameters = 0; 00171 ExceptionRecord.ExceptionFlags = 0; 00172 RtlRaiseException(&ExceptionRecord); 00173 }