[amd64] Fully initialize the the MonoContext used by the generic trampoline code.
[mono.git] / mono / mini / tramp-amd64.c
index 3d98213711059359b36a0d9b96b48c4fbce10606..4be828414da66c2fdd47259d72db0fc4ae9060ee 100644 (file)
@@ -401,7 +401,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
 {
        char *tramp_name;
        guint8 *buf, *code, *tramp, *br [2], *r11_save_code, *after_r11_save_code;
-       int i, lmf_offset, offset, res_offset, arg_offset, rax_offset, tramp_offset, saved_regs_offset;
+       int i, lmf_offset, offset, res_offset, arg_offset, rax_offset, tramp_offset, ctx_offset, saved_regs_offset;
        int saved_fpregs_offset, rbp_offset, framesize, orig_rsp_to_rbp_offset, cfa_offset;
        gboolean has_caller;
        GSList *unwind_ops = NULL;
@@ -435,11 +435,10 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        offset += sizeof(mgreg_t);
        res_offset = -offset;
 
-       offset += AMD64_NREG * sizeof (mgreg_t);
-       saved_regs_offset = -offset;
-
-       offset += 8 * sizeof(mgreg_t);
-       saved_fpregs_offset = -offset;
+       offset += sizeof (MonoContext);
+       ctx_offset = -offset;
+       saved_regs_offset = ctx_offset + MONO_STRUCT_OFFSET (MonoContext, gregs);
+       saved_fpregs_offset = ctx_offset + MONO_STRUCT_OFFSET (MonoContext, fregs);
 
        offset += sizeof (MonoLMFTramp);
        lmf_offset = -offset;
@@ -448,8 +447,8 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
 
        orig_rsp_to_rbp_offset = 0;
        r11_save_code = code;
-       /* Reserve 5 bytes for the mov_membase_reg to save R11 */
-       code += 5;
+       /* Reserve space for the mov_membase_reg to save R11 */
+       code += 8;
        after_r11_save_code = code;
 
        // CFA = sp + 16 (the trampoline address is on the stack)
@@ -498,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 {
@@ -591,16 +600,13 @@ 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 */
-       amd64_lea_membase (code, AMD64_R11, AMD64_RBP, saved_regs_offset);
-       amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + MONO_STRUCT_OFFSET (MonoLMFTramp, regs), AMD64_R11, sizeof(mgreg_t));
+       /* 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));
 
        if (aot) {
                code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_get_lmf_addr");
@@ -679,7 +685,6 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        for (i = 0; i < AMD64_NREG; ++i)
                if (AMD64_IS_ARGUMENT_REG (i) || i == AMD64_R10 || i == AMD64_RAX)
                        amd64_mov_reg_membase (code, i, AMD64_RBP, saved_regs_offset + (i * sizeof(mgreg_t)), sizeof(mgreg_t));
-
        for (i = 0; i < 8; ++i)
                amd64_movsd_reg_membase (code, i, AMD64_RBP, saved_fpregs_offset + (i * sizeof(mgreg_t)));