Browse Source

Fixup setjmp implementation so it actaully works as expected
-Erik

Eric Andersen 23 years ago
parent
commit
a6cf8dc644

+ 12 - 14
libc/signal/sigjmp.c

@@ -2,19 +2,19 @@
    This file is part of the GNU C Library.
    This file is part of the GNU C Library.
 
 
    The GNU C Library is free software; you can redistribute it and/or
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
+   modify it under the terms of the GNU Lesser General Public
-   published by the Free Software Foundation; either version 2 of the
+   License as published by the Free Software Foundation; either
-   License, or (at your option) any later version.
+   version 2.1 of the License, or (at your option) any later version.
 
 
    The GNU C Library is distributed in the hope that it will be useful,
    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
+   Lesser General Public License for more details.
 
 
-   You should have received a copy of the GNU Library General Public
+   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   License along with the GNU C Library; if not, write to the Free
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   Boston, MA 02111-1307, USA.  */
+   02111-1307 USA.  */
 
 
 #include <stddef.h>
 #include <stddef.h>
 #include <setjmp.h>
 #include <setjmp.h>
@@ -24,12 +24,10 @@
    before doing a `__setjmp' on ENV[0].__jmpbuf.
    before doing a `__setjmp' on ENV[0].__jmpbuf.
    Always return zero.  */
    Always return zero.  */
 
 
-int
+int __sigjmp_save (sigjmp_buf env, int savemask)
-__sigjmp_save (sigjmp_buf env, int savemask)
 {
 {
-  env[0].__mask_was_saved = (savemask &&
+    env[0].__mask_was_saved = (savemask && 
-			     sigprocmask (SIG_BLOCK, (sigset_t *) NULL,
+	    sigprocmask (SIG_BLOCK, (sigset_t *) NULL, &env[0].__saved_mask) == 0);
-					    &env[0].__saved_mask) == 0);
 
 
-  return 0;
+    return 0;
 }
 }

+ 1 - 1
libc/sysdeps/linux/i386/Makefile

@@ -36,7 +36,7 @@ CRT0_OBJ=$(patsubst %.S,%.o, $(CRT0))
 endif
 endif
 
 
 
 
-SSRC=__longjmp.S setjmp.S vfork.S clone.S
+SSRC=__longjmp.S vfork.S clone.S setjmp.S bsd-setjmp.S bsd-_setjmp.S
 ifeq ($(UNIFIED_SYSCALL),true)
 ifeq ($(UNIFIED_SYSCALL),true)
 	SSRC += __uClibc_syscall.S
 	SSRC += __uClibc_syscall.S
 endif
 endif

+ 51 - 0
libc/sysdeps/linux/i386/bsd-_setjmp.S

@@ -0,0 +1,51 @@
+/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'.  i386 version.
+   Copyright (C) 1994,1995,1996,1997,2000,2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
+   We cannot do it in C because it must be a tail-call, so frame-unwinding
+   in setjmp doesn't clobber the state restored by longjmp.  */
+
+#define _ASM
+#define _SETJMP_H
+#include <bits/setjmp.h>
+
+
+.globl _setjmp;
+.type    _setjmp,@function
+.align 4;
+
+_setjmp:
+	xorl %eax, %eax
+	movl 4   (%esp), %edx
+
+     	/* Save registers.  */
+	movl %ebx, (JB_BX*4)(%edx)
+	movl %esi, (JB_SI*4)(%edx)
+	movl %edi, (JB_DI*4)(%edx)
+	leal 4 (%esp), %ecx	/* Save SP as it will be after we return.  */
+     	movl %ecx, (JB_SP*4)(%edx)
+	movl 0 (%esp), %ecx	/* Save PC we are returning to now.  */
+     	movl %ecx, (JB_PC*4)(%edx)
+	movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer.  */
+
+	movl %eax, JB_SIZE(%edx) /* No signal mask set.  */
+	ret
+.size _setjmp,.-_setjmp;
+
+

+ 61 - 0
libc/sysdeps/linux/i386/bsd-setjmp.S

@@ -0,0 +1,61 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'.  i386 version.
+   Copyright (C) 1995, 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define _ASM
+#define _SETJMP_H
+#include <bits/setjmp.h>
+
+.globl setjmp;
+.type    setjmp,@function
+.align 4;
+setjmp:
+        movl 4   (%esp), %eax
+	/* Save registers.  */
+        movl %ebx, (0 *4)(%eax)
+        movl %esi, (1 *4)(%eax)
+        movl %edi, (2 *4)(%eax)
+	/* Save SP as it will be after we return.  */
+        leal 4   (%esp), %ecx
+        movl %ecx, (4 *4)(%eax)
+	/* Save PC we are returning to now.  */
+        movl 0 (%esp), %ecx
+        movl %ecx, (5 *4)(%eax)
+	/* Save caller's frame pointer.  */
+        movl %ebp, (3 *4)(%eax)  
+
+	/* Call __sigjmp_save.  */
+	pushl $1
+	pushl 8(%esp)
+#ifdef	PIC
+	/* We cannot use the PLT, because it requires that %ebx be set, but
+           we can't save and restore our caller's value.  Instead, we do an
+           indirect jump through the GOT, using for the temporary register
+           %ecx, which is call-clobbered.  */
+	call here2
+here2:	popl %ecx
+	addl $_GLOBAL_OFFSET_TABLE_+[.-here2], %ecx
+	movl    __sigjmp_save    @GOT  (%ecx), %ecx
+	call *%ecx
+#else
+	call __sigjmp_save
+#endif
+	popl %ecx
+	popl %edx
+	ret
+.size setjmp,.-setjmp;

