Paul Gofman : mscoree: Implement VTable fixup for x86_64 architecture.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Jan 26 10:32:50 CST 2016


Module: wine
Branch: master
Commit: 43c43179cd1155213292c3693e2e6889899b4c72
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=43c43179cd1155213292c3693e2e6889899b4c72

Author: Paul Gofman <gofmanp at gmail.com>
Date:   Sun Jan 24 21:37:03 2016 +0300

mscoree: Implement VTable fixup for x86_64 architecture.

Signed-off-by: Paul Gofman <gofmanp at gmail.com>
Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mscoree/corruntimehost.c | 81 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 77 insertions(+), 4 deletions(-)

diff --git a/dlls/mscoree/corruntimehost.c b/dlls/mscoree/corruntimehost.c
index 037ae28..c790c44 100644
--- a/dlls/mscoree/corruntimehost.c
+++ b/dlls/mscoree/corruntimehost.c
@@ -919,7 +919,75 @@ static const struct vtable_fixup_thunk thunk_template = {
 
 #include "poppack.h"
 
-#else /* !defined(__i386__) */
+#elif __x86_64__ /* !__i386__ */
+
+# define CAN_FIXUP_VTABLE 1
+
+#include "pshpack1.h"
+
+struct vtable_fixup_thunk
+{
+    /* push %rbp;
+       mov %rsp, %rbp
+       sub $0x80, %rsp ; 0x8*4 + 0x10*4 + 0x20
+    */
+    BYTE i1[11];
+    /*
+        mov %rcx, 0x60(%rsp); mov %rdx, 0x68(%rsp); mov %r8, 0x70(%rsp); mov %r9, 0x78(%rsp);
+        movaps %xmm0,0x20(%rsp); ...; movaps %xmm3,0x50(%esp)
+    */
+    BYTE i2[40];
+    /* mov function,%rax */
+    BYTE i3[2];
+    void (CDECL *function)(struct dll_fixup *);
+    /* mov fixup,%rcx */
+    BYTE i4[2];
+    struct dll_fixup *fixup;
+    /* call *%rax */
+    BYTE i5[2];
+    /*
+        mov 0x60(%rsp),%rcx; mov 0x68(%rsp),%rdx; mov 0x70(%rsp),%r8; mov 0x78(%rsp),%r9;
+        movaps 0x20(%rsp),xmm0; ...; movaps 0x50(%esp),xmm3
+    */
+    BYTE i6[40];
+    /* mov %rbp, %rsp
+       pop %rbp
+    */
+    BYTE i7[4];
+    /* mov vtable_entry, %rax */
+    BYTE i8[2];
+    void *vtable_entry;
+    /* mov [%rax],%rax
+       jmp %rax */
+    BYTE i9[5];
+};
+
+static const struct vtable_fixup_thunk thunk_template = {
+    {0x55,0x48,0x89,0xE5,  0x48,0x81,0xEC,0x80,0x00,0x00,0x00},
+    {0x48,0x89,0x4C,0x24,0x60, 0x48,0x89,0x54,0x24,0x68,
+     0x4C,0x89,0x44,0x24,0x70, 0x4C,0x89,0x4C,0x24,0x78,
+     0x0F,0x29,0x44,0x24,0x20, 0x0F,0x29,0x4C,0x24,0x30,
+     0x0F,0x29,0x54,0x24,0x40, 0x0F,0x29,0x5C,0x24,0x50,
+    },
+    {0x48,0xB8},
+    NULL,
+    {0x48,0xB9},
+    NULL,
+    {0xFF,0xD0},
+    {0x48,0x8B,0x4C,0x24,0x60, 0x48,0x8B,0x54,0x24,0x68,
+     0x4C,0x8B,0x44,0x24,0x70, 0x4C,0x8B,0x4C,0x24,0x78,
+     0x0F,0x28,0x44,0x24,0x20, 0x0F,0x28,0x4C,0x24,0x30,
+     0x0F,0x28,0x54,0x24,0x40, 0x0F,0x28,0x5C,0x24,0x50,
+     },
+    {0x48,0x89,0xEC, 0x5D},
+    {0x48,0xB8},
+    NULL,
+    {0x48,0x8B,0x00,0xFF,0xE0}
+};
+
+#include "poppack.h"
+
+#else /* !__i386__ && !__x86_64__ */
 
 # define CAN_FIXUP_VTABLE 0
 
@@ -982,7 +1050,11 @@ static void CDECL ReallyFixupVTable(struct dll_fixup *fixup)
         /* Mono needs an image that belongs to an assembly. */
         image = mono_assembly_get_image(assembly);
 
+#if __x86_64__
+        if (fixup->fixup->type & COR_VTABLE_64BIT)
+#else
         if (fixup->fixup->type & COR_VTABLE_32BIT)
+#endif
         {
             void **vtable = fixup->vtable;
             ULONG_PTR *tokens = fixup->tokens;
@@ -1030,16 +1102,17 @@ static void FixupVTableEntry(HMODULE hmodule, VTableFixup *vtable_fixup)
     fixup->done = FALSE;
 
     TRACE("vtable_fixup->type=0x%x\n",vtable_fixup->type);
+#if __x86_64__
+    if (vtable_fixup->type & COR_VTABLE_64BIT)
+#else
     if (vtable_fixup->type & COR_VTABLE_32BIT)
+#endif
     {
         void **vtable = fixup->vtable;
         ULONG_PTR *tokens;
         int i;
         struct vtable_fixup_thunk *thunks = fixup->thunk_code;
 
-        if (sizeof(void*) > 4)
-            ERR("32-bit fixup in 64-bit mode; broken image?\n");
-
         tokens = fixup->tokens = HeapAlloc(GetProcessHeap(), 0, sizeof(*tokens) * vtable_fixup->count);
         memcpy(tokens, vtable, sizeof(*tokens) * vtable_fixup->count);
         for (i=0; i<vtable_fixup->count; i++)




More information about the wine-cvs mailing list