ReactOS  0.4.14-dev-297-g23e575c
exp.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: BSD - See COPYING.ARM in the top level directory
4  * FILE: ntoskrnl/ke/arm/exp.c
5  * PURPOSE: Implements exception helper routines for ARM machines
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* FUNCTIONS ******************************************************************/
16 
17 VOID
18 NTAPI
20  IN OUT PKEXCEPTION_FRAME ExceptionFrame,
21  IN OUT PKTRAP_FRAME TrapFrame,
22  IN ULONG ContextFlags,
24 {
25  KIRQL OldIrql;
26 
27  //
28  // Do this at APC_LEVEL
29  //
32 
33  //
34  // Start with the Control flags
35  //
36  if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
37  {
38  //
39  // So this basically means all the special stuff
40  //
41 
42  //
43  // ARM has register banks
44  //
45  TrapFrame->Sp = Context->Sp;
46  TrapFrame->Lr = Context->Lr;
47 
48  //
49  // The rest is already in the right mode
50  //
51  TrapFrame->Pc = Context->Pc;
52  TrapFrame->Cpsr = Context->Cpsr;
53  }
54 
55  //
56  // Now do the integers
57  //
58  if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
59  {
60  //
61  // Basically everything else but FPU
62  //
63  TrapFrame->R0 = Context->R0;
64  TrapFrame->R1 = Context->R1;
65  TrapFrame->R2 = Context->R2;
66  TrapFrame->R3 = Context->R3;
67  ExceptionFrame->R4 = Context->R4;
68  ExceptionFrame->R5 = Context->R5;
69  ExceptionFrame->R6 = Context->R6;
70  ExceptionFrame->R7 = Context->R7;
71  ExceptionFrame->R8 = Context->R8;
72  ExceptionFrame->R9 = Context->R9;
73  ExceptionFrame->R10 = Context->R10;
74  ExceptionFrame->R11 = Context->R11;
75  TrapFrame->R12 = Context->R12;
76  }
77 
78  //
79  // Restore IRQL
80  //
82 }
83 
84 VOID
85 NTAPI
87  IN PKEXCEPTION_FRAME ExceptionFrame,
89 {
90  KIRQL OldIrql;
91 
92  //
93  // Do this at APC_LEVEL
94  //
97 
98  //
99  // Start with the Control flags
100  //
101  if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
102  {
103  //
104  // So this basically means all the special stuff
105  //
106 
107  //
108  // ARM has register banks
109  //
110  Context->Sp = TrapFrame->Sp;
111  Context->Lr = TrapFrame->Lr;
112 
113  //
114  // The rest is already in the right mode
115  //
116  Context->Pc = TrapFrame->Pc;
117  Context->Cpsr = TrapFrame->Cpsr;
118  }
119 
120  //
121  // Now do the integers
122  //
123  if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
124  {
125  //
126  // Basically everything else but FPU
127  //
128  Context->R0 = TrapFrame->R0;
129  Context->R1 = TrapFrame->R1;
130  Context->R2 = TrapFrame->R2;
131  Context->R3 = TrapFrame->R3;
132  Context->R4 = ExceptionFrame->R4;
133  Context->R5 = ExceptionFrame->R5;
134  Context->R6 = ExceptionFrame->R6;
135  Context->R7 = ExceptionFrame->R7;
136  Context->R8 = ExceptionFrame->R8;
137  Context->R0 = ExceptionFrame->R9;
138  Context->R10 = ExceptionFrame->R10;
139  Context->R11 = ExceptionFrame->R11;
140  Context->R12 = TrapFrame->R12;
141  }
142 
143  //
144  // Restore IRQL
145  //
147 }
148 
149 VOID
150 NTAPI
152  IN PKEXCEPTION_FRAME ExceptionFrame,
153  IN PKTRAP_FRAME TrapFrame,
155  IN BOOLEAN FirstChance)
156 {
158 
159  /* Increase number of Exception Dispatches */
160  KeGetCurrentPrcb()->KeExceptionDispatchCount++;
161 
162  /* Set the context flags */
163  Context.ContextFlags = CONTEXT_FULL;
164 
165  /* Check if User Mode or if the kernel debugger is enabled */
166  if ((PreviousMode == UserMode) || (KeGetPcr()->KdVersionBlock))
167  {
168  /* FIXME-V6: VFP Support */
169  }
170 
171  /* Get a Context */
172  KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
173 
174  /* Look at our exception code */
175  switch (ExceptionRecord->ExceptionCode)
176  {
177  /* Breakpoint */
178  case STATUS_BREAKPOINT:
179 
180  /* Decrement PC by four */
181  Context.Pc -= sizeof(ULONG);
182  break;
183 
184  /* Internal exception */
186 
187  /* Set correct code */
188  ExceptionRecord->ExceptionCode = STATUS_ACCESS_VIOLATION;
189  if (PreviousMode == UserMode)
190  {
191  /* FIXME: Handle no execute */
192  }
193  break;
194  }
195 
196  /* Handle kernel-mode first, it's simpler */
197  if (PreviousMode == KernelMode)
198  {
199  /* Check if this is a first-chance exception */
200  if (FirstChance != FALSE)
201  {
202  /* Break into the debugger for the first time */
203  if (KiDebugRoutine(TrapFrame,
204  ExceptionFrame,
205  ExceptionRecord,
206  &Context,
207  PreviousMode,
208  FALSE))
209  {
210  /* Exception was handled */
211  goto Handled;
212  }
213 
214  /* If the Debugger couldn't handle it, dispatch the exception */
215  if (RtlDispatchException(ExceptionRecord, &Context)) goto Handled;
216  }
217 
218  /* This is a second-chance exception, only for the debugger */
219  if (KiDebugRoutine(TrapFrame,
220  ExceptionFrame,
221  ExceptionRecord,
222  &Context,
223  PreviousMode,
224  TRUE))
225  {
226  /* Exception was handled */
227  goto Handled;
228  }
229 
230  /* Third strike; you're out */
231  KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
232  ExceptionRecord->ExceptionCode,
233  (ULONG_PTR)ExceptionRecord->ExceptionAddress,
234  (ULONG_PTR)TrapFrame,
235  0);
236  }
237  else
238  {
239  /* FIXME: TODO */
240  /* 3rd strike, kill the process */
241  DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %lx\n",
242  PsGetCurrentProcess()->ImageFileName,
243  ExceptionRecord->ExceptionCode,
244  ExceptionRecord->ExceptionAddress);
245 
246  ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode);
247  KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
248  ExceptionRecord->ExceptionCode,
249  (ULONG_PTR)ExceptionRecord->ExceptionAddress,
250  (ULONG_PTR)TrapFrame,
251  0);
252  }
253 
254 Handled:
255  /* Convert the context back into Trap/Exception Frames */
257  ExceptionFrame,
258  TrapFrame,
259  Context.ContextFlags,
260  PreviousMode);
261  return;
262 }
263 
264 NTSTATUS
265 NTAPI
268 {
269  ASSERT(FALSE);
270  return STATUS_NOT_IMPLEMENTED;
271 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1782
#define IN
Definition: typedefs.h:38
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
DBGKD_GET_VERSION64 KdVersionBlock
Definition: kddata.c:371
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
PKDEBUG_ROUTINE KiDebugRoutine
Definition: kdmain.c:489
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
#define CONTEXT_FULL
Definition: compat.h:270
#define KeGetPcr()
Definition: ke.h:25
uint32_t ULONG_PTR
Definition: typedefs.h:63
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: exp.c:86
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char BOOLEAN
#define STATUS_BREAKPOINT
Definition: ntstatus.h:172
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSYSAPI BOOLEAN NTAPI RtlDispatchException(_In_ PEXCEPTION_RECORD ExceptionRecord, _In_ PCONTEXT Context)
Definition: except.c:34
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define CONTEXT_CONTROL
Definition: compat.h:265
_In_ BOOLEAN Handled
Definition: ketypes.h:337
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define _In_
Definition: no_sal2.h:204
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI KeRaiseUserException(_In_ NTSTATUS ExceptionCode)
Definition: exp.c:266
VOID NTAPI KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN FirstChance)
Definition: exp.c:151
#define OUT
Definition: typedefs.h:39
struct tagContext Context
Definition: acpixf.h:1024
unsigned int ULONG
Definition: retypes.h:1
#define APC_LEVEL
Definition: env_spec_w32.h:695
VOID NTAPI KeContextToTrapFrame(IN PCONTEXT Context, IN OUT PKEXCEPTION_FRAME ExceptionFrame, IN OUT PKTRAP_FRAME TrapFrame, IN ULONG ContextFlags, IN KPROCESSOR_MODE PreviousMode)
Definition: exp.c:19
#define KI_EXCEPTION_ACCESS_VIOLATION
Definition: ketypes.h:177
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:107
#define CONTEXT_INTEGER
Definition: compat.h:266