>From 6a2bdfe7800ff0e78acff9d8115594b37a5ea455 Mon Sep 17 00:00:00 2001
From: Andrey Kutejko <andy128k@gmail.com>
Date: Mon, 14 Feb 2011 00:45:15 +0200
Subject: [PATCH] fix callback on x86_64

---
 callback/trampoline_r/trampoline.c |   20 ++++++++++++--------
 callback/vacall_r/vacall-x86_64.c  |    5 ++---
 callback/vacall_r/vacall-x86_64.s  |    3 +++
 3 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/callback/trampoline_r/trampoline.c b/callback/trampoline_r/trampoline.c
index ef2c248..035d643 100644
--- a/callback/trampoline_r/trampoline.c
+++ b/callback/trampoline_r/trampoline.c
@@ -299,7 +299,7 @@ extern void __TR_clear_cache();
 #define TRAMP_ALIGN 16
 #endif
 #ifdef __x86_64__
-#define TRAMP_LENGTH 22
+#define TRAMP_LENGTH 26
 #define TRAMP_ALIGN 16
 #endif
 #ifdef __s390__
@@ -945,6 +945,9 @@ __TR_function alloc_trampoline_r (__TR_function address, void* data0, void* data
 #ifdef __x86_64__
   /* function:
    *    movabsq $<data>,%r10		49 BA <data>
+   *    popq %rcx                   59
+   *    pushq %r10		            41 52
+   *    pushq %rcx                  51
    *    movabsq $<address>,%rax		48 B8 <address>
    *    jmp *%rax			FF E0
    */
@@ -952,21 +955,22 @@ __TR_function alloc_trampoline_r (__TR_function address, void* data0, void* data
   *(short *) (function + 2) = (unsigned long) data & 0xffff;
   *(int *)   (function + 4) = ((unsigned long) data >> 16) & 0xffffffff;
   *(short *) (function + 8) = ((unsigned long) data >> 48) & 0xffff;
-  *(short *) (function +10) = 0xB848;
-  *(int *)   (function +12) = (unsigned long) address & 0xffffffff;
-  *(int *)   (function +16) = ((unsigned long) address >> 32) & 0xffffffff;
-  *(short *) (function +20) = 0xE0FF;
+  *(int *)   (function +10) = 0x51524159;
+  *(short *) (function +14) = 0xB848;
+  *(int *)   (function +16) = (unsigned long) address & 0xffffffff;
+  *(int *)   (function +20) = ((unsigned long) address >> 32) & 0xffffffff;
+  *(short *) (function +24) = 0xE0FF;
 #define is_tramp(function)  \
   *(unsigned short *) (function + 0) == 0xBA49 && \
-  *(unsigned short *) (function +10) == 0xB848 && \
-  *(unsigned short *) (function +20) == 0xE0FF
+  *(unsigned short *) (function +14) == 0xB848 && \
+  *(unsigned short *) (function +24) == 0xE0FF
 #define hilo(hiword,loword)  \
   (((unsigned long) (hiword) << 32) | (unsigned long) (loword))
 #define himidlo(hishort,midword,loshort)  \
   (((unsigned long) (hishort) << 48) | (unsigned long) (midword) << 16 \
    | (unsigned long) (loshort))
 #define tramp_address(function)  \
-  hilo(*(unsigned int *) (function +16), *(unsigned int *) (function +12))
+  hilo(*(unsigned int *) (function +20), *(unsigned int *) (function +16))
 #define tramp_data(function)  \
   himidlo(*(unsigned short *) (function + 8), \
           *(unsigned int *)   (function + 4), \
diff --git a/callback/vacall_r/vacall-x86_64.c b/callback/vacall_r/vacall-x86_64.c
index 9ae2d16..2268bc0 100644
--- a/callback/vacall_r/vacall-x86_64.c
+++ b/callback/vacall_r/vacall-x86_64.c
@@ -17,8 +17,7 @@
 
 #ifdef REENTRANT
 #define __vacall __vacall_r
-register struct { void (*vacall_function) (void*,va_alist); void* arg; }
-         *		env	__asm__("r10");
+typedef struct { void (*vacall_function) (void*,va_alist); void* arg; } env_t;
 #endif
 
 register __vaword iarg1 __asm__("rdi");
@@ -51,7 +50,7 @@ register void*	dummy1	__asm__("%rbx");
 register void*	dummy2	__asm__("%rbp");
 
 void /* the return type is variable, not void! */
-__vacall (__vaword word1, __vaword word2, __vaword word3, __vaword word4,
+__vacall (env_t *env, __vaword word1, __vaword word2, __vaword word3, __vaword word4,
           __vaword word5, __vaword word6,
           __vaword firstword)
 {
diff --git a/callback/vacall_r/vacall-x86_64.s b/callback/vacall_r/vacall-x86_64.s
index 3e59347..30df874 100644
--- a/callback/vacall_r/vacall-x86_64.s
+++ b/callback/vacall_r/vacall-x86_64.s
@@ -4,6 +4,9 @@
 .globl __vacall_r
 	.type	__vacall_r,@function
 __vacall_r:
+    popq    %rcx
+    popq    %r10
+    pushq   %rcx
 .LFB1:
 	pushq	%r13
 .LCFI0:
-- 
1.7.2.3

