Browse Source

Hacked things so longjmp now works.
-Erik

Eric Andersen 24 years ago
parent
commit
6811c06413

+ 92 - 15
include/setjmp.h

@@ -1,22 +1,99 @@
+/* Copyright (C) 1991,92,93,94,95,96,97,98 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
 /*
-	setjmp.h
-	stubs for future use.
-*/
+ *	ISO C Standard: 4.6 NON-LOCAL JUMPS	<setjmp.h>
+ */
 
-#ifndef _SETJMP_H_
-#ifdef __cplusplus
-extern "C" {
-#endif
-#define _SETJMP_H_
+#ifndef	_SETJMP_H
+#define	_SETJMP_H	1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+#include <machine/setjmp.h>		/* Get `__jmp_buf'.  */
+#include <machine/sigset.h>		/* Get `__sigset_t'.  */
+
+/* Calling environment, plus possibly a saved signal mask.  */
+typedef struct __jmp_buf_tag	/* C++ doesn't like tagless structs.  */
+  {
+    /* NOTE: The machine-dependent definitions of `__sigsetjmp'
+       assume that a `jmp_buf' begins with a `__jmp_buf'.
+       Do not move this member or add others before it.  */
+    __jmp_buf __jmpbuf;		/* Calling environment.  */
+    int __mask_was_saved;	/* Saved the signal mask?  */
+    __sigset_t __saved_mask;	/* Saved signal mask.  */
+  } jmp_buf[1];
 
-#include "_ansi.h"
-#include <machine/setjmp.h>
 
-void	_EXFUN(longjmp,(jmp_buf __jmpb, int __retval));
-int	_EXFUN(setjmp,(jmp_buf __jmpb));
+/* Store the calling environment in ENV, also saving the
+   signal mask if SAVEMASK is nonzero.  Return 0.
+   This is the internal name for `sigsetjmp'.  */
+extern int __sigsetjmp __P ((jmp_buf __env, int __savemask));
 
-#ifdef __cplusplus
-}
+#ifndef	__FAVOR_BSD
+/* Set ENV to the current position and return 0, not saving the signal mask.
+   This is just like `sigsetjmp (ENV, 0)'.
+   The ISO C standard says `setjmp' is a macro.  */
+# define setjmp(env)	__sigsetjmp ((env), 0)
+#else
+/* We are in 4.3 BSD-compatibility mode in which `setjmp'
+   saves the signal mask like `sigsetjmp (ENV, 1)'.  */
+# define setjmp(env)	__sigsetjmp ((env), 1)
+#endif /* Favor BSD.  */
+
+#if defined __USE_BSD || defined __USE_XOPEN
+/* Set ENV to the current position and return 0, not saving the signal mask.
+   This is the 4.3 BSD name for ISO `setjmp'.  */
+# define _setjmp(env)	__sigsetjmp ((env), 0)
 #endif
-#endif /* _SETJMP_H_ */
 
+
+/* Jump to the environment saved in ENV, making the
+   `setjmp' call there return VAL, or 1 if VAL is 0.  */
+extern void longjmp __P ((jmp_buf __env, int __val))
+     __attribute__ ((__noreturn__));
+#if defined __USE_BSD || defined __USE_XOPEN
+/* Same.  Usually `_longjmp' is used with `_setjmp', which does not save
+   the signal mask.  But it is how ENV was saved that determines whether
+   `longjmp' restores the mask; `_longjmp' is just an alias.  */
+extern void _longjmp __P ((jmp_buf __env, int __val))
+     __attribute__ ((__noreturn__));
+#endif
+
+
+/* Use the same type for `jmp_buf' and `sigjmp_buf'.
+   The `__mask_was_saved' flag determines whether
+   or not `longjmp' will restore the signal mask.  */
+typedef jmp_buf sigjmp_buf;
+
+/* Store the calling environment in ENV, also saving the
+   signal mask if SAVEMASK is nonzero.  Return 0.  */
+# define sigsetjmp(env, savemask)	__sigsetjmp ((env), (savemask))
+
+/* Jump to the environment saved in ENV, making the
+   sigsetjmp call there return VAL, or 1 if VAL is 0.
+   Restore the signal mask if that sigsetjmp call saved it.
+   This is just an alias `longjmp'.  */
+extern void siglongjmp __P ((sigjmp_buf __env, int __val))
+     __attribute__ ((__noreturn__));
+
+__END_DECLS
+
+#endif /* setjmp.h  */

