[PATCH] ntdll: Implement unimplemented function handler for amd64

Maarten Lankhorst m.b.lankhorst at gmail.com
Sat Dec 13 17:41:39 CST 2008


---
 dlls/ntdll/loader.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 73 insertions(+), 3 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index d3a0067..86230fe 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -244,9 +244,79 @@ static ULONG_PTR allocate_stub( const char *dll, const char *name )
     return (ULONG_PTR)stub;
 }
 
-#else  /* __i386__ */
-static inline ULONG_PTR allocate_stub( const char *dll, const char *name ) { return 0xdeadbeef; }
-#endif  /* __i386__ */
+#elif defined(__x86_64__)
+
+static void WINAPI stub_entry_point( const char *dll, const char *name, void *entry_point )
+{
+    EXCEPTION_RECORD rec;
+
+    rec.ExceptionCode           = EXCEPTION_WINE_STUB;
+    rec.ExceptionFlags          = EH_NONCONTINUABLE;
+    rec.ExceptionRecord         = NULL;
+    rec.ExceptionAddress        = entry_point;
+    rec.NumberParameters        = 2;
+    rec.ExceptionInformation[0] = (ULONG_PTR)dll;
+    rec.ExceptionInformation[1] = (ULONG_PTR)name;
+    for (;;) RtlRaiseException( &rec );
+}
+
+#include "pshpack1.h"
+struct stub
+{
+    BYTE movq_rcx[2]; /* movq dll, %rcx */
+    const char *dll;
+    BYTE movq_rdx[2]; /* movq name, %rdx */
+    const char *name;
+    BYTE movq_rsp_r8[3]; /* movq %rsp, %r8 */
+    BYTE movq_rax[2]; /* movq entry, %rax */
+    const void* entry;
+    BYTE jmpq_rax[2]; /* jmp %rax */
+};
+#include "poppack.h"
+
+/*************************************************************************
+ *              allocate_stub
+ *
+ * Allocate a stub entry point.
+ */
+static ULONG_PTR allocate_stub( const char *dll, const char *name )
+{
+#define MAX_SIZE 65536
+    static struct stub *stubs;
+    static unsigned int nb_stubs;
+    struct stub *stub;
+
+    if (nb_stubs >= MAX_SIZE / sizeof(*stub)) return 0xdeadbeef;
+
+    if (!stubs)
+    {
+        SIZE_T size = MAX_SIZE;
+        if (NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&stubs, 0, &size,
+                                     MEM_COMMIT, PAGE_EXECUTE_WRITECOPY ) != STATUS_SUCCESS)
+            return 0xdeadbeef;
+    }
+    stub = &stubs[nb_stubs++];
+    stub->movq_rcx[0] = 0x48;
+    stub->movq_rcx[1] = 0xb9;
+    stub->dll = dll;
+    stub->movq_rdx[0] = 0x48;
+    stub->movq_rdx[1] = 0xba;
+    stub->name = name;
+    stub->movq_rsp_r8[0] = 0x49;
+    stub->movq_rsp_r8[1] = 0x89;
+    stub->movq_rsp_r8[2] = 0xe0;
+    stub->movq_rax[0] = 0x48;
+    stub->movq_rax[1] = 0xb8;
+    stub->entry = stub_entry_point;
+    stub->jmpq_rax[0] = 0xff;
+    stub->jmpq_rax[1] = 0xe0;
+
+    return (ULONG_PTR)stub;
+}
+
+#else
+static inline ULONG_PTR allocate_stub( const char *dll, const char *name ) { return 0xdeadbeed; }
+#endif
 
 
 /*************************************************************************
-- 
1.5.6.5


--------------090004020803040900070000--



More information about the wine-patches mailing list