else {
g_assert ((((guint64)(addr)) >> 32) == 0);
g_assert ((((guint64)(code)) >> 32) == 0);
- InterlockedExchange ((guint32*)(code - 4), ((gint64)addr - (gint64)code));
+ InterlockedExchange ((gint32*)(code - 4), ((gint64)addr - (gint64)code));
}
}
else if ((code [-7] == 0x41) && (code [-6] == 0xff) && (code [-5] == 0x15)) {
}
}
+void
+mono_arch_patch_plt_entry (guint8 *code, guint8 *addr)
+{
+ gint32 disp;
+ gpointer *plt_jump_table_entry;
+
+ /* A PLT entry: jmp *<DISP>(%rip) */
+ g_assert (code [0] == 0xff);
+ g_assert (code [1] == 0x25);
+
+ disp = *(gint32*)(code + 2);
+
+ plt_jump_table_entry = (gpointer*)(code + 6 + disp);
+
+ InterlockedExchangePointer (plt_jump_table_entry, addr);
+}
+
void
mono_arch_nullify_class_init_trampoline (guint8 *code, gssize *regs)
{
buf [2] = 0x90;
buf [3] = 0x66;
buf [4] = 0x90;
- } else if ((code [0] == 0x49) && (code [1] == 0xff)) {
+ } else if ((code [0] == 0x41) && (code [1] == 0xff)) {
/* call <REG> */
+ /* happens on machines without MAP_32BIT like freebsd */
/* amd64_set_reg_template is 10 bytes long */
guint8* buf = code - 10;
}
void
-mono_arch_patch_delegate_trampoline (guint8 *code, guint8 *tramp, gssize *regs, guint8 *addr)
+mono_arch_nullify_plt_entry (guint8 *code)
{
- guint8 rex = 0;
- guint32 reg;
- guint32 disp;
-
- if ((code [-3] == 0xff) && (amd64_modrm_reg (code [-2]) == 0x2) && (amd64_modrm_mod (code [-2]) == 0x1)) {
- /* call *[reg+disp8] */
- if (IS_REX (code [-4]))
- rex = code [-4];
- reg = amd64_modrm_rm (code [-2]);
- disp = *(guint8*)(code - 1);
- //printf ("B: [%%r%d+0x%x]\n", reg, disp);
- }
- else {
- int i;
-
- for (i = -16; i < 0; ++i)
- printf ("%d ", code [i]);
- printf ("\n");
- g_assert_not_reached ();
- }
-
- reg += amd64_rex_b (rex);
-
- /* R11 is clobbered by the trampoline code */
- g_assert (reg != AMD64_R11);
-
- *(gpointer*)(((guint64)(regs [reg])) + disp) = addr;
+ mono_arch_patch_plt_entry (code, nullified_class_init_trampoline);
}
guchar*
tramp = (guint8*)mono_class_init_trampoline;
else if (tramp_type == MONO_TRAMPOLINE_AOT)
tramp = (guint8*)mono_aot_trampoline;
+ else if (tramp_type == MONO_TRAMPOLINE_AOT_PLT)
+ tramp = (guint8*)mono_aot_plt_trampoline;
else if (tramp_type == MONO_TRAMPOLINE_DELEGATE)
tramp = (guint8*)mono_delegate_trampoline;
else
g_assert ((code - buf) <= TRAMPOLINE_SIZE);
mono_domain_lock (domain);
- /*
- * FIXME: Changing the size to code - buf causes strange crashes during
- * mcs bootstrap.
- */
- real_code = mono_code_manager_reserve (domain->code_mp, TRAMPOLINE_SIZE);
+ real_code = mono_code_manager_reserve (domain->code_mp, code - buf);
size = code - buf;
mono_domain_unlock (domain);
memcpy (real_code, buf, size);
/* Fix up jump */
- g_assert ((((gint64)tramp) >> 32) == 0);
code = (guint8*)real_code + jump_offset;
+ g_assert (amd64_is_imm32 (((gint64)tramp - (gint64)code)));
amd64_jump_disp (code, tramp - code);
- mono_jit_stats.method_trampolines++;
-
if (code_len)
*code_len = size;
/*
* This method is only called when running in the Mono Debugger.
*/
-guint8 *
-mono_debugger_create_notification_function ()
+gpointer
+mono_debugger_create_notification_function (void)
{
guint8 *buf, *code;