[System] Add new 'Mono.Security.Interface.MonoTlsProviderFactory' callback to let...
[mono.git] / mono / utils / mono-context.c
1 /*
2  * mono-context.c: plat independent machine state definitions
3  *
4  *
5  * Copyright (c) 2011 Novell, Inc (http://www.novell.com)
6  */
7
8 #include <mono/utils/mono-sigcontext.h>
9
10 #ifdef HAVE_UCONTEXT_H
11 #include <ucontext.h>
12 #endif
13
14 #if (defined(__i386__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_X86))
15
16 #include <mono/utils/mono-context.h>
17
18 #ifdef HOST_WIN32
19 #include <windows.h>
20 #endif
21
22 #ifdef __sun
23 #define REG_EAX EAX
24 #define REG_EBX EBX
25 #define REG_ECX ECX
26 #define REG_EDX EDX
27 #define REG_EBP EBP
28 #define REG_ESP ESP
29 #define REG_ESI ESI
30 #define REG_EDI EDI
31 #define REG_EIP EIP
32 #endif
33
34 void
35 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
36 {
37 #if defined (__native_client__) || defined (HOST_WATCHOS)
38         printf("WARNING: mono_arch_sigctx_to_monoctx() called!\n");
39         mctx->eax = 0xDEADBEEF;
40         mctx->ebx = 0xDEADBEEF;
41         mctx->ecx = 0xDEADBEEF;
42         mctx->edx = 0xDEADBEEF;
43         mctx->ebp = 0xDEADBEEF;
44         mctx->esp = 0xDEADBEEF;
45         mctx->esi = 0xDEADBEEF;
46         mctx->edi = 0xDEADBEEF;
47         mctx->eip = 0xDEADBEEF;
48 #elif MONO_CROSS_COMPILE
49         g_assert_not_reached ();
50 #elif defined(MONO_SIGNAL_USE_UCONTEXT_T)
51         ucontext_t *ctx = (ucontext_t*)sigctx;
52         
53         mctx->eax = UCONTEXT_REG_EAX (ctx);
54         mctx->ebx = UCONTEXT_REG_EBX (ctx);
55         mctx->ecx = UCONTEXT_REG_ECX (ctx);
56         mctx->edx = UCONTEXT_REG_EDX (ctx);
57         mctx->ebp = UCONTEXT_REG_EBP (ctx);
58         mctx->esp = UCONTEXT_REG_ESP (ctx);
59         mctx->esi = UCONTEXT_REG_ESI (ctx);
60         mctx->edi = UCONTEXT_REG_EDI (ctx);
61         mctx->eip = UCONTEXT_REG_EIP (ctx);
62 #elif defined(HOST_WIN32)
63         CONTEXT *context = (CONTEXT*)sigctx;
64
65         mctx->eip = context->Eip;
66         mctx->edi = context->Edi;
67         mctx->esi = context->Esi;
68         mctx->ebx = context->Ebx;
69         mctx->edx = context->Edx;
70         mctx->ecx = context->Ecx;
71         mctx->eax = context->Eax;
72         mctx->ebp = context->Ebp;
73         mctx->esp = context->Esp;
74 #else   
75         struct sigcontext *ctx = (struct sigcontext *)sigctx;
76
77         mctx->eax = ctx->SC_EAX;
78         mctx->ebx = ctx->SC_EBX;
79         mctx->ecx = ctx->SC_ECX;
80         mctx->edx = ctx->SC_EDX;
81         mctx->ebp = ctx->SC_EBP;
82         mctx->esp = ctx->SC_ESP;
83         mctx->esi = ctx->SC_ESI;
84         mctx->edi = ctx->SC_EDI;
85         mctx->eip = ctx->SC_EIP;
86 #endif /* if defined(__native_client__) */
87 }
88
89 void
90 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
91 {
92 #if defined(__native_client__) || defined(HOST_WATCHOS)
93         printf("WARNING: mono_arch_monoctx_to_sigctx() called!\n");
94 #elif MONO_CROSS_COMPILE
95         g_assert_not_reached ();
96 #elif defined(MONO_SIGNAL_USE_UCONTEXT_T)
97         ucontext_t *ctx = (ucontext_t*)sigctx;
98
99         UCONTEXT_REG_EAX (ctx) = mctx->eax;
100         UCONTEXT_REG_EBX (ctx) = mctx->ebx;
101         UCONTEXT_REG_ECX (ctx) = mctx->ecx;
102         UCONTEXT_REG_EDX (ctx) = mctx->edx;
103         UCONTEXT_REG_EBP (ctx) = mctx->ebp;
104         UCONTEXT_REG_ESP (ctx) = mctx->esp;
105         UCONTEXT_REG_ESI (ctx) = mctx->esi;
106         UCONTEXT_REG_EDI (ctx) = mctx->edi;
107         UCONTEXT_REG_EIP (ctx) = mctx->eip;
108 #elif defined(HOST_WIN32)
109         CONTEXT *context = (CONTEXT*)sigctx;
110
111         context->Eip = mctx->eip;
112         context->Edi = mctx->edi;
113         context->Esi = mctx->esi;
114         context->Ebx = mctx->ebx;
115         context->Edx = mctx->edx;
116         context->Ecx = mctx->ecx;
117         context->Eax = mctx->eax;
118         context->Ebp = mctx->ebp;
119         context->Esp = mctx->esp;
120 #else
121         struct sigcontext *ctx = (struct sigcontext *)sigctx;
122
123         ctx->SC_EAX = mctx->eax;
124         ctx->SC_EBX = mctx->ebx;
125         ctx->SC_ECX = mctx->ecx;
126         ctx->SC_EDX = mctx->edx;
127         ctx->SC_EBP = mctx->ebp;
128         ctx->SC_ESP = mctx->esp;
129         ctx->SC_ESI = mctx->esi;
130         ctx->SC_EDI = mctx->edi;
131         ctx->SC_EIP = mctx->eip;
132 #endif /* __native_client__ */
133 }
134
135 #elif (defined(__x86_64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_AMD64)) /* defined(__i386__) */
136
137 #include <mono/utils/mono-context.h>
138
139 #ifdef HOST_WIN32
140 #include <windows.h>
141 #endif
142
143 void
144 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
145 {
146 #if defined(__native_client_codegen__) || defined(__native_client__)
147         printf("WARNING: mono_arch_sigctx_to_monoctx() called!\n");
148 #endif
149
150 #ifdef MONO_CROSS_COMPILE
151         g_assert_not_reached ();
152 #elif defined(MONO_SIGNAL_USE_UCONTEXT_T)
153         ucontext_t *ctx = (ucontext_t*)sigctx;
154
155         mctx->gregs [AMD64_RAX] = UCONTEXT_REG_RAX (ctx);
156         mctx->gregs [AMD64_RBX] = UCONTEXT_REG_RBX (ctx);
157         mctx->gregs [AMD64_RCX] = UCONTEXT_REG_RCX (ctx);
158         mctx->gregs [AMD64_RDX] = UCONTEXT_REG_RDX (ctx);
159         mctx->gregs [AMD64_RBP] = UCONTEXT_REG_RBP (ctx);
160         mctx->gregs [AMD64_RSP] = UCONTEXT_REG_RSP (ctx);
161         mctx->gregs [AMD64_RSI] = UCONTEXT_REG_RSI (ctx);
162         mctx->gregs [AMD64_RDI] = UCONTEXT_REG_RDI (ctx);
163         mctx->gregs [AMD64_R8] = UCONTEXT_REG_R8 (ctx);
164         mctx->gregs [AMD64_R9] = UCONTEXT_REG_R9 (ctx);
165         mctx->gregs [AMD64_R10] = UCONTEXT_REG_R10 (ctx);
166         mctx->gregs [AMD64_R11] = UCONTEXT_REG_R11 (ctx);
167         mctx->gregs [AMD64_R12] = UCONTEXT_REG_R12 (ctx);
168         mctx->gregs [AMD64_R13] = UCONTEXT_REG_R13 (ctx);
169         mctx->gregs [AMD64_R14] = UCONTEXT_REG_R14 (ctx);
170         mctx->gregs [AMD64_R15] = UCONTEXT_REG_R15 (ctx);
171         mctx->gregs [AMD64_RIP] = UCONTEXT_REG_RIP (ctx);
172 #elif defined(HOST_WIN32)
173         CONTEXT *context = (CONTEXT*)sigctx;
174
175         mctx->gregs [AMD64_RIP] = context->Rip;
176         mctx->gregs [AMD64_RAX] = context->Rax;
177         mctx->gregs [AMD64_RCX] = context->Rcx;
178         mctx->gregs [AMD64_RDX] = context->Rdx;
179         mctx->gregs [AMD64_RBX] = context->Rbx;
180         mctx->gregs [AMD64_RSP] = context->Rsp;
181         mctx->gregs [AMD64_RBP] = context->Rbp;
182         mctx->gregs [AMD64_RSI] = context->Rsi;
183         mctx->gregs [AMD64_RDI] = context->Rdi;
184         mctx->gregs [AMD64_R8] = context->R8;
185         mctx->gregs [AMD64_R9] = context->R9;
186         mctx->gregs [AMD64_R10] = context->R10;
187         mctx->gregs [AMD64_R11] = context->R11;
188         mctx->gregs [AMD64_R12] = context->R12;
189         mctx->gregs [AMD64_R13] = context->R13;
190         mctx->gregs [AMD64_R14] = context->R14;
191         mctx->gregs [AMD64_R15] = context->R15;
192 #else
193         g_assert_not_reached ();
194 #endif
195 }
196
197 void
198 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
199 {
200 #if defined(__native_client__) || defined(__native_client_codegen__)
201   printf("WARNING: mono_arch_monoctx_to_sigctx() called!\n");
202 #endif
203
204 #ifdef MONO_CROSS_COMPILE
205         g_assert_not_reached ();
206 #elif defined(MONO_SIGNAL_USE_UCONTEXT_T)
207         ucontext_t *ctx = (ucontext_t*)sigctx;
208
209         UCONTEXT_REG_RAX (ctx) = mctx->gregs [AMD64_RAX];
210         UCONTEXT_REG_RBX (ctx) = mctx->gregs [AMD64_RBX];
211         UCONTEXT_REG_RCX (ctx) = mctx->gregs [AMD64_RCX];
212         UCONTEXT_REG_RDX (ctx) = mctx->gregs [AMD64_RDX];
213         UCONTEXT_REG_RBP (ctx) = mctx->gregs [AMD64_RBP];
214         UCONTEXT_REG_RSP (ctx) = mctx->gregs [AMD64_RSP];
215         UCONTEXT_REG_RSI (ctx) = mctx->gregs [AMD64_RSI];
216         UCONTEXT_REG_RDI (ctx) = mctx->gregs [AMD64_RDI];
217         UCONTEXT_REG_R8 (ctx) = mctx->gregs [AMD64_R8];
218         UCONTEXT_REG_R9 (ctx) = mctx->gregs [AMD64_R9];
219         UCONTEXT_REG_R10 (ctx) = mctx->gregs [AMD64_R10];
220         UCONTEXT_REG_R11 (ctx) = mctx->gregs [AMD64_R11];
221         UCONTEXT_REG_R12 (ctx) = mctx->gregs [AMD64_R12];
222         UCONTEXT_REG_R13 (ctx) = mctx->gregs [AMD64_R13];
223         UCONTEXT_REG_R14 (ctx) = mctx->gregs [AMD64_R14];
224         UCONTEXT_REG_R15 (ctx) = mctx->gregs [AMD64_R15];
225         UCONTEXT_REG_RIP (ctx) = mctx->gregs [AMD64_RIP];
226 #elif defined(HOST_WIN32)
227         CONTEXT *context = (CONTEXT*)sigctx;
228
229         context->Rip = mctx->gregs [AMD64_RIP];
230         context->Rax = mctx->gregs [AMD64_RAX];
231         context->Rcx = mctx->gregs [AMD64_RCX];
232         context->Rdx = mctx->gregs [AMD64_RDX];
233         context->Rbx = mctx->gregs [AMD64_RBX];
234         context->Rsp = mctx->gregs [AMD64_RSP];
235         context->Rbp = mctx->gregs [AMD64_RBP];
236         context->Rsi = mctx->gregs [AMD64_RSI];
237         context->Rdi = mctx->gregs [AMD64_RDI];
238         context->R8 = mctx->gregs [AMD64_R8];
239         context->R9 = mctx->gregs [AMD64_R9];
240         context->R10 = mctx->gregs [AMD64_R10];
241         context->R11 = mctx->gregs [AMD64_R11];
242         context->R12 = mctx->gregs [AMD64_R12];
243         context->R13 = mctx->gregs [AMD64_R13];
244         context->R14 = mctx->gregs [AMD64_R14];
245         context->R15 = mctx->gregs [AMD64_R15];
246 #else
247         g_assert_not_reached ();
248 #endif
249 }
250
251 #elif defined(__s390x__)
252
253 #include <mono/utils/mono-context.h>
254
255 /*------------------------------------------------------------------*/
256 /*                                                                  */
257 /* Name         - mono_arch_sigctx_to_monoctx.                      */
258 /*                                                                  */
259 /* Function     - Called from the signal handler to convert signal  */
260 /*                context to MonoContext.                           */
261 /*                                                                  */
262 /*------------------------------------------------------------------*/
263
264 void
265 mono_sigctx_to_monoctx (void *ctx, MonoContext *mctx)
266 {
267         memcpy (mctx, ctx, sizeof(MonoContext));
268 }
269
270 /*========================= End of Function ========================*/
271
272 /*------------------------------------------------------------------*/
273 /*                                                                  */
274 /* Name         - mono_arch_monoctx_to_sigctx.                      */
275 /*                                                                  */
276 /* Function     - Convert MonoContext structure to signal context.  */
277 /*                                                                  */
278 /*------------------------------------------------------------------*/
279
280 void
281 mono_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
282 {
283         memcpy (ctx, mctx, sizeof(MonoContext));
284 }
285
286 /*========================= End of Function ========================*/
287
288 #elif (defined(__arm__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM))
289
290 #include <mono/utils/mono-context.h>
291 #include <mono/arch/arm/arm-codegen.h>
292 #include <mono/arch/arm/arm-vfp-codegen.h>
293
294 void
295 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
296 {
297 #ifdef MONO_CROSS_COMPILE
298         g_assert_not_reached ();
299 #elif defined(__native_client__)
300         g_assert_not_reached ();
301 #else
302         arm_ucontext *my_uc = sigctx;
303
304         mctx->pc = UCONTEXT_REG_PC (my_uc);
305         mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (my_uc);
306         mctx->cpsr = UCONTEXT_REG_CPSR (my_uc);
307         memcpy (&mctx->regs, &UCONTEXT_REG_R0 (my_uc), sizeof (mgreg_t) * 16);
308 #ifdef UCONTEXT_REG_VFPREGS
309         memcpy (&mctx->fregs, UCONTEXT_REG_VFPREGS (my_uc), sizeof (double) * 16);
310 #endif
311 #endif
312 }
313
314 void
315 mono_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
316 {
317 #ifdef MONO_CROSS_COMPILE
318         g_assert_not_reached ();
319 #elif defined(__native_client__)
320         g_assert_not_reached ();
321 #else
322         arm_ucontext *my_uc = ctx;
323
324         UCONTEXT_REG_PC (my_uc) = mctx->pc;
325         UCONTEXT_REG_SP (my_uc) = mctx->regs [ARMREG_SP];
326         UCONTEXT_REG_CPSR (my_uc) = mctx->cpsr;
327         /* The upper registers are not guaranteed to be valid */
328         memcpy (&UCONTEXT_REG_R0 (my_uc), &mctx->regs, sizeof (mgreg_t) * 12);
329 #ifdef UCONTEXT_REG_VFPREGS
330         memcpy (UCONTEXT_REG_VFPREGS (my_uc), &mctx->fregs, sizeof (double) * 16);
331 #endif
332 #endif
333 }
334
335 #elif (defined(__aarch64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM64))
336
337 #include <mono/utils/mono-context.h>
338
339 void
340 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
341 {
342 #ifdef MONO_CROSS_COMPILE
343         g_assert_not_reached ();
344 #else
345         memcpy (mctx->regs, UCONTEXT_GREGS (sigctx), sizeof (mgreg_t) * 31);
346         mctx->pc = UCONTEXT_REG_PC (sigctx);
347         mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (sigctx);
348         /*
349          * We don't handle fp regs, this is not currrently a
350          * problem, since we don't allocate them globally.
351          */
352 #endif
353 }
354
355 void
356 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
357 {
358 #ifdef MONO_CROSS_COMPILE
359         g_assert_not_reached ();
360 #else
361         memcpy (UCONTEXT_GREGS (sigctx), mctx->regs, sizeof (mgreg_t) * 31);
362         UCONTEXT_REG_PC (sigctx) = mctx->pc;
363         UCONTEXT_REG_SP (sigctx) = mctx->regs [ARMREG_SP];
364 #endif
365 }
366
367 #elif (defined(__mips__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_MIPS))
368
369 #include <mono/utils/mono-context.h>
370 #include <mono/arch/mips/mips-codegen.h>
371
372 void
373 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
374 {
375         int i;
376
377         mctx->sc_pc = UCONTEXT_REG_PC (sigctx);
378         for (i = 0; i < 32; ++i) {
379                 mctx->sc_regs[i] = UCONTEXT_GREGS (sigctx) [i];
380                 mctx->sc_fpregs[i] = UCONTEXT_FPREGS (sigctx) [i];
381         }
382 }
383
384 void
385 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
386 {
387         int i;
388
389         UCONTEXT_REG_PC (sigctx) = mctx->sc_pc;
390         for (i = 0; i < 32; ++i) {
391                 UCONTEXT_GREGS (sigctx) [i] = mctx->sc_regs[i];
392                 UCONTEXT_FPREGS (sigctx) [i] = mctx->sc_fpregs[i];
393         }
394 }
395
396 #elif (((defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__)) && !defined(MONO_CROSS_COMPILE))) || (defined(TARGET_POWERPC))
397
398 #include <mono/utils/mono-context.h>
399 #include <mono/mini/mini-ppc.h>
400
401 void
402 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
403 {
404         os_ucontext *uc = sigctx;
405
406         mctx->sc_ir = UCONTEXT_REG_NIP(uc);
407         mctx->sc_sp = UCONTEXT_REG_Rn(uc, 1);
408         memcpy (&mctx->regs, &UCONTEXT_REG_Rn(uc, 13), sizeof (mgreg_t) * MONO_SAVED_GREGS);
409         memcpy (&mctx->fregs, &UCONTEXT_REG_FPRn(uc, 14), sizeof (double) * MONO_SAVED_FREGS);
410 }
411
412 void
413 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
414 {
415         os_ucontext *uc = sigctx;
416
417         UCONTEXT_REG_NIP(uc) = mctx->sc_ir;
418         UCONTEXT_REG_Rn(uc, 1) = mctx->sc_sp;
419         memcpy (&UCONTEXT_REG_Rn(uc, 13), &mctx->regs, sizeof (mgreg_t) * MONO_SAVED_GREGS);
420         memcpy (&UCONTEXT_REG_FPRn(uc, 14), &mctx->fregs, sizeof (double) * MONO_SAVED_FREGS);
421 }
422
423 #endif /* #if defined(__i386__) */