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
);
173 #elif defined(HOST_WIN32)
174 CONTEXT
*context
= (CONTEXT
*)sigctx
;
176 mctx
->gregs
[AMD64_RIP
] = context
->Rip
;
177 mctx
->gregs
[AMD64_RAX
] = context
->Rax
;
178 mctx
->gregs
[AMD64_RCX
] = context
->Rcx
;
179 mctx
->gregs
[AMD64_RDX
] = context
->Rdx
;
180 mctx
->gregs
[AMD64_RBX
] = context
->Rbx
;
181 mctx
->gregs
[AMD64_RSP
] = context
->Rsp
;
182 mctx
->gregs
[AMD64_RBP
] = context
->Rbp
;
183 mctx
->gregs
[AMD64_RSI
] = context
->Rsi
;
184 mctx
->gregs
[AMD64_RDI
] = context
->Rdi
;
185 mctx
->gregs
[AMD64_R8
] = context
->R8
;
186 mctx
->gregs
[AMD64_R9
] = context
->R9
;
187 mctx
->gregs
[AMD64_R10
] = context
->R10
;
188 mctx
->gregs
[AMD64_R11
] = context
->R11
;
189 mctx
->gregs
[AMD64_R12
] = context
->R12
;
190 mctx
->gregs
[AMD64_R13
] = context
->R13
;
191 mctx
->gregs
[AMD64_R14
] = context
->R14
;
192 mctx
->gregs
[AMD64_R15
] = context
->R15
;
194 g_assert_not_reached ();
199 mono_monoctx_to_sigctx (MonoContext
*mctx
, void *sigctx
)
201 #if defined(__native_client__) || defined(__native_client_codegen__)
202 printf("WARNING: mono_arch_monoctx_to_sigctx() called!\n");
205 #ifdef MONO_CROSS_COMPILE
206 g_assert_not_reached ();
207 #elif defined(MONO_SIGNAL_USE_UCONTEXT_T)
208 ucontext_t
*ctx
= (ucontext_t
*)sigctx
;
210 UCONTEXT_REG_RAX (ctx
) = mctx
->gregs
[AMD64_RAX
];
211 UCONTEXT_REG_RBX (ctx
) = mctx
->gregs
[AMD64_RBX
];
212 UCONTEXT_REG_RCX (ctx
) = mctx
->gregs
[AMD64_RCX
];
213 UCONTEXT_REG_RDX (ctx
) = mctx
->gregs
[AMD64_RDX
];
214 UCONTEXT_REG_RBP (ctx
) = mctx
->gregs
[AMD64_RBP
];
215 UCONTEXT_REG_RSP (ctx
) = mctx
->gregs
[AMD64_RSP
];
216 UCONTEXT_REG_RSI (ctx
) = mctx
->gregs
[AMD64_RSI
];
217 UCONTEXT_REG_RDI (ctx
) = mctx
->gregs
[AMD64_RDI
];
218 UCONTEXT_REG_R8 (ctx
) = mctx
->gregs
[AMD64_R8
];
219 UCONTEXT_REG_R9 (ctx
) = mctx
->gregs
[AMD64_R9
];
220 UCONTEXT_REG_R10 (ctx
) = mctx
->gregs
[AMD64_R10
];
221 UCONTEXT_REG_R11 (ctx
) = mctx
->gregs
[AMD64_R11
];
222 UCONTEXT_REG_R12 (ctx
) = mctx
->gregs
[AMD64_R12
];
223 UCONTEXT_REG_R13 (ctx
) = mctx
->gregs
[AMD64_R13
];
224 UCONTEXT_REG_R14 (ctx
) = mctx
->gregs
[AMD64_R14
];
225 UCONTEXT_REG_R15 (ctx
) = mctx
->gregs
[AMD64_R15
];
226 UCONTEXT_REG_RIP (ctx
) = mctx
->gregs
[AMD64_RIP
];
227 #elif defined(HOST_WIN32)
228 CONTEXT
*context
= (CONTEXT
*)sigctx
;
230 context
->Rip
= mctx
->gregs
[AMD64_RIP
];
231 context
->Rax
= mctx
->gregs
[AMD64_RAX
];
232 context
->Rcx
= mctx
->gregs
[AMD64_RCX
];
233 context
->Rdx
= mctx
->gregs
[AMD64_RDX
];
234 context
->Rbx
= mctx
->gregs
[AMD64_RBX
];
235 context
->Rsp
= mctx
->gregs
[AMD64_RSP
];
236 context
->Rbp
= mctx
->gregs
[AMD64_RBP
];
237 context
->Rsi
= mctx
->gregs
[AMD64_RSI
];
238 context
->Rdi
= mctx
->gregs
[AMD64_RDI
];
239 context
->R8
= mctx
->gregs
[AMD64_R8
];
240 context
->R9
= mctx
->gregs
[AMD64_R9
];
241 context
->R10
= mctx
->gregs
[AMD64_R10
];
242 context
->R11
= mctx
->gregs
[AMD64_R11
];
243 context
->R12
= mctx
->gregs
[AMD64_R12
];
244 context
->R13
= mctx
->gregs
[AMD64_R13
];
245 context
->R14
= mctx
->gregs
[AMD64_R14
];
246 context
->R15
= mctx
->gregs
[AMD64_R15
];
248 g_assert_not_reached ();
252 #elif defined(__s390x__)
254 #include <mono/utils/mono-context.h>
256 /*------------------------------------------------------------------*/
258 /* Name - mono_arch_sigctx_to_monoctx. */
260 /* Function - Called from the signal handler to convert signal */
261 /* context to MonoContext. */
263 /*------------------------------------------------------------------*/
266 mono_sigctx_to_monoctx (void *ctx
, MonoContext
*mctx
)
268 memcpy (mctx
, ctx
, sizeof(MonoContext
));
271 /*========================= End of Function ========================*/
273 /*------------------------------------------------------------------*/
275 /* Name - mono_arch_monoctx_to_sigctx. */
277 /* Function - Convert MonoContext structure to signal context. */
279 /*------------------------------------------------------------------*/
282 mono_monoctx_to_sigctx (MonoContext
*mctx
, void *ctx
)
284 memcpy (ctx
, mctx
, sizeof(MonoContext
));
287 /*========================= End of Function ========================*/
289 #elif (defined(__arm__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM))
291 #include <mono/utils/mono-context.h>
292 #include <mono/arch/arm/arm-codegen.h>
293 #include <mono/arch/arm/arm-vfp-codegen.h>
296 mono_sigctx_to_monoctx (void *sigctx
, MonoContext
*mctx
)
298 #ifdef MONO_CROSS_COMPILE
299 g_assert_not_reached ();
300 #elif defined(__native_client__)
301 g_assert_not_reached ();
303 arm_ucontext
*my_uc
= sigctx
;
305 mctx
->pc
= UCONTEXT_REG_PC (my_uc
);
306 mctx
->regs
[ARMREG_SP
] = UCONTEXT_REG_SP (my_uc
);
307 mctx
->cpsr
= UCONTEXT_REG_CPSR (my_uc
);
308 memcpy (&mctx
->regs
, &UCONTEXT_REG_R0 (my_uc
), sizeof (mgreg_t
) * 16);
309 #ifdef UCONTEXT_REG_VFPREGS
310 memcpy (&mctx
->fregs
, UCONTEXT_REG_VFPREGS (my_uc
), sizeof (double) * 16);
316 mono_monoctx_to_sigctx (MonoContext
*mctx
, void *ctx
)
318 #ifdef MONO_CROSS_COMPILE
319 g_assert_not_reached ();
320 #elif defined(__native_client__)
321 g_assert_not_reached ();
323 arm_ucontext
*my_uc
= ctx
;
325 UCONTEXT_REG_PC (my_uc
) = mctx
->pc
;
326 UCONTEXT_REG_SP (my_uc
) = mctx
->regs
[ARMREG_SP
];
327 UCONTEXT_REG_CPSR (my_uc
) = mctx
->cpsr
;
328 /* The upper registers are not guaranteed to be valid */
329 memcpy (&UCONTEXT_REG_R0 (my_uc
), &mctx
->regs
, sizeof (mgreg_t
) * 12);
330 #ifdef UCONTEXT_REG_VFPREGS
331 memcpy (UCONTEXT_REG_VFPREGS (my_uc
), &mctx
->fregs
, sizeof (double) * 16);
336 #elif (defined(__aarch64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM64))
338 #include <mono/utils/mono-context.h>
341 mono_sigctx_to_monoctx (void *sigctx
, MonoContext
*mctx
)
343 #ifdef MONO_CROSS_COMPILE
344 g_assert_not_reached ();
346 memcpy (mctx
->regs
, UCONTEXT_GREGS (sigctx
), sizeof (mgreg_t
) * 31);
347 mctx
->pc
= UCONTEXT_REG_PC (sigctx
);
348 mctx
->regs
[ARMREG_SP
] = UCONTEXT_REG_SP (sigctx
);
350 * We don't handle fp regs, this is not currrently a
351 * problem, since we don't allocate them globally.
357 mono_monoctx_to_sigctx (MonoContext
*mctx
, void *sigctx
)
359 #ifdef MONO_CROSS_COMPILE
360 g_assert_not_reached ();
362 memcpy (UCONTEXT_GREGS (sigctx
), mctx
->regs
, sizeof (mgreg_t
) * 31);
363 UCONTEXT_REG_PC (sigctx
) = mctx
->pc
;
364 UCONTEXT_REG_SP (sigctx
) = mctx
->regs
[ARMREG_SP
];
368 #elif (defined(__mips__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_MIPS))
370 #include <mono/utils/mono-context.h>
371 #include <mono/arch/mips/mips-codegen.h>
374 mono_sigctx_to_monoctx (void *sigctx
, MonoContext
*mctx
)
378 mctx
->sc_pc
= UCONTEXT_REG_PC (sigctx
);
379 for (i
= 0; i
< 32; ++i
) {
380 mctx
->sc_regs
[i
] = UCONTEXT_GREGS (sigctx
) [i
];
381 mctx
->sc_fpregs
[i
] = UCONTEXT_FPREGS (sigctx
) [i
];
386 mono_monoctx_to_sigctx (MonoContext
*mctx
, void *sigctx
)
390 UCONTEXT_REG_PC (sigctx
) = mctx
->sc_pc
;
391 for (i
= 0; i
< 32; ++i
) {
392 UCONTEXT_GREGS (sigctx
) [i
] = mctx
->sc_regs
[i
];
393 UCONTEXT_FPREGS (sigctx
) [i
] = mctx
->sc_fpregs
[i
];
397 #elif (((defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__)) && !defined(MONO_CROSS_COMPILE))) || (defined(TARGET_POWERPC))
399 #include <mono/utils/mono-context.h>
400 #include <mono/mini/mini-ppc.h>
403 mono_sigctx_to_monoctx (void *sigctx
, MonoContext
*mctx
)
405 os_ucontext
*uc
= sigctx
;
407 mctx
->sc_ir
= UCONTEXT_REG_NIP(uc
);
408 mctx
->sc_sp
= UCONTEXT_REG_Rn(uc
, 1);
409 memcpy (&mctx
->regs
, &UCONTEXT_REG_Rn(uc
, 13), sizeof (mgreg_t
) * MONO_SAVED_GREGS
);
410 memcpy (&mctx
->fregs
, &UCONTEXT_REG_FPRn(uc
, 14), sizeof (double) * MONO_SAVED_FREGS
);
414 mono_monoctx_to_sigctx (MonoContext
*mctx
, void *sigctx
)
416 os_ucontext
*uc
= sigctx
;
418 UCONTEXT_REG_NIP(uc
) = mctx
->sc_ir
;
419 UCONTEXT_REG_Rn(uc
, 1) = mctx
->sc_sp
;
420 memcpy (&UCONTEXT_REG_Rn(uc
, 13), &mctx
->regs
, sizeof (mgreg_t
) * MONO_SAVED_GREGS
);
421 memcpy (&UCONTEXT_REG_FPRn(uc
, 14), &mctx
->fregs
, sizeof (double) * MONO_SAVED_FREGS
);
424 #endif /* #if defined(__i386__) */