Fix wrong conditional
[mono.git] / mono / utils / mono-context.h
index 71874a663e013c442f9326d2176d57af4103e2eb..a1395f0d8090f7fc109edbb150ee20e01186cbb7 100644 (file)
@@ -25,7 +25,7 @@
  * MONO_CONTEXT_GET_CURRENT captures the current context as close as possible. One reg might be clobbered
  *  to hold the address of the target MonoContext. It will be a caller save one, so should not be a problem.
  */
-#if defined(__i386__)
+#if (defined(__i386__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_X86))
 
 /*HACK, move this to an eventual mono-signal.c*/
 #if defined( __linux__) || defined(__sun) || defined(__APPLE__) || defined(__NetBSD__) || \
@@ -121,8 +121,11 @@ typedef struct {
        : "a" (&(ctx))  \
        : "memory")
 
+#if !defined(HOST_WIN32)
+#define MONO_ARCH_HAS_MONO_CONTEXT 1
+#endif
 
-#elif defined(__x86_64__) /* defined(__i386__) */
+#elif (defined(__x86_64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_AMD64)) /* defined(__i386__) */
 
 
 #if !defined( HOST_WIN32 ) && !defined(__native_client__) && !defined(__native_client_codegen__)
@@ -159,6 +162,31 @@ typedef struct {
 #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->rbp))
 #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->rsp))
 
+#if defined(__native_client__)
+#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 %%rsi, %%nacl:0x30(%%r15, %0, 1)\n"       \
+               "movq %%rdi, %%nacl:0x38(%%r15, %0, 1)\n"       \
+               "movq %%r8,  %%nacl:0x40(%%r15, %0, 1)\n"       \
+               "movq %%r9,  %%nacl:0x48(%%r15, %0, 1)\n"       \
+               "movq %%r10, %%nacl:0x50(%%r15, %0, 1)\n"       \
+               "movq %%r11, %%nacl:0x58(%%r15, %0, 1)\n"       \
+               "movq %%r12, %%nacl:0x60(%%r15, %0, 1)\n"       \
+               "movq %%r13, %%nacl:0x68(%%r15, %0, 1)\n"       \
+               "movq %%r14, %%nacl:0x70(%%r15, %0, 1)\n"       \
+               "movq %%r15, %%nacl:0x78(%%r15, %0, 1)\n"       \
+               "leaq (%%rip), %%rdx\n" \
+               "movq %%rdx, %%nacl:0x80(%%r15, %0, 1)\n"       \
+               :       \
+               : "a" ((int64_t)&(ctx)) \
+               : "rdx", "memory")
+#else
 #define MONO_CONTEXT_GET_CURRENT(ctx)  \
        __asm__ __volatile__(   \
                "movq $0x0,  0x00(%0)\n"        \
@@ -182,6 +210,11 @@ typedef struct {
                :       \
                : "a" (&(ctx))  \
                : "rdx", "memory")
+#endif
+
+#if !defined(HOST_WIN32)
+#define MONO_ARCH_HAS_MONO_CONTEXT 1
+#endif
 
 #elif defined(__arm__) /* defined(__x86_64__) */
 
@@ -190,6 +223,7 @@ typedef struct {
        gulong esp;          // sp
        gulong regs [16];
        double fregs [8];
+       gulong cpsr;
 } MonoContext;
 
 /* we have the stack pointer, not the base pointer in sigcontext */
@@ -201,7 +235,188 @@ typedef struct {
 #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->regs [ARMREG_FP]))
 #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->esp))
 
-#else  
+// FIXME:
+#define MONO_CONTEXT_GET_CURRENT(ctx)  do {    \
+       g_assert_not_reached (); \
+} while (0)
+
+#elif defined(__mono_ppc__) /* defined(__arm__) */
+
+/* we define our own structure and we'll copy the data
+ * from sigcontext/ucontext/mach when we need it.
+ * This also makes us save stack space and time when copying
+ * We might also want to add an additional field to propagate
+ * the original context from the signal handler.
+ */
+typedef struct {
+       gulong sc_ir;          // pc 
+       gulong sc_sp;          // r1
+       mgreg_t regs [19]; /*FIXME, this must be changed to 32 for sgen*/
+       double fregs [18];
+} 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);
+/* FIXME: should be called SET_SP */
+#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))
+
+#elif defined(__sparc__) || defined(sparc) /* defined(__mono_ppc__) */
+
+typedef struct MonoContext {
+       guint8 *ip;
+       gpointer *sp;
+       gpointer *fp;
+} MonoContext;
+
+#define MONO_CONTEXT_SET_IP(ctx,eip) do { (ctx)->ip = (gpointer)(eip); } while (0); 
+#define MONO_CONTEXT_SET_BP(ctx,ebp) do { (ctx)->fp = (gpointer*)(ebp); } while (0); 
+#define MONO_CONTEXT_SET_SP(ctx,esp) do { (ctx)->sp = (gpointer*)(esp); } while (0); 
+
+#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->ip))
+#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->fp))
+#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->sp))
+
+#elif defined(__ia64__) /*defined(__sparc__) || defined(sparc) */
+
+#ifndef UNW_LOCAL_ONLY
+
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+
+#endif
+
+typedef struct MonoContext {
+       unw_cursor_t cursor;
+       /* Whenever the ip in 'cursor' points to the ip where the exception happened */
+       /* This is true for the initial context for exceptions thrown from signal handlers */
+       gboolean precise_ip;
+} MonoContext;
+
+/*XXX SET_BP is missing*/
+#define MONO_CONTEXT_SET_IP(ctx,eip) do { int err = unw_set_reg (&(ctx)->cursor, UNW_IA64_IP, (unw_word_t)(eip)); g_assert (err == 0); } while (0)
+#define MONO_CONTEXT_SET_SP(ctx,esp) do { int err = unw_set_reg (&(ctx)->cursor, UNW_IA64_SP, (unw_word_t)(esp)); g_assert (err == 0); } while (0)
+
+#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)(mono_ia64_context_get_ip ((ctx))))
+#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)(mono_ia64_context_get_fp ((ctx))))
+#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)(mono_ia64_context_get_sp ((ctx))))
+
+static inline unw_word_t
+mono_ia64_context_get_ip (MonoContext *ctx)
+{
+       unw_word_t ip;
+       int err;
+
+       err = unw_get_reg (&ctx->cursor, UNW_IA64_IP, &ip);
+       g_assert (err == 0);
+
+       if (ctx->precise_ip) {
+               return ip;
+       } else {
+               /* Subtrack 1 so ip points into the actual instruction */
+               return ip - 1;
+       }
+}
+
+static inline unw_word_t
+mono_ia64_context_get_sp (MonoContext *ctx)
+{
+       unw_word_t sp;
+       int err;
+
+       err = unw_get_reg (&ctx->cursor, UNW_IA64_SP, &sp);
+       g_assert (err == 0);
+
+       return sp;
+}
+
+static inline unw_word_t
+mono_ia64_context_get_fp (MonoContext *ctx)
+{
+       unw_cursor_t new_cursor;
+       unw_word_t fp;
+       int err;
+
+       {
+               unw_word_t ip, sp;
+
+               err = unw_get_reg (&ctx->cursor, UNW_IA64_SP, &sp);
+               g_assert (err == 0);
+
+               err = unw_get_reg (&ctx->cursor, UNW_IA64_IP, &ip);
+               g_assert (err == 0);
+       }
+
+       /* fp is the SP of the parent frame */
+       new_cursor = ctx->cursor;
+
+       err = unw_step (&new_cursor);
+       g_assert (err >= 0);
+
+       err = unw_get_reg (&new_cursor, UNW_IA64_SP, &fp);
+       g_assert (err == 0);
+
+       return fp;
+}
+
+#elif defined(__mips__) && SIZEOF_REGISTER == 4 /* defined(__ia64__) */
+
+/* we define our own structure and we'll copy the data
+ * from sigcontext/ucontext/mach when we need it.
+ * This also makes us save stack space and time when copying
+ * We might also want to add an additional field to propagate
+ * the original context from the signal handler.
+ */
+typedef struct {
+       gpointer        sc_pc;
+       guint32         sc_regs [32];
+       gfloat          sc_fpregs [32];
+} MonoContext;
+
+/* we have the stack pointer, not the base pointer in sigcontext */
+#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->sc_pc = (int)(ip); } while (0);
+#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->sc_regs[mips_fp] = (int)(bp); } while (0);
+#define MONO_CONTEXT_SET_SP(ctx,sp) do { (ctx)->sc_regs[mips_sp] = (int)(sp); } while (0);
+
+#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->sc_pc))
+#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->sc_regs[mips_fp]))
+#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->sc_regs[mips_sp]))
+
+#elif defined(__s390x__)
+
+#define MONO_ARCH_HAS_MONO_CONTEXT 1
+
+typedef struct ucontext MonoContext;
+
+#define MONO_CONTEXT_SET_IP(ctx,ip)                                    \
+       do {                                                            \
+               (ctx)->uc_mcontext.gregs[14] = (unsigned long)ip;       \
+               (ctx)->uc_mcontext.psw.addr = (unsigned long)ip;        \
+       } while (0); 
+
+#define MONO_CONTEXT_SET_SP(ctx,bp) MONO_CONTEXT_SET_BP((ctx),(bp))
+#define MONO_CONTEXT_SET_BP(ctx,bp)                                    \
+       do {                                                            \
+               (ctx)->uc_mcontext.gregs[15] = (unsigned long)bp;       \
+               (ctx)->uc_stack.ss_sp        = (void*)bp;               \
+       } while (0) 
+
+#define MONO_CONTEXT_GET_IP(ctx) (gpointer) (ctx)->uc_mcontext.psw.addr
+#define MONO_CONTEXT_GET_BP(ctx) MONO_CONTEXT_GET_SP((ctx))
+#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->uc_mcontext.gregs[15]))
+
+#define MONO_CONTEXT_GET_CURRENT(ctx)  \
+       __asm__ __volatile__(   \
+               "stmg   %%r0,%%r15,0(%0)\n"     \
+               : : "r" (&(ctx).uc_mcontext.gregs[0])   \
+               : "memory"                      \
+       )
+
+#else
 
 #error "Implement mono-context for the current arch"