[amd64] Fully initialize the the MonoContext used by the generic trampoline code.
authorZoltan Varga <vargaz@gmail.com>
Mon, 1 Jun 2015 22:42:32 +0000 (18:42 -0400)
committerZoltan Varga <vargaz@gmail.com>
Mon, 1 Jun 2015 22:42:32 +0000 (18:42 -0400)
mono/mini/exceptions-amd64.c
mono/mini/mini-amd64.h
mono/mini/tramp-amd64.c

index d10de0296914d607533b85762301deda555aa9c9..12a8675dffee0e83b0af45b8c16a17242f676baa 100644 (file)
@@ -586,7 +586,11 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
                        return TRUE;
                }
 
-               if (((guint64)(*lmf)->previous_lmf) & 1) {
+               if (((guint64)(*lmf)->previous_lmf) & 4) {
+                       MonoLMFTramp *ext = (MonoLMFTramp*)(*lmf);
+
+                       rip = (guint64)MONO_CONTEXT_GET_IP (ext->ctx);
+               } else if (((guint64)(*lmf)->previous_lmf) & 1) {
                        /* This LMF has the rip field set */
                        rip = (*lmf)->rip;
                } else if ((*lmf)->rsp == 0) {
@@ -610,29 +614,27 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
                if (!ji)
                        return FALSE;
 
-               /* Adjust IP */
-               rip --;
-
                frame->ji = ji;
                frame->type = FRAME_TYPE_MANAGED_TO_NATIVE;
 
-               new_ctx->gregs [AMD64_RIP] = rip;
-               new_ctx->gregs [AMD64_RBP] = (*lmf)->rbp;
-               new_ctx->gregs [AMD64_RSP] = (*lmf)->rsp;
-
                if (((guint64)(*lmf)->previous_lmf) & 4) {
                        MonoLMFTramp *ext = (MonoLMFTramp*)(*lmf);
 
                        /* Trampoline frame */
-                       for (i = 0; i < AMD64_NREG; ++i) {
-                               if (AMD64_IS_CALLEE_SAVED_REG (i) && i != AMD64_RBP)
-                                       new_ctx->gregs [i] = ext->ctx->gregs [i];
-                       }
+                       for (i = 0; i < AMD64_NREG; ++i)
+                               new_ctx->gregs [i] = ext->ctx->gregs [i];
+                       /* Adjust IP */
+                       new_ctx->gregs [AMD64_RIP] --;
                } else {
                        /*
                         * The registers saved in the LMF will be restored using the normal unwind info,
                         * when the wrapper frame is processed.
                         */
+                       /* Adjust IP */
+                       rip --;
+                       new_ctx->gregs [AMD64_RIP] = rip;
+                       new_ctx->gregs [AMD64_RSP] = (*lmf)->rsp;
+                       new_ctx->gregs [AMD64_RBP] = (*lmf)->rbp;
                        for (i = 0; i < AMD64_NREG; ++i) {
                                if (AMD64_IS_CALLEE_SAVED_REG (i) && i != AMD64_RBP)
                                        new_ctx->gregs [i] = 0;
@@ -976,7 +978,7 @@ mono_arch_notify_pending_exc (MonoThreadInfo *info)
                /* Initial LMF */
                return;
 
-       if ((guint64)lmf->previous_lmf & 1)
+       if ((guint64)lmf->previous_lmf & 5)
                /* Already hijacked or trampoline LMF entry */
                return;
 
index 5bdbfbd6462f0814657205d51cfd120036e911c1..3588a31e86aa050f20605ebecc15ac256d689b62 100644 (file)
@@ -171,7 +171,8 @@ struct MonoLMF {
         * the caller ip is saved.
         * If the second lowest bit is set, then this is a MonoLMFExt structure, and
         * the other fields are not valid.
-        * If the third lowest bit is set, then this is a MonoLMFTramp structure.
+        * If the third lowest bit is set, then this is a MonoLMFTramp structure, and
+        * the 'rbp' field is not valid.
         */
        gpointer    previous_lmf;
 #if defined(__default_codegen__) || defined(HOST_WIN32)
index 78bcad3106dbfe284e00169417f9155796164d59..4be828414da66c2fdd47259d72db0fc4ae9060ee 100644 (file)
@@ -497,6 +497,16 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
                        /* RAX is already saved */
                        amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RBP, rbp_offset, sizeof(mgreg_t));
                        amd64_mov_membase_reg (code, AMD64_RBP, saved_regs_offset + (i * sizeof(mgreg_t)), AMD64_RAX, sizeof(mgreg_t));
+               } else if (i == AMD64_RIP) {
+                       if (has_caller)
+                               amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, 8, sizeof(gpointer));
+                       else
+                               amd64_mov_reg_imm (code, AMD64_R11, 0);
+                       amd64_mov_membase_reg (code, AMD64_RBP, saved_regs_offset + (i * sizeof(mgreg_t)), AMD64_R11, sizeof(mgreg_t));
+               } else if (i == AMD64_RSP) {
+                       amd64_mov_reg_reg (code, AMD64_R11, AMD64_RSP, sizeof(mgreg_t));
+                       amd64_alu_reg_imm (code, X86_ADD, AMD64_R11, framesize + 16);
+                       amd64_mov_membase_reg (code, AMD64_RBP, saved_regs_offset + (i * sizeof(mgreg_t)), AMD64_R11, sizeof(mgreg_t));
                } else if (i != AMD64_R11) {
                        amd64_mov_membase_reg (code, AMD64_RBP, saved_regs_offset + (i * sizeof(mgreg_t)), i, sizeof(mgreg_t));
                } else {
@@ -590,14 +600,11 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        else
                amd64_mov_reg_imm (code, AMD64_R11, 0);
        amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + MONO_STRUCT_OFFSET (MonoLMF, rip), AMD64_R11, sizeof(mgreg_t));
-       /* Save fp */
-       amd64_mov_reg_membase (code, AMD64_R11, AMD64_RSP, framesize, sizeof(mgreg_t));
-       amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + MONO_STRUCT_OFFSET (MonoLMF, rbp), AMD64_R11, sizeof(mgreg_t));
        /* Save sp */
        amd64_mov_reg_reg (code, AMD64_R11, AMD64_RSP, sizeof(mgreg_t));
        amd64_alu_reg_imm (code, X86_ADD, AMD64_R11, framesize + 16);
        amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + MONO_STRUCT_OFFSET (MonoLMF, rsp), AMD64_R11, sizeof(mgreg_t));
-       /* Save pointer to registers */
+       /* Save pointer to context */
        amd64_lea_membase (code, AMD64_R11, AMD64_RBP, ctx_offset);
        amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + MONO_STRUCT_OFFSET (MonoLMFTramp, ctx), AMD64_R11, sizeof(mgreg_t));