#include <config.h>
#include <glib.h>
+#include <mono/metadata/abi-details.h>
#include <mono/metadata/appdomain.h>
#include <mono/metadata/marshal.h>
#include <mono/metadata/tabledefs.h>
#define IS_REX(inst) (((inst) >= 0x40) && ((inst) <= 0x4f))
-static guint8* nullified_class_init_trampoline;
-
/*
* mono_arch_get_unbox_trampoline:
* @m: method pointer
/* Print some diagnostics */
MonoJitInfo *ji = mono_jit_info_table_find (mono_domain_get (), (char*)orig_code);
if (ji)
- fprintf (stderr, "At %s, offset 0x%zx\n", mono_method_full_name (ji->method, TRUE), (guint8*)orig_code - (guint8*)ji->code_start);
+ fprintf (stderr, "At %s, offset 0x%zx\n", mono_method_full_name (jinfo_get_method (ji), TRUE), (guint8*)orig_code - (guint8*)ji->code_start);
fprintf (stderr, "Addr: %p\n", addr);
ji = mono_jit_info_table_find (mono_domain_get (), (char*)addr);
if (ji)
- fprintf (stderr, "Callee: %s\n", mono_method_full_name (ji->method, TRUE));
+ fprintf (stderr, "Callee: %s\n", mono_method_full_name (jinfo_get_method (ji), TRUE));
g_assert_not_reached ();
#else
/*
guint8 buf [16];
MonoJitInfo *ji = NULL;
gboolean can_write;
+ gpointer tramp = mini_get_nullified_class_init_trampoline ();
if (mono_use_llvm) {
/* code - 7 might be before the start of the method */
vtable_slot = get_vcall_slot_addr (code, regs);
g_assert (vtable_slot);
- *vtable_slot = nullified_class_init_trampoline;
+ *vtable_slot = tramp;
} else if (buf [2] == 0xe8) {
/* call <TARGET> */
//guint8 *buf = code - 2;
buf [4] = 0x90;
*/
- mono_arch_patch_callsite (code - 5, code, nullified_class_init_trampoline);
+ mono_arch_patch_callsite (code - 5, code, tramp);
} else if ((buf [5] == 0xff) && x86_modrm_mod (buf [6]) == 3 && x86_modrm_reg (buf [6]) == 2) {
/* call *<reg> */
/* Generated by the LLVM JIT or on platforms without MAP_32BIT set */
- mono_arch_patch_callsite (code - 13, code, nullified_class_init_trampoline);
+ mono_arch_patch_callsite (code - 13, code, tramp);
} else if (buf [4] == 0x90 || buf [5] == 0xeb || buf [6] == 0x66) {
/* Already changed by another thread */
;
}
}
-void
-mono_arch_nullify_plt_entry (guint8 *code, mgreg_t *regs)
-{
- if (mono_aot_only && !nullified_class_init_trampoline)
- nullified_class_init_trampoline = mono_aot_get_trampoline ("nullified_class_init_trampoline");
-
- mono_arch_patch_plt_entry (code, NULL, regs, nullified_class_init_trampoline);
-}
-
static void
stack_unaligned (MonoTrampolineType tramp_type)
{
code = buf = mono_global_codeman_reserve (kMaxCodeSize);
- framesize = kMaxCodeSize + sizeof (MonoLMF);
+ framesize = kMaxCodeSize + sizeof (MonoLMFTramp);
framesize = (framesize + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
orig_rsp_to_rbp_offset = 0;
/* Save LMF begin */
- offset += sizeof (MonoLMF);
+ offset += sizeof (MonoLMFTramp);
lmf_offset = - offset;
/* Save ip */
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, lmf_offset + G_STRUCT_OFFSET (MonoLMF, rip), AMD64_R11, sizeof(mgreg_t));
+ 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 + G_STRUCT_OFFSET (MonoLMF, rbp), AMD64_R11, 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 + G_STRUCT_OFFSET (MonoLMF, rsp), AMD64_R11, sizeof(mgreg_t));
- /* Save method */
- if (tramp_type == MONO_TRAMPOLINE_JIT || tramp_type == MONO_TRAMPOLINE_JUMP) {
- amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, arg_offset, sizeof(gpointer));
- amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, method), AMD64_R11, sizeof(gpointer));
- } else {
- amd64_mov_membase_imm (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, method), 0, sizeof(gpointer));
- }
- /* Save callee saved regs */
-#ifdef TARGET_WIN32
- amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, rdi), AMD64_RDI, sizeof(mgreg_t));
- amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, rsi), AMD64_RSI, sizeof(mgreg_t));
-#endif
- amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, rbx), AMD64_RBX, sizeof(mgreg_t));
- amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, r12), AMD64_R12, sizeof(mgreg_t));
- amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, r13), AMD64_R13, sizeof(mgreg_t));
- amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, r14), AMD64_R14, sizeof(mgreg_t));
- amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, r15), AMD64_R15, sizeof(mgreg_t));
+ 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));
if (aot) {
code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_get_lmf_addr");
amd64_call_reg (code, AMD64_R11);
/* Save lmf_addr */
- amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, lmf_addr), AMD64_RAX, sizeof(gpointer));
+ amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + MONO_STRUCT_OFFSET (MonoLMFTramp, lmf_addr), AMD64_RAX, sizeof(gpointer));
/* Save previous_lmf */
- /* Set the lowest bit to 1 to signal that this LMF has the ip field set */
+ /* Set the lowest bit to signal that this LMF has the ip field set */
+ /* Set the third lowest bit to signal that this is a MonoLMFTramp structure */
amd64_mov_reg_membase (code, AMD64_R11, AMD64_RAX, 0, sizeof(gpointer));
- amd64_alu_reg_imm_size (code, X86_ADD, AMD64_R11, 1, sizeof(gpointer));
- amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), AMD64_R11, sizeof(gpointer));
+ amd64_alu_reg_imm_size (code, X86_ADD, AMD64_R11, 0x5, sizeof(gpointer));
+ amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + MONO_STRUCT_OFFSET (MonoLMF, previous_lmf), AMD64_R11, sizeof(gpointer));
/* Set new lmf */
amd64_lea_membase (code, AMD64_R11, AMD64_RBP, lmf_offset);
amd64_mov_membase_reg (code, AMD64_RAX, 0, AMD64_R11, sizeof(gpointer));
amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RBP, res_offset, sizeof(mgreg_t));
/* Restore LMF */
-
- amd64_mov_reg_membase (code, AMD64_RCX, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), sizeof(gpointer));
- amd64_alu_reg_imm_size (code, X86_SUB, AMD64_RCX, 1, sizeof(gpointer));
- amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, lmf_addr), sizeof(gpointer));
+ amd64_mov_reg_membase (code, AMD64_RCX, AMD64_RBP, lmf_offset + MONO_STRUCT_OFFSET (MonoLMF, previous_lmf), sizeof(gpointer));
+ amd64_alu_reg_imm_size (code, X86_SUB, AMD64_RCX, 0x5, sizeof(gpointer));
+ amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, lmf_offset + MONO_STRUCT_OFFSET (MonoLMFTramp, lmf_addr), sizeof(gpointer));
amd64_mov_membase_reg (code, AMD64_R11, 0, AMD64_RCX, sizeof(gpointer));
/*
mono_arch_flush_icache (buf, code - buf);
- if (tramp_type == MONO_TRAMPOLINE_CLASS_INIT) {
- /* Initialize the nullified class init trampoline used in the AOT case */
- nullified_class_init_trampoline = mono_arch_get_nullified_class_init_trampoline (NULL);
- }
-
if (info) {
tramp_name = mono_get_generic_trampoline_name (tramp_type);
*info = mono_tramp_info_create (tramp_name, buf, code - buf, ji, unwind_ops);
if (info)
*info = mono_tramp_info_create ("nullified_class_init_trampoline", buf, code - buf, NULL, NULL);
- if (mono_jit_map_is_enabled ())
- mono_emit_jit_tramp (buf, code - buf, "nullified_class_init_trampoline");
-
return buf;
}
amd64_mov_reg_reg (code, AMD64_RAX, AMD64_ARG_REG1, 8);
} else {
/* load rgctx ptr from vtable */
- amd64_mov_reg_membase (code, AMD64_RAX, AMD64_ARG_REG1, G_STRUCT_OFFSET (MonoVTable, runtime_generic_context), sizeof(gpointer));
+ amd64_mov_reg_membase (code, AMD64_RAX, AMD64_ARG_REG1, MONO_STRUCT_OFFSET (MonoVTable, runtime_generic_context), sizeof(gpointer));
/* is the rgctx ptr null? */
amd64_test_reg_reg (code, AMD64_RAX, AMD64_RAX);
/* if yes, jump to actual trampoline */
unwind_ops = mono_arch_get_cie_program ();
- if (mono_thread_get_tls_offset () != -1) {
+ if (!aot && mono_thread_get_tls_offset () != -1) {
/* MonoObject* obj is in RDI */
/* is obj null? */
amd64_test_reg_reg (code, AMD64_RDI, AMD64_RDI);
amd64_branch8 (code, X86_CC_Z, -1, 1);
/* load obj->synchronization to RCX */
- amd64_mov_reg_membase (code, AMD64_RCX, AMD64_RDI, G_STRUCT_OFFSET (MonoObject, synchronisation), 8);
+ amd64_mov_reg_membase (code, AMD64_RCX, AMD64_RDI, MONO_STRUCT_OFFSET (MonoObject, synchronisation), 8);
if (mono_gc_is_moving ()) {
/*if bit zero is set it's a thin hash*/
/* load MonoInternalThread* into RDX */
code = mono_amd64_emit_tls_get (code, AMD64_RDX, mono_thread_get_tls_offset ());
/* load TID into RDX */
- amd64_mov_reg_membase (code, AMD64_RDX, AMD64_RDX, G_STRUCT_OFFSET (MonoInternalThread, tid), 8);
+ amd64_mov_reg_membase (code, AMD64_RDX, AMD64_RDX, MONO_STRUCT_OFFSET (MonoInternalThread, tid), 8);
/* is synchronization->owner null? */
amd64_alu_membase_imm_size (code, X86_CMP, AMD64_RCX, owner_offset, 0, 8);
unwind_ops = mono_arch_get_cie_program ();
- if (mono_thread_get_tls_offset () != -1) {
+ if (!aot && mono_thread_get_tls_offset () != -1) {
/* MonoObject* obj is in RDI */
/* is obj null? */
amd64_test_reg_reg (code, AMD64_RDI, AMD64_RDI);
amd64_branch8 (code, X86_CC_Z, -1, 1);
/* load obj->synchronization to RCX */
- amd64_mov_reg_membase (code, AMD64_RCX, AMD64_RDI, G_STRUCT_OFFSET (MonoObject, synchronisation), 8);
+ amd64_mov_reg_membase (code, AMD64_RCX, AMD64_RDI, MONO_STRUCT_OFFSET (MonoObject, synchronisation), 8);
if (mono_gc_is_moving ()) {
/*if bit zero is set it's a thin hash*/
/* load MonoInternalThread* into RDX */
code = mono_amd64_emit_tls_get (code, AMD64_RDX, mono_thread_get_tls_offset ());
/* load TID into RDX */
- amd64_mov_reg_membase (code, AMD64_RDX, AMD64_RDX, G_STRUCT_OFFSET (MonoInternalThread, tid), 8);
+ amd64_mov_reg_membase (code, AMD64_RDX, AMD64_RDX, MONO_STRUCT_OFFSET (MonoInternalThread, tid), 8);
/* is synchronization->owner == TID */
amd64_alu_membase_reg_size (code, X86_CMP, AMD64_RCX, owner_offset, AMD64_RDX, 8);
/* if no, jump to actual trampoline */
}
gpointer
-mono_arch_create_handler_block_trampoline (void)
+mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot)
{
guint8 *tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD);
guint8 *code, *buf;
int tramp_size = 64;
+ MonoJumpInfo *ji = NULL;
+ GSList *unwind_ops = NULL;
+
+ g_assert (!aot);
+
code = buf = mono_global_codeman_reserve (tramp_size);
/*
if (mono_get_jit_tls_offset () != -1) {
code = mono_amd64_emit_tls_get (code, AMD64_RDI, mono_get_jit_tls_offset ());
- amd64_mov_reg_membase (code, AMD64_RDI, AMD64_RDI, G_STRUCT_OFFSET (MonoJitTlsData, handler_block_return_address), 8);
+ amd64_mov_reg_membase (code, AMD64_RDI, AMD64_RDI, MONO_STRUCT_OFFSET (MonoJitTlsData, handler_block_return_address), 8);
/* Simulate a call */
amd64_push_reg (code, AMD64_RAX);
amd64_jump_code (code, tramp);
mono_arch_flush_icache (buf, code - buf);
g_assert (code - buf <= tramp_size);
- if (mono_jit_map_is_enabled ())
- mono_emit_jit_tramp (buf, code - buf, "handler_block_trampoline");
+ if (info)
+ *info = mono_tramp_info_create ("handler_block_trampoline", buf, code - buf, ji, unwind_ops);
return buf;
}
mono_arch_get_call_target (guint8 *code)
{
if (code [-5] == 0xe8) {
- guint32 disp = *(guint32*)(code - 4);
+ gint32 disp = *(gint32*)(code - 4);
guint8 *target = code + disp;
return target;