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