From 709661acd4c4100385dc6779b3c10442599ae342 Mon Sep 17 00:00:00 2001 From: mdejong Date: Fri, 24 Jan 2003 08:04:25 +0000 Subject: * win/configure: Regen. * win/configure.in: * win/tclWin32Dll.c (TclpCheckStackSpace): Rework the SEH exception handler logic to avoid using the stack since alloca will modify the stack. This was causing a nasty bug that would set the exception handler to 0 because it tried to pop the previous exception handler off the top of the stack. --- ChangeLog | 12 +++++++ win/configure | 95 ++++++++++++++++++++++++++++++++++++++++--------------- win/configure.in | 25 ++++++++++++++- win/tclWin32Dll.c | 27 ++++++++++++---- 4 files changed, 126 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index 194170b..e45a864 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2003-01-24 Mo DeJong + + * win/configure: Regen. + * win/configure.in: + * win/tclWin32Dll.c (TclpCheckStackSpace): Rework + the SEH exception handler logic to avoid using + the stack since alloca will modify the stack. + This was causing a nasty bug that would set the + exception handler to 0 because it tried to pop + the previous exception handler off the top of + the stack. + 2003-01-23 Donal K. Fellows * doc/lset.n: Fixed fault in return values from lset in diff --git a/win/configure b/win/configure index 248408e..aae48ca 100755 --- a/win/configure +++ b/win/configure @@ -1167,18 +1167,63 @@ EOF fi +# Check to see if malloc.h is missing the alloca function +# declaration. This is known to be a problem with Mingw. + +echo $ac_n "checking for alloca declaration in malloc.h""... $ac_c" 1>&6 +echo "configure:1175: checking for alloca declaration in malloc.h" >&5 +if eval "test \"`echo '$''{'tcl_cv_malloc_decl_alloca'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < + +int main() { + + size_t arg = 0; + void* ptr; + ptr = alloca; + ptr = alloca(arg); + +; return 0; } +EOF +if { (eval echo configure:1194: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + tcl_cv_malloc_decl_alloca=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + tcl_cv_malloc_decl_alloca=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$tcl_cv_malloc_decl_alloca" 1>&6 +if test "$tcl_cv_malloc_decl_alloca" = "no" ; then + cat >> confdefs.h <<\EOF +#define HAVE_NO_ALLOC_DECL 1 +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:1176: checking for object suffix" >&5 +echo "configure:1221: 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:1182: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1227: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then for ac_file in conftest.*; do case $ac_file in *.c) ;; @@ -1196,19 +1241,19 @@ OBJEXT=$ac_cv_objext ac_objext=$ac_cv_objext echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 -echo "configure:1200: checking for mingw32 environment" >&5 +echo "configure:1245: 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 <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1257: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_mingw32=yes else @@ -1227,7 +1272,7 @@ test "$ac_cv_mingw32" = yes && MINGW32=yes echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 -echo "configure:1231: checking for executable suffix" >&5 +echo "configure:1276: checking for executable suffix" >&5 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1237,7 +1282,7 @@ else rm -f conftest* echo 'int main () { return 0; }' > conftest.$ac_ext ac_cv_exeext= - if { (eval echo configure:1241: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + if { (eval echo configure:1286: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then for file in conftest.*; do case $file in *.c | *.o | *.obj) ;; @@ -1264,7 +1309,7 @@ ac_exeext=$EXEEXT echo $ac_n "checking for building with threads""... $ac_c" 1>&6 -echo "configure:1268: checking for building with threads" >&5 +echo "configure:1313: 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" @@ -1301,7 +1346,7 @@ EOF echo $ac_n "checking how to build libraries""... $ac_c" 1>&6 -echo "configure:1305: checking how to build libraries" >&5 +echo "configure:1350: 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" @@ -1342,7 +1387,7 @@ EOF # Step 0: Enable 64 bit support? echo $ac_n "checking if 64bit support is requested""... $ac_c" 1>&6 -echo "configure:1346: checking if 64bit support is requested" >&5 +echo "configure:1391: 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" @@ -1359,7 +1404,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:1363: checking for $ac_word" >&5 +echo "configure:1408: 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 @@ -1403,9 +1448,9 @@ fi echo "END" >> $conftest echo $ac_n "checking for Windows native path bug in windres""... $ac_c" 1>&6 -echo "configure:1407: checking for Windows native path bug in windres" >&5 +echo "configure:1452: checking for Windows native path bug in windres" >&5 cyg_conftest=`$CYGPATH $conftest` - if { ac_try='$RC -o conftest.res.o $cyg_conftest'; { (eval echo configure:1409: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } ; then + if { ac_try='$RC -o conftest.res.o $cyg_conftest'; { (eval echo configure:1454: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } ; then echo "$ac_t""no" 1>&6 else echo "$ac_t""yes" 1>&6 @@ -1424,7 +1469,7 @@ echo "configure:1407: checking for Windows native path bug in windres" >&5 # 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:1428: checking compiler flags" >&5 +echo "configure:1473: 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 @@ -1640,7 +1685,7 @@ echo "configure:1428: checking compiler flags" >&5 echo $ac_n "checking for build with symbols""... $ac_c" 1>&6 -echo "configure:1644: checking for build with symbols" >&5 +echo "configure:1689: 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" @@ -1700,7 +1745,7 @@ TCL_DBGX=${DBGX} #-------------------------------------------------------------------- echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1704: checking how to run the C preprocessor" >&5 +echo "configure:1749: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1715,13 +1760,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1725: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1770: \"$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 : @@ -1732,13 +1777,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1742: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1787: \"$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 : @@ -1749,13 +1794,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1759: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1804: \"$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 : @@ -1781,17 +1826,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:1785: checking for errno.h" >&5 +echo "configure:1830: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1795: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1840: \"$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 b641255..0b99959 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.62 2003/01/13 07:01:06 mdejong Exp $ +# RCS: @(#) $Id: configure.in,v 1.63 2003/01/24 08:04:28 mdejong Exp $ AC_INIT(../generic/tcl.h) AC_PREREQ(2.13) @@ -194,6 +194,29 @@ if test "$tcl_cv_winnt_ignore_void" = "yes" ; then [Defined when cygwin/mingw ignores VOID define in winnt.h]) fi +# Check to see if malloc.h is missing the alloca function +# declaration. This is known to be a problem with Mingw. + +AC_CACHE_CHECK(for alloca declaration in malloc.h, + tcl_cv_malloc_decl_alloca, +AC_TRY_COMPILE([ +#include +], +[ + size_t arg = 0; + void* ptr; + ptr = alloca; + ptr = alloca(arg); +], + tcl_cv_malloc_decl_alloca=yes, + tcl_cv_malloc_decl_alloca=no) +) +if test "$tcl_cv_malloc_decl_alloca" = "no" ; then + AC_DEFINE(HAVE_NO_ALLOC_DECL, 1, + [Defined when alloca decl is missing from malloc.h]) +fi + + #-------------------------------------------------------------------- # Determines the correct binary file extension (.o, .obj, .exe etc.) #-------------------------------------------------------------------- diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index ac9e8cd..1c029f8 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -9,11 +9,16 @@ * 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.20 2003/01/16 19:01:59 mdejong Exp $ + * RCS: @(#) $Id: tclWin32Dll.c,v 1.21 2003/01/24 08:04:29 mdejong Exp $ */ #include "tclWinInt.h" +#if defined(HAVE_NO_ALLOC_DECL) +void* __cdecl _alloca(size_t size); +#define alloca _alloca +#endif /* HAVE_NO_ALLOC_DECL */ + /* * The following data structures are used when loading the thunking * library for execing child processes under Win32s. @@ -40,6 +45,9 @@ 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 */ /* @@ -378,9 +386,12 @@ TclpCheckStackSpace() "movl %ebp, _EBP"); __asm__ __volatile__ ( - "pushl $__except_checkstackspace_handler" "\n\t" - "pushl %fs:0" "\n\t" - "mov %esp, %fs:0"); + "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"); #else __try { #endif /* HAVE_NO_SEH */ @@ -395,9 +406,8 @@ TclpCheckStackSpace() __asm__ __volatile__ ( "checkstackspace_pop:" "\n\t" - "mov (%esp), %eax" "\n\t" - "mov %eax, %fs:0" "\n\t" - "add $8, %esp"); + "mov _OLD_HANDLER, %eax" "\n\t" + "mov %eax, %fs:0"); #else } __except (EXCEPTION_EXECUTE_HANDLER) {} #endif /* HAVE_NO_SEH */ @@ -625,6 +635,9 @@ static void squelch_warnings() ptr = _except_checkstackspace_handler; ESP = 0; EBP = 0; + OLD_HANDLER = 0; + NEW_HANDLER = 0; + HANDLER[0] = 0; squelch_warnings(); } #endif /* HAVE_NO_SEH */ -- cgit v0.12