#include "mini.h"
#include "mini-mips.h"
+static guint8* nullified_class_init_trampoline;
+
/*
* get_unbox_trampoline:
- * @gsctx: the generic sharing context
* @m: method pointer
* @addr: pointer to native code for @m
*
* unboxing before calling the method
*/
gpointer
-mono_arch_get_unbox_trampoline (MonoGenericSharingContext *gsctx, MonoMethod *m, gpointer addr)
+mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
{
guint8 *code, *start;
int this_pos = mips_a0;
{
guint32 *code = (guint32*)orig_code;
- /* Locate the address of the method-specific trampoline. The call using
- the vtable slot that took the processing flow to 'arch_create_jit_trampoline'
- looks something like this:
+ /* Locate the address of the method-specific trampoline.
+ The call using the vtable slot that took the processing flow to
+ 'arch_create_jit_trampoline' looks something like one of these:
jal XXXXYYYY
nop
if ((code[-2] >> 26) == 0x03) {
//g_print ("direct patching\n");
mips_patch ((code-2), (gsize)addr);
- } else {
- /* Sanity check: look for the jalr */
- g_assert((code[-2] & 0xfc1f003f) == 0x00000009);
-
- //printf ("mips_magic_trampoline: jalr @ 0x%0x, w/ reg %d\n", code-2, reg);
-
+ return;
+ }
+ /* Look for the jalr */
+ if ((code[-2] & 0xfc1f003f) == 0x00000009) {
/* The lui / addiu / jalr case */
- if ((code [-4] >> 26) == 0x0f && (code [-3] >> 26) == 0x09 && (code [-2] >> 26) == 0) {
+ if ((code [-4] >> 26) == 0x0f && (code [-3] >> 26) == 0x09
+ && (code [-2] >> 26) == 0) {
mips_patch ((code-4), (gsize)addr);
- } else {
- g_assert_not_reached ();
+ return;
}
}
+ g_print("error: bad patch at 0x%08x\n", code);
+ g_assert_not_reached ();
}
void
-mono_arch_patch_plt_entry (guint8 *code, guint8 *addr)
+mono_arch_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr)
{
g_assert_not_reached ();
}
gpointer
-mono_arch_get_vcall_slot (guint8 *code_ptr, gpointer *regs, int *displacement)
+mono_arch_get_vcall_slot (guint8 *code_ptr, mgreg_t *regs, int *displacement)
{
char *o = NULL;
char *vtable = NULL;
o = (gpointer)lmf->iregs [base];
}
else {
- o = regs [base];
+ o = (gpointer) regs [base];
}
break;
}
return o;
}
-gpointer*
-mono_arch_get_vcall_slot_addr (guint8 *code, gpointer *regs)
-{
- gpointer vt;
- int displacement;
- vt = mono_arch_get_vcall_slot (code, regs, &displacement);
- if (!vt)
- return NULL;
- return (gpointer*)((char*)vt + displacement);
-}
-
void
-mono_arch_nullify_plt_entry (guint8 *code)
+mono_arch_nullify_plt_entry (guint8 *code, mgreg_t *regs)
{
- g_assert_not_reached ();
+ 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);
}
void
-mono_arch_nullify_class_init_trampoline (guint8 *code, gssize *regs)
+mono_arch_nullify_class_init_trampoline (guint8 *code, mgreg_t *regs)
{
guint32 *code32 = (guint32*)code;
mips_nop (code32);
mono_arch_flush_icache ((gpointer)(code32 - 1), 4);
return;
- } else {
- g_assert_not_reached ();
}
+ g_assert_not_reached ();
+}
+
+gpointer
+mono_arch_get_nullified_class_init_trampoline (MonoTrampInfo **info)
+{
+ guint8 *buf, *code;
+
+ code = buf = mono_global_codeman_reserve (16);
+
+ mips_jr (code, mips_ra);
+ mips_nop (code);
+
+ mono_arch_flush_icache (buf, code - buf);
+
+ if (info)
+ *info = mono_tramp_info_create (g_strdup_printf ("nullified_class_init_trampoline"), buf, code - buf, NULL, NULL);
+
+ return buf;
}
/*
* -------------------
*/
guchar*
-mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
+mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInfo **info, gboolean aot)
{
guint8 *buf, *tramp, *code = NULL;
int i, lmf;
+ GSList *unwind_ops = NULL;
+ MonoJumpInfo *ji = NULL;
int max_code_len = 768;
+ /* AOT not supported on MIPS yet */
+ g_assert (!aot);
+
/* Now we'll create in 'buf' the MIPS trampoline code. This
is the trampoline code common to all methods */
* Now we're ready to call mips_magic_trampoline ().
*/
- /* Arg 1: stack pointer so that the magic trampoline can access the
- * registers we saved above
+ /* Arg 1: pointer to registers so that the magic trampoline can
+ * access what we saved above
*/
- mips_move (code, mips_a0, mips_sp);
-
+ mips_addiu (code, mips_a0, mips_sp, lmf + G_STRUCT_OFFSET (MonoLMF, iregs[0]));
+
/* Arg 2: code (next address to the instruction that called us) */
if (tramp_type == MONO_TRAMPOLINE_JUMP) {
mips_move (code, mips_a1, mips_zero);
/* Sanity check */
g_assert ((code - buf) <= max_code_len);
+ 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)
+ *info = mono_tramp_info_create (mono_get_generic_trampoline_name (tramp_type), buf, code - buf, ji, unwind_ops);
+
return buf;
}
}
gpointer
-mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 encoded_offset)
+mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info, gboolean aot)
{
/* FIXME: implement! */
g_assert_not_reached ();
}
gpointer
-mono_arch_create_generic_class_init_trampoline (void)
+mono_arch_create_generic_class_init_trampoline (MonoTrampInfo **info, gboolean aot)
{
/* FIXME: implement! */
g_assert_not_reached ();