summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--win/tclWin32Dll.c92
-rw-r--r--win/tclWinChan.c94
-rw-r--r--win/tclWinFCmd.c133
4 files changed, 209 insertions, 125 deletions
diff --git a/ChangeLog b/ChangeLog
index 37fbaef..92dd6de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
2003-01-25 Mo DeJong <mdejong@users.sourceforge.net>
+ * win/tclWin32Dll.c (TclpCheckStackSpace, squelch_warnings):
+ * win/tclWinChan.c (Tcl_MakeFileChannel, squelch_warnings):
+ * win/tclWinFCmd.c (DoRenameFile, DoCopyFile, squelch_warnings):
+ Re-implement inline ASM SEH handlers for gcc.
+ The esp and ebp registers are now saved on the
+ stack instead of in global variables so that
+ the code is thread safe. Add additional checks
+ when TCL_MEM_DEBUG is defined to be sure the
+ values were recovered from the stack properly.
+ Remove squelch_warnings functions and add
+ a dummy call in the handler methods to squelch
+ compiler warnings.
+
+2003-01-25 Mo DeJong <mdejong@users.sourceforge.net>
+
* win/configure:
* win/configure.in: Define HAVE_ALLOCA_GCC_INLINE
when we detect that no alloca function is found
diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c
index 13f2a4b..62d9e1c 100644
--- a/win/tclWin32Dll.c
+++ b/win/tclWin32Dll.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWin32Dll.c,v 1.22 2003/01/25 12:48:12 mdejong Exp $
+ * RCS: @(#) $Id: tclWin32Dll.c,v 1.23 2003/01/25 14:11:32 mdejong Exp $
*/
#include "tclWinInt.h"
@@ -37,13 +37,14 @@ typedef VOID (WINAPI UTUNREGISTER)(HANDLE hModule);
static HINSTANCE hInstance; /* HINSTANCE of this DLL. */
static int platformId; /* Running under NT, or 95/98? */
-#ifdef HAVE_NO_SEH
-static void *ESP;
-static void *EBP;
-static void* HANDLER[2];
-static void* NEW_HANDLER = &(HANDLER[0]);
-static void* OLD_HANDLER = &(HANDLER[1]);
-#endif /* HAVE_NO_SEH */
+#if defined(HAVE_NO_SEH) && defined(TCL_MEM_DEBUG)
+static void *INITIAL_ESP,
+ *INITIAL_EBP,
+ *INITIAL_HANDLER,
+ *RESTORED_ESP,
+ *RESTORED_EBP,
+ *RESTORED_HANDLER;
+#endif /* HAVE_NO_SEH && TCL_MEM_DEBUG */
/*
* The following function tables are used to dispatch to either the
@@ -376,17 +377,21 @@ TclpCheckStackSpace()
*/
#ifdef HAVE_NO_SEH
+# ifdef TCL_MEM_DEBUG
__asm__ __volatile__ (
- "movl %esp, _ESP" "\n\t"
- "movl %ebp, _EBP");
+ "movl %%esp, %0" "\n\t"
+ "movl %%ebp, %1" "\n\t"
+ "movl %%fs:0, %2" "\n\t"
+ : "=m"(INITIAL_ESP),
+ "=m"(INITIAL_EBP),
+ "=r"(INITIAL_HANDLER) );
+# endif /* TCL_MEM_DEBUG */
__asm__ __volatile__ (
- "movl %fs:0, %eax" "\n\t"
- "movl %eax, _OLD_HANDLER" "\n\t"
- "movl __except_checkstackspace_handler, %eax" "\n\t"
- "movl %eax, _NEW_HANDLER" "\n\t"
- "movl _HANDLER, %eax" "\n\t"
- "movl %eax, %fs:0");
+ "pushl %ebp" "\n\t"
+ "pushl $__except_checkstackspace_handler" "\n\t"
+ "pushl %fs:0" "\n\t"
+ "movl %esp, %fs:0");
#else
__try {
#endif /* HAVE_NO_SEH */
@@ -403,15 +408,36 @@ TclpCheckStackSpace()
retval = 1;
#ifdef HAVE_NO_SEH
__asm__ __volatile__ (
- "jmp checkstackspace_pop" "\n"
- "checkstackspace_reentry:" "\n\t"
- "movl _ESP, %esp" "\n\t"
- "movl _EBP, %ebp");
+ "movl %%fs:0, %%esp" "\n\t"
+ "jmp checkstackspace_pop" "\n"
+ "checkstackspace_reentry:" "\n\t"
+ "movl %%fs:0, %%eax" "\n\t"
+ "movl 0x8(%%eax), %%esp" "\n\t"
+ "movl 0x8(%%esp), %%ebp" "\n"
+ "checkstackspace_pop:" "\n\t"
+ "movl (%%esp), %%eax" "\n\t"
+ "movl %%eax, %%fs:0" "\n\t"
+ "add $12, %%esp" "\n\t"
+ :
+ :
+ : "%eax");
+# ifdef TCL_MEM_DEBUG
__asm__ __volatile__ (
- "checkstackspace_pop:" "\n\t"
- "mov _OLD_HANDLER, %eax" "\n\t"
- "mov %eax, %fs:0");
+ "movl %%esp, %0" "\n\t"
+ "movl %%ebp, %1" "\n\t"
+ "movl %%fs:0, %2" "\n\t"
+ : "=m"(RESTORED_ESP),
+ "=m"(RESTORED_EBP),
+ "=r"(RESTORED_HANDLER) );
+
+ if (INITIAL_ESP != RESTORED_ESP)
+ panic("ESP restored incorrectly");
+ if (INITIAL_EBP != RESTORED_EBP)
+ panic("EBP restored incorrectly");
+ if (INITIAL_HANDLER != RESTORED_HANDLER)
+ panic("HANDLER restored incorrectly");
+# endif /* TCL_MEM_DEBUG */
#else
} __except (EXCEPTION_EXECUTE_HANDLER) {}
#endif /* HAVE_NO_SEH */
@@ -433,6 +459,8 @@ _except_checkstackspace_handler(
{
__asm__ __volatile__ (
"jmp checkstackspace_reentry");
+ /* Nuke compiler warning about unused static function */
+ _except_checkstackspace_handler(NULL, NULL, NULL, NULL);
return 0; /* Function does not return */
}
#endif /* HAVE_NO_SEH */
@@ -627,21 +655,3 @@ Tcl_WinTCharToUtf(string, len, dsPtr)
return Tcl_ExternalToUtfDString(tclWinTCharEncoding,
(CONST char *) string, len, dsPtr);
}
-
-#ifdef HAVE_NO_SEH
-/*
- * This method exists only to stop the compiler from emitting
- * warnings about variables and methods accessed only from asm.
- */
-static void squelch_warnings()
-{
- void *ptr;
- ptr = _except_checkstackspace_handler;
- ESP = 0;
- EBP = 0;
- OLD_HANDLER = 0;
- NEW_HANDLER = 0;
- HANDLER[0] = 0;
- squelch_warnings();
-}
-#endif /* HAVE_NO_SEH */
diff --git a/win/tclWinChan.c b/win/tclWinChan.c
index 9ba2f64..c377245 100644
--- a/win/tclWinChan.c
+++ b/win/tclWinChan.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinChan.c,v 1.28 2003/01/16 19:01:59 mdejong Exp $
+ * RCS: @(#) $Id: tclWinChan.c,v 1.29 2003/01/25 14:11:32 mdejong Exp $
*/
#include "tclWinInt.h"
@@ -121,10 +121,14 @@ static Tcl_ChannelType fileChannelType = {
FileWideSeekProc, /* Wide seek proc. */
};
-#ifdef HAVE_NO_SEH
-static void *ESP;
-static void *EBP;
-#endif /* HAVE_NO_SEH */
+#if defined(HAVE_NO_SEH) && defined(TCL_MEM_DEBUG)
+static void *INITIAL_ESP,
+ *INITIAL_EBP,
+ *INITIAL_HANDLER,
+ *RESTORED_ESP,
+ *RESTORED_EBP,
+ *RESTORED_HANDLER;
+#endif /* HAVE_NO_SEH && TCL_MEM_DEBUG */
/*
@@ -1049,34 +1053,59 @@ Tcl_MakeFileChannel(rawHandle, mode)
*/
#ifdef HAVE_NO_SEH
+# ifdef TCL_MEM_DEBUG
__asm__ __volatile__ (
- "movl %esp, _ESP" "\n\t"
- "movl %ebp, _EBP");
-
- __asm__ __volatile__ (
- "pushl $__except_makefilechannel_handler" "\n\t"
- "pushl %fs:0" "\n\t"
- "mov %esp, %fs:0");
+ "movl %%esp, %0" "\n\t"
+ "movl %%ebp, %1" "\n\t"
+ "movl %%fs:0, %2" "\n\t"
+ : "=m"(INITIAL_ESP),
+ "=m"(INITIAL_EBP),
+ "=r"(INITIAL_HANDLER) );
+# endif /* TCL_MEM_DEBUG */
result = 0;
+
+ __asm__ __volatile__ (
+ "pushl %ebp" "\n\t"
+ "pushl $__except_makefilechannel_handler" "\n\t"
+ "pushl %fs:0" "\n\t"
+ "movl %esp, %fs:0");
#else
__try {
#endif /* HAVE_NO_SEH */
CloseHandle(dupedHandle);
#ifdef HAVE_NO_SEH
__asm__ __volatile__ (
- "jmp makefilechannel_pop" "\n"
- "makefilechannel_reentry:" "\n\t"
- "movl _ESP, %esp" "\n\t"
- "movl _EBP, %ebp");
-
- result = 1; /* True when exception was raised */
-
- __asm__ __volatile__ (
- "makefilechannel_pop:" "\n\t"
- "mov (%esp), %eax" "\n\t"
- "mov %eax, %fs:0" "\n\t"
- "add $8, %esp");
+ "jmp makefilechannel_pop" "\n"
+ "makefilechannel_reentry:" "\n\t"
+ "movl %%fs:0, %%eax" "\n\t"
+ "movl 0x8(%%eax), %%esp" "\n\t"
+ "movl 0x8(%%esp), %%ebp" "\n"
+ "movl $1, %0" "\n"
+ "makefilechannel_pop:" "\n\t"
+ "movl (%%esp), %%eax" "\n\t"
+ "movl %%eax, %%fs:0" "\n\t"
+ "add $12, %%esp" "\n\t"
+ : "=m"(result)
+ :
+ : "%eax");
+
+# ifdef TCL_MEM_DEBUG
+ __asm__ __volatile__ (
+ "movl %%esp, %0" "\n\t"
+ "movl %%ebp, %1" "\n\t"
+ "movl %%fs:0, %2" "\n\t"
+ : "=m"(RESTORED_ESP),
+ "=m"(RESTORED_EBP),
+ "=r"(RESTORED_HANDLER) );
+
+ if (INITIAL_ESP != RESTORED_ESP)
+ panic("ESP restored incorrectly");
+ if (INITIAL_EBP != RESTORED_EBP)
+ panic("EBP restored incorrectly");
+ if (INITIAL_HANDLER != RESTORED_HANDLER)
+ panic("HANDLER restored incorrectly");
+# endif /* TCL_MEM_DEBUG */
if (result)
return NULL;
@@ -1116,6 +1145,8 @@ _except_makefilechannel_handler(
{
__asm__ __volatile__ (
"jmp makefilechannel_reentry");
+ /* Nuke compiler warning about unused static function */
+ _except_makefilechannel_handler(NULL, NULL, NULL, NULL);
return 0; /* Function does not return */
}
#endif
@@ -1314,18 +1345,3 @@ TclWinFlushDirtyChannels ()
}
}
}
-
-#ifdef HAVE_NO_SEH
-/*
- * This method exists only to stop the compiler from emitting
- * warnings about variables and methods accessed only from asm.
- */
-static void squelch_warnings()
-{
- void *ptr;
- ptr = _except_makefilechannel_handler;
- ESP = 0;
- EBP = 0;
- squelch_warnings();
-}
-#endif /* HAVE_NO_SEH */
diff --git a/win/tclWinFCmd.c b/win/tclWinFCmd.c
index f1d5dfe..66d2931 100644
--- a/win/tclWinFCmd.c
+++ b/win/tclWinFCmd.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinFCmd.c,v 1.32 2003/01/16 19:01:59 mdejong Exp $
+ * RCS: @(#) $Id: tclWinFCmd.c,v 1.33 2003/01/25 14:11:33 mdejong Exp $
*/
#include "tclWinInt.h"
@@ -73,10 +73,14 @@ CONST TclFileAttrProcs tclpFileAttrProcs[] = {
{GetWinFileShortName, CannotSetAttribute},
{GetWinFileAttributes, SetWinFileAttributes}};
-#ifdef HAVE_NO_SEH
-static void *ESP;
-static void *EBP;
-#endif /* HAVE_NO_SEH */
+#if defined(HAVE_NO_SEH) && defined(TCL_MEM_DEBUG)
+static void *INITIAL_ESP,
+ *INITIAL_EBP,
+ *INITIAL_HANDLER,
+ *RESTORED_ESP,
+ *RESTORED_EBP,
+ *RESTORED_HANDLER;
+#endif /* HAVE_NO_SEH && TCL_MEM_DEBUG */
/*
* Prototype for the TraverseWinTree callback function.
@@ -188,14 +192,21 @@ DoRenameFile(
*/
#ifdef HAVE_NO_SEH
+# ifdef TCL_MEM_DEBUG
__asm__ __volatile__ (
- "movl %esp, _ESP" "\n\t"
- "movl %ebp, _EBP");
+ "movl %%esp, %0" "\n\t"
+ "movl %%ebp, %1" "\n\t"
+ "movl %%fs:0, %2" "\n\t"
+ : "=m"(INITIAL_ESP),
+ "=m"(INITIAL_EBP),
+ "=r"(INITIAL_HANDLER) );
+# endif /* TCL_MEM_DEBUG */
__asm__ __volatile__ (
+ "pushl %ebp" "\n\t"
"pushl $__except_dorenamefile_handler" "\n\t"
"pushl %fs:0" "\n\t"
- "mov %esp, %fs:0");
+ "movl %esp, %fs:0");
#else
__try {
#endif /* HAVE_NO_SEH */
@@ -204,16 +215,35 @@ DoRenameFile(
}
#ifdef HAVE_NO_SEH
__asm__ __volatile__ (
- "jmp dorenamefile_pop" "\n"
- "dorenamefile_reentry:" "\n\t"
- "movl _ESP, %esp" "\n\t"
- "movl _EBP, %ebp");
-
+ "jmp dorenamefile_pop" "\n"
+ "dorenamefile_reentry:" "\n\t"
+ "movl %%fs:0, %%eax" "\n\t"
+ "movl 0x8(%%eax), %%esp" "\n\t"
+ "movl 0x8(%%esp), %%ebp" "\n"
+ "dorenamefile_pop:" "\n\t"
+ "movl (%%esp), %%eax" "\n\t"
+ "movl %%eax, %%fs:0" "\n\t"
+ "add $12, %%esp" "\n\t"
+ :
+ :
+ : "%eax");
+
+# ifdef TCL_MEM_DEBUG
__asm__ __volatile__ (
- "dorenamefile_pop:" "\n\t"
- "mov (%esp), %eax" "\n\t"
- "mov %eax, %fs:0" "\n\t"
- "add $8, %esp");
+ "movl %%esp, %0" "\n\t"
+ "movl %%ebp, %1" "\n\t"
+ "movl %%fs:0, %2" "\n\t"
+ : "=m"(RESTORED_ESP),
+ "=m"(RESTORED_EBP),
+ "=r"(RESTORED_HANDLER) );
+
+ if (INITIAL_ESP != RESTORED_ESP)
+ panic("ESP restored incorrectly");
+ if (INITIAL_EBP != RESTORED_EBP)
+ panic("EBP restored incorrectly");
+ if (INITIAL_HANDLER != RESTORED_HANDLER)
+ panic("HANDLER restored incorrectly");
+# endif /* TCL_MEM_DEBUG */
#else
} __except (EXCEPTION_EXECUTE_HANDLER) {}
#endif /* HAVE_NO_SEH */
@@ -450,6 +480,8 @@ _except_dorenamefile_handler(
{
__asm__ __volatile__ (
"jmp dorenamefile_reentry");
+ /* Nuke compiler warning about unused static function */
+ _except_dorenamefile_handler(NULL, NULL, NULL, NULL);
return 0; /* Function does not return */
}
#endif /* HAVE_NO_SEH */
@@ -514,14 +546,21 @@ DoCopyFile(
*/
#ifdef HAVE_NO_SEH
+# ifdef TCL_MEM_DEBUG
__asm__ __volatile__ (
- "movl %esp, _ESP" "\n\t"
- "movl %ebp, _EBP");
+ "movl %%esp, %0" "\n\t"
+ "movl %%ebp, %1" "\n\t"
+ "movl %%fs:0, %2" "\n\t"
+ : "=m"(INITIAL_ESP),
+ "=m"(INITIAL_EBP),
+ "=r"(INITIAL_HANDLER) );
+# endif /* TCL_MEM_DEBUG */
__asm__ __volatile__ (
+ "pushl %ebp" "\n\t"
"pushl $__except_docopyfile_handler" "\n\t"
"pushl %fs:0" "\n\t"
- "mov %esp, %fs:0");
+ "movl %esp, %fs:0");
#else
__try {
#endif /* HAVE_NO_SEH */
@@ -530,16 +569,35 @@ DoCopyFile(
}
#ifdef HAVE_NO_SEH
__asm__ __volatile__ (
- "jmp docopyfile_pop" "\n"
- "docopyfile_reentry:" "\n\t"
- "movl _ESP, %esp" "\n\t"
- "movl _EBP, %ebp");
-
+ "jmp docopyfile_pop" "\n"
+ "docopyfile_reentry:" "\n\t"
+ "movl %%fs:0, %%eax" "\n\t"
+ "movl 0x8(%%eax), %%esp" "\n\t"
+ "movl 0x8(%%esp), %%ebp" "\n"
+ "docopyfile_pop:" "\n\t"
+ "movl (%%esp), %%eax" "\n\t"
+ "movl %%eax, %%fs:0" "\n\t"
+ "add $12, %%esp" "\n\t"
+ :
+ :
+ : "%eax");
+
+# ifdef TCL_MEM_DEBUG
__asm__ __volatile__ (
- "docopyfile_pop:" "\n\t"
- "mov (%esp), %eax" "\n\t"
- "mov %eax, %fs:0" "\n\t"
- "add $8, %esp");
+ "movl %%esp, %0" "\n\t"
+ "movl %%ebp, %1" "\n\t"
+ "movl %%fs:0, %2" "\n\t"
+ : "=m"(RESTORED_ESP),
+ "=m"(RESTORED_EBP),
+ "=r"(RESTORED_HANDLER) );
+
+ if (INITIAL_ESP != RESTORED_ESP)
+ panic("ESP restored incorrectly");
+ if (INITIAL_EBP != RESTORED_EBP)
+ panic("EBP restored incorrectly");
+ if (INITIAL_HANDLER != RESTORED_HANDLER)
+ panic("HANDLER restored incorrectly");
+# endif /* TCL_MEM_DEBUG */
#else
} __except (EXCEPTION_EXECUTE_HANDLER) {}
#endif /* HAVE_NO_SEH */
@@ -604,6 +662,7 @@ _except_docopyfile_handler(
{
__asm__ __volatile__ (
"jmp docopyfile_reentry");
+ _except_docopyfile_handler(NULL,NULL,NULL,NULL);
return 0; /* Function does not return */
}
#endif /* HAVE_NO_SEH */
@@ -1834,19 +1893,3 @@ TclpObjListVolumes(void)
Tcl_IncrRefCount(resultPtr);
return resultPtr;
}
-
-#ifdef HAVE_NO_SEH
-/*
- * This method exists only to stop the compiler from emitting
- * warnings about variables and methods accessed only from asm.
- */
-static void squelch_warnings()
-{
- void *ptr;
- ptr = _except_dorenamefile_handler;
- ptr = _except_docopyfile_handler;
- ESP = 0;
- EBP = 0;
- squelch_warnings();
-}
-#endif /* HAVE_NO_SEH */