diff options
author | mdejong <mdejong@noemail.net> | 2003-01-25 14:11:31 (GMT) |
---|---|---|
committer | mdejong <mdejong@noemail.net> | 2003-01-25 14:11:31 (GMT) |
commit | a723a185f7423882157f7844e7023ba4485410d5 (patch) | |
tree | 8e09cb15a16baa630dc51a0b34c9af26e3eac4b6 /win/tclWinFCmd.c | |
parent | a71801bb07d00ca3d6d5a2bead7194268339843d (diff) | |
download | tcl-a723a185f7423882157f7844e7023ba4485410d5.zip tcl-a723a185f7423882157f7844e7023ba4485410d5.tar.gz tcl-a723a185f7423882157f7844e7023ba4485410d5.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.
FossilOrigin-Name: 071e3de4fc8d388318a4c06dd743de46f5cbb1fc
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 */ |