ReactOS  r76032
context.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * PURPOSE: CONTEXT related functions
5  * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
6  */
7 
8 /* INCLUDES ******************************************************************/
9 
10 #include <ntoskrnl.h>
11 
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  /* Make sure we have an amd64 context, then remove the flag */
28  ASSERT(ContextFlags & CONTEXT_AMD64);
29  ContextFlags &= ~CONTEXT_AMD64;
30 
31  /* Do this at APC_LEVEL */
32  OldIrql = KeGetCurrentIrql();
33  if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
34 
35  /* Handle integer registers */
36  if (ContextFlags & CONTEXT_INTEGER)
37  {
38  TrapFrame->Rax = Context->Rax;
39  TrapFrame->Rbx = Context->Rbx;
40  TrapFrame->Rcx = Context->Rcx;
41  TrapFrame->Rdx = Context->Rdx;
42  TrapFrame->Rsi = Context->Rsi;
43  TrapFrame->Rdi = Context->Rdi;
44  TrapFrame->Rbp = Context->Rbp;
45  TrapFrame->R8 = Context->R8;
46  TrapFrame->R9 = Context->R9;
47  TrapFrame->R10 = Context->R10;
48  TrapFrame->R11 = Context->R11;
49  if (ExceptionFrame)
50  {
51  ExceptionFrame->R12 = Context->R12;
52  ExceptionFrame->R13 = Context->R13;
53  ExceptionFrame->R14 = Context->R14;
54  ExceptionFrame->R15 = Context->R15;
55  }
56  }
57 
58  /* Handle floating point registers */
59  if ((ContextFlags & CONTEXT_FLOATING_POINT) &&
60  (Context->SegCs & MODE_MASK))
61  {
62  TrapFrame->Xmm0 = Context->Xmm0;
63  TrapFrame->Xmm1 = Context->Xmm1;
64  TrapFrame->Xmm2 = Context->Xmm2;
65  TrapFrame->Xmm3 = Context->Xmm3;
66  TrapFrame->Xmm4 = Context->Xmm4;
67  TrapFrame->Xmm5 = Context->Xmm5;
68  if (ExceptionFrame)
69  {
70  ExceptionFrame->Xmm6 = Context->Xmm6;
71  ExceptionFrame->Xmm7 = Context->Xmm7;
72  ExceptionFrame->Xmm8 = Context->Xmm8;
73  ExceptionFrame->Xmm9 = Context->Xmm9;
74  ExceptionFrame->Xmm10 = Context->Xmm10;
75  ExceptionFrame->Xmm11 = Context->Xmm11;
76  ExceptionFrame->Xmm12 = Context->Xmm12;
77  ExceptionFrame->Xmm13 = Context->Xmm13;
78  ExceptionFrame->Xmm14 = Context->Xmm14;
79  ExceptionFrame->Xmm15 = Context->Xmm15;
80  }
81  }
82 
83  /* Handle control registers */
84  if (ContextFlags & CONTEXT_CONTROL)
85  {
86  /* Check if this was a Kernel Trap */
87  if (Context->SegCs == KGDT64_R0_CODE)
88  {
89  /* Set valid selectors */
90  TrapFrame->SegCs = KGDT64_R0_CODE;
91  TrapFrame->SegSs = KGDT64_R0_DATA;
92  }
93  else
94  {
95  /* Copy selectors */
96  TrapFrame->SegCs = Context->SegCs;
97  TrapFrame->SegSs = Context->SegSs;
98  }
99 
100  /* RIP, RSP, EFLAGS */
101  TrapFrame->Rip = Context->Rip;
102  TrapFrame->Rsp = Context->Rsp;
103  TrapFrame->EFlags = Context->EFlags;
104  }
105 
106  /* Handle segment selectors */
107  if (ContextFlags & CONTEXT_SEGMENTS)
108  {
109  /* Check if this was a Kernel Trap */
110  if (Context->SegCs == KGDT64_R0_CODE)
111  {
112  /* Set valid selectors */
113  TrapFrame->SegDs = KGDT64_R3_DATA | RPL_MASK;
114  TrapFrame->SegEs = KGDT64_R3_DATA | RPL_MASK;
115  TrapFrame->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
116  TrapFrame->SegGs = KGDT64_R3_DATA | RPL_MASK;
117  }
118  else
119  {
120  /* Copy selectors */
121  TrapFrame->SegDs = Context->SegDs;
122  TrapFrame->SegEs = Context->SegEs;
123  TrapFrame->SegFs = Context->SegFs;
124  TrapFrame->SegGs = Context->SegGs;
125  }
126  }
127 
128  /* Handle debug registers */
129  if (ContextFlags & CONTEXT_DEBUG_REGISTERS)
130  {
131  /* Copy the debug registers */
132  TrapFrame->Dr0 = Context->Dr0;
133  TrapFrame->Dr1 = Context->Dr1;
134  TrapFrame->Dr2 = Context->Dr2;
135  TrapFrame->Dr3 = Context->Dr3;
136  TrapFrame->Dr6 = Context->Dr6;
137  TrapFrame->Dr7 = Context->Dr7;
138  }
139 
140  /* Restore IRQL */
141  if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
142 }
143 
144 VOID
145 NTAPI
147  IN PKEXCEPTION_FRAME ExceptionFrame,
149 {
150  KIRQL OldIrql;
151 
152  /* Do this at APC_LEVEL */
153  OldIrql = KeGetCurrentIrql();
154  if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
155 
156  /* Handle integer registers */
157  if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
158  {
159  Context->Rax = TrapFrame->Rax;
160  Context->Rbx = TrapFrame->Rbx;
161  Context->Rcx = TrapFrame->Rcx;
162  Context->Rdx = TrapFrame->Rdx;
163  Context->Rsi = TrapFrame->Rsi;
164  Context->Rdi = TrapFrame->Rdi;
165  Context->Rbp = TrapFrame->Rbp;
166  Context->R8 = TrapFrame->R8;
167  Context->R9 = TrapFrame->R9;
168  Context->R10 = TrapFrame->R10;
169  Context->R11 = TrapFrame->R11;
170 
171  if (ExceptionFrame)
172  {
173  Context->R12 = ExceptionFrame->R12;
174  Context->R13 = ExceptionFrame->R13;
175  Context->R14 = ExceptionFrame->R14;
176  Context->R15 = ExceptionFrame->R15;
177  }
178  }
179 
180  /* Handle floating point registers */
181  if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) ==
182  CONTEXT_FLOATING_POINT) && (TrapFrame->SegCs & MODE_MASK))
183  {
184  Context->Xmm0 = TrapFrame->Xmm0;
185  Context->Xmm1 = TrapFrame->Xmm1;
186  Context->Xmm2 = TrapFrame->Xmm2;
187  Context->Xmm3 = TrapFrame->Xmm3;
188  Context->Xmm4 = TrapFrame->Xmm4;
189  Context->Xmm5 = TrapFrame->Xmm5;
190  if (ExceptionFrame)
191  {
192  Context->Xmm6 = ExceptionFrame->Xmm6;
193  Context->Xmm7 = ExceptionFrame->Xmm7;
194  Context->Xmm8 = ExceptionFrame->Xmm8;
195  Context->Xmm9 = ExceptionFrame->Xmm9;
196  Context->Xmm10 = ExceptionFrame->Xmm10;
197  Context->Xmm11 = ExceptionFrame->Xmm11;
198  Context->Xmm12 = ExceptionFrame->Xmm12;
199  Context->Xmm13 = ExceptionFrame->Xmm13;
200  Context->Xmm14 = ExceptionFrame->Xmm14;
201  Context->Xmm15 = ExceptionFrame->Xmm15;
202  }
203  }
204 
205  /* Handle control registers */
206  if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
207  {
208  /* Check if this was a Kernel Trap */
209  if (TrapFrame->SegCs == KGDT64_R0_CODE)
210  {
211  /* Set valid selectors */
212  Context->SegCs = KGDT64_R0_CODE;
213  Context->SegSs = KGDT64_R0_DATA;
214  }
215  else
216  {
217  /* Copy selectors */
218  Context->SegCs = TrapFrame->SegCs;
219  Context->SegSs = TrapFrame->SegSs;
220  }
221 
222  /* Copy RIP, RSP, EFLAGS */
223  Context->Rip = TrapFrame->Rip;
224  Context->Rsp = TrapFrame->Rsp;
225  Context->EFlags = TrapFrame->EFlags;
226  }
227 
228  /* Handle segment selectors */
229  if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
230  {
231  /* Check if this was a Kernel Trap */
232  if (TrapFrame->SegCs == KGDT64_R0_CODE)
233  {
234  /* Set valid selectors */
235  Context->SegDs = KGDT64_R3_DATA | RPL_MASK;
236  Context->SegEs = KGDT64_R3_DATA | RPL_MASK;
237  Context->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
238  Context->SegGs = KGDT64_R3_DATA | RPL_MASK;
239  }
240  else
241  {
242  /* Copy selectors */
243  Context->SegDs = TrapFrame->SegDs;
244  Context->SegEs = TrapFrame->SegEs;
245  Context->SegFs = TrapFrame->SegFs;
246  Context->SegGs = TrapFrame->SegGs;
247  }
248  }
249 
250  /* Handle debug registers */
251  if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
253  {
254  /* Copy the debug registers */
255  Context->Dr0 = TrapFrame->Dr0;
256  Context->Dr1 = TrapFrame->Dr1;
257  Context->Dr2 = TrapFrame->Dr2;
258  Context->Dr3 = TrapFrame->Dr3;
259  Context->Dr6 = TrapFrame->Dr6;
260  Context->Dr7 = TrapFrame->Dr7;
261  }
262 
263  /* Restore IRQL */
264  if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
265 }
266 
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define IN
Definition: typedefs.h:38
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define MODE_MASK
Definition: orders.h:326
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define KGDT64_R3_CMTEB
Definition: ketypes.h:78
VOID NTAPI KeContextToTrapFrame(IN PCONTEXT Context, IN OUT PKEXCEPTION_FRAME ExceptionFrame, IN OUT PKTRAP_FRAME TrapFrame, IN ULONG ContextFlags, IN KPROCESSOR_MODE PreviousMode)
Definition: context.c:19
#define CONTEXT_AMD64
#define CONTEXT_SEGMENTS
Definition: nt_native.h:1371
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define KGDT64_R3_DATA
Definition: ketypes.h:75
#define RPL_MASK
Definition: ketypes.h:69
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define CONTEXT_CONTROL
Definition: compat.h:265
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define KGDT64_R0_CODE
Definition: ketypes.h:72
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: context.c:146
#define CONTEXT_FLOATING_POINT
Definition: compat.h:267
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
#define KGDT64_R0_DATA
Definition: ketypes.h:73
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define CONTEXT_INTEGER
Definition: compat.h:266
#define CONTEXT_DEBUG_REGISTERS
Definition: compat.h:268