delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin-developers/1999/09/03/03:42:05

Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Unsubscribe: <mailto:cygwin-developers-unsubscribe-archive-cygwin-developers=delorie DOT com AT sourceware DOT cygnus DOT com>
List-Subscribe: <mailto:cygwin-developers-subscribe AT sourceware DOT cygnus DOT com>
List-Archive: <http://sourceware.cygnus.com/ml/cygwin-developers/>
List-Post: <mailto:cygwin-developers AT sourceware DOT cygnus DOT com>
List-Help: <mailto:cygwin-developers-help AT sourceware DOT cygnus DOT com>,
<http://sourceware.cygnus.com/ml/#faqs>
Sender: cygwin-developers-owner AT sourceware DOT cygnus DOT com
Delivered-To: mailing list cygwin-developers AT sourceware DOT cygnus DOT com
Message-ID: <37CF7B31.7D712E@1c.ru>
Date: Fri, 03 Sep 1999 11:39:29 +0400
From: Vadim Egorov <egorovv AT 1c DOT ru>
X-Mailer: Mozilla 4.61 [en] (WinNT; I)
X-Accept-Language: ru,en
MIME-Version: 1.0
To: "cygwin-developers AT sourceware DOT cygnus DOT com"
<cygwin-developers AT sourceware DOT cygnus DOT com>
Subject: setjmp/longjmp patch
X-MDaemon-Deliver-To: cygwin-developers AT sourceware DOT cygnus DOT com
X-Return-Path: EgorovV AT 1c DOT ru

Hello,
Here is a patch for setjmp/longjmp to behave correctly when called
during win32 exception handling.
seljmp uses four bites to store fs:0 at offset 44 of jmp_buffer.
longjmp compares it with current fs:0 value and if doesn't match
calls seh_unwind. It shouldn't do much harm for a normal case.
seh_unwind makes an attempt to notify seh handlers to be removed
about unwinding and restore original seh frame state.

Regards,
Vadim


--- config/i386/setjmp.c	Fri Oct 23 11:23:57 1998
+++ config/i386/setjmp.c.1	Fri Sep 03 08:29:54 1999
@@ -40,4 +40,6 @@ asm("	.globl	_setjmp  		\n"
 "	movw	%ss, %ax		\n"
 "	movw	%ax, 42(%edi)		\n"
+"	movl	%fs:0, %eax		\n"
+"	movl	%eax, 44(%edi)		\n"
 "	popl	%edi			\n"
 "	movl	$0,%eax			\n"
--- config/i386/longjmp.c	Fri Oct 23 11:23:57 1998
+++ config/i386/longjmp.c.1	Fri Sep 03 08:48:20 1999
@@ -11,4 +11,5 @@ details. */
 #ifdef __i386__
 #if 1
+
 asm ("	.globl	_longjmp          \n"
 "_longjmp:                        \n"
@@ -16,4 +17,12 @@ asm ("	.globl	_longjmp          \n"
 "	movl	%esp,%ebp	  \n"
 "	movl	8(%ebp),%edi	  \n"
+"      movl 8(%ebp),%eax         \n"
+"      movl 44(%eax),%eax        \n"
+"      cmpl %fs:0,%eax           \n"
+"      je L1                     \n"
+"      pushl %eax                \n"
+"      call _seh_unwind          \n"
+"      add   $4, %esp            \n"
+"L1:                             \n"
 "	movl	12(%ebp),%eax	  \n"
 "	testl	%eax,%eax	  \n"
--- exceptions.cc	Fri Sep 03 10:55:46 1999
+++ exceptions.cc.1	Fri Sep 03 10:36:29 1999
@@ -821,2 +821,49 @@ _sigreturn:
 ");
 }
+
+#ifdef __i386__
+
+/* Win32 SEH stack unwinding. It is called from longjmp when
+current SEH frame doesnt match stored in jmp_buf one
+seh_unwind from currently installed at fs:0 SEH frame down to 
+given frame and and calls tham for unwinding. Does the nearly 
+the same _RtlUnwind API function's work but without any sanity 
+checking 
+*/
+extern "C"
+void seh_unwind(exception_list * frame)
+{
+    EXCEPTION_RECORD ex_rec;
+    CONTEXT ctx;
+    exception_list* dispatched_frame;
+        
+    exception_list* p = _except_list;
+    if (p != frame)
+        debug_printf ("unwinding SEH frames down to %p", frame);
+    else
+        return ;
+
+    ex_rec.ExceptionCode = 0; 
+    ex_rec.ExceptionFlags = 2; 
+    ex_rec.ExceptionRecord = 0; 
+    ex_rec.ExceptionAddress = 0; 
+
+    GetThreadContext(GetCurrentThread(), &ctx); 
+    while (p != (exception_list*)(-1))
+    {
+        if (p == frame)
+        {
+            _except_list = p;
+            return;
+        }
+        else
+        {
+            p->handler(&ex_rec, p, &ctx, &dispatched_frame);
+            debug_printf ("calling SEH frame %p", p);
+            p = p->prev;
+        }
+    }
+    // if we get here something is wrong
+    debug_printf ("failed to find SEH frame %p", frame);
+}
+#endif /*__i386__*/

-- 
*********************************************
Vadim Egorov, 1C      *       ÷ÁÄÉÍ åÇÏÒÏ×,1C
egorovv AT 1c DOT ru         *         egorovv AT 1c DOT ru
*********************************************

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019