First set of licensing changes
[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 #elif defined(HOST_WIN32)
174         CONTEXT *context = (CONTEXT*)sigctx;
175
176         mctx->gregs [AMD64_RIP] = context->Rip;
177         mctx->gregs [AMD64_RAX] = context->Rax;
178         mctx->gregs [AMD64_RCX] = context->Rcx;
179         mctx->gregs [AMD64_RDX] = context->Rdx;
180         mctx->gregs [AMD64_RBX] = context->Rbx;
181         mctx->gregs [AMD64_RSP] = context->Rsp;
182         mctx->gregs [AMD64_RBP] = context->Rbp;
183         mctx->gregs [AMD64_RSI] = context->Rsi;
184         mctx->gregs [AMD64_RDI] = context->Rdi;
185         mctx->gregs [AMD64_R8] = context->R8;
186         mctx->gregs [AMD64_R9] = context->R9;
187         mctx->gregs [AMD64_R10] = context->R10;
188         mctx->gregs [AMD64_R11] = context->R11;
189         mctx->gregs [AMD64_R12] = context->R12;
190         mctx->gregs [AMD64_R13] = context->R13;
191         mctx->gregs [AMD64_R14] = context->R14;
192         mctx->gregs [AMD64_R15] = context->R15;
193 #else
194         g_assert_not_reached ();
195 #endif
196 }
197
198 void
199 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
200 {
201 #if defined(__native_client__) || defined(__native_client_codegen__)
202   printf("WARNING: mono_arch_monoctx_to_sigctx() called!\n");
203 #endif
204
205 #ifdef MONO_CROSS_COMPILE
206         g_assert_not_reached ();
207 #elif defined(MONO_SIGNAL_USE_UCONTEXT_T)
208         ucontext_t *ctx = (ucontext_t*)sigctx;
209
210         UCONTEXT_REG_RAX (ctx) = mctx->gregs [AMD64_RAX];
211         UCONTEXT_REG_RBX (ctx) = mctx->gregs [AMD64_RBX];
212         UCONTEXT_REG_RCX (ctx) = mctx->gregs [AMD64_RCX];
213         UCONTEXT_REG_RDX (ctx) = mctx->gregs [AMD64_RDX];
214         UCONTEXT_REG_RBP (ctx) = mctx->gregs [AMD64_RBP];
215         UCONTEXT_REG_RSP (ctx) = mctx->gregs [AMD64_RSP];
216         UCONTEXT_REG_RSI (ctx) = mctx->gregs [AMD64_RSI];
217         UCONTEXT_REG_RDI (ctx) = mctx->gregs [AMD64_RDI];
218         UCONTEXT_REG_R8 (ctx) = mctx->gregs [AMD64_R8];
219         UCONTEXT_REG_R9 (ctx) = mctx->gregs [AMD64_R9];
220         UCONTEXT_REG_R10 (ctx) = mctx->gregs [AMD64_R10];
221         UCONTEXT_REG_R11 (ctx) = mctx->gregs [AMD64_R11];
222         UCONTEXT_REG_R12 (ctx) = mctx->gregs [AMD64_R12];
223         UCONTEXT_REG_R13 (ctx) = mctx->gregs [AMD64_R13];
224         UCONTEXT_REG_R14 (ctx) = mctx->gregs [AMD64_R14];
225         UCONTEXT_REG_R15 (ctx) = mctx->gregs [AMD64_R15];
226         UCONTEXT_REG_RIP (ctx) = mctx->gregs [AMD64_RIP];
227 #elif defined(HOST_WIN32)
228         CONTEXT *context = (CONTEXT*)sigctx;
229
230         context->Rip = mctx->gregs [AMD64_RIP];
231         context->Rax = mctx->gregs [AMD64_RAX];
232         context->Rcx = mctx->gregs [AMD64_RCX];
233         context->Rdx = mctx->gregs [AMD64_RDX];
234         context->Rbx = mctx->gregs [AMD64_RBX];
235         context->Rsp = mctx->gregs [AMD64_RSP];
236         context->Rbp = mctx->gregs [AMD64_RBP];
237         context->Rsi = mctx->gregs [AMD64_RSI];
238         context->Rdi = mctx->gregs [AMD64_RDI];
239         context->R8 = mctx->gregs [AMD64_R8];
240         context->R9 = mctx->gregs [AMD64_R9];
241         context->R10 = mctx->gregs [AMD64_R10];
242         context->R11 = mctx->gregs [AMD64_R11];
243         context->R12 = mctx->gregs [AMD64_R12];
244         context->R13 = mctx->gregs [AMD64_R13];
245         context->R14 = mctx->gregs [AMD64_R14];
246         context->R15 = mctx->gregs [AMD64_R15];
247 #else
248         g_assert_not_reached ();
249 #endif
250 }
251
252 #elif defined(__s390x__)
253
254 #include <mono/utils/mono-context.h>
255
256 /*------------------------------------------------------------------*/
257 /*                                                                  */
258 /* Name         - mono_arch_sigctx_to_monoctx.                      */
259 /*                                                                  */
260 /* Function     - Called from the signal handler to convert signal  */
261 /*                context to MonoContext.                           */
262 /*                                                                  */
263 /*------------------------------------------------------------------*/
264
265 void
266 mono_sigctx_to_monoctx (void *ctx, MonoContext *mctx)
267 {
268         memcpy (mctx, ctx, sizeof(MonoContext));
269 }
270
271 /*========================= End of Function ========================*/
272
273 /*------------------------------------------------------------------*/
274 /*                                                                  */
275 /* Name         - mono_arch_monoctx_to_sigctx.                      */
276 /*                                                                  */
277 /* Function     - Convert MonoContext structure to signal context.  */
278 /*                                                                  */
279 /*------------------------------------------------------------------*/
280
281 void
282 mono_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
283 {
284         memcpy (ctx, mctx, sizeof(MonoContext));
285 }
286
287 /*========================= End of Function ========================*/
288
289 #elif (defined(__arm__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM))
290
291 #include <mono/utils/mono-context.h>
292 #include <mono/arch/arm/arm-codegen.h>
293 #include <mono/arch/arm/arm-vfp-codegen.h>
294
295 void
296 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
297 {
298 #ifdef MONO_CROSS_COMPILE
299         g_assert_not_reached ();
300 #elif defined(__native_client__)
301         g_assert_not_reached ();
302 #else
303         arm_ucontext *my_uc = sigctx;
304
305         mctx->pc = UCONTEXT_REG_PC (my_uc);
306         mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (my_uc);
307         mctx->cpsr = UCONTEXT_REG_CPSR (my_uc);
308         memcpy (&mctx->regs, &UCONTEXT_REG_R0 (my_uc), sizeof (mgreg_t) * 16);
309 #ifdef UCONTEXT_REG_VFPREGS
310         memcpy (&mctx->fregs, UCONTEXT_REG_VFPREGS (my_uc), sizeof (double) * 16);
311 #endif
312 #endif
313 }
314
315 void
316 mono_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
317 {
318 #ifdef MONO_CROSS_COMPILE
319         g_assert_not_reached ();
320 #elif defined(__native_client__)
321         g_assert_not_reached ();
322 #else
323         arm_ucontext *my_uc = ctx;
324
325         UCONTEXT_REG_PC (my_uc) = mctx->pc;
326         UCONTEXT_REG_SP (my_uc) = mctx->regs [ARMREG_SP];
327         UCONTEXT_REG_CPSR (my_uc) = mctx->cpsr;
328         /* The upper registers are not guaranteed to be valid */
329         memcpy (&UCONTEXT_REG_R0 (my_uc), &mctx->regs, sizeof (mgreg_t) * 12);
330 #ifdef UCONTEXT_REG_VFPREGS
331         memcpy (UCONTEXT_REG_VFPREGS (my_uc), &mctx->fregs, sizeof (double) * 16);
332 #endif
333 #endif
334 }
335
336 #elif (defined(__aarch64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM64))
337
338 #include <mono/utils/mono-context.h>
339
340 void
341 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
342 {
343 #ifdef MONO_CROSS_COMPILE
344         g_assert_not_reached ();
345 #else
346         memcpy (mctx->regs, UCONTEXT_GREGS (sigctx), sizeof (mgreg_t) * 31);
347         mctx->pc = UCONTEXT_REG_PC (sigctx);
348         mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (sigctx);
349         /*
350          * We don't handle fp regs, this is not currrently a
351          * problem, since we don't allocate them globally.
352          */
353 #endif
354 }
355
356 void
357 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
358 {
359 #ifdef MONO_CROSS_COMPILE
360         g_assert_not_reached ();
361 #else
362         memcpy (UCONTEXT_GREGS (sigctx), mctx->regs, sizeof (mgreg_t) * 31);
363         UCONTEXT_REG_PC (sigctx) = mctx->pc;
364         UCONTEXT_REG_SP (sigctx) = mctx->regs [ARMREG_SP];
365 #endif
366 }
367
368 #elif (defined(__mips__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_MIPS))
369
370 #include <mono/utils/mono-context.h>
371 #include <mono/arch/mips/mips-codegen.h>
372
373 void
374 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
375 {
376         int i;
377
378         mctx->sc_pc = UCONTEXT_REG_PC (sigctx);
379         for (i = 0; i < 32; ++i) {
380                 mctx->sc_regs[i] = UCONTEXT_GREGS (sigctx) [i];
381                 mctx->sc_fpregs[i] = UCONTEXT_FPREGS (sigctx) [i];
382         }
383 }
384
385 void
386 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
387 {
388         int i;
389
390         UCONTEXT_REG_PC (sigctx) = mctx->sc_pc;
391         for (i = 0; i < 32; ++i) {
392                 UCONTEXT_GREGS (sigctx) [i] = mctx->sc_regs[i];
393                 UCONTEXT_FPREGS (sigctx) [i] = mctx->sc_fpregs[i];
394         }
395 }
396
397 #elif (((defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__)) && !defined(MONO_CROSS_COMPILE))) || (defined(TARGET_POWERPC))
398
399 #include <mono/utils/mono-context.h>
400 #include <mono/mini/mini-ppc.h>
401
402 void
403 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
404 {
405         os_ucontext *uc = sigctx;
406
407         mctx->sc_ir = UCONTEXT_REG_NIP(uc);
408         mctx->sc_sp = UCONTEXT_REG_Rn(uc, 1);
409         memcpy (&mctx->regs, &UCONTEXT_REG_Rn(uc, 13), sizeof (mgreg_t) * MONO_SAVED_GREGS);
410         memcpy (&mctx->fregs, &UCONTEXT_REG_FPRn(uc, 14), sizeof (double) * MONO_SAVED_FREGS);
411 }
412
413 void
414 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
415 {
416         os_ucontext *uc = sigctx;
417
418         UCONTEXT_REG_NIP(uc) = mctx->sc_ir;
419         UCONTEXT_REG_Rn(uc, 1) = mctx->sc_sp;
420         memcpy (&UCONTEXT_REG_Rn(uc, 13), &mctx->regs, sizeof (mgreg_t) * MONO_SAVED_GREGS);
421         memcpy (&UCONTEXT_REG_FPRn(uc, 14), &mctx->fregs, sizeof (double) * MONO_SAVED_FREGS);
422 }
423
424 #endif /* #if defined(__i386__) */