2 * mono-context.c: plat independent machine state definitions
5 * Copyright (c) 2011 Novell, Inc (http://www.novell.com)
8 #include <mono/utils/mono-sigcontext.h>
10 #ifdef HAVE_UCONTEXT_H
14 #if (defined(__i386__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_X86))
16 #include <mono/utils/mono-context.h>
35 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
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 MONO_CROSS_COMPILE
49 g_assert_not_reached ();
50 #elif defined(MONO_SIGNAL_USE_UCONTEXT_T)
51 ucontext_t *ctx = (ucontext_t*)sigctx;
53 mctx->eax = UCONTEXT_REG_EAX (ctx);
54 mctx->ebx = UCONTEXT_REG_EBX (ctx);
55 mctx->ecx = UCONTEXT_REG_ECX (ctx);
56 mctx->edx = UCONTEXT_REG_EDX (ctx);
57 mctx->ebp = UCONTEXT_REG_EBP (ctx);
58 mctx->esp = UCONTEXT_REG_ESP (ctx);
59 mctx->esi = UCONTEXT_REG_ESI (ctx);
60 mctx->edi = UCONTEXT_REG_EDI (ctx);
61 mctx->eip = UCONTEXT_REG_EIP (ctx);
62 #elif defined(HOST_WIN32)
63 CONTEXT *context = (CONTEXT*)sigctx;
65 mctx->eip = context->Eip;
66 mctx->edi = context->Edi;
67 mctx->esi = context->Esi;
68 mctx->ebx = context->Ebx;
69 mctx->edx = context->Edx;
70 mctx->ecx = context->Ecx;
71 mctx->eax = context->Eax;
72 mctx->ebp = context->Ebp;
73 mctx->esp = context->Esp;
75 struct sigcontext *ctx = (struct sigcontext *)sigctx;
77 mctx->eax = ctx->SC_EAX;
78 mctx->ebx = ctx->SC_EBX;
79 mctx->ecx = ctx->SC_ECX;
80 mctx->edx = ctx->SC_EDX;
81 mctx->ebp = ctx->SC_EBP;
82 mctx->esp = ctx->SC_ESP;
83 mctx->esi = ctx->SC_ESI;
84 mctx->edi = ctx->SC_EDI;
85 mctx->eip = ctx->SC_EIP;
86 #endif /* if defined(__native_client__) */
90 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
92 #if defined(__native_client__) || defined(HOST_WATCHOS)
93 printf("WARNING: mono_arch_monoctx_to_sigctx() called!\n");
94 #elif MONO_CROSS_COMPILE
95 g_assert_not_reached ();
96 #elif defined(MONO_SIGNAL_USE_UCONTEXT_T)
97 ucontext_t *ctx = (ucontext_t*)sigctx;
99 UCONTEXT_REG_EAX (ctx) = mctx->eax;
100 UCONTEXT_REG_EBX (ctx) = mctx->ebx;
101 UCONTEXT_REG_ECX (ctx) = mctx->ecx;
102 UCONTEXT_REG_EDX (ctx) = mctx->edx;
103 UCONTEXT_REG_EBP (ctx) = mctx->ebp;
104 UCONTEXT_REG_ESP (ctx) = mctx->esp;
105 UCONTEXT_REG_ESI (ctx) = mctx->esi;
106 UCONTEXT_REG_EDI (ctx) = mctx->edi;
107 UCONTEXT_REG_EIP (ctx) = mctx->eip;
108 #elif defined(HOST_WIN32)
109 CONTEXT *context = (CONTEXT*)sigctx;
111 context->Eip = mctx->eip;
112 context->Edi = mctx->edi;
113 context->Esi = mctx->esi;
114 context->Ebx = mctx->ebx;
115 context->Edx = mctx->edx;
116 context->Ecx = mctx->ecx;
117 context->Eax = mctx->eax;
118 context->Ebp = mctx->ebp;
119 context->Esp = mctx->esp;
121 struct sigcontext *ctx = (struct sigcontext *)sigctx;
123 ctx->SC_EAX = mctx->eax;
124 ctx->SC_EBX = mctx->ebx;
125 ctx->SC_ECX = mctx->ecx;
126 ctx->SC_EDX = mctx->edx;
127 ctx->SC_EBP = mctx->ebp;
128 ctx->SC_ESP = mctx->esp;
129 ctx->SC_ESI = mctx->esi;
130 ctx->SC_EDI = mctx->edi;
131 ctx->SC_EIP = mctx->eip;
132 #endif /* __native_client__ */
135 #elif (defined(__x86_64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_AMD64)) /* defined(__i386__) */
137 #include <mono/utils/mono-context.h>
144 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
146 #if defined(__native_client_codegen__) || defined(__native_client__)
147 printf("WARNING: mono_arch_sigctx_to_monoctx() called!\n");
150 #ifdef MONO_CROSS_COMPILE
151 g_assert_not_reached ();
152 #elif defined(MONO_SIGNAL_USE_UCONTEXT_T)
153 ucontext_t *ctx = (ucontext_t*)sigctx;
155 mctx->gregs [AMD64_RAX] = UCONTEXT_REG_RAX (ctx);
156 mctx->gregs [AMD64_RBX] = UCONTEXT_REG_RBX (ctx);
157 mctx->gregs [AMD64_RCX] = UCONTEXT_REG_RCX (ctx);
158 mctx->gregs [AMD64_RDX] = UCONTEXT_REG_RDX (ctx);
159 mctx->gregs [AMD64_RBP] = UCONTEXT_REG_RBP (ctx);
160 mctx->gregs [AMD64_RSP] = UCONTEXT_REG_RSP (ctx);
161 mctx->gregs [AMD64_RSI] = UCONTEXT_REG_RSI (ctx);
162 mctx->gregs [AMD64_RDI] = UCONTEXT_REG_RDI (ctx);
163 mctx->gregs [AMD64_R8] = UCONTEXT_REG_R8 (ctx);
164 mctx->gregs [AMD64_R9] = UCONTEXT_REG_R9 (ctx);
165 mctx->gregs [AMD64_R10] = UCONTEXT_REG_R10 (ctx);
166 mctx->gregs [AMD64_R11] = UCONTEXT_REG_R11 (ctx);
167 mctx->gregs [AMD64_R12] = UCONTEXT_REG_R12 (ctx);
168 mctx->gregs [AMD64_R13] = UCONTEXT_REG_R13 (ctx);
169 mctx->gregs [AMD64_R14] = UCONTEXT_REG_R14 (ctx);
170 mctx->gregs [AMD64_R15] = UCONTEXT_REG_R15 (ctx);
171 mctx->gregs [AMD64_RIP] = UCONTEXT_REG_RIP (ctx);
172 #elif defined(HOST_WIN32)
173 CONTEXT *context = (CONTEXT*)sigctx;
175 mctx->gregs [AMD64_RIP] = context->Rip;
176 mctx->gregs [AMD64_RAX] = context->Rax;
177 mctx->gregs [AMD64_RCX] = context->Rcx;
178 mctx->gregs [AMD64_RDX] = context->Rdx;
179 mctx->gregs [AMD64_RBX] = context->Rbx;
180 mctx->gregs [AMD64_RSP] = context->Rsp;
181 mctx->gregs [AMD64_RBP] = context->Rbp;
182 mctx->gregs [AMD64_RSI] = context->Rsi;
183 mctx->gregs [AMD64_RDI] = context->Rdi;
184 mctx->gregs [AMD64_R8] = context->R8;
185 mctx->gregs [AMD64_R9] = context->R9;
186 mctx->gregs [AMD64_R10] = context->R10;
187 mctx->gregs [AMD64_R11] = context->R11;
188 mctx->gregs [AMD64_R12] = context->R12;
189 mctx->gregs [AMD64_R13] = context->R13;
190 mctx->gregs [AMD64_R14] = context->R14;
191 mctx->gregs [AMD64_R15] = context->R15;
193 g_assert_not_reached ();
198 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
200 #if defined(__native_client__) || defined(__native_client_codegen__)
201 printf("WARNING: mono_arch_monoctx_to_sigctx() called!\n");
204 #ifdef MONO_CROSS_COMPILE
205 g_assert_not_reached ();
206 #elif defined(MONO_SIGNAL_USE_UCONTEXT_T)
207 ucontext_t *ctx = (ucontext_t*)sigctx;
209 UCONTEXT_REG_RAX (ctx) = mctx->gregs [AMD64_RAX];
210 UCONTEXT_REG_RBX (ctx) = mctx->gregs [AMD64_RBX];
211 UCONTEXT_REG_RCX (ctx) = mctx->gregs [AMD64_RCX];
212 UCONTEXT_REG_RDX (ctx) = mctx->gregs [AMD64_RDX];
213 UCONTEXT_REG_RBP (ctx) = mctx->gregs [AMD64_RBP];
214 UCONTEXT_REG_RSP (ctx) = mctx->gregs [AMD64_RSP];
215 UCONTEXT_REG_RSI (ctx) = mctx->gregs [AMD64_RSI];
216 UCONTEXT_REG_RDI (ctx) = mctx->gregs [AMD64_RDI];
217 UCONTEXT_REG_R8 (ctx) = mctx->gregs [AMD64_R8];
218 UCONTEXT_REG_R9 (ctx) = mctx->gregs [AMD64_R9];
219 UCONTEXT_REG_R10 (ctx) = mctx->gregs [AMD64_R10];
220 UCONTEXT_REG_R11 (ctx) = mctx->gregs [AMD64_R11];
221 UCONTEXT_REG_R12 (ctx) = mctx->gregs [AMD64_R12];
222 UCONTEXT_REG_R13 (ctx) = mctx->gregs [AMD64_R13];
223 UCONTEXT_REG_R14 (ctx) = mctx->gregs [AMD64_R14];
224 UCONTEXT_REG_R15 (ctx) = mctx->gregs [AMD64_R15];
225 UCONTEXT_REG_RIP (ctx) = mctx->gregs [AMD64_RIP];
226 #elif defined(HOST_WIN32)
227 CONTEXT *context = (CONTEXT*)sigctx;
229 context->Rip = mctx->gregs [AMD64_RIP];
230 context->Rax = mctx->gregs [AMD64_RAX];
231 context->Rcx = mctx->gregs [AMD64_RCX];
232 context->Rdx = mctx->gregs [AMD64_RDX];
233 context->Rbx = mctx->gregs [AMD64_RBX];
234 context->Rsp = mctx->gregs [AMD64_RSP];
235 context->Rbp = mctx->gregs [AMD64_RBP];
236 context->Rsi = mctx->gregs [AMD64_RSI];
237 context->Rdi = mctx->gregs [AMD64_RDI];
238 context->R8 = mctx->gregs [AMD64_R8];
239 context->R9 = mctx->gregs [AMD64_R9];
240 context->R10 = mctx->gregs [AMD64_R10];
241 context->R11 = mctx->gregs [AMD64_R11];
242 context->R12 = mctx->gregs [AMD64_R12];
243 context->R13 = mctx->gregs [AMD64_R13];
244 context->R14 = mctx->gregs [AMD64_R14];
245 context->R15 = mctx->gregs [AMD64_R15];
247 g_assert_not_reached ();
251 #elif defined(__s390x__)
253 #include <mono/utils/mono-context.h>
255 /*------------------------------------------------------------------*/
257 /* Name - mono_arch_sigctx_to_monoctx. */
259 /* Function - Called from the signal handler to convert signal */
260 /* context to MonoContext. */
262 /*------------------------------------------------------------------*/
265 mono_sigctx_to_monoctx (void *ctx, MonoContext *mctx)
267 memcpy (mctx, ctx, sizeof(MonoContext));
270 /*========================= End of Function ========================*/
272 /*------------------------------------------------------------------*/
274 /* Name - mono_arch_monoctx_to_sigctx. */
276 /* Function - Convert MonoContext structure to signal context. */
278 /*------------------------------------------------------------------*/
281 mono_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
283 memcpy (ctx, mctx, sizeof(MonoContext));
286 /*========================= End of Function ========================*/
288 #elif (defined(__arm__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM))
290 #include <mono/utils/mono-context.h>
291 #include <mono/arch/arm/arm-codegen.h>
292 #include <mono/arch/arm/arm-vfp-codegen.h>
295 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
297 #ifdef MONO_CROSS_COMPILE
298 g_assert_not_reached ();
299 #elif defined(__native_client__)
300 g_assert_not_reached ();
302 arm_ucontext *my_uc = sigctx;
304 mctx->pc = UCONTEXT_REG_PC (my_uc);
305 mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (my_uc);
306 mctx->cpsr = UCONTEXT_REG_CPSR (my_uc);
307 memcpy (&mctx->regs, &UCONTEXT_REG_R0 (my_uc), sizeof (mgreg_t) * 16);
308 #ifdef UCONTEXT_REG_VFPREGS
309 memcpy (&mctx->fregs, UCONTEXT_REG_VFPREGS (my_uc), sizeof (double) * 16);
315 mono_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
317 #ifdef MONO_CROSS_COMPILE
318 g_assert_not_reached ();
319 #elif defined(__native_client__)
320 g_assert_not_reached ();
322 arm_ucontext *my_uc = ctx;
324 UCONTEXT_REG_PC (my_uc) = mctx->pc;
325 UCONTEXT_REG_SP (my_uc) = mctx->regs [ARMREG_SP];
326 UCONTEXT_REG_CPSR (my_uc) = mctx->cpsr;
327 /* The upper registers are not guaranteed to be valid */
328 memcpy (&UCONTEXT_REG_R0 (my_uc), &mctx->regs, sizeof (mgreg_t) * 12);
329 #ifdef UCONTEXT_REG_VFPREGS
330 memcpy (UCONTEXT_REG_VFPREGS (my_uc), &mctx->fregs, sizeof (double) * 16);
335 #elif (defined(__aarch64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM64))
337 #include <mono/utils/mono-context.h>
340 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
342 #ifdef MONO_CROSS_COMPILE
343 g_assert_not_reached ();
345 memcpy (mctx->regs, UCONTEXT_GREGS (sigctx), sizeof (mgreg_t) * 31);
346 mctx->pc = UCONTEXT_REG_PC (sigctx);
347 mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (sigctx);
349 * We don't handle fp regs, this is not currrently a
350 * problem, since we don't allocate them globally.
356 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
358 #ifdef MONO_CROSS_COMPILE
359 g_assert_not_reached ();
361 memcpy (UCONTEXT_GREGS (sigctx), mctx->regs, sizeof (mgreg_t) * 31);
362 UCONTEXT_REG_PC (sigctx) = mctx->pc;
363 UCONTEXT_REG_SP (sigctx) = mctx->regs [ARMREG_SP];
367 #elif (defined(__mips__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_MIPS))
369 #include <mono/utils/mono-context.h>
370 #include <mono/arch/mips/mips-codegen.h>
373 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
377 mctx->sc_pc = UCONTEXT_REG_PC (sigctx);
378 for (i = 0; i < 32; ++i) {
379 mctx->sc_regs[i] = UCONTEXT_GREGS (sigctx) [i];
380 mctx->sc_fpregs[i] = UCONTEXT_FPREGS (sigctx) [i];
385 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
389 UCONTEXT_REG_PC (sigctx) = mctx->sc_pc;
390 for (i = 0; i < 32; ++i) {
391 UCONTEXT_GREGS (sigctx) [i] = mctx->sc_regs[i];
392 UCONTEXT_FPREGS (sigctx) [i] = mctx->sc_fpregs[i];
396 #elif (((defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__)) && !defined(MONO_CROSS_COMPILE))) || (defined(TARGET_POWERPC))
398 #include <mono/utils/mono-context.h>
399 #include <mono/mini/mini-ppc.h>
402 mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
404 os_ucontext *uc = sigctx;
406 mctx->sc_ir = UCONTEXT_REG_NIP(uc);
407 mctx->sc_sp = UCONTEXT_REG_Rn(uc, 1);
408 memcpy (&mctx->regs, &UCONTEXT_REG_Rn(uc, 13), sizeof (mgreg_t) * MONO_SAVED_GREGS);
409 memcpy (&mctx->fregs, &UCONTEXT_REG_FPRn(uc, 14), sizeof (double) * MONO_SAVED_FREGS);
413 mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
415 os_ucontext *uc = sigctx;
417 UCONTEXT_REG_NIP(uc) = mctx->sc_ir;
418 UCONTEXT_REG_Rn(uc, 1) = mctx->sc_sp;
419 memcpy (&UCONTEXT_REG_Rn(uc, 13), &mctx->regs, sizeof (mgreg_t) * MONO_SAVED_GREGS);
420 memcpy (&UCONTEXT_REG_FPRn(uc, 14), &mctx->fregs, sizeof (double) * MONO_SAVED_FREGS);
423 #endif /* #if defined(__i386__) */