diff options
Diffstat (limited to 'win/tclWinFCmd.c')
-rw-r--r-- | win/tclWinFCmd.c | 133 |
1 files changed, 88 insertions, 45 deletions
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 */ |