3 * plat independent machine state definitions
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.
10 #include <mono/utils/mono-sigcontext.h>
12 #ifdef HAVE_UCONTEXT_H
16 #if (defined(__i386__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_X86))
18 #include <mono/utils/mono-context.h>
37 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
39 #if 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;
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);
74 #elif defined(HOST_WIN32)
75 CONTEXT *context = (CONTEXT*)sigctx;
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;
87 struct sigcontext *ctx = (struct sigcontext *)sigctx;
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;
102 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
104 #if 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;
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];
130 #elif defined(HOST_WIN32)
131 CONTEXT *context = (CONTEXT*)sigctx;
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;
143 struct sigcontext *ctx = (struct sigcontext *)sigctx;
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;
157 #elif (defined(__x86_64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_AMD64)) /* defined(__i386__) */
159 #include <mono/utils/mono-context.h>
166 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
168 #ifdef MONO_CROSS_COMPILE
169 g_assert_not_reached ();
170 #elif defined(MONO_SIGNAL_USE_UCONTEXT_T)
171 ucontext_t *ctx = (ucontext_t*)sigctx;
173 mctx->gregs [AMD64_RAX] = UCONTEXT_REG_RAX (ctx);
174 mctx->gregs [AMD64_RBX] = UCONTEXT_REG_RBX (ctx);
175 mctx->gregs [AMD64_RCX] = UCONTEXT_REG_RCX (ctx);
176 mctx->gregs [AMD64_RDX] = UCONTEXT_REG_RDX (ctx);
177 mctx->gregs [AMD64_RBP] = UCONTEXT_REG_RBP (ctx);
178 mctx->gregs [AMD64_RSP] = UCONTEXT_REG_RSP (ctx);
179 mctx->gregs [AMD64_RSI] = UCONTEXT_REG_RSI (ctx);
180 mctx->gregs [AMD64_RDI] = UCONTEXT_REG_RDI (ctx);
181 mctx->gregs [AMD64_R8] = UCONTEXT_REG_R8 (ctx);
182 mctx->gregs [AMD64_R9] = UCONTEXT_REG_R9 (ctx);
183 mctx->gregs [AMD64_R10] = UCONTEXT_REG_R10 (ctx);
184 mctx->gregs [AMD64_R11] = UCONTEXT_REG_R11 (ctx);
185 mctx->gregs [AMD64_R12] = UCONTEXT_REG_R12 (ctx);
186 mctx->gregs [AMD64_R13] = UCONTEXT_REG_R13 (ctx);
187 mctx->gregs [AMD64_R14] = UCONTEXT_REG_R14 (ctx);
188 mctx->gregs [AMD64_R15] = UCONTEXT_REG_R15 (ctx);
189 mctx->gregs [AMD64_RIP] = UCONTEXT_REG_RIP (ctx);
191 #ifdef UCONTEXT_REG_XMM
192 mctx->fregs [0] = UCONTEXT_REG_XMM0 (ctx);
193 mctx->fregs [1] = UCONTEXT_REG_XMM1 (ctx);
194 mctx->fregs [2] = UCONTEXT_REG_XMM2 (ctx);
195 mctx->fregs [3] = UCONTEXT_REG_XMM3 (ctx);
196 mctx->fregs [4] = UCONTEXT_REG_XMM4 (ctx);
197 mctx->fregs [5] = UCONTEXT_REG_XMM5 (ctx);
198 mctx->fregs [6] = UCONTEXT_REG_XMM6 (ctx);
199 mctx->fregs [7] = UCONTEXT_REG_XMM7 (ctx);
200 mctx->fregs [8] = UCONTEXT_REG_XMM8 (ctx);
201 mctx->fregs [9] = UCONTEXT_REG_XMM9 (ctx);
202 mctx->fregs [10] = UCONTEXT_REG_XMM10 (ctx);
203 mctx->fregs [11] = UCONTEXT_REG_XMM11 (ctx);
204 mctx->fregs [12] = UCONTEXT_REG_XMM12 (ctx);
205 mctx->fregs [13] = UCONTEXT_REG_XMM13 (ctx);
206 mctx->fregs [14] = UCONTEXT_REG_XMM14 (ctx);
207 mctx->fregs [15] = UCONTEXT_REG_XMM15 (ctx);
210 #elif defined(HOST_WIN32)
211 CONTEXT *context = (CONTEXT*)sigctx;
213 mctx->gregs [AMD64_RIP] = context->Rip;
214 mctx->gregs [AMD64_RAX] = context->Rax;
215 mctx->gregs [AMD64_RCX] = context->Rcx;
216 mctx->gregs [AMD64_RDX] = context->Rdx;
217 mctx->gregs [AMD64_RBX] = context->Rbx;
218 mctx->gregs [AMD64_RSP] = context->Rsp;
219 mctx->gregs [AMD64_RBP] = context->Rbp;
220 mctx->gregs [AMD64_RSI] = context->Rsi;
221 mctx->gregs [AMD64_RDI] = context->Rdi;
222 mctx->gregs [AMD64_R8] = context->R8;
223 mctx->gregs [AMD64_R9] = context->R9;
224 mctx->gregs [AMD64_R10] = context->R10;
225 mctx->gregs [AMD64_R11] = context->R11;
226 mctx->gregs [AMD64_R12] = context->R12;
227 mctx->gregs [AMD64_R13] = context->R13;
228 mctx->gregs [AMD64_R14] = context->R14;
229 mctx->gregs [AMD64_R15] = context->R15;
231 g_assert_not_reached ();
236 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
238 #ifdef MONO_CROSS_COMPILE
239 g_assert_not_reached ();
240 #elif defined(MONO_SIGNAL_USE_UCONTEXT_T)
241 ucontext_t *ctx = (ucontext_t*)sigctx;
243 UCONTEXT_REG_RAX (ctx) = mctx->gregs [AMD64_RAX];
244 UCONTEXT_REG_RBX (ctx) = mctx->gregs [AMD64_RBX];
245 UCONTEXT_REG_RCX (ctx) = mctx->gregs [AMD64_RCX];
246 UCONTEXT_REG_RDX (ctx) = mctx->gregs [AMD64_RDX];
247 UCONTEXT_REG_RBP (ctx) = mctx->gregs [AMD64_RBP];
248 UCONTEXT_REG_RSP (ctx) = mctx->gregs [AMD64_RSP];
249 UCONTEXT_REG_RSI (ctx) = mctx->gregs [AMD64_RSI];
250 UCONTEXT_REG_RDI (ctx) = mctx->gregs [AMD64_RDI];
251 UCONTEXT_REG_R8 (ctx) = mctx->gregs [AMD64_R8];
252 UCONTEXT_REG_R9 (ctx) = mctx->gregs [AMD64_R9];
253 UCONTEXT_REG_R10 (ctx) = mctx->gregs [AMD64_R10];
254 UCONTEXT_REG_R11 (ctx) = mctx->gregs [AMD64_R11];
255 UCONTEXT_REG_R12 (ctx) = mctx->gregs [AMD64_R12];
256 UCONTEXT_REG_R13 (ctx) = mctx->gregs [AMD64_R13];
257 UCONTEXT_REG_R14 (ctx) = mctx->gregs [AMD64_R14];
258 UCONTEXT_REG_R15 (ctx) = mctx->gregs [AMD64_R15];
259 UCONTEXT_REG_RIP (ctx) = mctx->gregs [AMD64_RIP];
261 #ifdef UCONTEXT_REG_XMM
262 UCONTEXT_REG_XMM0 (ctx) = mctx->fregs [0];
263 UCONTEXT_REG_XMM1 (ctx) = mctx->fregs [1];
264 UCONTEXT_REG_XMM2 (ctx) = mctx->fregs [2];
265 UCONTEXT_REG_XMM3 (ctx) = mctx->fregs [3];
266 UCONTEXT_REG_XMM4 (ctx) = mctx->fregs [4];
267 UCONTEXT_REG_XMM5 (ctx) = mctx->fregs [5];
268 UCONTEXT_REG_XMM6 (ctx) = mctx->fregs [6];
269 UCONTEXT_REG_XMM7 (ctx) = mctx->fregs [7];
270 UCONTEXT_REG_XMM8 (ctx) = mctx->fregs [8];
271 UCONTEXT_REG_XMM9 (ctx) = mctx->fregs [9];
272 UCONTEXT_REG_XMM10 (ctx) = mctx->fregs [10];
273 UCONTEXT_REG_XMM11 (ctx) = mctx->fregs [11];
274 UCONTEXT_REG_XMM12 (ctx) = mctx->fregs [12];
275 UCONTEXT_REG_XMM13 (ctx) = mctx->fregs [13];
276 UCONTEXT_REG_XMM14 (ctx) = mctx->fregs [14];
277 UCONTEXT_REG_XMM15 (ctx) = mctx->fregs [15];
280 #elif defined(HOST_WIN32)
281 CONTEXT *context = (CONTEXT*)sigctx;
283 context->Rip = mctx->gregs [AMD64_RIP];
284 context->Rax = mctx->gregs [AMD64_RAX];
285 context->Rcx = mctx->gregs [AMD64_RCX];
286 context->Rdx = mctx->gregs [AMD64_RDX];
287 context->Rbx = mctx->gregs [AMD64_RBX];
288 context->Rsp = mctx->gregs [AMD64_RSP];
289 context->Rbp = mctx->gregs [AMD64_RBP];
290 context->Rsi = mctx->gregs [AMD64_RSI];
291 context->Rdi = mctx->gregs [AMD64_RDI];
292 context->R8 = mctx->gregs [AMD64_R8];
293 context->R9 = mctx->gregs [AMD64_R9];
294 context->R10 = mctx->gregs [AMD64_R10];
295 context->R11 = mctx->gregs [AMD64_R11];
296 context->R12 = mctx->gregs [AMD64_R12];
297 context->R13 = mctx->gregs [AMD64_R13];
298 context->R14 = mctx->gregs [AMD64_R14];
299 context->R15 = mctx->gregs [AMD64_R15];
301 g_assert_not_reached ();
305 #elif defined(__s390x__)
307 #include <mono/utils/mono-context.h>
309 /*------------------------------------------------------------------*/
311 /* Name - mono_arch_sigctx_to_monoctx. */
313 /* Function - Called from the signal handler to convert signal */
314 /* context to MonoContext. */
316 /*------------------------------------------------------------------*/
319 mono_sigctx_to_monoctx (void *ctx, MonoContext *mctx)
321 memcpy (mctx, ctx, sizeof(MonoContext));
324 /*========================= End of Function ========================*/
326 /*------------------------------------------------------------------*/
328 /* Name - mono_arch_monoctx_to_sigctx. */
330 /* Function - Convert MonoContext structure to signal context. */
332 /*------------------------------------------------------------------*/
335 mono_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
337 memcpy (ctx, mctx, sizeof(MonoContext));
340 /*========================= End of Function ========================*/
342 #elif (defined(__arm__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM))
344 #include <mono/utils/mono-context.h>
345 #include <mono/arch/arm/arm-codegen.h>
346 #include <mono/arch/arm/arm-vfp-codegen.h>
349 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
351 #ifdef MONO_CROSS_COMPILE
352 g_assert_not_reached ();
354 arm_ucontext *my_uc = sigctx;
356 mctx->pc = UCONTEXT_REG_PC (my_uc);
357 mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (my_uc);
358 mctx->cpsr = UCONTEXT_REG_CPSR (my_uc);
359 memcpy (&mctx->regs, &UCONTEXT_REG_R0 (my_uc), sizeof (mgreg_t) * 16);
360 #ifdef UCONTEXT_REG_VFPREGS
361 memcpy (&mctx->fregs, UCONTEXT_REG_VFPREGS (my_uc), sizeof (double) * 16);
367 mono_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
369 #ifdef MONO_CROSS_COMPILE
370 g_assert_not_reached ();
372 arm_ucontext *my_uc = ctx;
374 UCONTEXT_REG_PC (my_uc) = mctx->pc;
375 UCONTEXT_REG_SP (my_uc) = mctx->regs [ARMREG_SP];
376 UCONTEXT_REG_CPSR (my_uc) = mctx->cpsr;
377 /* The upper registers are not guaranteed to be valid */
378 memcpy (&UCONTEXT_REG_R0 (my_uc), &mctx->regs, sizeof (mgreg_t) * 12);
379 #ifdef UCONTEXT_REG_VFPREGS
380 memcpy (UCONTEXT_REG_VFPREGS (my_uc), &mctx->fregs, sizeof (double) * 16);
385 #elif (defined(__aarch64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM64))
387 #include <mono/utils/mono-context.h>
390 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
392 #ifdef MONO_CROSS_COMPILE
393 g_assert_not_reached ();
395 memcpy (mctx->regs, UCONTEXT_GREGS (sigctx), sizeof (mgreg_t) * 31);
396 mctx->pc = UCONTEXT_REG_PC (sigctx);
397 mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (sigctx);
399 struct fpsimd_context *fpctx = (struct fpsimd_context*)&((ucontext_t*)sigctx)->uc_mcontext.__reserved;
402 g_assert (fpctx->head.magic == FPSIMD_MAGIC);
403 for (i = 0; i < 32; ++i)
404 /* Only store the bottom 8 bytes for now */
405 *(guint64*)&(mctx->fregs [i]) = fpctx->vregs [i];
412 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
414 #ifdef MONO_CROSS_COMPILE
415 g_assert_not_reached ();
417 memcpy (UCONTEXT_GREGS (sigctx), mctx->regs, sizeof (mgreg_t) * 31);
418 UCONTEXT_REG_PC (sigctx) = mctx->pc;
419 UCONTEXT_REG_SP (sigctx) = mctx->regs [ARMREG_SP];
423 #elif (defined(__mips__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_MIPS))
425 #include <mono/utils/mono-context.h>
426 #include <mono/arch/mips/mips-codegen.h>
429 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
433 mctx->sc_pc = UCONTEXT_REG_PC (sigctx);
434 for (i = 0; i < 32; ++i) {
435 mctx->sc_regs[i] = UCONTEXT_GREGS (sigctx) [i];
436 mctx->sc_fpregs[i] = UCONTEXT_FPREGS (sigctx) [i];
441 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
445 UCONTEXT_REG_PC (sigctx) = mctx->sc_pc;
446 for (i = 0; i < 32; ++i) {
447 UCONTEXT_GREGS (sigctx) [i] = mctx->sc_regs[i];
448 UCONTEXT_FPREGS (sigctx) [i] = mctx->sc_fpregs[i];
452 #elif (((defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__)) && !defined(MONO_CROSS_COMPILE))) || (defined(TARGET_POWERPC))
454 #include <mono/utils/mono-context.h>
455 #include <mono/mini/mini-ppc.h>
458 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
460 os_ucontext *uc = sigctx;
462 mctx->sc_ir = UCONTEXT_REG_NIP(uc);
463 mctx->sc_sp = UCONTEXT_REG_Rn(uc, 1);
465 memcpy (&mctx->regs, &UCONTEXT_REG_Rn(uc, 0), sizeof (mgreg_t) * MONO_MAX_IREGS);
466 memcpy (&mctx->fregs, &UCONTEXT_REG_FPRn(uc, 0), sizeof (double) * MONO_MAX_FREGS);
470 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
472 os_ucontext *uc = sigctx;
474 memcpy (&UCONTEXT_REG_Rn(uc, 0), &mctx->regs, sizeof (mgreg_t) * MONO_MAX_IREGS);
475 memcpy (&UCONTEXT_REG_FPRn(uc, 0), &mctx->fregs, sizeof (double) * MONO_MAX_FREGS);
477 /* The valid values for pc and sp are stored here and not in regs array */
478 UCONTEXT_REG_NIP(uc) = mctx->sc_ir;
479 UCONTEXT_REG_Rn(uc, 1) = mctx->sc_sp;
482 #endif /* #if defined(__i386__) */