Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

npxnp.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 npxnp.c 00008 00009 Abstract: 00010 00011 This module contains support for non-Flat mode NPX faults when 00012 the application has it's CR0_EM bit clear. 00013 00014 Author: 00015 00016 Ken Reneris (kenr) 8-Dec-1994 00017 00018 Environment: 00019 00020 User Mode only 00021 00022 Revision History: 00023 00024 --*/ 00025 00026 00027 #include "csrdll.h" 00028 00029 static UCHAR MOD16[] = { 0, 1, 2, 0 }; 00030 static UCHAR MOD32[] = { 0, 1, 4, 0 }; 00031 00032 UCHAR 00033 NpxNpReadCSEip ( 00034 IN PCONTEXT Context 00035 ) 00036 #pragma warning(disable:4035) 00037 { 00038 _asm { 00039 push es 00040 mov ecx, Context 00041 mov eax, [ecx] CONTEXT.SegCs 00042 mov es, ax 00043 mov eax, [ecx] CONTEXT.Eip 00044 inc dword ptr [ecx] CONTEXT.Eip ; Advance EIP 00045 mov al, es:[eax] 00046 pop es 00047 } 00048 } 00049 #pragma warning(default:4035) 00050 00051 00052 VOID 00053 NpxNpSkipInstruction ( 00054 IN PCONTEXT Context 00055 ) 00056 /*++ 00057 00058 Routine Description: 00059 00060 This functions gains control when the system has no installed 00061 NPX support, but the thread has cleared it's EM bit in CR0. 00062 00063 The purpose of this function is to move the instruction 00064 pointer forward over the current NPX instruction. 00065 00066 Enviroment: 00067 00068 16:16 mode 00069 00070 Arguments: 00071 00072 Return Value: 00073 00074 --*/ 00075 { 00076 BOOLEAN fPrefix; 00077 UCHAR ibyte, Mod, rm; 00078 UCHAR Address32Bits; 00079 ULONG CallerCs; 00080 00081 Address32Bits = 0; // assume called from 16:16 00082 00083 // 00084 // Lookup and determine callers default mode 00085 // 00086 00087 CallerCs = Context->SegCs; 00088 _asm { 00089 mov eax, CallerCs 00090 lar eax, eax 00091 test eax, 400000h 00092 jz short IsDefault16Bit 00093 00094 mov Address32Bits, 1 00095 00096 IsDefault16Bit: 00097 } 00098 00099 // 00100 // No sense in using a try-except since we are not on the 00101 // correct stack. A fault here could occur if the start 00102 // of an NPX instruction is near the end of a selector, and the 00103 // end of the instruction is past the selectors end. This 00104 // would kill the app anyway. 00105 // 00106 00107 // 00108 // Read any instruction prefixes 00109 // 00110 00111 fPrefix = TRUE; 00112 while (fPrefix) { 00113 ibyte = NpxNpReadCSEip(Context); 00114 00115 switch (ibyte) { 00116 case 0x2e: // cs override, skip it 00117 case 0x36: // ss override, skip it 00118 case 0x3e: // ds override, skip it 00119 case 0x26: // es override, skip it 00120 case 0x64: // fs override, skip it 00121 case 0x65: // gs override, skip it 00122 case 0x66: // operand size override, skip it 00123 break; 00124 00125 case 0x67: 00126 // address size override 00127 Address32Bits ^= 1; 00128 break; 00129 00130 default: 00131 fPrefix = FALSE; 00132 break; 00133 } 00134 } 00135 00136 // 00137 // Handle first byte of NPX instruction 00138 // 00139 00140 if (ibyte == 0x9b) { 00141 00142 // 00143 // FWait instruction - single byte opcode - all done 00144 // 00145 00146 return; 00147 } 00148 00149 if (ibyte < 0xD8 || ibyte > 0xDF) { 00150 00151 // 00152 // Not an ESC instruction 00153 // 00154 00155 #if DBG 00156 DbgPrint ("P5_FPU_PATCH: 16: Not NPX ESC instruction\n"); 00157 #endif 00158 return; 00159 } 00160 00161 // 00162 // Get ModR/M byte for NPX opcode 00163 // 00164 00165 ibyte = NpxNpReadCSEip(Context); 00166 00167 if (ibyte > 0xbf) { 00168 // 00169 // Outside of ModR/M range for addressing, all done 00170 // 00171 00172 return; 00173 } 00174 00175 Mod = ibyte >> 6; 00176 rm = ibyte & 0x7; 00177 if (Address32Bits) { 00178 Context->Eip += MOD32 [Mod]; 00179 if (Mod == 0 && rm == 5) { 00180 // disp 32 00181 Context->Eip += 4; 00182 } 00183 00184 // 00185 // If SIB byte, read it 00186 // 00187 00188 if (rm == 4) { 00189 ibyte = NpxNpReadCSEip(Context); 00190 00191 if (Mod == 0 && (ibyte & 7) == 5) { 00192 // disp 32 00193 Context->Eip += 4; 00194 } 00195 } 00196 00197 } else { 00198 Context->Eip += MOD16 [Mod]; 00199 if (Mod == 0 && rm == 6) { 00200 // disp 16 00201 Context->Eip += 2; 00202 } 00203 } 00204 }

Generated on Sat May 15 19:40:58 2004 for test by doxygen 1.3.7