return can_write;
}
-gpointer
-mono_arch_get_vcall_slot (guint8 *code, mgreg_t *regs, int *displacement)
-{
- guint8 buf [10];
- gint32 disp;
- MonoJitInfo *ji = NULL;
-
-#ifdef ENABLE_LLVM
- /* code - 9 might be before the start of the method */
- /* FIXME: Avoid this expensive call somehow */
- ji = mono_jit_info_table_find (mono_domain_get (), (char*)code);
-#endif
-
- mono_breakpoint_clean_code (ji ? ji->code_start : NULL, code, 9, buf, sizeof (buf));
- code = buf + 9;
-
- *displacement = 0;
-
- code -= 7;
-
- /*
- * This function is no longer used, the only caller is
- * mono_arch_nullify_class_init_trampoline ().
- */
- if ((code [0] == 0x41) && (code [1] == 0xff) && (code [2] == 0x15)) {
- /* call OFFSET(%rip) */
- g_assert_not_reached ();
- *displacement = *(guint32*)(code + 3);
- return (gpointer*)(code + disp + 7);
- } else {
- g_assert_not_reached ();
- return NULL;
- }
-}
-
int
mono_arch_get_this_arg_reg (MonoMethodSignature *sig, MonoGenericSharingContext *gsctx, guint8 *code)
{
return frame_size;
}
-gpointer
-mono_arch_get_vcall_slot (guint8 *code_ptr, mgreg_t *regs, int *displacement)
-{
- /* Not used on ARM */
- g_assert_not_reached ();
-
- return NULL;
-}
-
#define MAX_ARCH_DELEGATE_PARAMS 3
static gpointer
return 0;
}
-gpointer
-mono_arch_get_vcall_slot (guint8* code, mgreg_t *regs, int *displacement)
-{
- /* Not used on IA64 */
- g_assert_not_reached ();
- return NULL;
-}
-
gpointer*
mono_arch_get_delegate_method_ptr_addr (guint8* code, mgreg_t *regs)
{
#endif
}
-gpointer
-mono_arch_get_vcall_slot (guint8 *code_ptr, mgreg_t *regs, int *displacement)
-{
- *displacement = 0;
-
- /* Not used on PPC */
- g_assert_not_reached ();
- return NULL;
-}
-
#define MAX_ARCH_DELEGATE_PARAMS 7
static gpointer
return FALSE;
}
-/*
- * mono_arch_get_vcall_slot:
- *
- * Determine the vtable slot used by a virtual call.
- */
-gpointer
-mono_arch_get_vcall_slot (guint8 *code8, mgreg_t *regs, int *displacement)
-{
- /* Not used on sparc */
- g_assert_not_reached ();
- return NULL;
-}
-
#define CMP_SIZE 3
#define BR_SMALL_SIZE 2
#define BR_LARGE_SIZE 2
}
#endif
-gpointer*
-mono_get_vcall_slot_addr (guint8* code, mgreg_t *regs)
-{
- gpointer vt;
- int displacement;
- vt = mono_arch_get_vcall_slot (code, regs, &displacement);
- if (!vt)
- return NULL;
- return (gpointer*)((char*)vt + displacement);
-}
-
#ifdef MONO_ARCH_HAVE_IMT
static gpointer*
MonoMethod *m;
gboolean need_rgctx_tramp = FALSE;
gpointer addr;
-#ifndef MONO_ARCH_THIS_AS_FIRST_ARG
- int displacement;
-#endif
trampoline_calls ++;
* We use one vtable trampoline per vtable slot index, so we need only the vtable,
* the other two can be computed from the vtable + the slot index.
*/
-#ifdef MONO_ARCH_THIS_AS_FIRST_ARG
+#ifndef MONO_ARCH_THIS_AS_FIRST_ARG
+ /* All architectures should support this */
+ g_assert_not_reached ();
+#endif
+
/*
- * If the arch passes 'this' as the first arg, obtain the vtable using it.
+ * Obtain the vtable from the 'this' arg.
*/
this = mono_arch_get_this_arg_from_call (NULL, NULL, regs, code);
g_assert (this);
vt = this->vtable;
-#else
- g_assert (!mono_use_llvm);
- /*
- * Obtain the vtable pointer in an arch specific manner.
- */
- vt = mono_arch_get_vcall_slot (code, regs, &displacement);
-
- if (!vt) {
- int i;
- MonoJitInfo *ji;
-
- ji = mono_jit_info_table_find (mono_domain_get (), (char*)code);
- if (ji)
- printf ("Caller: %s\n", mono_method_full_name (ji->method, TRUE));
- /* Print some debug info */
- for (i = 0; i < 32; ++i)
- printf ("0x%x ", code [-32 + i]);
- printf ("\n");
- g_assert (vt);
- }
-#endif
if (slot >= 0) {
/* Normal virtual call */
need_rgctx_tramp = FALSE;
}
- // FIXME:
- // - get rid of mono_arch_get_vcall_slot where possible
-
return common_call_trampoline (regs, code, m, tramp, vt, vtable_slot, need_rgctx_tramp);
}
return can_write;
}
-gpointer
-mono_arch_get_vcall_slot (guint8 *code, mgreg_t *regs, int *displacement)
-{
- guint8 buf [8];
- guint8 reg = 0;
- gint32 disp = 0;
-
- mono_breakpoint_clean_code (NULL, code, 8, buf, sizeof (buf));
- code = buf + 8;
-
- *displacement = 0;
-
- code -= 6;
-
- /*
- * This function is no longer used, the only caller is
- * mono_arch_nullify_class_init_trampoline ().
- */
- if ((code [0] == 0xff) && ((code [1] & 0x18) == 0x10) && ((code [1] >> 6) == 2)) {
- reg = code [1] & 0x07;
- disp = *((gint32*)(code + 2));
- } else {
- g_assert_not_reached ();
- return NULL;
- }
-
- *displacement = disp;
- return (gpointer)regs [reg];
-}
-
/*
* mono_x86_get_this_arg_offset:
*
void mono_monitor_exit_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp) MONO_INTERNAL;
gconstpointer mono_get_trampoline_func (MonoTrampolineType tramp_type);
gpointer mini_get_vtable_trampoline (int slot_index) MONO_INTERNAL;
-gpointer* mono_get_vcall_slot_addr (guint8* code, mgreg_t *regs) MONO_INTERNAL;
char* mono_get_generic_trampoline_name (MonoTrampolineType tramp_type) MONO_INTERNAL;
char* mono_get_rgctx_fetch_trampoline_name (int slot) MONO_INTERNAL;
gboolean mono_arch_is_int_overflow (void *sigctx, void *info) MONO_INTERNAL;
void mono_arch_invalidate_method (MonoJitInfo *ji, void *func, gpointer func_arg) MONO_INTERNAL;
guint32 mono_arch_get_patch_offset (guint8 *code) MONO_INTERNAL;
-gpointer mono_arch_get_vcall_slot (guint8 *code, mgreg_t *regs, int *displacement) MONO_INTERNAL;
gpointer*mono_arch_get_delegate_method_ptr_addr (guint8* code, mgreg_t *regs) MONO_INTERNAL;
void mono_arch_create_vars (MonoCompile *cfg) MONO_INTERNAL;
void mono_arch_save_unwind_info (MonoCompile *cfg) MONO_INTERNAL;
InterlockedExchangePointer (plt_jump_table_entry, addr);
}
+static gpointer
+get_vcall_slot (guint8 *code, mgreg_t *regs, int *displacement)
+{
+ guint8 buf [10];
+ gint32 disp;
+ MonoJitInfo *ji = NULL;
+
+#ifdef ENABLE_LLVM
+ /* code - 9 might be before the start of the method */
+ /* FIXME: Avoid this expensive call somehow */
+ ji = mono_jit_info_table_find (mono_domain_get (), (char*)code);
+#endif
+
+ mono_breakpoint_clean_code (ji ? ji->code_start : NULL, code, 9, buf, sizeof (buf));
+ code = buf + 9;
+
+ *displacement = 0;
+
+ code -= 7;
+
+ if ((code [0] == 0x41) && (code [1] == 0xff) && (code [2] == 0x15)) {
+ /* call OFFSET(%rip) */
+ g_assert_not_reached ();
+ *displacement = *(guint32*)(code + 3);
+ return (gpointer*)(code + disp + 7);
+ } else {
+ g_assert_not_reached ();
+ return NULL;
+ }
+}
+
+static gpointer*
+get_vcall_slot_addr (guint8* code, mgreg_t *regs)
+{
+ gpointer vt;
+ int displacement;
+ vt = get_vcall_slot (code, regs, &displacement);
+ if (!vt)
+ return NULL;
+ return (gpointer*)((char*)vt + displacement);
+}
+
void
mono_arch_nullify_class_init_trampoline (guint8 *code, mgreg_t *regs)
{
gpointer *vtable_slot;
/* call *<OFFSET>(%rip) */
- vtable_slot = mono_get_vcall_slot_addr (code, regs);
+ vtable_slot = get_vcall_slot_addr (code, regs);
g_assert (vtable_slot);
*vtable_slot = nullified_class_init_trampoline;
/*========================= End of Function ========================*/
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_vcall_slot */
-/* */
-/* Function - This method is called by the arch independent */
-/* trampoline code to determine the vtable slot used by */
-/* the call which invoked the trampoline. */
-/* */
-/* Parameters - code - Pointer into caller code */
-/* regs - Register state at the point of the call */
-/* displacement - Out parameter which will receive */
-/* the displacement of the vtable slot */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_vcall_slot (guint8 *code, mgreg_t *regs, int *displacement)
-{
- /* Not used on s390x */
- g_assert_not_reached ();
- return NULL;
-}
-
-/*========================= End of Function ========================*/
-
/*------------------------------------------------------------------*/
/* */
/* Name - mono_arch_create_trampoline_code */
*(guint8**)((guint8*)got + offset) = addr;
}
+static gpointer
+get_vcall_slot (guint8 *code, mgreg_t *regs, int *displacement)
+{
+ guint8 buf [8];
+ guint8 reg = 0;
+ gint32 disp = 0;
+
+ mono_breakpoint_clean_code (NULL, code, 8, buf, sizeof (buf));
+ code = buf + 8;
+
+ *displacement = 0;
+
+ code -= 6;
+
+ if ((code [0] == 0xff) && ((code [1] & 0x18) == 0x10) && ((code [1] >> 6) == 2)) {
+ reg = code [1] & 0x07;
+ disp = *((gint32*)(code + 2));
+ } else {
+ g_assert_not_reached ();
+ return NULL;
+ }
+
+ *displacement = disp;
+ return (gpointer)regs [reg];
+}
+
+static gpointer*
+get_vcall_slot_addr (guint8* code, mgreg_t *regs)
+{
+ gpointer vt;
+ int displacement;
+ vt = get_vcall_slot (code, regs, &displacement);
+ if (!vt)
+ return NULL;
+ return (gpointer*)((char*)vt + displacement);
+}
+
void
mono_arch_nullify_class_init_trampoline (guint8 *code, mgreg_t *regs)
{
/* call *<OFFSET>(<REG>) -> Call made from AOT code */
gpointer *vtable_slot;
- vtable_slot = mono_get_vcall_slot_addr (code + 5, regs);
+ vtable_slot = get_vcall_slot_addr (code + 5, regs);
g_assert (vtable_slot);
*vtable_slot = nullified_class_init_trampoline;