[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