Alexandre Julliard : ntdll:
Added emulation of ATL thunks for platforms with NX support.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Feb 10 08:55:11 CST 2006
Module: wine
Branch: refs/heads/master
Commit: 57550776cec6f3eac92082bb3bf893b0e31f162e
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=57550776cec6f3eac92082bb3bf893b0e31f162e
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Feb 10 15:13:59 2006 +0100
ntdll: Added emulation of ATL thunks for platforms with NX support.
---
dlls/ntdll/signal_i386.c | 33 ++++++++++++++++++++++++++++++++-
1 files changed, 32 insertions(+), 1 deletions(-)
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index be5164d..0cacd7a 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -902,6 +902,34 @@ static inline int is_privileged_instr( C
}
+#include "pshpack1.h"
+struct atl_thunk
+{
+ DWORD movl; /* movl this,4(%esp) */
+ DWORD this;
+ BYTE jmp; /* jmp func */
+ int func;
+};
+#include "poppack.h"
+
+/**********************************************************************
+ * check_atl_thunk
+ *
+ * Check if code destination is an ATL thunk, and emulate it if so.
+ */
+static BOOL check_atl_thunk( EXCEPTION_RECORD *rec, CONTEXT *context )
+{
+ struct atl_thunk *thunk = (struct atl_thunk *)rec->ExceptionInformation[1];
+
+ if (thunk->movl != 0x042444c7 || thunk->jmp != 0xe9) return FALSE;
+ *((DWORD *)context->Esp + 1) = thunk->this;
+ context->Eip = (DWORD_PTR)(&thunk->func + 1) + thunk->func;
+ TRACE( "emulating ATL thunk at %p, func=%08lx arg=%08lx\n",
+ thunk, context->Eip, *((DWORD *)context->Esp + 1) );
+ return TRUE;
+}
+
+
/***********************************************************************
* setup_exception
*
@@ -1026,7 +1054,10 @@ static void WINAPI raise_segv_exception(
{
case EXCEPTION_ACCESS_VIOLATION:
if (rec->NumberParameters == 2)
+ {
+ if ((rec->ExceptionInformation[0] == 8) && check_atl_thunk( rec, context )) goto done;
rec->ExceptionCode = VIRTUAL_HandleFault( (void *)rec->ExceptionInformation[1] );
+ }
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
/* FIXME: pass through exception handler first? */
@@ -1175,7 +1206,7 @@ static HANDLER_DEF(segv_handler)
rec->ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
#ifdef FAULT_ADDRESS
rec->NumberParameters = 2;
- rec->ExceptionInformation[0] = (get_error_code(HANDLER_CONTEXT) & 2) != 0;
+ rec->ExceptionInformation[0] = (get_error_code(HANDLER_CONTEXT) >> 1) & 0x09;
rec->ExceptionInformation[1] = (ULONG_PTR)FAULT_ADDRESS;
#endif
break;
More information about the wine-cvs
mailing list