2 * mono-context.c: plat independent machine state definitions
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.
9 #include <mono/utils/mono-sigcontext.h>
11 #ifdef HAVE_UCONTEXT_H
15 #if (defined(__i386__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_X86))
17 #include <mono/utils/mono-context.h>
36 mono_sigctx_to_monoctx (void *sigctx
, MonoContext
*mctx
)
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
;
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
;
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
;
76 struct sigcontext
*ctx
= (struct sigcontext
*)sigctx
;
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__) */
91 mono_monoctx_to_sigctx (MonoContext
*mctx
, void *sigctx
)
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
;
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
;
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
;
122 struct sigcontext
*ctx
= (struct sigcontext
*)sigctx
;
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__ */
136 #elif (defined(__x86_64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_AMD64)) /* defined(__i386__) */
138 #include <mono/utils/mono-context.h>
145 mono_sigctx_to_monoctx (void *sigctx
, MonoContext
*mctx
)
147 #if defined(__native_client_codegen__) || defined(__native_client__)
148 printf("WARNING: mono_arch_sigctx_to_monoctx() called!\n");
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
;
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
);
174 #ifdef UCONTEXT_REG_XMM
175 mctx
->fregs
[0] = UCONTEXT_REG_XMM0 (ctx
);
176 mctx
->fregs
[1] = UCONTEXT_REG_XMM1 (ctx
);
177 mctx
->fregs
[2] = UCONTEXT_REG_XMM2 (ctx
);
178 mctx
->fregs
[3] = UCONTEXT_REG_XMM3 (ctx
);
179 mctx
->fregs
[4] = UCONTEXT_REG_XMM4 (ctx
);
180 mctx
->fregs
[5] = UCONTEXT_REG_XMM5 (ctx
);
181 mctx
->fregs
[6] = UCONTEXT_REG_XMM6 (ctx
);
182 mctx
->fregs
[7] = UCONTEXT_REG_XMM7 (ctx
);
183 mctx
->fregs
[8] = UCONTEXT_REG_XMM8 (ctx
);
184 mctx
->fregs
[9] = UCONTEXT_REG_XMM9 (ctx
);
185 mctx
->fregs
[10] = UCONTEXT_REG_XMM10 (ctx
);
186 mctx
->fregs
[11] = UCONTEXT_REG_XMM11 (ctx
);
187 mctx
->fregs
[12] = UCONTEXT_REG_XMM12 (ctx
);
188 mctx
->fregs
[13] = UCONTEXT_REG_XMM13 (ctx
);
189 mctx
->fregs
[14] = UCONTEXT_REG_XMM14 (ctx
);
190 mctx
->fregs
[15] = UCONTEXT_REG_XMM15 (ctx
);
193 #elif defined(HOST_WIN32)
194 CONTEXT
*context
= (CONTEXT
*)sigctx
;
196 mctx
->gregs
[AMD64_RIP
] = context
->Rip
;
197 mctx
->gregs
[AMD64_RAX
] = context
->Rax
;
198 mctx
->gregs
[AMD64_RCX
] = context
->Rcx
;
199 mctx
->gregs
[AMD64_RDX
] = context
->Rdx
;
200 mctx
->gregs
[AMD64_RBX
] = context
->Rbx
;
201 mctx
->gregs
[AMD64_RSP
] = context
->Rsp
;
202 mctx
->gregs
[AMD64_RBP
] = context
->Rbp
;
203 mctx
->gregs
[AMD64_RSI
] = context
->Rsi
;
204 mctx
->gregs
[AMD64_RDI
] = context
->Rdi
;
205 mctx
->gregs
[AMD64_R8
] = context
->R8
;
206 mctx
->gregs
[AMD64_R9
] = context
->R9
;
207 mctx
->gregs
[AMD64_R10
] = context
->R10
;
208 mctx
->gregs
[AMD64_R11
] = context
->R11
;
209 mctx
->gregs
[AMD64_R12
] = context
->R12
;
210 mctx
->gregs
[AMD64_R13
] = context
->R13
;
211 mctx
->gregs
[AMD64_R14
] = context
->R14
;
212 mctx
->gregs
[AMD64_R15
] = context
->R15
;
214 g_assert_not_reached ();
219 mono_monoctx_to_sigctx (MonoContext
*mctx
, void *sigctx
)
221 #if defined(__native_client__) || defined(__native_client_codegen__)
222 printf("WARNING: mono_arch_monoctx_to_sigctx() called!\n");
225 #ifdef MONO_CROSS_COMPILE
226 g_assert_not_reached ();
227 #elif defined(MONO_SIGNAL_USE_UCONTEXT_T)
228 ucontext_t
*ctx
= (ucontext_t
*)sigctx
;
230 UCONTEXT_REG_RAX (ctx
) = mctx
->gregs
[AMD64_RAX
];
231 UCONTEXT_REG_RBX (ctx
) = mctx
->gregs
[AMD64_RBX
];
232 UCONTEXT_REG_RCX (ctx
) = mctx
->gregs
[AMD64_RCX
];
233 UCONTEXT_REG_RDX (ctx
) = mctx
->gregs
[AMD64_RDX
];
234 UCONTEXT_REG_RBP (ctx
) = mctx
->gregs
[AMD64_RBP
];
235 UCONTEXT_REG_RSP (ctx
) = mctx
->gregs
[AMD64_RSP
];
236 UCONTEXT_REG_RSI (ctx
) = mctx
->gregs
[AMD64_RSI
];
237 UCONTEXT_REG_RDI (ctx
) = mctx
->gregs
[AMD64_RDI
];
238 UCONTEXT_REG_R8 (ctx
) = mctx
->gregs
[AMD64_R8
];
239 UCONTEXT_REG_R9 (ctx
) = mctx
->gregs
[AMD64_R9
];
240 UCONTEXT_REG_R10 (ctx
) = mctx
->gregs
[AMD64_R10
];
241 UCONTEXT_REG_R11 (ctx
) = mctx
->gregs
[AMD64_R11
];
242 UCONTEXT_REG_R12 (ctx
) = mctx
->gregs
[AMD64_R12
];
243 UCONTEXT_REG_R13 (ctx
) = mctx
->gregs
[AMD64_R13
];
244 UCONTEXT_REG_R14 (ctx
) = mctx
->gregs
[AMD64_R14
];
245 UCONTEXT_REG_R15 (ctx
) = mctx
->gregs
[AMD64_R15
];
246 UCONTEXT_REG_RIP (ctx
) = mctx
->gregs
[AMD64_RIP
];
248 #ifdef UCONTEXT_REG_XMM
249 UCONTEXT_REG_XMM0 (ctx
) = mctx
->fregs
[0];
250 UCONTEXT_REG_XMM1 (ctx
) = mctx
->fregs
[1];
251 UCONTEXT_REG_XMM2 (ctx
) = mctx
->fregs
[2];
252 UCONTEXT_REG_XMM3 (ctx
) = mctx
->fregs
[3];
253 UCONTEXT_REG_XMM4 (ctx
) = mctx
->fregs
[4];
254 UCONTEXT_REG_XMM5 (ctx
) = mctx
->fregs
[5];
255 UCONTEXT_REG_XMM6 (ctx
) = mctx
->fregs
[6];
256 UCONTEXT_REG_XMM7 (ctx
) = mctx
->fregs
[7];
257 UCONTEXT_REG_XMM8 (ctx
) = mctx
->fregs
[8];
258 UCONTEXT_REG_XMM9 (ctx
) = mctx
->fregs
[9];
259 UCONTEXT_REG_XMM10 (ctx
) = mctx
->fregs
[10];
260 UCONTEXT_REG_XMM11 (ctx
) = mctx
->fregs
[11];
261 UCONTEXT_REG_XMM12 (ctx
) = mctx
->fregs
[12];
262 UCONTEXT_REG_XMM13 (ctx
) = mctx
->fregs
[13];
263 UCONTEXT_REG_XMM14 (ctx
) = mctx
->fregs
[14];
264 UCONTEXT_REG_XMM15 (ctx
) = mctx
->fregs
[15];
267 #elif defined(HOST_WIN32)
268 CONTEXT
*context
= (CONTEXT
*)sigctx
;
270 context
->Rip
= mctx
->gregs
[AMD64_RIP
];
271 context
->Rax
= mctx
->gregs
[AMD64_RAX
];
272 context
->Rcx
= mctx
->gregs
[AMD64_RCX
];
273 context
->Rdx
= mctx
->gregs
[AMD64_RDX
];
274 context
->Rbx
= mctx
->gregs
[AMD64_RBX
];
275 context
->Rsp
= mctx
->gregs
[AMD64_RSP
];
276 context
->Rbp
= mctx
->gregs
[AMD64_RBP
];
277 context
->Rsi
= mctx
->gregs
[AMD64_RSI
];
278 context
->Rdi
= mctx
->gregs
[AMD64_RDI
];
279 context
->R8
= mctx
->gregs
[AMD64_R8
];
280 context
->R9
= mctx
->gregs
[AMD64_R9
];
281 context
->R10
= mctx
->gregs
[AMD64_R10
];
282 context
->R11
= mctx
->gregs
[AMD64_R11
];
283 context
->R12
= mctx
->gregs
[AMD64_R12
];
284 context
->R13
= mctx
->gregs
[AMD64_R13
];
285 context
->R14
= mctx
->gregs
[AMD64_R14
];
286 context
->R15
= mctx
->gregs
[AMD64_R15
];
288 g_assert_not_reached ();
292 #elif defined(__s390x__)
294 #include <mono/utils/mono-context.h>
296 /*------------------------------------------------------------------*/
298 /* Name - mono_arch_sigctx_to_monoctx. */
300 /* Function - Called from the signal handler to convert signal */
301 /* context to MonoContext. */
303 /*------------------------------------------------------------------*/
306 mono_sigctx_to_monoctx (void *ctx
, MonoContext
*mctx
)
308 memcpy (mctx
, ctx
, sizeof(MonoContext
));
311 /*========================= End of Function ========================*/
313 /*------------------------------------------------------------------*/
315 /* Name - mono_arch_monoctx_to_sigctx. */
317 /* Function - Convert MonoContext structure to signal context. */
319 /*------------------------------------------------------------------*/
322 mono_monoctx_to_sigctx (MonoContext
*mctx
, void *ctx
)
324 memcpy (ctx
, mctx
, sizeof(MonoContext
));
327 /*========================= End of Function ========================*/
329 #elif (defined(__arm__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM))
331 #include <mono/utils/mono-context.h>
332 #include <mono/arch/arm/arm-codegen.h>
333 #include <mono/arch/arm/arm-vfp-codegen.h>
336 mono_sigctx_to_monoctx (void *sigctx
, MonoContext
*mctx
)
338 #ifdef MONO_CROSS_COMPILE
339 g_assert_not_reached ();
340 #elif defined(__native_client__)
341 g_assert_not_reached ();
343 arm_ucontext
*my_uc
= sigctx
;
345 mctx
->pc
= UCONTEXT_REG_PC (my_uc
);
346 mctx
->regs
[ARMREG_SP
] = UCONTEXT_REG_SP (my_uc
);
347 mctx
->cpsr
= UCONTEXT_REG_CPSR (my_uc
);
348 memcpy (&mctx
->regs
, &UCONTEXT_REG_R0 (my_uc
), sizeof (mgreg_t
) * 16);
349 #ifdef UCONTEXT_REG_VFPREGS
350 memcpy (&mctx
->fregs
, UCONTEXT_REG_VFPREGS (my_uc
), sizeof (double) * 16);
356 mono_monoctx_to_sigctx (MonoContext
*mctx
, void *ctx
)
358 #ifdef MONO_CROSS_COMPILE
359 g_assert_not_reached ();
360 #elif defined(__native_client__)
361 g_assert_not_reached ();
363 arm_ucontext
*my_uc
= ctx
;
365 UCONTEXT_REG_PC (my_uc
) = mctx
->pc
;
366 UCONTEXT_REG_SP (my_uc
) = mctx
->regs
[ARMREG_SP
];
367 UCONTEXT_REG_CPSR (my_uc
) = mctx
->cpsr
;
368 /* The upper registers are not guaranteed to be valid */
369 memcpy (&UCONTEXT_REG_R0 (my_uc
), &mctx
->regs
, sizeof (mgreg_t
) * 12);
370 #ifdef UCONTEXT_REG_VFPREGS
371 memcpy (UCONTEXT_REG_VFPREGS (my_uc
), &mctx
->fregs
, sizeof (double) * 16);
376 #elif (defined(__aarch64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM64))
378 #include <mono/utils/mono-context.h>
381 mono_sigctx_to_monoctx (void *sigctx
, MonoContext
*mctx
)
383 #ifdef MONO_CROSS_COMPILE
384 g_assert_not_reached ();
386 memcpy (mctx
->regs
, UCONTEXT_GREGS (sigctx
), sizeof (mgreg_t
) * 31);
387 mctx
->pc
= UCONTEXT_REG_PC (sigctx
);
388 mctx
->regs
[ARMREG_SP
] = UCONTEXT_REG_SP (sigctx
);
390 struct fpsimd_context
*fpctx
= (struct fpsimd_context
*)&((ucontext_t
*)sigctx
)->uc_mcontext
.__reserved
;
393 g_assert (fpctx
->head
.magic
== FPSIMD_MAGIC
);
394 for (i
= 0; i
< 32; ++i
)
395 /* Only store the bottom 8 bytes for now */
396 *(guint64
*)&(mctx
->fregs
[i
]) = fpctx
->vregs
[i
];
403 mono_monoctx_to_sigctx (MonoContext
*mctx
, void *sigctx
)
405 #ifdef MONO_CROSS_COMPILE
406 g_assert_not_reached ();
408 memcpy (UCONTEXT_GREGS (sigctx
), mctx
->regs
, sizeof (mgreg_t
) * 31);
409 UCONTEXT_REG_PC (sigctx
) = mctx
->pc
;
410 UCONTEXT_REG_SP (sigctx
) = mctx
->regs
[ARMREG_SP
];
414 #elif (defined(__mips__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_MIPS))
416 #include <mono/utils/mono-context.h>
417 #include <mono/arch/mips/mips-codegen.h>
420 mono_sigctx_to_monoctx (void *sigctx
, MonoContext
*mctx
)
424 mctx
->sc_pc
= UCONTEXT_REG_PC (sigctx
);
425 for (i
= 0; i
< 32; ++i
) {
426 mctx
->sc_regs
[i
] = UCONTEXT_GREGS (sigctx
) [i
];
427 mctx
->sc_fpregs
[i
] = UCONTEXT_FPREGS (sigctx
) [i
];
432 mono_monoctx_to_sigctx (MonoContext
*mctx
, void *sigctx
)
436 UCONTEXT_REG_PC (sigctx
) = mctx
->sc_pc
;
437 for (i
= 0; i
< 32; ++i
) {
438 UCONTEXT_GREGS (sigctx
) [i
] = mctx
->sc_regs
[i
];
439 UCONTEXT_FPREGS (sigctx
) [i
] = mctx
->sc_fpregs
[i
];
443 #elif (((defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__)) && !defined(MONO_CROSS_COMPILE))) || (defined(TARGET_POWERPC))
445 #include <mono/utils/mono-context.h>
446 #include <mono/mini/mini-ppc.h>
449 mono_sigctx_to_monoctx (void *sigctx
, MonoContext
*mctx
)
451 os_ucontext
*uc
= sigctx
;
453 mctx
->sc_ir
= UCONTEXT_REG_NIP(uc
);
454 mctx
->sc_sp
= UCONTEXT_REG_Rn(uc
, 1);
455 memcpy (&mctx
->regs
, &UCONTEXT_REG_Rn(uc
, 13), sizeof (mgreg_t
) * MONO_SAVED_GREGS
);
456 memcpy (&mctx
->fregs
, &UCONTEXT_REG_FPRn(uc
, 14), sizeof (double) * MONO_SAVED_FREGS
);
460 mono_monoctx_to_sigctx (MonoContext
*mctx
, void *sigctx
)
462 os_ucontext
*uc
= sigctx
;
464 UCONTEXT_REG_NIP(uc
) = mctx
->sc_ir
;
465 UCONTEXT_REG_Rn(uc
, 1) = mctx
->sc_sp
;
466 memcpy (&UCONTEXT_REG_Rn(uc
, 13), &mctx
->regs
, sizeof (mgreg_t
) * MONO_SAVED_GREGS
);
467 memcpy (&UCONTEXT_REG_FPRn(uc
, 14), &mctx
->fregs
, sizeof (double) * MONO_SAVED_FREGS
);
470 #endif /* #if defined(__i386__) */