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