+ 30 - 165
libc/sysdeps/linux/i386/bits/setjmp.h

@@ -1,176 +1,41 @@
-#if defined(__arm__) || defined(__thumb__)
-/*
- * All callee preserved registers:
- * v1 - v7, fp, ip, sp, lr, f4, f5, f6, f7
- */
-#define _JBLEN 23
-#endif
-
-#ifdef __sparc__
-/*
- * onsstack,sigmask,sp,pc,npc,psr,g1,o0,wbcnt (sigcontext).
- * All else recovered by under/over(flow) handling.
- */
-#define	_JBLEN	13
-#endif
-
-/* necv70 was 9 as well. */
-
-#ifdef __mc68000__
-/*
- * onsstack,sigmask,sp,pc,psl,d2-d7,a2-a6,
- * fp2-fp7	for 68881.
- * All else recovered by under/over(flow) handling.
- */
-#define	_JBLEN	34
-#endif
-
-#if defined(__Z8001__) || defined(__Z8002__)
-/* 16 regs + pc */
-#define _JBLEN 20
-#endif
-
-#ifdef _AM29K
-/*
- * onsstack,sigmask,sp,pc,npc,psr,g1,o0,wbcnt (sigcontext).
- * All else recovered by under/over(flow) handling.
- */
-#define	_JBLEN	9
-#endif
-
-#ifdef __i386__
-#ifdef __unix__
-# define _JBLEN	36
-#elif defined(_WIN32)
-#define _JBLEN (13 * 4)
-#else
-#include "setjmp-dj.h"
-#endif
-#endif
-
-#ifdef __i960__
-#define _JBLEN 35
-#endif
-
-#ifdef __M32R__
-/* Only 8 words are currently needed.  10 gives us some slop if we need
-   to expand.  */
-#define _JBLEN 10
-#endif
-
-#ifdef __mips__
-#define _JBLEN 11
-#endif
-
-#ifdef __m88000__
-#define _JBLEN 21
-#endif
-
-#ifdef __H8300__
-#define _JBLEN 5
-typedef int jmp_buf[_JBLEN];
-#endif
-
-#ifdef __H8300H__
-/* same as H8/300 but registers are twice as big */
-#define _JBLEN 5
-#define _JBTYPE long
-#endif
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
 
-#ifdef __H8300S__
-/* same as H8/300 but registers are twice as big */
-#define _JBLEN 5
-#define _JBTYPE long
-#endif
-
-#ifdef __H8500__
-#define _JBLEN 4
-#endif
+   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
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-#ifdef  __sh__
-#define _JBLEN 20
-#endif
+   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
+   Library General Public License for more details.
 
-#ifdef  __v800
-#define _JBLEN 28
-#endif
-
-#ifdef __PPC__
-#define _JBLEN 32
-#define _JBTYPE double
-#endif
-
-#ifdef __hppa__
-/* %r30, %r2-%r18, %r27, pad, %fr12-%fr15.
-   Note space exists for the FP registers, but they are not
-   saved.  */
-#define _JBLEN 28
-#endif
-
-#if defined(mn10300) || defined(mn10200)
-/* A guess */
-#define _JBLEN 10
-#endif
-
-#ifdef __v850
-/* I think our setjmp is saving 15 regs at the moment.  Gives us one word
-   slop if we need to expand.  */
-#define _JBLEN 16
-#endif
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
+/* Define the machine-dependent type `jmp_buf'.  Intel 386 version.  */
 
