#include <signal.h>
#endif
+#if defined (HOST_WATCHOS) || defined (HOST_APPLETVOS)
+#include <libunwind.h>
+#endif
+
/*
* General notes about mono-context.
* Each arch defines a MonoContext struct with all GPR regs + IP/PC.
typedef struct {
mgreg_t gregs [AMD64_NREG];
+ double fregs [AMD64_XMM_NREG];
} MonoContext;
#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->gregs [AMD64_RIP] = (mgreg_t)(ip); } while (0);
#define MONO_CONTEXT_GET_CURRENT(ctx) \
__asm__ __volatile__( \
"movq $0x0, %%nacl:0x00(%%r15, %0, 1)\n" \
- "movq %%rbx, %%nacl:0x08(%%r15, %0, 1)\n" \
- "movq %%rcx, %%nacl:0x10(%%r15, %0, 1)\n" \
- "movq %%rdx, %%nacl:0x18(%%r15, %0, 1)\n" \
- "movq %%rbp, %%nacl:0x20(%%r15, %0, 1)\n" \
- "movq %%rsp, %%nacl:0x28(%%r15, %0, 1)\n" \
+ "movq %%rcx, %%nacl:0x08(%%r15, %0, 1)\n" \
+ "movq %%rdx, %%nacl:0x10(%%r15, %0, 1)\n" \
+ "movq %%rbx, %%nacl:0x18(%%r15, %0, 1)\n" \
+ "movq %%rsp, %%nacl:0x20(%%r15, %0, 1)\n" \
+ "movq %%rbp, %%nacl:0x28(%%r15, %0, 1)\n" \
"movq %%rsi, %%nacl:0x30(%%r15, %0, 1)\n" \
"movq %%rdi, %%nacl:0x38(%%r15, %0, 1)\n" \
"movq %%r8, %%nacl:0x40(%%r15, %0, 1)\n" \
: "a" ((int64_t)&(ctx)) \
: "rdx", "memory")
#else
+
#define MONO_CONTEXT_GET_CURRENT(ctx) \
__asm__ __volatile__( \
"movq $0x0, 0x00(%0)\n" \
- "movq %%rbx, 0x08(%0)\n" \
- "movq %%rcx, 0x10(%0)\n" \
- "movq %%rdx, 0x18(%0)\n" \
- "movq %%rbp, 0x20(%0)\n" \
- "movq %%rsp, 0x28(%0)\n" \
+ "movq %%rcx, 0x08(%0)\n" \
+ "movq %%rdx, 0x10(%0)\n" \
+ "movq %%rbx, 0x18(%0)\n" \
+ "movq %%rsp, 0x20(%0)\n" \
+ "movq %%rbp, 0x28(%0)\n" \
"movq %%rsi, 0x30(%0)\n" \
"movq %%rdi, 0x38(%0)\n" \
"movq %%r8, 0x40(%0)\n" \
#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->regs [ARMREG_FP]))
#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->regs [ARMREG_SP]))
+#if defined(HOST_WATCHOS)
+
+#define MONO_CONTEXT_GET_CURRENT(ctx) do { \
+ unw_context_t uctx; \
+ unw_cursor_t c; \
+ unw_word_t data; \
+ g_assert (unw_getcontext (&uctx) == 0); \
+ g_assert (unw_init_local (&c, &uctx) == 0); \
+ for (int reg = 0; reg < 13; ++reg) { \
+ unw_get_reg (&c, (unw_regnum_t) UNW_ARM_R0 + reg, &data); \
+ ctx.regs[reg] = data; \
+ } \
+ unw_get_reg (&c, UNW_ARM_SP, &data); \
+ ctx.regs[ARMREG_SP] = data; \
+ unw_get_reg (&c, UNW_ARM_LR, &data); \
+ ctx.regs[ARMREG_LR] = data; \
+ unw_get_reg (&c, UNW_ARM_IP, &data); \
+ ctx.regs[ARMREG_PC] = data; \
+ ctx.pc = ctx.regs[ARMREG_PC]; \
+ for (int reg = 0; reg < 16; ++reg) { \
+ unw_get_reg (&c, (unw_regnum_t) UNW_ARM_D0 + reg, &data); \
+ ctx.fregs[reg] = data; \
+ } \
+} while (0);
+
+#else
+
#define MONO_CONTEXT_GET_CURRENT(ctx) do { \
__asm__ __volatile__( \
"push {r0}\n" \
ctx.pc = ctx.regs [15]; \
} while (0)
+#endif
+
#define MONO_ARCH_HAS_MONO_CONTEXT 1
#elif (defined(__aarch64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM64))
#define MONO_CONTEXT_GET_BP(ctx) (gpointer)((ctx)->regs [ARMREG_FP])
#define MONO_CONTEXT_GET_SP(ctx) (gpointer)((ctx)->regs [ARMREG_SP])
+#if defined (HOST_APPLETVOS)
+
+#define MONO_CONTEXT_GET_CURRENT(ctx) do { \
+ fprintf (stderr, "MONO_CONTEXT_GET_CURRENT: Not implemented"); \
+ g_error ("MONO_CONTEXT_GET_CURRENT: Not implemented"); \
+} while (0);
+
+#else
+
#define MONO_CONTEXT_GET_CURRENT(ctx) do { \
__asm__ __volatile__( \
"mov x16, %0\n" \
: "x30", "memory" \
); \
__asm__ __volatile__( \
- "adr %0, L0\n" \
- "L0:\n" \
+ "adr %0, L0%=\n" \
+ "L0%=:\n" \
: "=r" (ctx.pc) \
: \
: "memory" \
); \
} while (0)
+#endif
+
#define MONO_ARCH_HAS_MONO_CONTEXT 1
#elif defined(__mono_ppc__) /* defined(__arm__) */
* We might also want to add an additional field to propagate
* the original context from the signal handler.
*/
+#ifdef __mono_ppc64__
+
+typedef struct {
+ gulong sc_ir; // pc
+ gulong sc_sp; // r1
+ mgreg_t regs [32];
+ double fregs [32];
+} MonoContext;
+
+/* we have the stack pointer, not the base pointer in sigcontext */
+#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->sc_ir = (gulong)ip; } while (0);
+#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->sc_sp = (gulong)bp; } while (0);
+#define MONO_CONTEXT_SET_SP(ctx,sp) do { (ctx)->sc_sp = (gulong)sp; } while (0);
+
+#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->sc_ir))
+#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->regs [ppc_r31-13]))
+#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->sc_sp))
+
+#define MONO_CONTEXT_GET_CURRENT(ctx) \
+ __asm__ __volatile__( \
+ "std 0, 0(%0)\n" \
+ "std 1, 8(%0)\n" \
+ "std 0, 8*0+16(%0)\n" \
+ "std 1, 8*1+16(%0)\n" \
+ "std 2, 8*2+16(%0)\n" \
+ "std 3, 8*3+16(%0)\n" \
+ "std 4, 8*4+16(%0)\n" \
+ "std 5, 8*5+16(%0)\n" \
+ "std 6, 8*6+16(%0)\n" \
+ "std 7, 8*7+16(%0)\n" \
+ "std 8, 8*8+16(%0)\n" \
+ "std 9, 8*9+16(%0)\n" \
+ "std 10, 8*10+16(%0)\n" \
+ "std 11, 8*11+16(%0)\n" \
+ "std 12, 8*12+16(%0)\n" \
+ "std 13, 8*13+16(%0)\n" \
+ "std 14, 8*14+16(%0)\n" \
+ "std 15, 8*15+16(%0)\n" \
+ "std 16, 8*16+16(%0)\n" \
+ "std 17, 8*17+16(%0)\n" \
+ "std 18, 8*18+16(%0)\n" \
+ "std 19, 8*19+16(%0)\n" \
+ "std 20, 8*20+16(%0)\n" \
+ "std 21, 8*21+16(%0)\n" \
+ "std 22, 8*22+16(%0)\n" \
+ "std 23, 8*23+16(%0)\n" \
+ "std 24, 8*24+16(%0)\n" \
+ "std 25, 8*25+16(%0)\n" \
+ "std 26, 8*26+16(%0)\n" \
+ "std 27, 8*27+16(%0)\n" \
+ "std 28, 8*28+16(%0)\n" \
+ "std 29, 8*29+16(%0)\n" \
+ "std 30, 8*30+16(%0)\n" \
+ "std 31, 8*31+16(%0)\n" \
+ "stfd 0, 8*0+8*32+16(%0)\n" \
+ "stfd 1, 8*1+8*32+16(%0)\n" \
+ "stfd 2, 8*2+8*32+16(%0)\n" \
+ "stfd 3, 8*3+8*32+16(%0)\n" \
+ "stfd 4, 8*4+8*32+16(%0)\n" \
+ "stfd 5, 8*5+8*32+16(%0)\n" \
+ "stfd 6, 8*6+8*32+16(%0)\n" \
+ "stfd 7, 8*7+8*32+16(%0)\n" \
+ "stfd 8, 8*8+8*32+16(%0)\n" \
+ "stfd 9, 8*9+8*32+16(%0)\n" \
+ "stfd 10, 8*10+8*32+16(%0)\n" \
+ "stfd 11, 8*11+8*32+16(%0)\n" \
+ "stfd 12, 8*12+8*32+16(%0)\n" \
+ "stfd 13, 8*13+8*32+16(%0)\n" \
+ "stfd 14, 8*14+8*32+16(%0)\n" \
+ "stfd 15, 8*15+8*32+16(%0)\n" \
+ "stfd 16, 8*16+8*32+16(%0)\n" \
+ "stfd 17, 8*17+8*32+16(%0)\n" \
+ "stfd 18, 8*18+8*32+16(%0)\n" \
+ "stfd 19, 8*19+8*32+16(%0)\n" \
+ "stfd 20, 8*20+8*32+16(%0)\n" \
+ "stfd 21, 8*21+8*32+16(%0)\n" \
+ "stfd 22, 8*22+8*32+16(%0)\n" \
+ "stfd 23, 8*23+8*32+16(%0)\n" \
+ "stfd 24, 8*24+8*32+16(%0)\n" \
+ "stfd 25, 8*25+8*32+16(%0)\n" \
+ "stfd 26, 8*26+8*32+16(%0)\n" \
+ "stfd 27, 8*27+8*32+16(%0)\n" \
+ "stfd 28, 8*28+8*32+16(%0)\n" \
+ "stfd 29, 8*29+8*32+16(%0)\n" \
+ "stfd 30, 8*30+8*32+16(%0)\n" \
+ "stfd 31, 8*31+8*32+16(%0)\n" \
+ : : "r" (&(ctx)) \
+ : "memory" \
+ )
+
+#define MONO_ARCH_HAS_MONO_CONTEXT 1
+
+#else
+
typedef struct {
gulong sc_ir; // pc
gulong sc_sp; // r1
#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->sc_ir))
#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->regs [ppc_r31-13]))
#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->sc_sp))
+#endif
#elif defined(__sparc__) || defined(sparc) /* defined(__mono_ppc__) */