if (((code [-13] == 0x49) && (code [-12] == 0xbb)) || (code [-5] == 0xe8)) {
if (code [-5] != 0xe8) {
if (can_write) {
+ g_assert ((guint64)(orig_code - 11) % 8 == 0);
InterlockedExchangePointer ((gpointer*)(orig_code - 11), addr);
VALGRIND_DISCARD_TRANSLATIONS (orig_code - 11, sizeof (gpointer));
}
MonoJumpInfo *ji = NULL;
const guint kMaxCodeSize = 630;
- if (tramp_type == MONO_TRAMPOLINE_JUMP || tramp_type == MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD)
+ if (tramp_type == MONO_TRAMPOLINE_JUMP)
has_caller = FALSE;
else
has_caller = TRUE;
mono_amd64_patch (br [0], code);
//amd64_breakpoint (code);
- if (tramp_type != MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD) {
- /* Obtain the trampoline argument which is encoded in the instruction stream */
- if (aot) {
- /* Load the GOT offset */
- amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, tramp_offset, sizeof(gpointer));
- /*
- * r11 points to a call *<offset>(%rip) instruction, load the
- * pc-relative offset from the instruction itself.
- */
- amd64_mov_reg_membase (code, AMD64_RAX, AMD64_R11, 3, 4);
- /* 7 is the length of the call, 8 is the offset to the next got slot */
- amd64_alu_reg_imm_size (code, X86_ADD, AMD64_RAX, 7 + sizeof (gpointer), sizeof(gpointer));
- /* Compute the address of the GOT slot */
- amd64_alu_reg_reg_size (code, X86_ADD, AMD64_R11, AMD64_RAX, sizeof(gpointer));
- /* Load the value */
- amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 0, sizeof(gpointer));
- } else {
- amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, tramp_offset, sizeof(gpointer));
- amd64_mov_reg_membase (code, AMD64_RAX, AMD64_R11, 5, 1);
- amd64_widen_reg (code, AMD64_RAX, AMD64_RAX, TRUE, FALSE);
- amd64_alu_reg_imm_size (code, X86_CMP, AMD64_RAX, 4, 1);
- br [0] = code;
- x86_branch8 (code, X86_CC_NE, 6, FALSE);
- /* 32 bit immediate */
- amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 6, 4);
- br [1] = code;
- x86_jump8 (code, 10);
- /* 64 bit immediate */
- mono_amd64_patch (br [0], code);
- amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 6, 8);
- mono_amd64_patch (br [1], code);
- }
- amd64_mov_membase_reg (code, AMD64_RBP, arg_offset, AMD64_R11, sizeof(gpointer));
+ /* Obtain the trampoline argument which is encoded in the instruction stream */
+ if (aot) {
+ /* Load the GOT offset */
+ amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, tramp_offset, sizeof(gpointer));
+ /*
+ * r11 points to a call *<offset>(%rip) instruction, load the
+ * pc-relative offset from the instruction itself.
+ */
+ amd64_mov_reg_membase (code, AMD64_RAX, AMD64_R11, 3, 4);
+ /* 7 is the length of the call, 8 is the offset to the next got slot */
+ amd64_alu_reg_imm_size (code, X86_ADD, AMD64_RAX, 7 + sizeof (gpointer), sizeof(gpointer));
+ /* Compute the address of the GOT slot */
+ amd64_alu_reg_reg_size (code, X86_ADD, AMD64_R11, AMD64_RAX, sizeof(gpointer));
+ /* Load the value */
+ amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 0, sizeof(gpointer));
} else {
- amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, saved_regs_offset + (MONO_AMD64_ARG_REG1 * sizeof(mgreg_t)), sizeof(mgreg_t));
- amd64_mov_membase_reg (code, AMD64_RBP, arg_offset, AMD64_R11, sizeof(gpointer));
+ amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, tramp_offset, sizeof(gpointer));
+ amd64_mov_reg_membase (code, AMD64_RAX, AMD64_R11, 5, 1);
+ amd64_widen_reg (code, AMD64_RAX, AMD64_RAX, TRUE, FALSE);
+ amd64_alu_reg_imm_size (code, X86_CMP, AMD64_RAX, 4, 1);
+ br [0] = code;
+ x86_branch8 (code, X86_CC_NE, 6, FALSE);
+ /* 32 bit immediate */
+ amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 6, 4);
+ br [1] = code;
+ x86_jump8 (code, 10);
+ /* 64 bit immediate */
+ mono_amd64_patch (br [0], code);
+ amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 6, 8);
+ mono_amd64_patch (br [1], code);
}
+ amd64_mov_membase_reg (code, AMD64_RBP, arg_offset, AMD64_R11, sizeof(gpointer));
/* Save LMF begin */
g_free (rgctx_null_jumps);
- /* move the rgctx pointer to the VTABLE register */
- amd64_mov_reg_reg (code, MONO_ARCH_VTABLE_REG, AMD64_ARG_REG1, sizeof(gpointer));
+ if (MONO_ARCH_VTABLE_REG != AMD64_ARG_REG1) {
+ /* move the rgctx pointer to the VTABLE register */
+ amd64_mov_reg_reg (code, MONO_ARCH_VTABLE_REG, AMD64_ARG_REG1, sizeof(gpointer));
+ }
if (aot) {
code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, g_strdup_printf ("specific_trampoline_lazy_fetch_%u", slot));
}
#endif /* !DISABLE_JIT */
-gpointer
-mono_amd64_handler_block_trampoline_helper (void)
-{
- MonoJitTlsData *jit_tls = (MonoJitTlsData *)mono_tls_get_jit_tls ();
- return jit_tls->handler_block_return_address;
-}
-
-#ifndef DISABLE_JIT
-gpointer
-mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot)
-{
- guint8 *code, *buf;
- int tramp_size = 64;
- MonoJumpInfo *ji = NULL;
- GSList *unwind_ops;
-
- code = buf = (guint8 *)mono_global_codeman_reserve (tramp_size + MONO_TRAMPOLINE_UNWINDINFO_SIZE(0));
-
- unwind_ops = mono_arch_get_cie_program ();
-
- /*
- * This trampoline restore the call chain of the handler block then jumps into the code that deals with it.
- * We get here from the ret emitted by CEE_ENDFINALLY.
- * The stack is misaligned.
- */
- /* Align the stack before the call to mono_amd64_handler_block_trampoline_helper() */
-#ifdef TARGET_WIN32
- /* Also make room for the "register parameter stack area" as specified by the Windows x64 ABI (4 64-bit registers) */
- amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, 8 + 4 * 8);
-#else
- amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, 8);
-#endif
- if (aot) {
- code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_amd64_handler_block_trampoline_helper");
- amd64_call_reg (code, AMD64_R11);
- } else {
- amd64_mov_reg_imm (code, AMD64_RAX, mono_amd64_handler_block_trampoline_helper);
- amd64_call_reg (code, AMD64_RAX);
- }
- /* Undo stack alignment */
-#ifdef TARGET_WIN32
- amd64_alu_reg_imm (code, X86_ADD, AMD64_RSP, 8 + 4 * 8);
-#else
- amd64_alu_reg_imm (code, X86_ADD, AMD64_RSP, 8);
-#endif
- /* Save the result to the stack */
- amd64_push_reg (code, AMD64_RAX);
-#ifdef TARGET_WIN32
- /* Make room for the "register parameter stack area" as specified by the Windows x64 ABI (4 64-bit registers) */
- amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, 4 * 8);
-#endif
- if (aot) {
- char *name = g_strdup_printf ("trampoline_func_%d", MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD);
- code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, name);
- amd64_mov_reg_reg (code, AMD64_RAX, AMD64_R11, 8);
- } else {
- amd64_mov_reg_imm (code, AMD64_RAX, mono_get_trampoline_func (MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD));
- }
- /* The stack is aligned */
- amd64_call_reg (code, AMD64_RAX);
-#ifdef TARGET_WIN32
- amd64_alu_reg_imm (code, X86_ADD, AMD64_RSP, 4 * 8);
-#endif
- /* Load return address */
- amd64_pop_reg (code, AMD64_RAX);
- /* The stack is misaligned, thats what the code we branch to expects */
- amd64_jump_reg (code, AMD64_RAX);
-
- mono_arch_flush_icache (buf, code - buf);
- MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf, MONO_PROFILER_CODE_BUFFER_HELPER, NULL));
- g_assert (code - buf <= tramp_size);
- g_assert_checked (mono_arch_unwindinfo_validate_size (unwind_ops, MONO_TRAMPOLINE_UNWINDINFO_SIZE(0)));
-
- *info = mono_tramp_info_create ("handler_block_trampoline", buf, code - buf, ji, unwind_ops);
-
- return buf;
-}
-#endif /* !DISABLE_JIT */
-
/*
* mono_arch_get_call_target:
*
return NULL;
}
-gpointer
-mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot)
-{
- g_assert_not_reached ();
- return NULL;
-}
-
void
mono_arch_invalidate_method (MonoJitInfo *ji, void *func, gpointer func_arg)
{