-#ifdef __D10V__
-#define _JBLEN 8
+#ifndef _SETJMP_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
 #endif
 
-/* start-sanitize-d30v */
-#ifdef __D30V__
-#define _JBLEN (64 /* GPR */ + (2*2) /* ACs */ + 18 /* CRs */)
+#if defined __USE_MISC || defined _ASM
+# define JB_BX	0
+# define JB_SI	1
+# define JB_DI	2
+# define JB_BP	3
+# define JB_SP	4
+# define JB_PC	5
 #endif
-/* end-sanitize-d30v */
 
-#ifdef _JBLEN
-#ifdef _JBTYPE
-typedef	_JBTYPE jmp_buf[_JBLEN];
-#else
-typedef	int jmp_buf[_JBLEN];
+#ifndef	_ASM
+typedef int __jmp_buf[6];
 #endif
 
-#ifdef __CYGWIN32__
-#include <signal.h>
-
-/* POSIX sigsetjmp/siglongjmp macros */
-typedef int sigjmp_buf[_JBLEN+2];
-
-#define _SAVEMASK	_JBLEN
-#define _SIGMASK	(_JBLEN+1)
-
-#define sigsetjmp(env, savemask) (env[_SAVEMASK] = savemask,\
-               sigprocmask (SIG_SETMASK, 0, (sigset_t *) &env[_SIGMASK]),\
-               setjmp (env))
-
-#define siglongjmp(env, val) (((env[_SAVEMASK])?\
-               sigprocmask (SIG_SETMASK, (sigset_t *) &env[_SIGMASK], 0):0),\
-               longjmp (env, val))
-
-#endif /* __CYGWIN32__*/
-
-#if defined(__linux__) && defined(__mc68000__)
-#include <signal.h>
-
-/* POSIX sigsetjmp/siglongjmp macros */
-typedef int sigjmp_buf[_JBLEN];
-
-#define _SAVEMASK	4
-#define _SIGMASK	1
-
-#define sigsetjmp(env, savemask) (env[_SAVEMASK] = savemask,\
-               sigprocmask (SIG_SETMASK, 0, (sigset_t *) &env[_SIGMASK]),\
-               setjmp (env))
-
-#define siglongjmp(env, val) (((env[_SAVEMASK])?\
-               sigprocmask (SIG_SETMASK, (sigset_t *) &env[_SIGMASK], 0):0),\
-               longjmp (env, val))
-
-#endif /* __linux__*/
-#endif
+/* Test if longjmp to JMPBUF would unwind the frame
+   containing a local variable at ADDRESS.  */
+#define _JMPBUF_UNWINDS(jmpbuf, address) \
+  ((void *) (address) < (void *) (jmpbuf)[JB_SP])

+ 125 - 0
libc/sysdeps/linux/i386/bits/sigset.h

