#include <mono/metadata/monitor.h>
#include <mono/arch/x86/x86-codegen.h>
-#ifdef HAVE_VALGRIND_MEMCHECK_H
-#include <valgrind/memcheck.h>
-#endif
+#include <mono/utils/memcheck.h>
#include "mini.h"
#include "mini-x86.h"
if (MONO_TYPE_ISSTRUCT (mono_method_signature (m)->ret))
this_pos = 8;
- mono_domain_lock (domain);
- start = code = mono_code_manager_reserve (domain->code_mp, 16);
- mono_domain_unlock (domain);
+ start = code = mono_domain_code_reserve (domain, 16);
x86_alu_membase_imm (code, X86_ADD, X86_ESP, this_pos, sizeof (MonoObject));
x86_jump_code (code, addr);
return start;
}
+gpointer
+mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericContext *mrgctx, gpointer addr)
+{
+ guint8 *code, *start;
+ int buf_len;
+
+ MonoDomain *domain = mono_domain_get ();
+
+ buf_len = 10;
+
+ start = code = mono_domain_code_reserve (domain, buf_len);
+
+ x86_mov_reg_imm (code, MONO_ARCH_RGCTX_REG, mrgctx);
+ x86_jump_code (code, addr);
+ g_assert ((code - start) <= buf_len);
+
+ mono_arch_flush_icache (start, code - start);
+
+ return start;
+}
+
+gpointer
+mono_arch_get_llvm_imt_trampoline (MonoDomain *domain, MonoMethod *m, int vt_offset)
+{
+ guint8 *code, *start;
+ int buf_len;
+ int this_offset;
+
+ buf_len = 32;
+
+ start = code = mono_domain_code_reserve (domain, buf_len);
+
+ this_offset = mono_x86_get_this_arg_offset (NULL, mono_method_signature (m));
+
+ /* Set imt arg */
+ x86_mov_reg_imm (code, MONO_ARCH_IMT_REG, m);
+ /* Load this */
+ x86_mov_reg_membase (code, X86_EAX, X86_ESP, this_offset + 4, 4);
+ /* Load vtable address */
+ x86_mov_reg_membase (code, X86_EAX, X86_EAX, 0, 4);
+ x86_jump_membase (code, X86_EAX, vt_offset);
+
+ g_assert ((code - start) < buf_len);
+
+ mono_arch_flush_icache (start, code - start);
+
+ return start;
+}
+
void
mono_arch_patch_callsite (guint8 *method_start, guint8 *orig_code, guint8 *addr)
{
gboolean can_write = mono_breakpoint_clean_code (method_start, orig_code, 8, buf, sizeof (buf));
code = buf + 8;
- if (mono_running_on_valgrind ())
- can_write = FALSE;
/* go to the start of the call instruction
*
if (can_write) {
InterlockedExchange ((gint32*)(orig_code + 2), (guint)addr - ((guint)orig_code + 1) - 5);
-#ifdef HAVE_VALGRIND_MEMCHECK_H
- /* Tell valgrind to recompile the patched code */
- //VALGRIND_DISCARD_TRANSLATIONS (code + 2, code + 6);
-#endif
+ /* Tell valgrind to recompile the patched code */
+ VALGRIND_DISCARD_TRANSLATIONS (orig_code + 2, 4);
}
} else if (code [1] == 0xe9) {
/* A PLT entry: jmp <DISP> */
}
void
-mono_arch_patch_plt_entry (guint8 *code, guint8 *addr)
+mono_arch_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr)
{
/* A PLT entry: jmp <DISP> */
g_assert (code [0] == 0xe9);
}
void
-mono_arch_nullify_class_init_trampoline (guint8 *code, gssize *regs)
+mono_arch_nullify_class_init_trampoline (guint8 *code, mgreg_t *regs)
{
guint8 buf [16];
gboolean can_write = mono_breakpoint_clean_code (NULL, code, 6, buf, sizeof (buf));
/* Then atomically change the first 4 bytes to a nop as well */
ops = 0x90909090;
InterlockedExchange ((gint32*)code, ops);
-#ifdef HAVE_VALGRIND_MEMCHECK_H
/* FIXME: the calltree skin trips on the self modifying code above */
/* Tell valgrind to recompile the patched code */
- //VALGRIND_DISCARD_TRANSLATIONS (code, code + 8);
-#endif
+ //VALGRIND_DISCARD_TRANSLATIONS (code, 8);
}
} else if (code [0] == 0x90 || code [0] == 0xeb) {
/* Already changed by another thread */
/* call *<OFFSET>(<REG>) -> Call made from AOT code */
gpointer *vtable_slot;
- vtable_slot = mono_arch_get_vcall_slot_addr (code + 5, (gpointer*)regs);
+ vtable_slot = mono_get_vcall_slot_addr (code + 5, regs);
g_assert (vtable_slot);
*vtable_slot = nullified_class_init_trampoline;
}
void
-mono_arch_nullify_plt_entry (guint8 *code)
+mono_arch_nullify_plt_entry (guint8 *code, mgreg_t *regs)
{
if (!mono_running_on_valgrind ()) {
guint32 ops;
/* Put all registers into an array on the stack
* If this code is changed, make sure to update the offset value in
- * mono_arch_find_this_argument () in mini-x86.c.
+ * mono_arch_get_this_arg_from_call () in mini-x86.c.
*/
x86_push_reg (buf, X86_EDI);
x86_push_reg (buf, X86_ESI);
/* Check for thread interruption */
/* This is not perf critical code so no need to check the interrupt flag */
+ /* Align the stack on osx */
+ x86_alu_reg_imm (buf, X86_SUB, X86_ESP, 3 * 4);
x86_push_reg (buf, X86_EAX);
x86_call_code (buf, (guint8*)mono_thread_force_interruption_checkpoint);
x86_pop_reg (buf, X86_EAX);
+ x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 3 * 4);
/* Restore LMF */
tramp = mono_get_trampoline_code (tramp_type);
- mono_domain_lock (domain);
- code = buf = mono_code_manager_reserve_align (domain->code_mp, TRAMPOLINE_SIZE, 4);
- mono_domain_unlock (domain);
+ code = buf = mono_domain_code_reserve_align (domain, TRAMPOLINE_SIZE, 4);
x86_push_imm (buf, arg1);
x86_jump_code (buf, tramp);
mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot);
index = MONO_RGCTX_SLOT_INDEX (slot);
if (mrgctx)
- index += sizeof (MonoMethodRuntimeGenericContext) / sizeof (gpointer);
+ index += MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT / sizeof (gpointer);
for (depth = 0; ; ++depth) {
int size = mono_class_rgctx_get_array_size (depth, mrgctx);
for (i = 0; i < depth; ++i) {
/* load ptr to next array */
if (mrgctx && i == 0)
- x86_mov_reg_membase (buf, X86_EAX, X86_EAX, sizeof (MonoMethodRuntimeGenericContext), 4);
+ x86_mov_reg_membase (buf, X86_EAX, X86_EAX, MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT, 4);
else
x86_mov_reg_membase (buf, X86_EAX, X86_EAX, 0, 4);
/* is the ptr null? */
jump_sync_null = buf;
x86_branch8 (buf, X86_CC_Z, -1, 1);
- /* load MonoThread* into EDX */
+ /* load MonoInternalThread* into EDX */
buf = mono_x86_emit_tls_get (buf, X86_EDX, mono_thread_get_tls_offset ());
/* load TID into EDX */
- x86_mov_reg_membase (buf, X86_EDX, X86_EDX, G_STRUCT_OFFSET (MonoThread, tid), 4);
+ x86_mov_reg_membase (buf, X86_EDX, X86_EDX, G_STRUCT_OFFSET (MonoInternalThread, tid), 4);
/* is synchronization->owner null? */
x86_alu_membase_imm (buf, X86_CMP, X86_ECX, owner_offset, 0);
/* next case: synchronization is not null */
x86_patch (jump_next, buf);
- /* load MonoThread* into EDX */
+ /* load MonoInternalThread* into EDX */
buf = mono_x86_emit_tls_get (buf, X86_EDX, mono_thread_get_tls_offset ());
/* load TID into EDX */
- x86_mov_reg_membase (buf, X86_EDX, X86_EDX, G_STRUCT_OFFSET (MonoThread, tid), 4);
+ x86_mov_reg_membase (buf, X86_EDX, X86_EDX, G_STRUCT_OFFSET (MonoInternalThread, tid), 4);
/* is synchronization->owner == TID */
x86_alu_membase_reg (buf, X86_CMP, X86_ECX, owner_offset, X86_EDX);
/* if yes, jump to next case */