X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Ftramp-amd64-gsharedvt.c;h=f5600adbde78198f5a9935ef9971316cc1abfb8c;hb=68be3904cf770be9f98a6ce0e8d71899cb94f189;hp=1be75933c8efa6041ac798234d72967e4c8f6b8d;hpb=69f207ee9e4f440e66e98bf5f685807f6527c39d;p=mono.git diff --git a/mono/mini/tramp-amd64-gsharedvt.c b/mono/mini/tramp-amd64-gsharedvt.c index 1be75933c8e..f5600adbde7 100644 --- a/mono/mini/tramp-amd64-gsharedvt.c +++ b/mono/mini/tramp-amd64-gsharedvt.c @@ -5,6 +5,7 @@ * Zoltan Varga * Rodrigo Kumpera * Andi McClure + * Johan Lorensson * * Copyright 2015 Xamarin, Inc (http://www.xamarin.com) * Licensed under the MIT license. See LICENSE file in the project root for full license information. @@ -138,7 +139,6 @@ mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpoint amd64_jump_code (code, addr); g_assert ((code - start) < buf_len); - nacl_domain_code_validate (domain, &start, buf_len, &code); mono_arch_flush_icache (start, code - start); mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL); @@ -146,7 +146,6 @@ mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpoint return start; } - gpointer mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) { @@ -246,8 +245,8 @@ mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) - - + + */ /* Call start_gsharedvt_call () */ @@ -264,7 +263,23 @@ mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) if (aot) { code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_amd64_start_gsharedvt_call"); - amd64_call_reg (code, AMD64_R11); + #ifdef TARGET_WIN32 + /* Since we are doing a call as part of setting up stackframe, the reserved shadow stack used by Windows platform is allocated up in + the callee stack area but currently the callee reg area is in between. Windows calling convention dictates that room is made on stack where + callee can save any parameters passed in registers. Since Windows x64 calling convention + uses 4 registers for the first 4 parameters, stack needs to be adjusted before making the call. + NOTE, Windows calling convention assumes that space for all registers have been reserved, regardless + of the number of function parameters actually used. + */ + int shadow_reg_size = 0; + + shadow_reg_size = ALIGN_TO (PARAM_REGS * sizeof(gpointer), MONO_ARCH_FRAME_ALIGNMENT); + amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, shadow_reg_size); + amd64_call_reg (code, AMD64_R11); + amd64_alu_reg_imm (code, X86_ADD, AMD64_RSP, shadow_reg_size); + #else + amd64_call_reg (code, AMD64_R11); + #endif } else { g_error ("no aot"); } @@ -303,13 +318,14 @@ mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) */ /* Load vret_slot */ - amd64_mov_reg_membase (code, AMD64_RDI, AMD64_R10, MONO_STRUCT_OFFSET (GSharedVtCallInfo, vret_slot), 4); - amd64_alu_reg_imm (code, X86_SUB, AMD64_RDI, n_arg_regs + n_arg_fregs); - amd64_shift_reg_imm (code, X86_SHL, AMD64_RDI, 3); + /* Use first input parameter register as scratch since it is volatile on all platforms */ + amd64_mov_reg_membase (code, MONO_AMD64_ARG_REG1, AMD64_R10, MONO_STRUCT_OFFSET (GSharedVtCallInfo, vret_slot), 4); + amd64_alu_reg_imm (code, X86_SUB, MONO_AMD64_ARG_REG1, n_arg_regs + n_arg_fregs); + amd64_shift_reg_imm (code, X86_SHL, MONO_AMD64_ARG_REG1, 3); /* vret address is RBP - (framesize - caller_reg_area_offset) */ amd64_mov_reg_reg (code, AMD64_R11, AMD64_RSP, sizeof(mgreg_t)); - amd64_alu_reg_reg (code, X86_ADD, AMD64_R11, AMD64_RDI); + amd64_alu_reg_reg (code, X86_ADD, AMD64_R11, MONO_AMD64_ARG_REG1); /* Load ret marshal type */ /* Load vret address in R11 */ @@ -367,10 +383,10 @@ mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) /* Address to write return to is in the original value of the register specified by vret_arg_reg. - This will be either RSI or RDI depending on whether this is a static call. + This will be either RSI, RDI (System V) or RCX, RDX (Windows) depending on whether this is a static call. Its location: We alloc 'framesize' bytes below RBP to save regs, info and rgctx. RSP = RBP - framesize - We store rdi at RSP + caller_reg_area_offset + slot_index_of (register) * 8. + We store RDI (System V), RCX (Windows) at RSP + caller_reg_area_offset + slot_index_of (register) * 8. address: RBP - framesize + caller_reg_area_offset + 8*slot */ @@ -439,6 +455,22 @@ mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) return buf; } +#else + +gpointer +mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpointer addr) +{ + g_assert_not_reached (); + return NULL; +} + +gpointer +mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) +{ + g_assert_not_reached (); + return NULL; +} + #endif #else