@@ -0,0 +1,125 @@
+/* __sig_atomic_t, __sigset_t, and related definitions.  Linux version.
+   Copyright (C) 1991, 1992, 1994, 1996, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef	_SIGSET_H_types
+# define _SIGSET_H_types	1
+
+typedef int __sig_atomic_t;
+
+/* A `sigset_t' has a bit for each signal.  */
+
+# define _SIGSET_NWORDS	(1024 / (8 * sizeof (unsigned long int)))
+typedef struct
+  {
+    unsigned long int __val[_SIGSET_NWORDS];
+  } __sigset_t;
+
+#endif
+
+
+/* We only want to define these functions if <signal.h> was actually
+   included; otherwise we were included just to define the types.  Since we
+   are namespace-clean, it wouldn't hurt to define extra macros.  But
+   trouble can be caused by functions being defined (e.g., any global
+   register vars declared later will cause compilation errors).  */
+
+#if !defined _SIGSET_H_fns && defined _SIGNAL_H
+# define _SIGSET_H_fns 1
+
+# ifndef _EXTERN_INLINE
+#  define _EXTERN_INLINE extern __inline
+# endif
+
+/* Return a mask that includes the bit for SIG only.  */
+# define __sigmask(sig) \
+  (((unsigned long int) 1) << (((sig) - 1) % (8 * sizeof (unsigned long int))))
+
+/* Return the word index for SIG.  */
+# define __sigword(sig)	(((sig) - 1) / (8 * sizeof (unsigned long int)))
+
+# if defined __GNUC__ && __GNUC__ >= 2
+#  define __sigemptyset(set) \
+  (__extension__ ({ int __cnt = _SIGSET_NWORDS;				      \
+		    sigset_t *__set = (set);				      \
+		    while (--__cnt >= 0) __set->__val[__cnt] = 0;	      \
+		    0; }))
+#  define __sigfillset(set) \
+  (__extension__ ({ int __cnt = _SIGSET_NWORDS;				      \
+		    sigset_t *__set = (set);				      \
+		    while (--__cnt >= 0) __set->__val[__cnt] = ~0UL;	      \
+		    0; }))
+
+#  ifdef __USE_GNU
+/* The POSIX does not specify for handling the whole signal set in one
+   command.  This is often wanted and so we define three more functions
+   here.  */
+#   define __sigisemptyset(set) \
+  (__extension__ ({ int __cnt = _SIGSET_NWORDS;				      \
+		    const sigset_t *__set = (set);			      \
+		    int __ret = __set->__val[--__cnt];			      \
+		    while (!__ret && --__cnt >= 0)			      \
+			__ret = __set->__val[__cnt];			      \
+		    __ret == 0; }))
+#   define __sigandset(dest, left, right) \
+  (__extension__ ({ int __cnt = _SIGSET_NWORDS;				      \
+		    sigset_t *__dest = (dest);				      \
+		    const sigset_t *__left = (left);			      \
+		    const sigset_t *__right = (right);			      \
+		    while (--__cnt >= 0)				      \
+		      __dest->__val[__cnt] = (__left->__val[__cnt]	      \
+					      & __right->__val[__cnt]);	      \
+		    0; }))
+#   define __sigorset(dest, left, right) \
+  (__extension__ ({ int __cnt = _SIGSET_NWORDS;				      \
+		    sigset_t *__dest = (dest);				      \
+		    const sigset_t *__left = (left);			      \
+		    const sigset_t *__right = (right);			      \
+		    while (--__cnt >= 0)				      \
+		      __dest->__val[__cnt] = (__left->__val[__cnt]	      \
+					      | __right->__val[__cnt]);	      \
+		    0; }))
+#  endif
+# endif
+
+/* These functions needn't check for a bogus signal number -- error
+   checking is done in the non __ versions.  */
+
+extern int __sigismember (__const __sigset_t *, int);
+extern int __sigaddset (__sigset_t *, int);
+extern int __sigdelset (__sigset_t *, int);
+
+# ifdef __USE_EXTERN_INLINES
+#  define __SIGSETFN(NAME, BODY, CONST)					      \
+  _EXTERN_INLINE int							      \
+  NAME (CONST __sigset_t *__set, int __sig)				      \
+  {									      \
+    unsigned long int __mask = __sigmask (__sig);			      \
+    unsigned long int __word = __sigword (__sig);			      \
+    return BODY;							      \
+  }
+
+__SIGSETFN (__sigismember, (__set->__val[__word] & __mask) ? 1 : 0, __const)
+__SIGSETFN (__sigaddset, ((__set->__val[__word] |= __mask), 0), )
+__SIGSETFN (__sigdelset, ((__set->__val[__word] &= ~__mask), 0), )
+
+#  undef __SIGSETFN
+# endif
+
+
+#endif /* ! _SIGSET_H_fns.  */

+ 58 - 87
libc/sysdeps/linux/i386/setjmp.S

