$OpenBSD: patch-mono_mini_tramp-amd64_c,v 1.1 2011/06/04 11:17:08 robert Exp $
--- mono/mini/tramp-amd64.c.orig	Fri Jun  3 16:43:37 2011
+++ mono/mini/tramp-amd64.c	Fri Jun  3 16:43:42 2011
@@ -707,6 +707,7 @@ mono_arch_create_specific_trampoline (gpointer arg1, M
 {
 	guint8 *code, *buf, *tramp;
 	int size;
+	gboolean far_addr = FALSE;
 
 	tramp = mono_get_trampoline_code (tramp_type);
 
@@ -717,6 +718,15 @@ mono_arch_create_specific_trampoline (gpointer arg1, M
 		size = 5 + 1 + 8;
 
 	code = buf = mono_domain_code_reserve_align (domain, size, 1);
+
+	if (((gint64)tramp - (gint64)code) >> 31 != 0 && ((gint64)tramp - (gint64)code) >> 31 != -1) {
+#ifndef MONO_ARCH_NOMAP32BIT
+		g_assert_not_reached ();
+#endif
+		far_addr = TRUE;
+		size += 16;
+		code = buf = mono_domain_code_reserve_align (domain, size, 1);
+	}
 #elif defined(__native_client_codegen__)
 	size = 5 + 1 + 4;
 	/* Aligning the call site below could */
@@ -726,7 +736,12 @@ mono_arch_create_specific_trampoline (gpointer arg1, M
 	code = buf;
 #endif
 
-	amd64_call_code (code, tramp);
+	if (far_addr) {
+		amd64_mov_reg_imm (code, AMD64_R11, tramp);
+		amd64_call_reg (code, AMD64_R11);
+	} else {
+		amd64_call_code (code, tramp);
+	}
 	/* The trampoline code will obtain the argument from the instruction stream */
 #if defined(__default_codegen__)
 	if ((((guint64)arg1) >> 32) == 0) {
