From d4e6fe35464a1fb610e02cf6d397987c8518db60 Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Fri, 8 Dec 2006 16:23:18 +0000 Subject: [PATCH] Setjmp/longjmp updates and cleanup. --- include/minix/jmp_buf.h | 87 ------------------- include/setjmp.h | 158 +++++++++++------------------------ include/sys/jmp_buf.h | 45 ++++++++++ include/sys/sigcontext.h | 5 -- kernel/system/do_sigreturn.c | 13 --- kernel/system/do_sigsend.c | 2 +- lib/gnu/rts/Makefile.in | 6 +- lib/gnu/rts/__setjmp.gs | 31 +++++++ lib/gnu/rts/_longjmp.gs | 38 --------- lib/gnu/rts/_setjmp.gs | 35 -------- lib/gnu/rts/longjmp.gs | 40 ++++++++- lib/gnu/rts/setjmp.gs | 6 -- lib/posix/_sigreturn.c | 32 ------- lib/syscall/Makefile.in | 1 - lib/syscall/siglongjmp.s | 7 -- man/man3/setjmp.3 | 69 +++++++++++++++ 16 files changed, 231 insertions(+), 344 deletions(-) delete mode 100755 include/minix/jmp_buf.h create mode 100644 include/sys/jmp_buf.h create mode 100644 lib/gnu/rts/__setjmp.gs delete mode 100644 lib/gnu/rts/_longjmp.gs delete mode 100644 lib/gnu/rts/_setjmp.gs delete mode 100644 lib/gnu/rts/setjmp.gs delete mode 100644 lib/syscall/siglongjmp.s create mode 100644 man/man3/setjmp.3 diff --git a/include/minix/jmp_buf.h b/include/minix/jmp_buf.h deleted file mode 100755 index 8a85c4eea..000000000 --- a/include/minix/jmp_buf.h +++ /dev/null @@ -1,87 +0,0 @@ -/* This file is intended for use by assembly language programs that - * need to manipulate a jmp_buf. It may only be used by those systems - * for which a jmp_buf is identical to a struct sigcontext. - */ - -#ifndef _JMP_BUF_H -#define _JMP_BUF_H - -#if !defined(CHIP) -#include "error, configuration is not known" -#endif - -#if (CHIP == INTEL) -#if _WORD_SIZE == 4 -#define JB_FLAGS 0 -#define JB_MASK 4 -#define JB_GS 8 -#define JB_FS 10 -#define JB_ES 12 -#define JB_DS 14 -#define JB_DI 16 -#define JB_SI 20 -#define JB_BP 24 -#define JB_ST 28 -#define JB_BX 32 -#define JB_DX 36 -#define JB_CX 40 -#define JB_AX 44 -#define JB_RETADR 48 -#define JB_IP 52 -#define JB_CS 56 -#define JB_PSW 60 -#define JB_SP 64 -#define JB_SS 68 -#else /* _WORD_SIZE == 2 */ -#define JB_FLAGS 0 -#define JB_MASK 2 -#define JB_ES 6 -#define JB_DS 8 -#define JB_DI 10 -#define JB_SI 12 -#define JB_BP 14 -#define JB_ST 16 -#define JB_BX 18 -#define JB_DX 20 -#define JB_CX 22 -#define JB_AX 24 -#define JB_RETADR 26 -#define JB_IP 28 -#define JB_CS 30 -#define JB_PSW 32 -#define JB_SP 34 -#define JB_SS 36 -#endif /* _WORD_SIZE == 2 */ -#else /* !(CHIP == INTEL) */ -#if (CHIP == M68000) -#define JB_FLAGS 0 -#define JB_MASK 2 -#define JB_RETREG 6 -#define JB_D1 10 -#define JB_D2 14 -#define JB_D3 18 -#define JB_D4 22 -#define JB_D5 26 -#define JB_D6 20 -#define JB_D7 34 -#define JB_A0 38 -#define JB_A1 42 -#define JB_A2 46 -#define JB_A3 50 -#define JB_A4 54 -#define JB_A5 58 -#define JB_A6 62 -#define JB_SP 66 -#define JB_PC 70 -#define JB_PSW 74 -#else /* !(CHIP == INTEL) && !(CHIP == M68000) */ -#include "error, CHIP is not supported" -#endif /* (CHIP == INTEL) */ - -/* Defines from C headers needed in assembly code. The headers have too - * much C stuff to used directly. - */ -#define SIG_BLOCK 0 /* must agree with */ -#define SC_SIGCONTEXT 2 /* must agree with */ -#define SC_NOREGLOCALS 4 /* must agree with */ -#endif /* _JMP_BUF_H */ diff --git a/include/setjmp.h b/include/setjmp.h index 31a879533..1417bcd30 100755 --- a/include/setjmp.h +++ b/include/setjmp.h @@ -1,67 +1,51 @@ /* The header relates to the C phenomenon known as setjmp/longjmp. * It is used to escape out of the current situation into a previous one. - * A typical example is in an editor, where hitting DEL breaks off the current - * command and puts the editor back in the main loop, though care has to be - * taken when the DEL occurs while executing a library function, since - * some of them are not reentrant. * - * POSIX does not require the process signal mask to be saved and restored - * during setjmp/longjmp. However, the current implementation does this - * in order to agree with OSF/1 and other BSD derived systems. + * The actual implementations of all these functions and, by extension, parts + * of this header, are both compiler- and architecture-dependent. Currently + * two compilers are supported: ACK and GCC. Each of these has their own + * implementation of the functions in their runtime system library code. + * As it is impossible to predict the requirements for any other compilers, + * this header may not be compatible with such other compilers either. * - * The pair of functions _setjmp/_longjmp may be used when the signal - * mask is not to be saved/restored. These functions are traditional - * in BSD systems. + * The ACK compiler will not enregister any variables inside a function + * containing a setjmp call, even if those variables are explicitly declared + * as register variables. Thus for ACK, of all the registers, only the + * program counter, stack pointer and frame pointer have to be saved into the + * jmp_buf structure. This makes the jmp_buf structure very small, and + * moreover, the implementation of the setjmp/longjmp calls (written in EM) + * architecture-independent and thus very portable. The ACK compiler + * recognizes only the symbol __setjmp as being such a setjmp call. * - * There are different ways of implementing setjmp/longjmp. Probably - * the best way is to unify it with signal handling. This is true for the - * following reasons: Both setjmp/longjmp and signal delivery must save - * a context so that it may be restored later. The jmp_buf necessarily - * contains signal information, namely the signal mask to restore. Both - * longjmp and the return of a signal handler must trap to the operating - * system to restore the previous signal mask. Finally, the jmp_buf - * and the sigcontext structure contain the registers to restore. + * The GCC compiler recognizes all of the setjmp/_setjmp/__setjmp name + * variants as calls to setjmp functions, and treats them as special + * accordingly, but does require that the setjmp implementation save and + * restore most of the registers. It has no portable setjmp and longjmp + * functions like ACK, and therefore has to have enough space in the jmp_buf + * structure to store the registers on any architecture it's ported to. * - * Some compilers, namely ACK, will not enregister any variables inside a - * function containing a call to setjmp, even if those variables are - * explicitly declared as register variables. Thus for ACK, the - * identification of the jmp_buf with a sigcontext structure would cause - * unnecessary overhead: the jmp_buf has room for all the registers, but - * the only registers that need to be saved are the stack pointer, - * frame pointer, and program counter. + * Taking the common denominator of both compilers, the function definitions + * in this header rely on the presence of merely two functions: __setjmp and + * longjmp. On the other hand, the size of jmp_buf depends on the compiler + * used: for ACK, jmp_buf is exactly big enough to store the three mentioned + * registers; for GCC and any other compiler, the size is chosen in such a + * way that it's likely to offer enough room to store registers for any + * architecture. The POSIX sigjmp_buf is identical to jmp_buf in all cases. * - * So, for ACK a jmp_buf is much smaller than a sigcontext structure, and - * longjmp does not directly call sigreturn. Instead, longjmp calls a - * front-end function which initializes the appropriate fields of a - * sigcontext structure, marks this structure as containing no valid - * general purpose registers, and then calls sigreturn. + * As far as porting is concerned -- * - * The POSIX sigjmp_buf is identical to the jmp_buf in all cases. + * All code writers/porters that have to deal with the actual contents of the + * jmp_buf structure in one way or another, should look at . * - * Different compilers have different symbols that they recognize as - * setjmp symbols. ACK recognizes __setjmp, the GNU C compiler - * recognizes setjmp and _setjmp, and BCC recognizes all three. - * When these symbols occur within a function, the compiler may keep - * all local variables on the stack, avoid certain optimizations, or - * pass hidden arguments to the setjmp function. - * - * Thus, setjmp implementations vary in two independent ways which may - * be identified through the following preprocessor tokens: + * Porters of a new compiler to Minix have to make sure the compiler + * recognizes at least __setjmp as a setjmp call (if applicable) and provide + * library implementations of __setjmp and longjmp conforming to their + * declarations below; if this is not possible, compiler-specific code will + * have to be added to this header. * - * _SETJMP_SYMBOL -- If 0, this means the compiler treats setjmp and _setjmp - * specially. If 1, this means the compiler treats __setjmp specially. - * - * _SETJMP_SAVES_REGS -- If 1, this means setjmp/longjmp must explicitly - * save and restore all registers. This also implies that a jmp_buf is - * different than a sigcontext structure. If 0, this means that the compiler - * will not use register variables within a function that calls one of - * its SETJMP_SYMBOLs. - * - * When _SETJMP_SYMBOL = 1, the implementation has a few dozen bytes of - * unnecessary overhead. This happens in the following manner: a program uses - * _setjmp/_longjmp because it is not interested in saving and restoring the - * signal mask. Nevertheless, because _setjmp expands to the general purpose - * function __setjmp, code for sigprocmask(2) is linked into the program. + * Porters of Minix+GCC to other architectures have to make sure that the + * __regs array of the jmp_buf structure is large enough to hold all the + * registers the __setjmp implementation for that architecture has to save. */ #ifndef _SETJMP_H @@ -71,82 +55,34 @@ #include #endif -#if !defined(__ACK__) && !defined(__BCC__) && !defined(__GNUC__) -#define __ACK__ -#endif - -#ifdef __ACK__ -#define _SETJMP_SYMBOL 1 -#define _SETJMP_SAVES_REGS 0 -#endif -#ifdef __BCC__ -#define _SETJMP_SYMBOL 0 -#define _SETJMP_SAVES_REGS 1 -#endif -#ifdef __GNUC__ -#define _SETJMP_SYMBOL 1 -#define _SETJMP_SAVES_REGS 1 -#endif - -/* The jmp_buf data type. Do not change the order of these fields -- some - * C library code refers to these fields by name. When _SETJMP_SAVES_REGS - * is 1, the file gives the usage of the sixteen registers. - */ typedef struct { - int __flags; /* XXX - long might give better alignment */ - long __mask; /* must have size >= sizeof(sigset_t) */ -#if (_SETJMP_SAVES_REGS == 0) +#if defined(__ACK__) _PROTOTYPE(void (*__pc),(void)); /* program counter */ void *__sp; /* stack pointer */ void *__lb; /* local base (ACKspeak for frame pointer) */ -#else - void *__regs[16]; /* size is machine dependent */ + long __mask; /* must have size >= sizeof(sigset_t) */ + int __flags; +#else /* GCC */ + int __flags; /* XXX - long might give better alignment */ + long __mask; /* must have size >= sizeof(sigset_t) */ + void *__regs[16]; /* actual use is architecture dependent */ #endif } jmp_buf[1]; -#if (_SETJMP_SYMBOL == 1) - _PROTOTYPE( int __setjmp, (jmp_buf _env, int _savemask) ); _PROTOTYPE( void longjmp, (jmp_buf _env, int _val) ); -_PROTOTYPE(int sigjmp, (jmp_buf _jb, int _retval) ); #define setjmp(env) __setjmp((env), 1) #ifdef _MINIX #define _setjmp(env) __setjmp((env), 0) -_PROTOTYPE(void _longjmp, (jmp_buf _env, int _val) ); +#define _longjmp(env, val) longjmp((env), (val)) #endif #ifdef _POSIX_SOURCE typedef jmp_buf sigjmp_buf; -#ifdef __GNUC__ -#define siglongjmp longjmp -#else -_PROTOTYPE( void siglongjmp, (sigjmp_buf _env, int _val) ); -#endif - #define sigsetjmp(env, savemask) __setjmp((env), (savemask)) +#define siglongjmp(env, val) longjmp((env), (val)) #endif /* _POSIX_SOURCE */ -#endif /* _SETJMP_SYMBOL == 1 */ - -#if (_SETJMP_SYMBOL == 0) - -_PROTOTYPE( int setjmp, (jmp_buf _env) ); -_PROTOTYPE( void longjmp, (jmp_buf _env, int _val) ); - -#ifdef _MINIX -_PROTOTYPE( int _setjmp, (jmp_buf _env) ); -_PROTOTYPE( void _longjmp, (jmp_buf _env, int _val) ); -#endif - -#ifdef _POSIX_SOURCE -#define sigjmp_buf jmp_buf -_PROTOTYPE( void siglongjmp, (sigjmp_buf _env, int _val) ); -/* XXX - the name _setjmp is no good - that's why ACK used __setjmp. */ -#define sigsetjmp(env, savemask) ((savemask) ? setjmp(env) : _setjmp(env)) -#endif /* _POSIX_SOURCE */ - -#endif /* _SETJMP_SYMBOL == 0 */ - #endif /* _SETJMP_H */ diff --git a/include/sys/jmp_buf.h b/include/sys/jmp_buf.h new file mode 100644 index 000000000..94e692406 --- /dev/null +++ b/include/sys/jmp_buf.h @@ -0,0 +1,45 @@ +/* This file is intended for use by program code (possibly written in + * assembly) that needs to manipulate a jmp_buf or sigjmp_buf. The JB_* + * values are byte offsets into the jmp_buf and sigjmp_buf structures. + */ + +#ifndef _JMP_BUF_H +#define _JMP_BUF_H + +#include + +#if defined(__ACK__) +/* as per lib/ack/rts/setjmp.e */ + +/* note the lack of parentheses, which would confuse 'as' */ +#define JB_PC 0 +#define JB_SP JB_PC + _EM_PSIZE +#define JB_LB JB_SP + _EM_PSIZE +#define JB_MASK JB_LB + _EM_PSIZE +#define JB_FLAGS JB_MASK + _EM_LSIZE + +#if (CHIP == INTEL) +#define JB_BP JB_LB +#endif + +#elif defined(__GNUC__) + +#if (CHIP == INTEL) && (_WORD_SIZE == 4) +/* as per lib/gnu/rts/__setjmp.gs */ + +#define JB_FLAGS 0 +#define JB_MASK 4 +#define JB_PC 8 +#define JB_SP 12 +#define JB_BP 16 +#define JB_BX 20 +#define JB_CX 24 +#define JB_DX 28 +#define JB_SI 32 +#define JB_DI 36 + +#endif /* (CHIP == INTEL) && (_WORD_SIZE == 4) */ + +#endif /* __GNU__ */ + +#endif /* _JMP_BUF_H */ diff --git a/include/sys/sigcontext.h b/include/sys/sigcontext.h index 288ff8221..a9e0fb9db 100755 --- a/include/sys/sigcontext.h +++ b/include/sys/sigcontext.h @@ -136,11 +136,6 @@ struct sigcontext { #define sc_psw sc_regs.sr_psw #endif /* _MINIX_CHIP == M68000 */ -/* Values for sc_flags. Must agree with . */ -#define SC_SIGCONTEXT 2 /* nonzero when signal context is included */ -#define SC_NOREGLOCALS 4 /* nonzero when registers are not to be - saved and restored */ - _PROTOTYPE( int sigreturn, (struct sigcontext *_scp) ); #endif /* _SIGCONTEXT_H */ diff --git a/kernel/system/do_sigreturn.c b/kernel/system/do_sigreturn.c index f1b026d9e..f887eb428 100644 --- a/kernel/system/do_sigreturn.c +++ b/kernel/system/do_sigreturn.c @@ -38,19 +38,6 @@ message *m_ptr; /* pointer to request message */ if (src_phys == 0) return(EFAULT); phys_copy(src_phys, vir2phys(&sc), (phys_bytes) sizeof(struct sigcontext)); - /* Make sure that this is not just a jump buffer. */ - if ((sc.sc_flags & SC_SIGCONTEXT) == 0) return(EINVAL); - - /* Fix up only certain key registers if the compiler doesn't use - * register variables within functions containing setjmp. - */ - if (sc.sc_flags & SC_NOREGLOCALS) { - rp->p_reg.retreg = sc.sc_retreg; - rp->p_reg.fp = sc.sc_fp; - rp->p_reg.pc = sc.sc_pc; - rp->p_reg.sp = sc.sc_sp; - return(OK); - } sc.sc_psw = rp->p_reg.psw; #if (CHIP == INTEL) diff --git a/kernel/system/do_sigsend.c b/kernel/system/do_sigsend.c index 5e84bc374..85b62e7a3 100644 --- a/kernel/system/do_sigsend.c +++ b/kernel/system/do_sigsend.c @@ -47,7 +47,7 @@ message *m_ptr; /* pointer to request message */ memcpy(&sc.sc_regs, (char *) &rp->p_reg, sizeof(struct sigregs)); /* Finish the sigcontext initialization. */ - sc.sc_flags = SC_SIGCONTEXT; + sc.sc_flags = 0; /* unused at this time */ sc.sc_mask = smsg.sm_mask; /* Copy the sigcontext structure to the user's stack. */ diff --git a/lib/gnu/rts/Makefile.in b/lib/gnu/rts/Makefile.in index cd5f8b364..60611073e 100644 --- a/lib/gnu/rts/Makefile.in +++ b/lib/gnu/rts/Makefile.in @@ -2,9 +2,7 @@ LIBRARIES=libc libc_FILES=" \ - _longjmp.gs \ - _setjmp.gs \ - longjmp.gs \ - setjmp.gs" + __setjmp.gs \ + longjmp.gs" TYPE=gnu diff --git a/lib/gnu/rts/__setjmp.gs b/lib/gnu/rts/__setjmp.gs new file mode 100644 index 000000000..36419951b --- /dev/null +++ b/lib/gnu/rts/__setjmp.gs @@ -0,0 +1,31 @@ +/ __setjmp.gnu.s +/ +/ Created: Oct 14, 1993 by Philip Homburg + +.text +.globl ___setjmp +___setjmp: + movl 4(%esp), %eax # jmp_buf + movl %edx, 28(%eax) # save edx + movl 0(%esp), %edx + movl %edx, 8(%eax) # save program counter + movl %esp, 12(%eax) # save stack pointer + movl %ebp, 16(%eax) # save frame pointer + movl %ebx, 20(%eax) + movl %ecx, 24(%eax) + movl %esi, 32(%eax) + movl %edi, 36(%eax) + + movl 8(%esp), %edx # save mask? + movl %edx, 0(%eax) # save whether to restore mask + testl %edx, %edx + jz 1f + leal 4(%eax), %edx # pointer to sigset_t + pushl %edx + call ___newsigset # save mask + addl $4, %esp +1: + movl $0, %eax + ret + +/ $PchId: __setjmp.gnu.s,v 1.4 1996/03/12 19:30:54 philip Exp $ diff --git a/lib/gnu/rts/_longjmp.gs b/lib/gnu/rts/_longjmp.gs deleted file mode 100644 index 74cc58846..000000000 --- a/lib/gnu/rts/_longjmp.gs +++ /dev/null @@ -1,38 +0,0 @@ -/ _longjmp.gnu.s -/ -/ Created: Oct 15, 1993 by Philip Homburg - -.text -.globl __longjmp -__longjmp: - movl 4(%esp), %eax # jmp_buf - cmpl $0, 0(%eax) # save mask? - je 1f - leal 4(%eax), %ebx # pointer to sigset_t - pushl %ebx - call ___oldsigset # restore mask - addl $4, %esp - movl 4(%esp), %eax # jmp_buf -1: - movl 8(%esp), %ecx # result value - movl 12(%eax), %esp # restore stack pointer - - movl 8(%eax), %ebx # restore program counter - movl %ebx, 0(%esp) - - pushl %ecx # save result code - - movl 16(%eax), %ebp # restore frame pointer - movl 20(%eax), %ebx - movl 24(%eax), %ecx - movl 28(%eax), %edx - movl 32(%eax), %esi - movl 36(%eax), %edi - pop %eax - testl %eax, %eax - jz 1f - ret -1: movl $1, %eax - ret - -/ $PchId: _longjmp.gnu.s,v 1.4 1996/03/12 19:30:02 philip Exp $ diff --git a/lib/gnu/rts/_setjmp.gs b/lib/gnu/rts/_setjmp.gs deleted file mode 100644 index e9e76034f..000000000 --- a/lib/gnu/rts/_setjmp.gs +++ /dev/null @@ -1,35 +0,0 @@ -/ _setjmp.gnu.s -/ -/ Created: Oct 14, 1993 by Philip Homburg - -.text -.globl ___setjmp -___setjmp: - movl 4(%esp), %eax # jmp_buf - movl %ebx, 20(%eax) # save ebx - movl 0(%esp), %ebx - movl %ebx, 8(%eax) # save program counter - movl %esp, 12(%eax) # save stack pointer - movl %ebp, 16(%eax) # save frame pointer - movl %ecx, 24(%eax) - movl %edx, 28(%eax) - movl %esi, 32(%eax) - movl %edi, 36(%eax) - - movl 8(%esp), %ebx # save mask? - movl %ebx, 0(%eax) # save whether to restore mask - - pushl 20(%eax) # save ebx - - testl %ebx, %ebx - jz 1f - leal 4(%eax), %ebx # pointer to sigset_t - pushl %ebx - call ___newsigset # save mask - addl $4, %esp -1: - popl %ebx - movl $0, %eax - ret - -/ $PchId: _setjmp.gnu.s,v 1.4 1996/03/12 19:30:54 philip Exp $ diff --git a/lib/gnu/rts/longjmp.gs b/lib/gnu/rts/longjmp.gs index ca19beb3e..839385ae4 100644 --- a/lib/gnu/rts/longjmp.gs +++ b/lib/gnu/rts/longjmp.gs @@ -1,6 +1,38 @@ - .text -.globl _longjmp +/ longjmp.gnu.s +/ +/ Created: Oct 15, 1993 by Philip Homburg + +.text +.globl _longjmp _longjmp: - jmp __longjmp + movl 4(%esp), %eax # jmp_buf + cmpl $0, 0(%eax) # save mask? + je 1f + leal 4(%eax), %edx # pointer to sigset_t + pushl %edx + call ___oldsigset # restore mask + addl $4, %esp + movl 4(%esp), %eax # jmp_buf +1: + movl 8(%esp), %ecx # result value + movl 12(%eax), %esp # restore stack pointer + + movl 8(%eax), %edx # restore program counter + movl %edx, 0(%esp) + + pushl %ecx # save result code + + movl 16(%eax), %ebp # restore frame pointer + movl 20(%eax), %ebx + movl 24(%eax), %ecx + movl 28(%eax), %edx + movl 32(%eax), %esi + movl 36(%eax), %edi + pop %eax + testl %eax, %eax + jz 1f + ret +1: movl $1, %eax + ret -/ $PchId: longjmp.gnu.s,v 1.4 1996/03/12 19:31:18 philip Exp $ +/ $PchId: longjmp.gnu.s,v 1.4 1996/03/12 19:30:02 philip Exp $ diff --git a/lib/gnu/rts/setjmp.gs b/lib/gnu/rts/setjmp.gs deleted file mode 100644 index 93e4caa1b..000000000 --- a/lib/gnu/rts/setjmp.gs +++ /dev/null @@ -1,6 +0,0 @@ - .text -.globl _setjmp -_setjmp: - jmp ___setjmp - -/ $PchId: setjmp.gnu.s,v 1.4 1996/03/12 19:31:18 philip Exp $ diff --git a/lib/posix/_sigreturn.c b/lib/posix/_sigreturn.c index 5098cbebf..5514728bb 100755 --- a/lib/posix/_sigreturn.c +++ b/lib/posix/_sigreturn.c @@ -1,42 +1,10 @@ #include #define sigfillset _sigfillset -#define sigjmp _sigjmp #define sigprocmask _sigprocmask #define sigreturn _sigreturn #include -#include #include -_PROTOTYPE( int sigjmp, (jmp_buf jb, int retval)); - -#if (_SETJMP_SAVES_REGS == 0) -/* 'sigreturn' using a short format jmp_buf (no registers saved). */ -PUBLIC int sigjmp(jb, retval) -jmp_buf jb; -int retval; -{ - struct sigcontext sc; - - sc.sc_flags = jb[0].__flags; - sc.sc_mask = jb[0].__mask; - -#if (CHIP == INTEL) - sc.sc_pc = (int) jb[0].__pc; - sc.sc_sp = (int) jb[0].__sp; - sc.sc_fp = (int) jb[0].__lb; -#endif - -#if (CHIP == M68000) - sc.sc_pc = (long) jb[0].__pc; - sc.sc_sp = (long) jb[0].__sp; - sc.sc_fp = (long) jb[0].__lb; -#endif - - sc.sc_retreg = retval; - return sigreturn(&sc); -} -#endif - PUBLIC int sigreturn(scp) register struct sigcontext *scp; { diff --git a/lib/syscall/Makefile.in b/lib/syscall/Makefile.in index ed583db84..339044972 100644 --- a/lib/syscall/Makefile.in +++ b/lib/syscall/Makefile.in @@ -89,7 +89,6 @@ libc_FILES=" \ sigemptyset.s \ sigfillset.s \ sigismember.s \ - siglongjmp.s \ sigpending.s \ sigprocmask.s \ sigreturn.s \ diff --git a/lib/syscall/siglongjmp.s b/lib/syscall/siglongjmp.s deleted file mode 100644 index 914b293b1..000000000 --- a/lib/syscall/siglongjmp.s +++ /dev/null @@ -1,7 +0,0 @@ -.sect .text -.extern _longjmp -.define _siglongjmp -.align 2 - -_siglongjmp: - jmp _longjmp diff --git a/man/man3/setjmp.3 b/man/man3/setjmp.3 new file mode 100644 index 000000000..c55d0467a --- /dev/null +++ b/man/man3/setjmp.3 @@ -0,0 +1,69 @@ +.TH SETJMP 3 "June 22, 2006" +.UC 4 +.SH NAME +setjmp, longjmp, _setjmp, _longjmp, sigsetjmp, siglongjmp \- save and restore execution contexts +.SH SYNOPSIS +.nf +.ft B +#include + +int setjmp(jmp_buf env); +void longjmp(jmp_buf env, int val); + +int _setjmp(jmp_buf env); +void _longjmp(jmp_buf env, int val); + +#define _POSIX_SOURCE +int sigsetjmp(sigjmp_buf env, int savemask); +void siglongjmp(sigjmp_buf env, int val); +.SH DESCRIPTION +These calls provide a way for a process to save an execution context into a +buffer, and later resume execution from that context, effectively performing +a non-local jump. The +.B setjmp +family of functions store the context into the \fIenv\fP data structure, +and return the value 0. The +.B longjmp +family of functions jump to the context saved in the given \fIenv\fP data +structure, causing the process to continue as if it returned from the +corresponding +.B setjmp +call again, but this time with the non-zero return value in \fIval\fP. +.PP +The difference between the three pairs of setjmp/longjmp functions lies in the +behaviour with respect to saving/restoring the process signal mask. POSIX does +not require the process signal mask to be saved and restored during +.B setjmp +/ +.B longjmp +\. However, the current implementation does this in order to agree with OSF/1 +and other BSD derived systems. +.PP +The pair of functions +.B _setjmp +/ +.B _longjmp +, traditional in BSD systems, may be used when the signal mask is not to be +saved/restored. +.PP +Finally, the POSIX +.B sigsetjmp +/ +.B siglongjmp +functions allow the programmer to specify explicitly whether the signal mask +is to be saved/restored, by means of the \fIsavemask\fP parameter. If this +parameter is zero, the signal mask will not be saved/restored, otherwise it +will. +.SH NOTES +After the function calling +.B setjmp +has returned, the saved context may not be used in a call to +.B longjmp +anymore, since the relevant portion of the stack may already have been wiped +out at that point. +.PP +Using these functions to return to a previous state from a signal handler +is possible but should be done with extreme care, as some interrupted library +routines may not be reentrant and/or temporarily allocate resources. +.PP +See the setjmp.h header file for more implementation details specific to Minix. -- 2.44.0