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