From 30be6c1a93c62e6cac369d88b720615a147982d1 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 11 Mar 2011 23:47:09 +0000 Subject: SEH-emulation for AMD64 mingw-w64 does not accept _WIN32_IE < 0x0501 Merged --cherrypick from core-8-5-branch (2010-12-13, f4ecadb40d) remove conflicting definition of timezone struct --- ChangeLog | 7 +++ win/tkWin32Dll.c | 143 ++++++++++++++++++++++++++++++++++++++++++------------- win/tkWinPort.h | 9 ---- win/tkWinX.c | 2 +- 4 files changed, 119 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index 32ad046..d37e003 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-03-12 Jan Nijtmans + + * win/tkWin32Dll.c: SEH-emulation for AMD64 + * win/tkWinX.c: mingw-w64 does not accept _WIN32_IE < 0x0501 + Merged --cherrypick from core-8-5-branch (2010-12-13, f4ecadb40d) + * win/tkWinPort.h: remove conflicting definition of timezone struct + 2011-03-11 Jan Nijtmans * win/Makefile.in (VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE): diff --git a/win/tkWin32Dll.c b/win/tkWin32Dll.c index 958fdb4..7e1bd43 100644 --- a/win/tkWin32Dll.c +++ b/win/tkWin32Dll.c @@ -1,4 +1,4 @@ -/* +/* * tkWin32Dll.c -- * * This file contains a stub dll entry point. @@ -15,6 +15,7 @@ #ifndef STATIC_BUILD #ifdef HAVE_NO_SEH + /* * Unlike Borland and Microsoft, we don't register exception handlers by * pushing registration records onto the runtime stack. Instead, we register @@ -30,23 +31,23 @@ typedef struct EXCEPTION_REGISTRATION { int status; } EXCEPTION_REGISTRATION; -/* Need to add noinline flag to DllMain declaration so that gcc -O3 - * does not inline asm code into DllEntryPoint and cause a - * compile time error because of redefined local labels. +/* + * Need to add noinline flag to DllMain declaration so that gcc -O3 does not + * inline asm code into DllEntryPoint and cause a compile time error because + * of redefined local labels. */ -BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, - LPVOID reserved) - __attribute__ ((noinline)); +BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, + LPVOID reserved) __attribute__ ((noinline)); -#else +#else /* !HAVE_NO_SEH */ /* * The following declaration is for the VC++ DLL entry point. */ -BOOL WINAPI DllMain _ANSI_ARGS_((HINSTANCE hInst, - DWORD reason, LPVOID reserved)); +BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, + LPVOID reserved); #endif /* HAVE_NO_SEH */ /* @@ -54,9 +55,8 @@ BOOL WINAPI DllMain _ANSI_ARGS_((HINSTANCE hInst, * * DllEntryPoint -- * - * This wrapper function is used by Borland to invoke the - * initialization code for Tk. It simply calls the DllMain - * routine. + * This wrapper function is used by Borland to invoke the initialization + * code for Tk. It simply calls the DllMain routine. * * Results: * See DllMain. @@ -67,7 +67,7 @@ BOOL WINAPI DllMain _ANSI_ARGS_((HINSTANCE hInst, *---------------------------------------------------------------------- */ -BOOL WINAPI +BOOL APIENTRY DllEntryPoint(hInst, reason, reserved) HINSTANCE hInst; /* Library instance handle. */ DWORD reason; /* Reason this function is being called. */ @@ -81,18 +81,18 @@ DllEntryPoint(hInst, reason, reserved) * * DllMain -- * - * DLL entry point. It is only necessary to specify our dll here so - * that resources are found correctly. Otherwise Tk will initialize - * and clean up after itself through other methods, in order to be - * consistent whether the build is static or dynamic. + * DLL entry point. It is only necessary to specify our dll here so that + * resources are found correctly. Otherwise Tk will initialize and clean + * up after itself through other methods, in order to be consistent + * whether the build is static or dynamic. * * Results: * Always TRUE. * * Side effects: - * This might call some sycronization functions, but MSDN - * documentation states: "Waiting on synchronization objects in - * DllMain can cause a deadlock." + * This might call some synchronization functions, but MSDN documentation + * states: "Waiting on synchronization objects in DllMain can cause a + * deadlock." * *---------------------------------------------------------------------- */ @@ -108,8 +108,8 @@ DllMain(hInstance, reason, reserved) #endif /* - * If we are attaching to the DLL from a new process, tell Tk about - * the hInstance to use. + * If we are attaching to the DLL from a new process, tell Tk about the + * hInstance to use. */ switch (reason) { @@ -120,12 +120,82 @@ DllMain(hInstance, reason, reserved) case DLL_PROCESS_DETACH: /* - * Protect the call to TkFinalize in an SEH block. We can't - * be guarenteed Tk is always being unloaded from a stable - * condition. + * Protect the call to TkFinalize in an SEH block. We can't be + * guarenteed Tk is always being unloaded from a stable condition. */ #ifdef HAVE_NO_SEH +# ifdef __WIN64 + __asm__ __volatile__ ( + + /* + * Construct an EXCEPTION_REGISTRATION to protect the call to + * TkFinalize + */ + + "leaq %[registration], %%rdx" "\n\t" + "movq %%gs:0, %%rax" "\n\t" + "movq %%rax, 0x0(%%edx)" "\n\t" /* link */ + "leaq 1f, %%rax" "\n\t" + "movq %%rax, 0x8(%%rdx)" "\n\t" /* handler */ + "movq %%rbp, 0x10(%%rdx)" "\n\t" /* ebp */ + "movq %%rsp, 0x18(%%rdx)" "\n\t" /* esp */ + "movl %[error], 0x20(%%rdx)" "\n\t" /* status */ + + /* + * Link the EXCEPTION_REGISTRATION on the chain + */ + + "movq %%rdx, %%gs:0" "\n\t" + + /* + * Call TkFinalize + */ + + "movq $0x0, %%rcx" "\n\t" + "call TkFinalize" "\n\t" + + /* + * Come here on a normal exit. Recover the EXCEPTION_REGISTRATION + * and store a TCL_OK status + */ + + "movq %%gs:0, %%rdx" "\n\t" + "movl %[ok], %%eax" "\n\t" + "movl %%eax, 0x20(%%rdx)" "\n\t" + "jmp 2f" "\n" + + /* + * Come here on an exception. Get the EXCEPTION_REGISTRATION that + * we previously put on the chain. + */ + + "1:" "\t" + "movq %%gs:0, %%rdx" "\n\t" + "movq 0x10(%%rdx), %%rdx" "\n\t" + + /* + * Come here however we exited. Restore context from the + * EXCEPTION_REGISTRATION in case the stack is unbalanced. + */ + + "2:" "\t" + "movq 0x18(%%rdx), %%rsp" "\n\t" + "movq 0x10(%%rdx), %%rbp" "\n\t" + "movq 0x0(%%rdx), %%rax" "\n\t" + "movq %%rax, %%gs:0" "\n\t" + + : + /* No outputs */ + : + [registration] "m" (registration), + [ok] "i" (TCL_OK), + [error] "i" (TCL_ERROR) + : + "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "memory" + ); + +# else __asm__ __volatile__ ( /* @@ -175,7 +245,7 @@ DllMain(hInstance, reason, reserved) "movl 0x8(%%edx), %%edx" "\n" - /* + /* * Come here however we exited. Restore context from the * EXCEPTION_REGISTRATION in case the stack is unbalanced. */ @@ -194,15 +264,16 @@ DllMain(hInstance, reason, reserved) [error] "i" (TCL_ERROR) : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory" - ); + ); +# endif #else /* HAVE_NO_SEH */ __try { /* - * Run and remove our exit handlers, if they haven't already - * been run. Just in case we are being unloaded prior to - * Tcl (it can happen), we won't leave any dangling pointers - * hanging around for when Tcl gets unloaded later. + * Run and remove our exit handlers, if they haven't already been + * run. Just in case we are being unloaded prior to Tcl (it can + * happen), we won't leave any dangling pointers hanging around + * for when Tcl gets unloaded later. */ TkFinalize(NULL); @@ -217,3 +288,11 @@ DllMain(hInstance, reason, reserved) } #endif /* !STATIC_BUILD */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/win/tkWinPort.h b/win/tkWinPort.h index 4eaec99..c0868bf 100644 --- a/win/tkWinPort.h +++ b/win/tkWinPort.h @@ -119,15 +119,6 @@ #define TkpCreateNativeBitmap(display, source) None #define TkpGetNativeAppBitmap(display, name, w, h) None -/* - * Define timezone for gettimeofday. - */ - -struct timezone { - int tz_minuteswest; - int tz_dsttime; -}; - #ifndef _TCLINT #include #endif diff --git a/win/tkWinX.c b/win/tkWinX.c index d577466..d81e266 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -22,7 +22,7 @@ */ #ifndef _WIN32_IE -#define _WIN32_IE 0x0300 +#define _WIN32_IE 0x0501 /* IE 5 */ #endif #include -- cgit v0.12