+ 33 - 46
libc/sysdeps/linux/i386/setjmp.S

@@ -1,72 +1,59 @@
-/* setjmp for i386.
+/* setjmp for i386, ELF version.
-   Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    This file is part of the GNU C Library.
 
 
    The GNU C Library is free software; you can redistribute it and/or
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
+   modify it under the terms of the GNU Lesser General Public
-   published by the Free Software Foundation; either version 2 of the
+   License as published by the Free Software Foundation; either
-   License, or (at your option) any later version.
+   version 2.1 of the License, or (at your option) any later version.
 
 
    The GNU C Library is distributed in the hope that it will be useful,
    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
+   Lesser General Public License for more details.
 
 
-   You should have received a copy of the GNU Library General Public
+   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   License along with the GNU C Library; if not, write to the Free
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   Boston, MA 02111-1307, USA.  */
+   02111-1307 USA.  */
 
 
 #define _ASM
 #define _ASM
 #define _SETJMP_H
 #define _SETJMP_H
 #include <bits/setjmp.h>
 #include <bits/setjmp.h>
 
 
+
 .globl __sigsetjmp;
 .globl __sigsetjmp;
-.type	 __sigsetjmp,@function
+.type    __sigsetjmp,@function
-.align 4;                                                               \
+.align 4;
+
 __sigsetjmp:
 __sigsetjmp:
-	movl 4(%esp), %eax	/* User's jmp_buf in %eax.  */
+        movl 4   (%esp), %eax
      	/* Save registers.  */
      	/* Save registers.  */
-	movl %ebx, (JB_BX*4)(%eax)
+        movl %ebx, (0 *4)(%eax)
-	movl %esi, (JB_SI*4)(%eax)
+        movl %esi, (1 *4)(%eax)
-	movl %edi, (JB_DI*4)(%eax)
+        movl %edi, (2 *4)(%eax)
-	movl %ebp, (JB_BP*4)(%eax)
+	/* Save SP as it will be after we return.  */
-	leal 4(%esp), %ecx	/* Save SP as it will be after we return.  */
+        leal 4(%esp), %ecx       
-     	movl %ecx, (JB_SP*4)(%eax)
+        movl %ecx, (4 *4)(%eax)
-	movl 0(%esp), %ecx	/* Save PC we are returning to now.  */
+	/* Save PC we are returning to now.  */
-     	movl %ecx, (JB_PC*4)(%eax)
+        movl 0(%esp), %ecx       
-
+        movl %ecx, (5 *4)(%eax)
-	pushl 0x8(%esp) /* save mask */
+	/* Save caller's frame pointer.  */
-	pushl 0x8(%esp) /* jump buf */
+        movl %ebp, (3 *4)(%eax)  
 
 
 	/* Make a tail call to __sigjmp_save; it takes the same args.  */
 	/* Make a tail call to __sigjmp_save; it takes the same args.  */
-#if defined(PIC)
+#ifdef	PIC
 	/* We cannot use the PLT, because it requires that %ebx be set, but
 	/* We cannot use the PLT, because it requires that %ebx be set, but
            we can't save and restore our caller's value.  Instead, we do an
            we can't save and restore our caller's value.  Instead, we do an
            indirect jump through the GOT, using for the temporary register
            indirect jump through the GOT, using for the temporary register
            %ecx, which is call-clobbered.  */
            %ecx, which is call-clobbered.  */
-	call Lhere
+	call .Lhere
-Lhere:
+.Lhere:
 	popl %ecx
 	popl %ecx
-	addl $_GLOBAL_OFFSET_TABLE_+[.-Lhere], %ecx
+	addl $_GLOBAL_OFFSET_TABLE_+[.- .Lhere  ], %ecx
-	movl (__sigjmp_save)(%ecx), %ecx
+	movl    __sigjmp_save    @GOT  (%ecx), %ecx
-	call *%ecx
+	jmp *%ecx
 #else
 #else
-	call __sigjmp_save
+	jmp   __sigjmp_save
 #endif
 #endif
-
-	add  $8, %esp
-	ret
 .size __sigsetjmp,.-__sigsetjmp;
 .size __sigsetjmp,.-__sigsetjmp;
-
-.globl _setjmp;
-.type	 _setjmp,@function
-.align 4;                                                               \
-_setjmp:
-	pushl $0		/* Push zero argument.  */
-	pushl 0x8(%esp)	/* Push jmp_buf.  */
-	call  __sigsetjmp
-	add  $8, %esp
-	ret
-.size _setjmp,.-_setjmp;
-