Merge pull request #1870 from saper/langinfo_h
[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(MONO_SIGNAL_USE_SIGACTION)
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         MonoContext *ctx = (MonoContext *)sigctx;
188
189         mctx->gregs [AMD64_RAX] = ctx->gregs [AMD64_RAX];
190         mctx->gregs [AMD64_RBX] = ctx->gregs [AMD64_RBX];
191         mctx->gregs [AMD64_RCX] = ctx->gregs [AMD64_RCX];
192         mctx->gregs [AMD64_RDX] = ctx->gregs [AMD64_RDX];
193         mctx->gregs [AMD64_RBP] = ctx->gregs [AMD64_RBP];
194         mctx->gregs [AMD64_RSP] = ctx->gregs [AMD64_RSP];
195         mctx->gregs [AMD64_RSI] = ctx->gregs [AMD64_RSI];
196         mctx->gregs [AMD64_RDI] = ctx->gregs [AMD64_RDI];
197         mctx->gregs [AMD64_R8] = ctx->gregs [AMD64_R8];
198         mctx->gregs [AMD64_R9] = ctx->gregs [AMD64_R9];
199         mctx->gregs [AMD64_R10] = ctx->gregs [AMD64_R10];
200         mctx->gregs [AMD64_R11] = ctx->gregs [AMD64_R11];
201         mctx->gregs [AMD64_R12] = ctx->gregs [AMD64_R12];
202         mctx->gregs [AMD64_R13] = ctx->gregs [AMD64_R13];
203         mctx->gregs [AMD64_R14] = ctx->gregs [AMD64_R14];
204         mctx->gregs [AMD64_R15] = ctx->gregs [AMD64_R15];
205         mctx->gregs [AMD64_RIP] = ctx->gregs [AMD64_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->gregs [AMD64_RAX];
220         UCONTEXT_REG_RBX (ctx) = mctx->gregs [AMD64_RBX];
221         UCONTEXT_REG_RCX (ctx) = mctx->gregs [AMD64_RCX];
222         UCONTEXT_REG_RDX (ctx) = mctx->gregs [AMD64_RDX];
223         UCONTEXT_REG_RBP (ctx) = mctx->gregs [AMD64_RBP];
224         UCONTEXT_REG_RSP (ctx) = mctx->gregs [AMD64_RSP];
225         UCONTEXT_REG_RSI (ctx) = mctx->gregs [AMD64_RSI];
226         UCONTEXT_REG_RDI (ctx) = mctx->gregs [AMD64_RDI];
227         UCONTEXT_REG_R8 (ctx) = mctx->gregs [AMD64_R8];
228         UCONTEXT_REG_R9 (ctx) = mctx->gregs [AMD64_R9];
229         UCONTEXT_REG_R10 (ctx) = mctx->gregs [AMD64_R10];
230         UCONTEXT_REG_R11 (ctx) = mctx->gregs [AMD64_R11];
231         UCONTEXT_REG_R12 (ctx) = mctx->gregs [AMD64_R12];
232         UCONTEXT_REG_R13 (ctx) = mctx->gregs [AMD64_R13];
233         UCONTEXT_REG_R14 (ctx) = mctx->gregs [AMD64_R14];
234         UCONTEXT_REG_R15 (ctx) = mctx->gregs [AMD64_R15];
235         UCONTEXT_REG_RIP (ctx) = mctx->gregs [AMD64_RIP];
236 #elif defined(HOST_WIN32)
237         CONTEXT *context = (CONTEXT*)sigctx;
238
239         context->Rip = mctx->gregs [AMD64_RIP];
240         context->Rax = mctx->gregs [AMD64_RAX];
241         context->Rcx = mctx->gregs [AMD64_RCX];
242         context->Rdx = mctx->gregs [AMD64_RDX];
243         context->Rbx = mctx->gregs [AMD64_RBX];
244         context->Rsp = mctx->gregs [AMD64_RSP];
245         context->Rbp = mctx->gregs [AMD64_RBP];
246         context->Rsi = mctx->gregs [AMD64_RSI];
247         context->Rdi = mctx->gregs [AMD64_RDI];
248         context->R8 = mctx->gregs [AMD64_R8];
249         context->R9 = mctx->gregs [AMD64_R9];
250         context->R10 = mctx->gregs [AMD64_R10];
251         context->R11 = mctx->gregs [AMD64_R11];
252         context->R12 = mctx->gregs [AMD64_R12];
253         context->R13 = mctx->gregs [AMD64_R13];
254         context->R14 = mctx->gregs [AMD64_R14];
255         context->R15 = mctx->gregs [AMD64_R15];
256 #else
257         MonoContext *ctx = (MonoContext *)sigctx;
258
259         ctx->gregs [AMD64_RAX] = mctx->gregs [AMD64_RAX];
260         ctx->gregs [AMD64_RBX] = mctx->gregs [AMD64_RBX];
261         ctx->gregs [AMD64_RCX] = mctx->gregs [AMD64_RCX];
262         ctx->gregs [AMD64_RDX] = mctx->gregs [AMD64_RDX];
263         ctx->gregs [AMD64_RBP] = mctx->gregs [AMD64_RBP];
264         ctx->gregs [AMD64_RSP] = mctx->gregs [AMD64_RSP];
265         ctx->gregs [AMD64_RSI] = mctx->gregs [AMD64_RSI];
266         ctx->gregs [AMD64_RDI] = mctx->gregs [AMD64_RDI];
267         ctx->gregs [AMD64_R8] = mctx->gregs [AMD64_R8];
268         ctx->gregs [AMD64_R9] = mctx->gregs [AMD64_R9];
269         ctx->gregs [AMD64_R10] = mctx->gregs [AMD64_R10];
270         ctx->gregs [AMD64_R11] = mctx->gregs [AMD64_R11];
271         ctx->gregs [AMD64_R12] = mctx->gregs [AMD64_R12];
272         ctx->gregs [AMD64_R13] = mctx->gregs [AMD64_R13];
273         ctx->gregs [AMD64_R14] = mctx->gregs [AMD64_R14];
274         ctx->gregs [AMD64_R15] = mctx->gregs [AMD64_R15];
275         ctx->gregs [AMD64_RIP] = mctx->gregs [AMD64_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 #include <mono/mini/mini-ppc.h>
428
429 void
430 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
431 {
432         os_ucontext *uc = sigctx;
433
434         mctx->sc_ir = UCONTEXT_REG_NIP(uc);
435         mctx->sc_sp = UCONTEXT_REG_Rn(uc, 1);
436         memcpy (&mctx->regs, &UCONTEXT_REG_Rn(uc, 13), sizeof (mgreg_t) * MONO_SAVED_GREGS);
437         memcpy (&mctx->fregs, &UCONTEXT_REG_FPRn(uc, 14), sizeof (double) * MONO_SAVED_FREGS);
438 }
439
440 void
441 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
442 {
443         os_ucontext *uc = sigctx;
444
445         UCONTEXT_REG_NIP(uc) = mctx->sc_ir;
446         UCONTEXT_REG_Rn(uc, 1) = mctx->sc_sp;
447         memcpy (&UCONTEXT_REG_Rn(uc, 13), &mctx->regs, sizeof (mgreg_t) * MONO_SAVED_GREGS);
448         memcpy (&UCONTEXT_REG_FPRn(uc, 14), &mctx->fregs, sizeof (double) * MONO_SAVED_FREGS);
449 }
450
451 #endif /* #if defined(__i386__) */