Ejemplo n.º 1
0
void
mono_arch_patch_callsite (guint8 *method_start, guint8 *code, guint8 *addr)
{
	guint8 *callsite_begin;
	guint64 *callsite = (guint64*)(gpointer)(code - 16);
	guint64 *next_bundle;
	guint64 ins, instructions [3];
	guint64 buf [16];
	Ia64CodegenState gen;
	gpointer func = ((gpointer*)(gpointer)addr)[0];

	while ((ia64_bundle_template (callsite) != IA64_TEMPLATE_MLX) &&
		   (ia64_bundle_template (callsite) != IA64_TEMPLATE_MLXS))
		callsite -= 2;
	callsite_begin = (guint8*)callsite;

	next_bundle = callsite + 2;
	ins = ia64_bundle_ins1 (next_bundle);
	if (ia64_ins_opcode (ins) == 5) {
		/* ld8_inc_imm -> indirect call through a function pointer */
		g_assert (ia64_ins_r1 (ins) == GP_SCRATCH_REG2);
		g_assert (ia64_ins_r3 (ins) == GP_SCRATCH_REG);
		return;
	}

	/* Patch the code generated by emit_call */

	instructions [0] = ia64_bundle_ins1 (callsite);
	instructions [1] = ia64_bundle_ins2 (callsite);
	instructions [2] = ia64_bundle_ins3 (callsite);

	ia64_codegen_init (gen, (guint8*)buf);
	ia64_movl (gen, GP_SCRATCH_REG, func);
	instructions [1] = gen.instructions [0];
	instructions [2] = gen.instructions [1];

	ia64_codegen_init (gen, (guint8*)buf);
	ia64_emit_bundle_template (&gen, ia64_bundle_template (callsite), instructions [0], instructions [1], instructions [2]);
	ia64_codegen_close (gen);

	/* This might not be safe, but not all itanium processors support st16 */
	callsite [0] = buf [0];
	callsite [1] = buf [1];

	mono_arch_flush_icache (callsite_begin, code - callsite_begin);
}
Ejemplo n.º 2
0
	{
		guint8 *buf = code.buf;
		int template;
		guint64 dw1, dw2;
		guint64 ins1, ins2, ins3;

		ia64_break_i (code, 0x1234);

		ia64_codegen_close (code);

		dw1 = ((guint64*)buf) [0];
		dw2 = ((guint64*)buf) [1];

		template = ia64_bundle_template (buf);
		ins1 = ia64_bundle_ins1 (buf);
		ins2 = ia64_bundle_ins2 (buf);
		ins3 = ia64_bundle_ins3 (buf);

		code.buf = buf;
		ia64_emit_bundle_template (&code, template, ins1, ins2, ins3);

		g_assert (dw1 == ((guint64*)buf) [0]);
		g_assert (dw2 == ((guint64*)buf) [1]);
	}
#endif

	mono_disassemble_code (buf, 40960, "code");

	return 0;
}