On 22.01.2016 23:24, Paul Gofman wrote:
Signed-off-by: Paul Gofman gofmanp@gmail.com
dlls/mscoree/corruntimehost.c | 91 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 79 insertions(+), 12 deletions(-)
diff --git a/dlls/mscoree/corruntimehost.c b/dlls/mscoree/corruntimehost.c index e437cc2..05ac9c9 100644 --- a/dlls/mscoree/corruntimehost.c +++ b/dlls/mscoree/corruntimehost.c @@ -919,7 +919,68 @@ 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 %rcx; push %rdx; push %r8; push %r9 */
I think it would be better to allocate a proper stack frame (pushq %rbp, movq %rsp, %rbp, subq ...,%rsp) and then use movq instructions.
- BYTE i1[6];
- /* sub $0x68, %rsp ; 0x10*4 + 0x20 + 0x8 (align stack for subsequent func call)
movups %xmm0,0x28(%esp); ...; movups %xmm5,0x58(%esp)
Shouldn't it be %rsp ? Same for the precompiled assembler code below. Also, its theoretically safe to use movdqa like done in various other wine functions.
ReallyFixupVTable will crash if we are called with unaligned stack
There is no need to add a comment for that, its expected to crash when misaligning the stack.
- */
- BYTE i2[28];
- /* mov function,%eax */
- BYTE i3[2];
- void (CDECL *function)(struct dll_fixup *);
- /* mov fixup,%rcx */
- BYTE i4[2];
- struct dll_fixup *fixup;
- /* call *%eax */
- BYTE i5[2];
- /*
movups 0x28(%esp),xmm0; ...; movups 0x58(%esp),xmm3
add $0x68, %rsp
- */
- BYTE i6[28];
- /* pop %r9; pop %r8; pop %rdx; pop %rcx */
- BYTE i7[6];
- /* 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 = {
- {0x51,0x52,0x41,0x50,0x41,0x51},
- {0x48,0x83,0xEC,0x68,
0x67,0x0F,0x11,0x44,0x24,0x28, 0x67,0x0F,0x11,0x4C,0x24,0x38,
0x67,0x0F,0x11,0x54,0x24,0x48, 0x67,0x0F,0x11,0x5C,0x24,0x58,
- },
- {0x48,0xB8},
- NULL,
- {0x48,0xB9},
- NULL,
- {0xFF,0xD0},
- {0x67,0x0F,0x10,0x44,0x24,0x28, 0x67,0x0F,0x10,0x4C,0x24,0x38,
0x67,0x0F,0x10,0x54,0x24,0x48, 0x67,0x0F,0x10,0x5C,0x24,0x58,
0x48,0x83,0xC4,0x68},
- {0x41,0x59,0x41,0x58,0x5A,0x59},
- {0x48,0xB8},
- NULL,
- {0x48,0x8B,0x00,0xFF,0xE0}
+};
+#include "poppack.h"
+#else /* !__i386__ && !__x86_64__ */
# define CAN_FIXUP_VTABLE 0
@@ -982,15 +1043,19 @@ 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 {
DWORD *vtable = fixup->vtable;
DWORD *tokens = fixup->tokens;
void **vtable = fixup->vtable;
ULONG_PTR *tokens = fixup->tokens; for (i=0; i<fixup->fixup->count; i++) {
TRACE("%x\n", tokens[i]);
vtable[i] = PtrToUint(mono_marshal_get_vtfixup_ftnptr(
image, tokens[i], fixup->fixup->type));
TRACE("%#lx\n", tokens[i]);
vtable[i] = mono_marshal_get_vtfixup_ftnptr(
image, tokens[i], fixup->fixup->type);
I would suggest to move those changes and some of the changes below into a separate patch. They can easily be reviewed separately and using PtrToUint() instead of pointer types wasn't even a good idea on 32-bit. ;)
} }
@@ -1029,16 +1094,18 @@ static void FixupVTableEntry(HMODULE hmodule, VTableFixup *vtable_fixup) fixup->vtable = (BYTE*)hmodule + vtable_fixup->rva; 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 {
DWORD *vtable = fixup->vtable;
DWORD *tokens;
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++)
@@ -1047,7 +1114,7 @@ static void FixupVTableEntry(HMODULE hmodule, VTableFixup *vtable_fixup) thunks[i].fixup = fixup; thunks[i].function = ReallyFixupVTable; thunks[i].vtable_entry = &vtable[i];
vtable[i] = PtrToUint(&thunks[i]);
} elsevtable[i] = &thunks[i]; }