summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormdejong <mdejong>2003-01-25 14:11:31 (GMT)
committermdejong <mdejong>2003-01-25 14:11:31 (GMT)
commit45c06028d02a86a2c5e83c43af1919b031a5e45f (patch)
tree8e09cb15a16baa630dc51a0b34c9af26e3eac4b6
parent758234180a856302c7aa063a7fbb6cb06145cd56 (diff)
downloadtcl-45c06028d02a86a2c5e83c43af1919b031a5e45f.zip
tcl-45c06028d02a86a2c5e83c43af1919b031a5e45f.tar.gz
tcl-45c06028d02a86a2c5e83c43af1919b031a5e45f.tar.bz2
* 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.
-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 */