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