Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenexp.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: BSD - See COPYING.ARM in the top level directory 00004 * FILE: ntoskrnl/ke/arm/exp.c 00005 * PURPOSE: Implements exception helper routines for ARM machines 00006 * PROGRAMMERS: ReactOS Portable Systems Group 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #include <internal/arm/ksarm.h> 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 /* FUNCTIONS ******************************************************************/ 00017 00018 VOID 00019 NTAPI 00020 KeContextToTrapFrame(IN PCONTEXT Context, 00021 IN OUT PKEXCEPTION_FRAME ExceptionFrame, 00022 IN OUT PKTRAP_FRAME TrapFrame, 00023 IN ULONG ContextFlags, 00024 IN KPROCESSOR_MODE PreviousMode) 00025 { 00026 KIRQL OldIrql; 00027 00028 // 00029 // Do this at APC_LEVEL 00030 // 00031 OldIrql = KeGetCurrentIrql(); 00032 if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql); 00033 00034 // 00035 // Start with the Control flags 00036 // 00037 if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) 00038 { 00039 // 00040 // So this basically means all the special stuff 00041 // 00042 if (PreviousMode == UserMode) 00043 { 00044 // 00045 // ARM has register banks 00046 // 00047 TrapFrame->UserSp = Context->Sp; 00048 TrapFrame->UserLr = Context->Lr; 00049 } 00050 else 00051 { 00052 // 00053 // ARM has register banks 00054 // 00055 TrapFrame->SvcSp = Context->Sp; 00056 TrapFrame->SvcLr = Context->Lr; 00057 } 00058 00059 // 00060 // The rest is already in the right mode 00061 // 00062 TrapFrame->Pc = Context->Pc; 00063 TrapFrame->Spsr = Context->Psr; 00064 } 00065 00066 // 00067 // Now do the integers 00068 // 00069 if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) 00070 { 00071 // 00072 // Basically everything else but FPU 00073 // 00074 TrapFrame->R0 = Context->R0; 00075 TrapFrame->R1 = Context->R1; 00076 TrapFrame->R2 = Context->R2; 00077 TrapFrame->R3 = Context->R3; 00078 TrapFrame->R4 = Context->R4; 00079 TrapFrame->R5 = Context->R5; 00080 TrapFrame->R6 = Context->R6; 00081 TrapFrame->R7 = Context->R7; 00082 TrapFrame->R8 = Context->R8; 00083 TrapFrame->R0 = Context->R9; 00084 TrapFrame->R10 = Context->R10; 00085 TrapFrame->R11 = Context->R11; 00086 TrapFrame->R12 = Context->R12; 00087 } 00088 00089 // 00090 // Restore IRQL 00091 // 00092 if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql); 00093 } 00094 00095 VOID 00096 NTAPI 00097 KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, 00098 IN PKEXCEPTION_FRAME ExceptionFrame, 00099 IN OUT PCONTEXT Context) 00100 { 00101 KIRQL OldIrql; 00102 00103 // 00104 // Do this at APC_LEVEL 00105 // 00106 OldIrql = KeGetCurrentIrql(); 00107 if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql); 00108 00109 // 00110 // Start with the Control flags 00111 // 00112 if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) 00113 { 00114 // 00115 // So this basically means all the special stuff 00116 // 00117 if (KiGetPreviousMode(TrapFrame) == UserMode) 00118 { 00119 // 00120 // ARM has register banks 00121 // 00122 Context->Sp = TrapFrame->UserSp; 00123 Context->Lr = TrapFrame->UserLr; 00124 } 00125 else 00126 { 00127 // 00128 // ARM has register banks 00129 // 00130 Context->Sp = TrapFrame->SvcSp; 00131 Context->Lr = TrapFrame->SvcLr; 00132 } 00133 00134 // 00135 // The rest is already in the right mode 00136 // 00137 Context->Pc = TrapFrame->Pc; 00138 Context->Psr = TrapFrame->Spsr; 00139 } 00140 00141 // 00142 // Now do the integers 00143 // 00144 if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) 00145 { 00146 // 00147 // Basically everything else but FPU 00148 // 00149 Context->R0 = TrapFrame->R0; 00150 Context->R1 = TrapFrame->R1; 00151 Context->R2 = TrapFrame->R2; 00152 Context->R3 = TrapFrame->R3; 00153 Context->R4 = TrapFrame->R4; 00154 Context->R5 = TrapFrame->R5; 00155 Context->R6 = TrapFrame->R6; 00156 Context->R7 = TrapFrame->R7; 00157 Context->R8 = TrapFrame->R8; 00158 Context->R0 = TrapFrame->R9; 00159 Context->R10 = TrapFrame->R10; 00160 Context->R11 = TrapFrame->R11; 00161 Context->R12 = TrapFrame->R12; 00162 } 00163 00164 // 00165 // Restore IRQL 00166 // 00167 if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql); 00168 } 00169 00170 VOID 00171 NTAPI 00172 KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, 00173 IN PKEXCEPTION_FRAME ExceptionFrame, 00174 IN PKTRAP_FRAME TrapFrame, 00175 IN KPROCESSOR_MODE PreviousMode, 00176 IN BOOLEAN FirstChance) 00177 { 00178 CONTEXT Context; 00179 00180 /* Increase number of Exception Dispatches */ 00181 KeGetCurrentPrcb()->KeExceptionDispatchCount++; 00182 00183 /* Set the context flags */ 00184 Context.ContextFlags = CONTEXT_FULL; 00185 00186 /* Check if User Mode or if the kernel debugger is enabled */ 00187 if ((PreviousMode == UserMode) || (KeGetPcr()->KdVersionBlock)) 00188 { 00189 /* FIXME-V6: VFP Support */ 00190 } 00191 00192 /* Get a Context */ 00193 KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context); 00194 00195 /* Look at our exception code */ 00196 switch (ExceptionRecord->ExceptionCode) 00197 { 00198 /* Breakpoint */ 00199 case STATUS_BREAKPOINT: 00200 00201 /* Decrement PC by four */ 00202 Context.Pc -= sizeof(ULONG); 00203 break; 00204 00205 /* Internal exception */ 00206 case KI_EXCEPTION_ACCESS_VIOLATION: 00207 00208 /* Set correct code */ 00209 ExceptionRecord->ExceptionCode = STATUS_ACCESS_VIOLATION; 00210 if (PreviousMode == UserMode) 00211 { 00212 /* FIXME: Handle no execute */ 00213 } 00214 break; 00215 } 00216 00217 /* Handle kernel-mode first, it's simpler */ 00218 if (PreviousMode == KernelMode) 00219 { 00220 /* Check if this is a first-chance exception */ 00221 if (FirstChance == TRUE) 00222 { 00223 /* Break into the debugger for the first time */ 00224 if (KiDebugRoutine(TrapFrame, 00225 ExceptionFrame, 00226 ExceptionRecord, 00227 &Context, 00228 PreviousMode, 00229 FALSE)) 00230 { 00231 /* Exception was handled */ 00232 goto Handled; 00233 } 00234 00235 /* If the Debugger couldn't handle it, dispatch the exception */ 00236 if (RtlDispatchException(ExceptionRecord, &Context)) goto Handled; 00237 } 00238 00239 /* This is a second-chance exception, only for the debugger */ 00240 if (KiDebugRoutine(TrapFrame, 00241 ExceptionFrame, 00242 ExceptionRecord, 00243 &Context, 00244 PreviousMode, 00245 TRUE)) 00246 { 00247 /* Exception was handled */ 00248 goto Handled; 00249 } 00250 00251 /* Third strike; you're out */ 00252 KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED, 00253 ExceptionRecord->ExceptionCode, 00254 (ULONG_PTR)ExceptionRecord->ExceptionAddress, 00255 (ULONG_PTR)TrapFrame, 00256 0); 00257 } 00258 else 00259 { 00260 /* FIXME: TODO */ 00261 /* 3rd strike, kill the process */ 00262 DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %lx\n", 00263 PsGetCurrentProcess()->ImageFileName, 00264 ExceptionRecord->ExceptionCode, 00265 ExceptionRecord->ExceptionAddress); 00266 00267 ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode); 00268 KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED, 00269 ExceptionRecord->ExceptionCode, 00270 (ULONG_PTR)ExceptionRecord->ExceptionAddress, 00271 (ULONG_PTR)TrapFrame, 00272 0); 00273 } 00274 00275 Handled: 00276 /* Convert the context back into Trap/Exception Frames */ 00277 KeContextToTrapFrame(&Context, 00278 ExceptionFrame, 00279 TrapFrame, 00280 Context.ContextFlags, 00281 PreviousMode); 00282 return; 00283 } Generated on Fri May 25 2012 04:34:54 for ReactOS by
1.7.6.1
|