Alexandre Julliard : ntdll: Add support for dynamically generated stub entry points.
Alexandre Julliard
julliard at winehq.org
Tue Dec 16 08:40:32 CST 2008
Module: wine
Branch: master
Commit: ccdfa4941eab300148fe5a33be1abda70a90df21
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ccdfa4941eab300148fe5a33be1abda70a90df21
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Dec 16 12:25:07 2008 +0100
ntdll: Add support for dynamically generated stub entry points.
Based on a patch by Maarten Lankhorst.
---
dlls/ntdll/loader.c | 50 +++++++++++++++++++++++++++++++++++++-------------
1 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index d3a0067..3a2276f 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -172,24 +172,20 @@ static inline BOOL call_dll_entry_point( DLLENTRYPROC proc, void *module,
#endif /* __i386__ */
-#ifdef __i386__
+#if defined(__i386__) || defined(__x86_64__)
/*************************************************************************
* stub_entry_point
*
* Entry point for stub functions.
*/
-static void stub_entry_point( const char *dll, const char *name, ... )
+static void stub_entry_point( const char *dll, const char *name, void *ret_addr )
{
EXCEPTION_RECORD rec;
rec.ExceptionCode = EXCEPTION_WINE_STUB;
rec.ExceptionFlags = EH_NONCONTINUABLE;
rec.ExceptionRecord = NULL;
-#ifdef __GNUC__
- rec.ExceptionAddress = __builtin_return_address(0);
-#else
- rec.ExceptionAddress = *((void **)&dll - 1);
-#endif
+ rec.ExceptionAddress = ret_addr;
rec.NumberParameters = 2;
rec.ExceptionInformation[0] = (ULONG_PTR)dll;
rec.ExceptionInformation[1] = (ULONG_PTR)name;
@@ -198,17 +194,29 @@ static void stub_entry_point( const char *dll, const char *name, ... )
#include "pshpack1.h"
+#ifdef __i386__
struct stub
{
- BYTE popl_eax; /* popl %eax */
BYTE pushl1; /* pushl $name */
const char *name;
BYTE pushl2; /* pushl $dll */
const char *dll;
- BYTE pushl_eax; /* pushl %eax */
- BYTE jmp; /* jmp stub_entry_point */
+ BYTE call; /* call stub_entry_point */
DWORD entry;
};
+#else
+struct stub
+{
+ BYTE movq_rdi[2]; /* movq $dll,%rdi */
+ const char *dll;
+ BYTE movq_rsi[2]; /* movq $name,%rsi */
+ const char *name;
+ BYTE movq_rsp_rdx[4]; /* movq (%rsp),%rdx */
+ BYTE movq_rax[2]; /* movq $entry, %rax */
+ const void* entry;
+ BYTE jmpq_rax[2]; /* jmp %rax */
+};
+#endif
#include "poppack.h"
/*************************************************************************
@@ -233,14 +241,30 @@ static ULONG_PTR allocate_stub( const char *dll, const char *name )
return 0xdeadbeef;
}
stub = &stubs[nb_stubs++];
- stub->popl_eax = 0x58; /* popl %eax */
+#ifdef __i386__
stub->pushl1 = 0x68; /* pushl $name */
stub->name = name;
stub->pushl2 = 0x68; /* pushl $dll */
stub->dll = dll;
- stub->pushl_eax = 0x50; /* pushl %eax */
- stub->jmp = 0xe9; /* jmp stub_entry_point */
+ stub->call = 0xe8; /* call stub_entry_point */
stub->entry = (BYTE *)stub_entry_point - (BYTE *)(&stub->entry + 1);
+#else
+ stub->movq_rdi[0] = 0x48; /* movq $dll,%rdi */
+ stub->movq_rdi[1] = 0xbf;
+ stub->dll = dll;
+ stub->movq_rsi[0] = 0x48; /* movq $name,%rsi */
+ stub->movq_rsi[1] = 0xbe;
+ stub->name = name;
+ stub->movq_rsp_rdx[0] = 0x48; /* movq (%rsp),%rdx */
+ stub->movq_rsp_rdx[1] = 0x8b;
+ stub->movq_rsp_rdx[2] = 0x14;
+ stub->movq_rsp_rdx[3] = 0x24;
+ stub->movq_rax[0] = 0x48; /* movq $entry, %rax */
+ stub->movq_rax[1] = 0xb8;
+ stub->entry = stub_entry_point;
+ stub->jmpq_rax[0] = 0xff; /* jmp %rax */
+ stub->jmpq_rax[1] = 0xe0;
+#endif
return (ULONG_PTR)stub;
}
More information about the wine-cvs
mailing list