@@ -1,88 +1,59 @@
-/* These are predefined by new versions of GNU cpp.  */
-
-#ifndef __USER_LABEL_PREFIX__
-#define __USER_LABEL_PREFIX__ _
-#endif
-
-#ifndef __REGISTER_PREFIX__
-#define __REGISTER_PREFIX__
-#endif
-
-/* ANSI concatenation macros.  */
-
-#define CONCAT1(a, b) CONCAT2(a, b)
-#define CONCAT2(a, b) a ## b
-
-/* Use the right prefix for global labels.  */
-
-#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
-
-/* Use the right prefix for registers.  */
-
-#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
-
-#define d0 REG (d0)
-#define d1 REG (d1)
-#define d2 REG (d2)
-#define d3 REG (d3)
-#define d4 REG (d4)
-#define d5 REG (d5)
-#define d6 REG (d6)
-#define d7 REG (d7)
-#define a0 REG (a0)
-#define a1 REG (a1)
-#define a2 REG (a2)
-#define a3 REG (a3)
-#define a4 REG (a4)
-#define a5 REG (a5)
-#define a6 REG (a6)
-#define fp REG (fp)
-#define sp REG (sp)
-
-.global SYM (setjmp)
-.global SYM (longjmp)
-
-SYM (setjmp):
-	moveal sp@(4),a0
-	movel sp@(0),a0@(12)
-	movel sp,a0@(8)
-	moveml d2-d7/a2-a6,a0@(20)
-	clrl d0
-	rts
-
-SYM (longjmp):
-	moveal sp@(4),a0
-	movel sp@(8),d0
-	bne 1f
-	movel #1,d0
-1:
-	moveml a0@(20),d2-d7/a2-a6
-	moveal a0@(8),sp
-	movel a0@(12),sp@
-	rts
-
-#ifdef M68881
-.global SYM (setjmp_68881)
-.global SYM (longjmp_68881)
-
-SYM (setjmp_68881):
-	moveal sp@(4),a0
-	movel sp@(0),a0@(12)
-	movel sp,a0@(8)
-	moveml d2-d7/a2-a6,a0@(20)
-	fmovemx fp2-fp7,a0@(64)
-	clrl d0
-	rts
-
-SYM (longjmp_68881):
-	moveal sp@(4),a0
-	fmovemx a0@(64),fp2-fp7
-	movel sp@(8),d0
-	bne 1f
-	movel #1,d0
-1:
-	moveml a0@(20),d2-d7/a2-a6
-	moveal a0@(8),sp
-	movel a0@(12),sp@
-	rts
+/* setjmp for i386.
+   Copyright (C) 1995, 1996, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+#define _ASM
+#define _SETJMP_H
+#include <machine/setjmp.h>
+
+ENTRY (__setjmp)
+	popl %eax		/* Pop return address.  */
+	popl %ecx		/* Pop jmp_buf.  */
+	pushl $0		/* Push zero argument.  */
+	pushl %ecx		/* Push jmp_buf.  */
+	pushl %eax		/* Push back return address.  */
+
+ENTRY (__sigsetjmp)
+	movl 4(%esp), %eax	/* User's jmp_buf in %eax.  */
+     	/* Save registers.  */
+	movl %ebx, (JB_BX*4)(%eax)
+	movl %esi, (JB_SI*4)(%eax)
+	movl %edi, (JB_DI*4)(%eax)
+	movl %ebp, (JB_BP*4)(%eax)
+	leal 4(%esp), %ecx	/* Save SP as it will be after we return.  */
+     	movl %ecx, (JB_SP*4)(%eax)
+	movl 0(%esp), %ecx	/* Save PC we are returning to now.  */
+     	movl %ecx, (JB_PC*4)(%eax)
+
+	/* Make a tail call to __sigjmp_save; it takes the same args.  */
+#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 L(here)
+L(here):
+	popl %ecx
+	addl $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ecx
+	movl C_SYMBOL_NAME(__sigjmp_save@GOT)(%ecx), %ecx
+	jmp *%ecx
+#else
+	jmp __sigjmp_save
 #endif
+.size __sigsetjmp,.-__sigsetjmp;