summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormdejong <mdejong>2002-03-15 01:10:18 (GMT)
committermdejong <mdejong>2002-03-15 01:10:18 (GMT)
commit93f80c911dda1024d86d0faf63274fa858cc60f1 (patch)
tree69d06455b401989ef8a5ae460127b03d813d591d
parentd2a773ac3184a75ad5c98c315ea7cce8646fcf2a (diff)
downloadtcl-93f80c911dda1024d86d0faf63274fa858cc60f1.zip
tcl-93f80c911dda1024d86d0faf63274fa858cc60f1.tar.gz
tcl-93f80c911dda1024d86d0faf63274fa858cc60f1.tar.bz2
* win/configure: Regen.
* win/configure.in: Add configure time test for SEH support in the compiler. * win/tclWin32Dll.c (ESP, EBP, TclpCheckStackSpace, _except_checkstackspace_handler): * win/tclWinChan.c (ESP, EBP, Tcl_MakeFileChannel, _except_makefilechannel_handler): * win/tclWinFCmd.c (ESP, EBP, DoRenameFile, _except_dorenamefile_handler, DoCopyFile, _except_docopyfile_handler): Implement SEH support under gcc using inline asm. Tcl and Tk should now compile with Mingw 1.1. [Patch 525746]
-rw-r--r--ChangeLog15
-rwxr-xr-xwin/configure100
-rw-r--r--win/configure.in30
-rw-r--r--win/tclWin32Dll.c48
-rw-r--r--win/tclWinChan.c54
-rw-r--r--win/tclWinFCmd.c89
6 files changed, 306 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index 830415d..a05afdc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
2002-03-14 Mo DeJong <mdejong@users.sourceforge.net>
+ * win/configure: Regen.
+ * win/configure.in: Add configure time test for SEH
+ support in the compiler.
+ * win/tclWin32Dll.c (ESP, EBP, TclpCheckStackSpace,
+ _except_checkstackspace_handler):
+ * win/tclWinChan.c (ESP, EBP, Tcl_MakeFileChannel,
+ _except_makefilechannel_handler):
+ * win/tclWinFCmd.c (ESP, EBP, DoRenameFile,
+ _except_dorenamefile_handler,
+ DoCopyFile, _except_docopyfile_handler):
+ Implement SEH support under gcc using inline asm.
+ Tcl and Tk should now compile with Mingw 1.1. [Patch 525746]
+
+2002-03-14 Mo DeJong <mdejong@users.sourceforge.net>
+
* win/tclWinFCmd.c (DoRenameFile, DoCopyFile): Handle
an SEH exception with EXCEPTION_EXECUTE_HANDLER instead
of restarting the faulting instruction with
diff --git a/win/configure b/win/configure
index 35b178c..9dc3215 100755
--- a/win/configure
+++ b/win/configure
@@ -533,7 +533,7 @@ fi
TCL_VERSION=8.4
TCL_MAJOR_VERSION=8
TCL_MINOR_VERSION=4
-TCL_PATCH_LEVEL="a4"
+TCL_PATCH_LEVEL="a5"
VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
TCL_DDE_VERSION=1.2
@@ -966,18 +966,70 @@ if test "$ac_cv_cygwin" = "yes" ; then
Use the Mingw version of gcc from www.mingw.org instead." 1>&2; exit 1; }
fi
+
+echo $ac_n "checking for SEH support in compiler""... $ac_c" 1>&6
+echo "configure:972: checking for SEH support in compiler" >&5
+if eval "test \"`echo '$''{'tcl_cv_seh'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ tcl_cv_seh=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 980 "configure"
+#include "confdefs.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+int main(int argc, char** argv) {
+ int a, b = 0;
+ __try {
+ a = 666 / b;
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) {
+ return 0;
+ }
+ return 1;
+}
+
+EOF
+if { (eval echo configure:999: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ tcl_cv_seh=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ tcl_cv_seh=no
+fi
+rm -fr conftest*
+fi
+
+
+fi
+
+echo "$ac_t""$tcl_cv_seh" 1>&6
+if test "$tcl_cv_seh" = "no" ; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_NO_SEH
+EOF
+
+fi
+
#--------------------------------------------------------------------
# Determines the correct binary file extension (.o, .obj, .exe etc.)
#--------------------------------------------------------------------
echo $ac_n "checking for object suffix""... $ac_c" 1>&6
-echo "configure:975: checking for object suffix" >&5
+echo "configure:1027: checking for object suffix" >&5
if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
rm -f conftest*
echo 'int i = 1;' > conftest.$ac_ext
-if { (eval echo configure:981: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1033: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
for ac_file in conftest.*; do
case $ac_file in
*.c) ;;
@@ -995,19 +1047,19 @@ OBJEXT=$ac_cv_objext
ac_objext=$ac_cv_objext
echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
-echo "configure:999: checking for mingw32 environment" >&5
+echo "configure:1051: checking for mingw32 environment" >&5
if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1004 "configure"
+#line 1056 "configure"
#include "confdefs.h"
int main() {
return __MINGW32__;
; return 0; }
EOF
-if { (eval echo configure:1011: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1063: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_mingw32=yes
else
@@ -1026,7 +1078,7 @@ test "$ac_cv_mingw32" = yes && MINGW32=yes
echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
-echo "configure:1030: checking for executable suffix" >&5
+echo "configure:1082: checking for executable suffix" >&5
if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1036,7 +1088,7 @@ else
rm -f conftest*
echo 'int main () { return 0; }' > conftest.$ac_ext
ac_cv_exeext=
- if { (eval echo configure:1040: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ if { (eval echo configure:1092: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
for file in conftest.*; do
case $file in
*.c | *.o | *.obj) ;;
@@ -1063,7 +1115,7 @@ ac_exeext=$EXEEXT
echo $ac_n "checking for building with threads""... $ac_c" 1>&6
-echo "configure:1067: checking for building with threads" >&5
+echo "configure:1119: checking for building with threads" >&5
# Check whether --enable-threads or --disable-threads was given.
if test "${enable_threads+set}" = set; then
enableval="$enable_threads"
@@ -1094,7 +1146,7 @@ EOF
echo $ac_n "checking how to build libraries""... $ac_c" 1>&6
-echo "configure:1098: checking how to build libraries" >&5
+echo "configure:1150: checking how to build libraries" >&5
# Check whether --enable-shared or --disable-shared was given.
if test "${enable_shared+set}" = set; then
enableval="$enable_shared"
@@ -1135,7 +1187,7 @@ EOF
# Step 0: Enable 64 bit support?
echo $ac_n "checking if 64bit support is requested""... $ac_c" 1>&6
-echo "configure:1139: checking if 64bit support is requested" >&5
+echo "configure:1191: checking if 64bit support is requested" >&5
# Check whether --enable-64bit or --disable-64bit was given.
if test "${enable_64bit+set}" = set; then
enableval="$enable_64bit"
@@ -1152,7 +1204,7 @@ fi
# Extract the first word of "cygpath", so it can be a program name with args.
set dummy cygpath; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1156: checking for $ac_word" >&5
+echo "configure:1208: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CYGPATH'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1189,7 +1241,7 @@ fi
# set various compiler flags depending on whether we are using gcc or cl
echo $ac_n "checking compiler flags""... $ac_c" 1>&6
-echo "configure:1193: checking compiler flags" >&5
+echo "configure:1245: checking compiler flags" >&5
if test "${GCC}" = "yes" ; then
if test "$do64bit" = "yes" ; then
echo "configure: warning: "64bit mode not supported with GCC on Windows"" 1>&2
@@ -1379,7 +1431,7 @@ echo "configure:1193: checking compiler flags" >&5
echo $ac_n "checking for build with symbols""... $ac_c" 1>&6
-echo "configure:1383: checking for build with symbols" >&5
+echo "configure:1435: checking for build with symbols" >&5
# Check whether --enable-symbols or --disable-symbols was given.
if test "${enable_symbols+set}" = set; then
enableval="$enable_symbols"
@@ -1409,7 +1461,7 @@ TCL_DBGX=${DBGX}
#--------------------------------------------------------------------
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1413: checking how to run the C preprocessor" >&5
+echo "configure:1465: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@@ -1424,13 +1476,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 1428 "configure"
+#line 1480 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1434: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1486: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -1441,13 +1493,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 1445 "configure"
+#line 1497 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1451: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1503: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -1458,13 +1510,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
-#line 1462 "configure"
+#line 1514 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1468: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1520: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -1490,17 +1542,17 @@ echo "$ac_t""$CPP" 1>&6
ac_safe=`echo "errno.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for errno.h""... $ac_c" 1>&6
-echo "configure:1494: checking for errno.h" >&5
+echo "configure:1546: checking for errno.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1499 "configure"
+#line 1551 "configure"
#include "confdefs.h"
#include <errno.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1504: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1556: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
diff --git a/win/configure.in b/win/configure.in
index de84e19..067a790 100644
--- a/win/configure.in
+++ b/win/configure.in
@@ -3,7 +3,7 @@
# generate the file "configure", which is run during Tcl installation
# to configure the system for the local environment.
#
-# RCS: @(#) $Id: configure.in,v 1.47 2002/03/06 15:20:23 dkf Exp $
+# RCS: @(#) $Id: configure.in,v 1.48 2002/03/15 01:10:19 mdejong Exp $
AC_INIT(../generic/tcl.h)
@@ -83,6 +83,34 @@ if test "$ac_cv_cygwin" = "yes" ; then
Use the Mingw version of gcc from www.mingw.org instead.])
fi
+
+AC_CACHE_CHECK(for SEH support in compiler,
+ tcl_cv_seh,
+AC_TRY_RUN([
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+int main(int argc, char** argv) {
+ int a, b = 0;
+ __try {
+ a = 666 / b;
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) {
+ return 0;
+ }
+ return 1;
+}
+],
+ tcl_cv_seh=yes,
+ tcl_cv_seh=no,
+ tcl_cv_seh=no)
+)
+if test "$tcl_cv_seh" = "no" ; then
+ AC_DEFINE(HAVE_NO_SEH,,
+ [Defined when mingw does not support SEH])
+fi
+
#--------------------------------------------------------------------
# Determines the correct binary file extension (.o, .obj, .exe etc.)
#--------------------------------------------------------------------
diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c
index dde720e..c17285e 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.14 2002/03/08 01:45:52 mdejong Exp $
+ * RCS: @(#) $Id: tclWin32Dll.c,v 1.15 2002/03/15 01:10:19 mdejong Exp $
*/
#include "tclWinInt.h"
@@ -37,6 +37,11 @@ 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;
+#endif /* HAVE_NO_SEH */
+
/*
* The following function tables are used to dispatch to either the
* wide-character or multi-byte versions of the operating system calls,
@@ -349,17 +354,56 @@ TclpCheckStackSpace()
* exception if the stack pointer is set below the bottom of the stack.
*/
+#ifdef HAVE_NO_SEH
+ __asm__ __volatile__ (
+ "movl %esp, _ESP" "\n\t"
+ "movl %ebp, _EBP");
+
+ __asm__ __volatile__ (
+ "pushl $__except_checkstackspace_handler" "\n\t"
+ "pushl %fs:0" "\n\t"
+ "mov %esp, %fs:0");
+#else
__try {
+#endif /* HAVE_NO_SEH */
alloca(TCL_WIN_STACK_THRESHOLD);
retval = 1;
+#ifdef HAVE_NO_SEH
+ __asm__ __volatile__ (
+ "jmp checkstackspace_pop" "\n"
+ "checkstackspace_reentry:" "\n\t"
+ "movl _ESP, %esp" "\n\t"
+ "movl _EBP, %ebp");
+
+ __asm__ __volatile__ (
+ "checkstackspace_pop:" "\n\t"
+ "mov (%esp), %eax" "\n\t"
+ "mov %eax, %fs:0" "\n\t"
+ "add $8, %esp");
+#else
} __except (EXCEPTION_EXECUTE_HANDLER) {}
+#endif /* HAVE_NO_SEH */
/*
* Avoid using control flow statements in the SEH guarded block!
*/
return retval;
}
-
+#ifdef HAVE_NO_SEH
+static
+__attribute__ ((cdecl))
+EXCEPTION_DISPOSITION
+_except_checkstackspace_handler(
+ struct _EXCEPTION_RECORD *ExceptionRecord,
+ void *EstablisherFrame,
+ struct _CONTEXT *ContextRecord,
+ void *DispatcherContext)
+{
+ __asm__ __volatile__ (
+ "jmp checkstackspace_reentry");
+ return 0; /* Function does not return */
+}
+#endif /* HAVE_NO_SEH */
/*
*----------------------------------------------------------------------
diff --git a/win/tclWinChan.c b/win/tclWinChan.c
index 52084a6..d850b62 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.20 2002/02/15 14:28:51 dkf Exp $
+ * RCS: @(#) $Id: tclWinChan.c,v 1.21 2002/03/15 01:10:19 mdejong Exp $
*/
#include "tclWinInt.h"
@@ -118,6 +118,11 @@ static Tcl_ChannelType fileChannelType = {
NULL, /* handler proc. */
};
+#ifdef HAVE_NO_SEH
+static void *ESP;
+static void *EBP;
+#endif /* HAVE_NO_SEH */
+
/*
*----------------------------------------------------------------------
@@ -983,8 +988,39 @@ Tcl_MakeFileChannel(rawHandle, mode)
* of this duped handle which might throw EXCEPTION_INVALID_HANDLE.
*/
+#ifdef HAVE_NO_SEH
+ __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");
+
+ result = 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");
+
+ if (result)
+ return NULL;
+#else
}
__except (EXCEPTION_EXECUTE_HANDLER) {
/*
@@ -994,6 +1030,7 @@ Tcl_MakeFileChannel(rawHandle, mode)
return NULL;
}
+#endif /* HAVE_NO_SEH */
/* Fall through, the handle is valid. */
@@ -1007,6 +1044,21 @@ Tcl_MakeFileChannel(rawHandle, mode)
return channel;
}
+#ifdef HAVE_NO_SEH
+static
+__attribute__ ((cdecl))
+EXCEPTION_DISPOSITION
+_except_makefilechannel_handler(
+ struct _EXCEPTION_RECORD *ExceptionRecord,
+ void *EstablisherFrame,
+ struct _CONTEXT *ContextRecord,
+ void *DispatcherContext)
+{
+ __asm__ __volatile__ (
+ "jmp makefilechannel_reentry");
+ return 0; /* Function does not return */
+}
+#endif
/*
*----------------------------------------------------------------------
diff --git a/win/tclWinFCmd.c b/win/tclWinFCmd.c
index b3104f1..1843e8d 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.26 2002/03/14 20:51:44 mdejong Exp $
+ * RCS: @(#) $Id: tclWinFCmd.c,v 1.27 2002/03/15 01:10:19 mdejong Exp $
*/
#include "tclWinInt.h"
@@ -73,6 +73,11 @@ CONST TclFileAttrProcs tclpFileAttrProcs[] = {
{GetWinFileShortName, CannotSetAttribute},
{GetWinFileAttributes, SetWinFileAttributes}};
+#ifdef HAVE_NO_SEH
+static void *ESP;
+static void *EBP;
+#endif /* HAVE_NO_SEH */
+
/*
* Prototype for the TraverseWinTree callback function.
*/
@@ -182,11 +187,36 @@ DoRenameFile(
* if one of the arguments is a char block device.
*/
+#ifdef HAVE_NO_SEH
+ __asm__ __volatile__ (
+ "movl %esp, _ESP" "\n\t"
+ "movl %ebp, _EBP");
+
+ __asm__ __volatile__ (
+ "pushl $__except_dorenamefile_handler" "\n\t"
+ "pushl %fs:0" "\n\t"
+ "mov %esp, %fs:0");
+#else
__try {
+#endif /* HAVE_NO_SEH */
if ((*tclWinProcs->moveFileProc)(nativeSrc, nativeDst) != FALSE) {
retval = TCL_OK;
}
+#ifdef HAVE_NO_SEH
+ __asm__ __volatile__ (
+ "jmp dorenamefile_pop" "\n"
+ "dorenamefile_reentry:" "\n\t"
+ "movl _ESP, %esp" "\n\t"
+ "movl _EBP, %ebp");
+
+ __asm__ __volatile__ (
+ "dorenamefile_pop:" "\n\t"
+ "mov (%esp), %eax" "\n\t"
+ "mov %eax, %fs:0" "\n\t"
+ "add $8, %esp");
+#else
} __except (EXCEPTION_EXECUTE_HANDLER) {}
+#endif /* HAVE_NO_SEH */
/*
* Avoid using control flow statements in the SEH guarded block!
@@ -408,6 +438,21 @@ DoRenameFile(
}
return TCL_ERROR;
}
+#ifdef HAVE_NO_SEH
+static
+__attribute__ ((cdecl))
+EXCEPTION_DISPOSITION
+_except_dorenamefile_handler(
+ struct _EXCEPTION_RECORD *ExceptionRecord,
+ void *EstablisherFrame,
+ struct _CONTEXT *ContextRecord,
+ void *DispatcherContext)
+{
+ __asm__ __volatile__ (
+ "jmp dorenamefile_reentry");
+ return 0; /* Function does not return */
+}
+#endif /* HAVE_NO_SEH */
/*
*---------------------------------------------------------------------------
@@ -467,12 +512,37 @@ DoCopyFile(
* The CopyFile API would throw an exception under NT if one
* of the arguments is a char block device.
*/
-
+
+#ifdef HAVE_NO_SEH
+ __asm__ __volatile__ (
+ "movl %esp, _ESP" "\n\t"
+ "movl %ebp, _EBP");
+
+ __asm__ __volatile__ (
+ "pushl $__except_docopyfile_handler" "\n\t"
+ "pushl %fs:0" "\n\t"
+ "mov %esp, %fs:0");
+#else
__try {
+#endif /* HAVE_NO_SEH */
if ((*tclWinProcs->copyFileProc)(nativeSrc, nativeDst, 0) != FALSE) {
retval = TCL_OK;
}
+#ifdef HAVE_NO_SEH
+ __asm__ __volatile__ (
+ "jmp docopyfile_pop" "\n"
+ "docopyfile_reentry:" "\n\t"
+ "movl _ESP, %esp" "\n\t"
+ "movl _EBP, %ebp");
+
+ __asm__ __volatile__ (
+ "docopyfile_pop:" "\n\t"
+ "mov (%esp), %eax" "\n\t"
+ "mov %eax, %fs:0" "\n\t"
+ "add $8, %esp");
+#else
} __except (EXCEPTION_EXECUTE_HANDLER) {}
+#endif /* HAVE_NO_SEH */
/*
* Avoid using control flow statements in the SEH guarded block!
@@ -516,6 +586,21 @@ DoCopyFile(
}
return TCL_ERROR;
}
+#ifdef HAVE_NO_SEH
+static
+__attribute__ ((cdecl))
+EXCEPTION_DISPOSITION
+_except_docopyfile_handler(
+ struct _EXCEPTION_RECORD *ExceptionRecord,
+ void *EstablisherFrame,
+ struct _CONTEXT *ContextRecord,
+ void *DispatcherContext)
+{
+ __asm__ __volatile__ (
+ "jmp docopyfile_reentry");
+ return 0; /* Function does not return */
+}
+#endif /* HAVE_NO_SEH */
/*
*---------------------------------------------------------------------------