1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-14 10:09:48 +00:00

Re-introduction of sigcontext.

struct sigcontext and ucontext_t/mcontext_t are defined in such
a way that both (ie struct sigcontext and ucontext_t) can be
passed on to sigreturn. The signal handler is still given a
ucontext_t for maximum flexibility.

For backward compatibility sigreturn restores the state for the
alternate signal stack from sigcontext.sc_onstack and not from
ucontext_t.uc_stack. A good way to determine which value the
application has set and thus which value to use, is still open
for discussion.

NOTE: This change should only affect those binaries that use
      sigcontext and/or ucontext_t. In the source tree itself
      this is only doscmd. Recompilation is required for those
      applications.

This commit also fixes a lot of style bugs without hopefully
adding new ones.

NOTE: struct sigaltstack.ss_size now has type size_t again. For
      some reason I changed that into unsigned int.

Parts submitted by: bde
sigaltstack bug found by: bde
This commit is contained in:
Marcel Moolenaar 1999-10-04 19:33:58 +00:00
parent a93fdaac21
commit c5c6b7b38e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=51942
17 changed files with 390 additions and 218 deletions

View File

@ -1269,7 +1269,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
struct trapframe *frame;
struct sigacts *psp;
struct sigframe sf, *sfp;
int rndfsize;
int onstack, rndfsize;
p = curproc;
@ -1280,13 +1280,26 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame = p->p_md.md_tf;
psp = p->p_sigacts;
onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
rndfsize = ((sizeof(sf) + 15) / 16) * 16;
/* save user context */
bzero(&sf, sizeof(struct sigframe));
sf.sf_uc.uc_sigmask = *mask;
sf.sf_uc.uc_stack = psp->ps_sigstk;
sf.sf_uc.uc_mcontext.mc_tf = *frame;
sf.sf_uc.uc_mcontext.mc_onstack = onstack;
fill_regs(p, (struct reg *)sf.sf_uc.uc_mcontext.mc_regs);
sf.sf_uc.uc_mcontext.mc_regs[R_SP] = alpha_pal_rdusp();
sf.sf_uc.uc_mcontext.mc_regs[R_ZERO] = 0xACEDBADE; /* magic number */
sf.sf_uc.uc_mcontext.mc_regs[R_PS] = frame->tf_regs[FRAME_PS];
sf.sf_uc.uc_mcontext.mc_regs[R_PC] = frame->tf_regs[FRAME_PC];
sf.sf_uc.uc_mcontext.mc_regs[R_TRAPARG_A0] =
frame->tf_regs[FRAME_TRAPARG_A0];
sf.sf_uc.uc_mcontext.mc_regs[R_TRAPARG_A1] =
frame->tf_regs[FRAME_TRAPARG_A1];
sf.sf_uc.uc_mcontext.mc_regs[R_TRAPARG_A2] =
frame->tf_regs[FRAME_TRAPARG_A2];
/*
* Allocate and validate space for the signal handler
@ -1295,8 +1308,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
* will fail if the process has not already allocated
* the space with a `brk'.
*/
if ((psp->ps_flags & SAS_ALTSTACK) != 0 &&
(psp->ps_sigstk.ss_flags & SS_ONSTACK) == 0 &&
if ((psp->ps_flags & SAS_ALTSTACK) != 0 && !onstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
sfp = (struct sigframe *)((caddr_t)psp->ps_sigstk.ss_sp +
psp->ps_sigstk.ss_size - rndfsize);
@ -1328,8 +1340,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
return;
}
sf.sf_uc.uc_mcontext.mc_tf.tf_regs[FRAME_SP] = alpha_pal_rdusp();
/* save the floating-point state, if necessary, then copy it. */
if (p == fpcurproc) {
alpha_pal_wrfen(1);
@ -1418,6 +1428,10 @@ osigreturn(struct proc *p,
copyin((caddr_t)scp, (caddr_t)&ksc, sizeof ksc))
return (EINVAL);
/*
* XXX - Should we do this. What if we get a "handcrafted"
* but valid sigcontext that hasn't the magic number?
*/
if (ksc.sc_regs[R_ZERO] != 0xACEDBADE) /* magic number */
return (EINVAL);
/*
@ -1464,6 +1478,7 @@ sigreturn(struct proc *p,
{
ucontext_t uc, *ucp;
struct pcb *pcb;
unsigned long val;
ucp = uap->sigcntxp;
@ -1491,13 +1506,18 @@ sigreturn(struct proc *p,
/*
* Restore the user-supplied information
*/
*p->p_md.md_tf = uc.uc_mcontext.mc_tf;
p->p_md.md_tf->tf_regs[FRAME_PS] |= ALPHA_PSL_USERSET;
p->p_md.md_tf->tf_regs[FRAME_PS] &= ~ALPHA_PSL_USERCLR;
pcb->pcb_hw.apcb_usp = p->p_md.md_tf->tf_regs[FRAME_SP];
alpha_pal_wrusp(pcb->pcb_hw.apcb_usp);
set_regs(p, (struct reg *)uc.uc_mcontext.mc_regs);
val = (uc.uc_mcontext.mc_regs[R_PS] | ALPHA_PSL_USERSET) &
~ALPHA_PSL_USERCLR;
p->p_md.md_tf->tf_regs[FRAME_PS] = val;
p->p_md.md_tf->tf_regs[FRAME_PC] = uc.uc_mcontext.mc_regs[R_PC];
alpha_pal_wrusp(uc.uc_mcontext.mc_regs[R_SP]);
if (uc.uc_mcontext.mc_onstack & 1)
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
p->p_sigacts->ps_sigstk = uc.uc_stack;
p->p_sigmask = uc.uc_sigmask;
SIG_CANTMASK(p->p_sigmask);

View File

@ -73,6 +73,15 @@
#define R_SP 30
#define R_ZERO 31
/*
* Register extensions used in mcontext_t
*/
#define R_PS 32
#define R_PC 33
#define R_TRAPARG_A0 34
#define R_TRAPARG_A1 35
#define R_TRAPARG_A2 36
struct reg {
u_int64_t r_regs[32];
};

View File

@ -32,6 +32,7 @@
#define _ALPHA_SIGNAL_H_
typedef long sig_atomic_t;
#ifndef _ANSI_SOURCE
/*
@ -52,7 +53,6 @@ struct osigcontext {
long sc_pc; /* pc to restore */
long sc_ps; /* ps to restore */
unsigned long sc_regs[32]; /* integer register set (see above) */
#define sc_sp sc_regs[R_SP]
long sc_ownedfp; /* fp has been used */
unsigned long sc_fpregs[32]; /* FP register set (see above) */
unsigned long sc_fpcr; /* FP control register (see above) */
@ -65,5 +65,29 @@ struct osigcontext {
long sc_xxx2[3]; /* sc_fp_trap_pc, sc_fp_trigger_sum, sc_fp_trigger_inst */
};
/*
* The sequence of the fields should match those in
* mcontext_t. Keep them in sync!
*/
struct sigcontext {
sigset_t sc_mask; /* signal mask to restore */
long sc_onstack; /* sigstack state to restore */
unsigned long sc_regs[32]; /* integer register set (see above) */
long sc_ps; /* ps to restore */
long sc_pc; /* pc to restore */
unsigned long sc_traparg_a0; /* a0 argument to trap at exception */
unsigned long sc_traparg_a1; /* a1 argument to trap at exception */
unsigned long sc_traparg_a2; /* a2 argument to trap at exception */
unsigned long sc_fpregs[32]; /* FP register set (see above) */
unsigned long sc_fpcr; /* FP control register (see above) */
unsigned long sc_fp_control; /* FP software control word */
long sc_ownedfp; /* fp has been used */
long sc_xxx1[2]; /* sc_ssize, sc_sbase on DUX */
long sc_xxx2[3]; /* sc_fp_trap_pc, sc_fp_trigger_sum, sc_fp_trigger_inst */
long sc_reserved[2]; /* XXX */
};
#define sc_sp sc_regs[R_SP]
#endif /* !_ANSI_SOURCE */
#endif /* !_ALPHA_SIGNAL_H_*/

View File

@ -29,18 +29,24 @@
*/
#ifndef _MACHINE_UCONTEXT_H_
#define _MACHINE_UCONTEXT_H_ 1
#define _MACHINE_UCONTEXT_H_
#include <machine/frame.h>
typedef struct {
struct trapframe mc_tf;
unsigned long mc_fpregs[32];
unsigned long mc_fpcr;
unsigned long mc_fp_control;
unsigned long mc_apcb_usp;
long mc_ownedfp;
long __spare__[8];
typedef struct __mcontext {
/*
* These fields must match the definition
* of struct sigcontext. That way we can support
* struct sigcontext and ucontext_t at the same
* time.
*/
long mc_onstack; /* XXX - sigcontext compat. */
unsigned long mc_regs[37];
unsigned long mc_fpregs[32];
unsigned long mc_fpcr;
unsigned long mc_fp_control;
long mc_ownedfp;
long __spare__[7];
} mcontext_t;
#endif /* _MACHINE_UCONTEXT_H_ */
#endif /* !_MACHINE_UCONTEXT_H_ */

View File

@ -69,11 +69,10 @@
#include <machine/apic.h>
#endif
#include <machine/segments.h>
#include <machine/sigframe.h>
#include <machine/globaldata.h>
#include <machine/vm86.h>
#include <machine/sigframe.h>
#define OS(s, m) ((u_int)offsetof(struct s, m))
int main __P((void));
@ -157,7 +156,8 @@ main()
printf("#define\tSC_FS %#x\n", OS(osigcontext, sc_fs));
printf("#define\tSC_GS %#x\n", OS(osigcontext, sc_gs));
printf("#define\tUC_EFLAGS %#x\n", OS(__ucontext, uc_mcontext.mc_tf.tf_eflags));
printf("#define\tUC_EFLAGS %#x\n",
OS(__ucontext, uc_mcontext.mc_tf.tf_eflags));
printf("#define\tUC_GS %#x\n", OS(__ucontext, uc_mcontext.mc_gs));
printf("#define\tB_READ %#x\n", B_READ);

View File

@ -613,6 +613,7 @@ sendsig(catcher, sig, mask, code)
struct trapframe *regs;
struct sigacts *psp;
struct sigframe sf, *sfp;
int onstack;
p = curproc;
@ -623,17 +624,18 @@ sendsig(catcher, sig, mask, code)
regs = p->p_md.md_regs;
psp = p->p_sigacts;
onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
/* save user context */
bzero(&sf, sizeof(struct sigframe));
sf.sf_uc.uc_sigmask = *mask;
sf.sf_uc.uc_stack = psp->ps_sigstk;
sf.sf_uc.uc_mcontext.mc_onstack = onstack;
sf.sf_uc.uc_mcontext.mc_tf = *regs;
sf.sf_uc.uc_mcontext.mc_gs = rgs();
/* Allocate and validate space for the signal handler context. */
if ((psp->ps_flags & SAS_ALTSTACK) != 0 &&
(psp->ps_sigstk.ss_flags & SS_ONSTACK) == 0 &&
if ((psp->ps_flags & SAS_ALTSTACK) != 0 && !onstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
sfp = (struct sigframe *)(psp->ps_sigstk.ss_sp +
psp->ps_sigstk.ss_size - sizeof(struct sigframe));
@ -884,16 +886,13 @@ sigreturn(p, uap)
{
struct trapframe *regs;
ucontext_t *ucp;
struct sigframe *sfp;
int cs, eflags;
regs = p->p_md.md_regs;
ucp = uap->sigcntxp;
sfp = (struct sigframe *)
((caddr_t)ucp - offsetof(struct sigframe, sf_uc));
eflags = ucp->uc_mcontext.mc_tf.tf_eflags;
if (useracc((caddr_t)sfp, sizeof(struct sigframe), B_WRITE) == 0)
if (useracc((caddr_t)ucp, sizeof(ucontext_t), B_WRITE) == 0)
return(EFAULT);
if (eflags & PSL_VM) {
@ -963,7 +962,11 @@ sigreturn(p, uap)
*regs = ucp->uc_mcontext.mc_tf;
}
p->p_sigacts->ps_sigstk = ucp->uc_stack;
if (ucp->uc_mcontext.mc_onstack & 1)
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
p->p_sigmask = ucp->uc_sigmask;
SIG_CANTMASK(p->p_sigmask);
return(EJUSTRETURN);

View File

@ -57,33 +57,62 @@ typedef int sig_atomic_t;
typedef unsigned int osigset_t;
struct osigcontext {
int sc_onstack; /* sigstack state to restore */
osigset_t sc_mask; /* signal mask to restore */
int sc_esp; /* machine state */
int sc_ebp;
int sc_isp;
int sc_eip;
int sc_efl;
int sc_es;
int sc_ds;
int sc_cs;
int sc_ss;
int sc_edi;
int sc_esi;
int sc_ebx;
int sc_edx;
int sc_ecx;
int sc_eax;
int sc_gs;
int sc_fs;
int sc_onstack; /* sigstack state to restore */
osigset_t sc_mask; /* signal mask to restore */
int sc_esp; /* machine state */
int sc_ebp;
int sc_isp;
int sc_eip;
int sc_efl;
int sc_es;
int sc_ds;
int sc_cs;
int sc_ss;
int sc_edi;
int sc_esi;
int sc_ebx;
int sc_edx;
int sc_ecx;
int sc_eax;
int sc_gs;
int sc_fs;
int sc_trapno;
int sc_err;
};
/*
* The sequence of the fields/registers in sigcontext should match
* those in mcontext_t.
*/
struct sigcontext {
sigset_t sc_mask; /* signal mask to restore */
int sc_onstack; /* sigstack state to restore */
int sc_gs;
int sc_fs;
int sc_es;
int sc_ds;
int sc_edi;
int sc_esi;
int sc_ebp;
int sc_isp;
int sc_ebx;
int sc_edx;
int sc_ecx;
int sc_eax;
int sc_trapno;
int sc_err;
int sc_eip;
int sc_cs;
int sc_efl;
int sc_esp; /* machine state */
int sc_ss;
};
#define sc_sp sc_esp
#define sc_fp sc_ebp
#define sc_pc sc_eip
#define sc_ps sc_efl
#define sc_eflags sc_efl
int sc_trapno;
int sc_err;
};
#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */

View File

@ -29,15 +29,22 @@
*/
#ifndef _MACHINE_UCONTEXT_H_
#define _MACHINE_UCONTEXT_H_ 1
#define _MACHINE_UCONTEXT_H_
#include <machine/frame.h>
typedef struct {
int mc_gs; /* %gs */
struct trapframe mc_tf; /* trapframe */
int mc_fpregs[28]; /* env87 + fpacc87 + u_long */
int __spare__[17];
typedef struct __mcontext {
/*
* The first 3 fields must match the definition of
* sigcontext. So that we can support sigcontext
* and ucontext_t at the same time.
*/
int mc_onstack; /* XXX - sigcontext compat. */
int mc_gs;
struct trapframe mc_tf;
int mc_fpregs[28]; /* env87 + fpacc87 + u_long */
int __spare__[17];
} mcontext_t;
#endif /* _MACHINE_UCONTEXT_H_ */
#endif /* !_MACHINE_UCONTEXT_H_ */

View File

@ -69,11 +69,10 @@
#include <machine/apic.h>
#endif
#include <machine/segments.h>
#include <machine/sigframe.h>
#include <machine/globaldata.h>
#include <machine/vm86.h>
#include <machine/sigframe.h>
#define OS(s, m) ((u_int)offsetof(struct s, m))
int main __P((void));
@ -157,7 +156,8 @@ main()
printf("#define\tSC_FS %#x\n", OS(osigcontext, sc_fs));
printf("#define\tSC_GS %#x\n", OS(osigcontext, sc_gs));
printf("#define\tUC_EFLAGS %#x\n", OS(__ucontext, uc_mcontext.mc_tf.tf_eflags));
printf("#define\tUC_EFLAGS %#x\n",
OS(__ucontext, uc_mcontext.mc_tf.tf_eflags));
printf("#define\tUC_GS %#x\n", OS(__ucontext, uc_mcontext.mc_gs));
printf("#define\tB_READ %#x\n", B_READ);

View File

@ -613,6 +613,7 @@ sendsig(catcher, sig, mask, code)
struct trapframe *regs;
struct sigacts *psp;
struct sigframe sf, *sfp;
int onstack;
p = curproc;
@ -623,17 +624,18 @@ sendsig(catcher, sig, mask, code)
regs = p->p_md.md_regs;
psp = p->p_sigacts;
onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
/* save user context */
bzero(&sf, sizeof(struct sigframe));
sf.sf_uc.uc_sigmask = *mask;
sf.sf_uc.uc_stack = psp->ps_sigstk;
sf.sf_uc.uc_mcontext.mc_onstack = onstack;
sf.sf_uc.uc_mcontext.mc_tf = *regs;
sf.sf_uc.uc_mcontext.mc_gs = rgs();
/* Allocate and validate space for the signal handler context. */
if ((psp->ps_flags & SAS_ALTSTACK) != 0 &&
(psp->ps_sigstk.ss_flags & SS_ONSTACK) == 0 &&
if ((psp->ps_flags & SAS_ALTSTACK) != 0 && !onstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
sfp = (struct sigframe *)(psp->ps_sigstk.ss_sp +
psp->ps_sigstk.ss_size - sizeof(struct sigframe));
@ -884,16 +886,13 @@ sigreturn(p, uap)
{
struct trapframe *regs;
ucontext_t *ucp;
struct sigframe *sfp;
int cs, eflags;
regs = p->p_md.md_regs;
ucp = uap->sigcntxp;
sfp = (struct sigframe *)
((caddr_t)ucp - offsetof(struct sigframe, sf_uc));
eflags = ucp->uc_mcontext.mc_tf.tf_eflags;
if (useracc((caddr_t)sfp, sizeof(struct sigframe), B_WRITE) == 0)
if (useracc((caddr_t)ucp, sizeof(ucontext_t), B_WRITE) == 0)
return(EFAULT);
if (eflags & PSL_VM) {
@ -963,7 +962,11 @@ sigreturn(p, uap)
*regs = ucp->uc_mcontext.mc_tf;
}
p->p_sigacts->ps_sigstk = ucp->uc_stack;
if (ucp->uc_mcontext.mc_onstack & 1)
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
p->p_sigmask = ucp->uc_sigmask;
SIG_CANTMASK(p->p_sigmask);
return(EJUSTRETURN);

View File

@ -57,33 +57,62 @@ typedef int sig_atomic_t;
typedef unsigned int osigset_t;
struct osigcontext {
int sc_onstack; /* sigstack state to restore */
osigset_t sc_mask; /* signal mask to restore */
int sc_esp; /* machine state */
int sc_ebp;
int sc_isp;
int sc_eip;
int sc_efl;
int sc_es;
int sc_ds;
int sc_cs;
int sc_ss;
int sc_edi;
int sc_esi;
int sc_ebx;
int sc_edx;
int sc_ecx;
int sc_eax;
int sc_gs;
int sc_fs;
int sc_onstack; /* sigstack state to restore */
osigset_t sc_mask; /* signal mask to restore */
int sc_esp; /* machine state */
int sc_ebp;
int sc_isp;
int sc_eip;
int sc_efl;
int sc_es;
int sc_ds;
int sc_cs;
int sc_ss;
int sc_edi;
int sc_esi;
int sc_ebx;
int sc_edx;
int sc_ecx;
int sc_eax;
int sc_gs;
int sc_fs;
int sc_trapno;
int sc_err;
};
/*
* The sequence of the fields/registers in sigcontext should match
* those in mcontext_t.
*/
struct sigcontext {
sigset_t sc_mask; /* signal mask to restore */
int sc_onstack; /* sigstack state to restore */
int sc_gs;
int sc_fs;
int sc_es;
int sc_ds;
int sc_edi;
int sc_esi;
int sc_ebp;
int sc_isp;
int sc_ebx;
int sc_edx;
int sc_ecx;
int sc_eax;
int sc_trapno;
int sc_err;
int sc_eip;
int sc_cs;
int sc_efl;
int sc_esp; /* machine state */
int sc_ss;
};
#define sc_sp sc_esp
#define sc_fp sc_ebp
#define sc_pc sc_eip
#define sc_ps sc_efl
#define sc_eflags sc_efl
int sc_trapno;
int sc_err;
};
#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */

View File

@ -29,15 +29,22 @@
*/
#ifndef _MACHINE_UCONTEXT_H_
#define _MACHINE_UCONTEXT_H_ 1
#define _MACHINE_UCONTEXT_H_
#include <machine/frame.h>
typedef struct {
int mc_gs; /* %gs */
struct trapframe mc_tf; /* trapframe */
int mc_fpregs[28]; /* env87 + fpacc87 + u_long */
int __spare__[17];
typedef struct __mcontext {
/*
* The first 3 fields must match the definition of
* sigcontext. So that we can support sigcontext
* and ucontext_t at the same time.
*/
int mc_onstack; /* XXX - sigcontext compat. */
int mc_gs;
struct trapframe mc_tf;
int mc_fpregs[28]; /* env87 + fpacc87 + u_long */
int __spare__[17];
} mcontext_t;
#endif /* _MACHINE_UCONTEXT_H_ */
#endif /* !_MACHINE_UCONTEXT_H_ */

View File

@ -627,6 +627,7 @@ sendsig(catcher, sig, mask, code)
struct trapframe *regs;
struct sigacts *psp;
struct sigframe sf, *sfp;
int onstack;
p = curproc;
@ -637,17 +638,18 @@ sendsig(catcher, sig, mask, code)
regs = p->p_md.md_regs;
psp = p->p_sigacts;
onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
/* save user context */
bzero(&sf, sizeof(struct sigframe));
sf.sf_uc.uc_sigmask = *mask;
sf.sf_uc.uc_stack = psp->ps_sigstk;
sf.sf_uc.uc_mcontext.mc_onstack = onstack;
sf.sf_uc.uc_mcontext.mc_tf = *regs;
sf.sf_uc.uc_mcontext.mc_gs = rgs();
/* Allocate and validate space for the signal handler context. */
if ((psp->ps_flags & SAS_ALTSTACK) != 0 &&
(psp->ps_sigstk.ss_flags & SS_ONSTACK) == 0 &&
if ((psp->ps_flags & SAS_ALTSTACK) != 0 && !onstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
sfp = (struct sigframe *)(psp->ps_sigstk.ss_sp +
psp->ps_sigstk.ss_size - sizeof(struct sigframe));
@ -897,16 +899,13 @@ sigreturn(p, uap)
{
struct trapframe *regs;
ucontext_t *ucp;
struct sigframe *sfp;
int cs, eflags;
regs = p->p_md.md_regs;
ucp = uap->sigcntxp;
sfp = (struct sigframe *)
((caddr_t)ucp - offsetof(struct sigframe, sf_uc));
eflags = ucp->uc_mcontext.mc_tf.tf_eflags;
if (useracc((caddr_t)sfp, sizeof(struct sigframe), B_WRITE) == 0)
if (useracc((caddr_t)ucp, sizeof(ucontext_t), B_WRITE) == 0)
return(EFAULT);
if (eflags & PSL_VM) {
@ -976,7 +975,11 @@ sigreturn(p, uap)
*regs = ucp->uc_mcontext.mc_tf;
}
p->p_sigacts->ps_sigstk = ucp->uc_stack;
if (ucp->uc_mcontext.mc_onstack & 1)
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
p->p_sigmask = ucp->uc_sigmask;
SIG_CANTMASK(p->p_sigmask);
return(EJUSTRETURN);

View File

@ -627,6 +627,7 @@ sendsig(catcher, sig, mask, code)
struct trapframe *regs;
struct sigacts *psp;
struct sigframe sf, *sfp;
int onstack;
p = curproc;
@ -637,17 +638,18 @@ sendsig(catcher, sig, mask, code)
regs = p->p_md.md_regs;
psp = p->p_sigacts;
onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
/* save user context */
bzero(&sf, sizeof(struct sigframe));
sf.sf_uc.uc_sigmask = *mask;
sf.sf_uc.uc_stack = psp->ps_sigstk;
sf.sf_uc.uc_mcontext.mc_onstack = onstack;
sf.sf_uc.uc_mcontext.mc_tf = *regs;
sf.sf_uc.uc_mcontext.mc_gs = rgs();
/* Allocate and validate space for the signal handler context. */
if ((psp->ps_flags & SAS_ALTSTACK) != 0 &&
(psp->ps_sigstk.ss_flags & SS_ONSTACK) == 0 &&
if ((psp->ps_flags & SAS_ALTSTACK) != 0 && !onstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
sfp = (struct sigframe *)(psp->ps_sigstk.ss_sp +
psp->ps_sigstk.ss_size - sizeof(struct sigframe));
@ -897,16 +899,13 @@ sigreturn(p, uap)
{
struct trapframe *regs;
ucontext_t *ucp;
struct sigframe *sfp;
int cs, eflags;
regs = p->p_md.md_regs;
ucp = uap->sigcntxp;
sfp = (struct sigframe *)
((caddr_t)ucp - offsetof(struct sigframe, sf_uc));
eflags = ucp->uc_mcontext.mc_tf.tf_eflags;
if (useracc((caddr_t)sfp, sizeof(struct sigframe), B_WRITE) == 0)
if (useracc((caddr_t)ucp, sizeof(ucontext_t), B_WRITE) == 0)
return(EFAULT);
if (eflags & PSL_VM) {
@ -976,7 +975,11 @@ sigreturn(p, uap)
*regs = ucp->uc_mcontext.mc_tf;
}
p->p_sigacts->ps_sigstk = ucp->uc_stack;
if (ucp->uc_mcontext.mc_onstack & 1)
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
p->p_sigmask = ucp->uc_sigmask;
SIG_CANTMASK(p->p_sigmask);
return(EJUSTRETURN);

View File

@ -44,22 +44,20 @@
#include <sys/cdefs.h>
#include <sys/_posix.h>
#include <sys/types.h>
#include <machine/signal.h> /* sig_atomic_t; trap codes; sigcontext */
/*
* sigset_t macros
* sigset_t macros.
*/
#define _SIG_WORDS 4
#define _SIG_MAXSIG 128
#define _SIG_IDX(sig) ((sig) - 1)
#define _SIG_WORD(sig) (_SIG_IDX(sig) >> 5)
#define _SIG_BIT(sig) (1 << (_SIG_IDX(sig) & 31))
#define _SIG_WORDS 4
#define _SIG_MAXSIG 128
#define _SIG_IDX(sig) ((sig) - 1)
#define _SIG_WORD(sig) (_SIG_IDX(sig) >> 5)
#define _SIG_BIT(sig) (1 << (_SIG_IDX(sig) & 31))
/*
* system defined signals
* System defined signals.
*/
#define SIGHUP 1 /* hangup */
#define SIGHUP 1 /* hangup */
#define SIGINT 2 /* interrupt */
#define SIGQUIT 3 /* quit */
#define SIGILL 4 /* illegal instr. (not reset when caught) */
@ -98,11 +96,11 @@
#define SIGXFSZ 25 /* exceeded file size limit */
#define SIGVTALRM 26 /* virtual time alarm */
#define SIGPROF 27 /* profiling time alarm */
#define SIGWINCH 28 /* window size changes */
#define SIGINFO 29 /* information request */
#define SIGWINCH 28 /* window size changes */
#define SIGINFO 29 /* information request */
#endif
#define SIGUSR1 30 /* user defined signal 1 */
#define SIGUSR2 31 /* user defined signal 2 */
#define SIGUSR1 30 /* user defined signal 1 */
#define SIGUSR2 31 /* user defined signal 2 */
/*-
* Type of a signal handling function.
@ -124,50 +122,62 @@ typedef void __sighandler_t __P((int));
#define SIG_DFL ((__sighandler_t *)0)
#define SIG_IGN ((__sighandler_t *)1)
#define SIG_HOLD ((__sighandler_t *)2)
#define SIG_HOLD ((__sighandler_t *)2)
#define SIG_ERR ((__sighandler_t *)-1)
#ifndef _POSIX_SOURCE
union sigval {
/* Members as suggested by Annex C of POSIX 1003.1b. */
int sigval_int;
void *sigval_ptr;
int sigval_int;
void *sigval_ptr;
};
typedef struct {
int si_signo; /* signal number */
int si_errno; /* errno association */
typedef struct __siginfo {
int si_signo; /* signal number */
int si_errno; /* errno association */
/*
* Cause of signal, one of the SI_ macros or signal-specific
* values, i.e. one of the FPE_... values for SIGFPE. This
* value is equivalent to the second argument to an old-style
* FreeBSD signal handler.
*/
int si_code; /* signal code */
pid_t si_pid; /* sending process */
uid_t si_uid; /* sender's ruid */
int si_status; /* exit value */
void *si_addr; /* faulting instruction */
union sigval si_value; /* signal value */
long si_band; /* band event for SIGPOLL */
int __spare__[7]; /* gimme some slack */
int si_code; /* signal code */
int si_pid; /* sending process */
unsigned int si_uid; /* sender's ruid */
int si_status; /* exit value */
void *si_addr; /* faulting instruction */
union sigval si_value; /* signal value */
long si_band; /* band event for SIGPOLL */
int __spare__[7]; /* gimme some slack */
} siginfo_t;
#endif
typedef struct {
typedef struct __sigset {
unsigned int __bits[_SIG_WORDS];
} sigset_t;
/*
* XXX - there are some nasty dependencies.
* Now that sigset_t has been defined we can
* include the MD structures.
*/
#include <machine/signal.h> /* sig_atomic_t; trap codes; sigcontext */
#if !defined(_ANSI_SOURCE)
struct __siginfo;
/*
* Signal vector "template" used in sigaction call.
*/
struct sigaction {
union {
void (*__sa_handler) __P((int));
void (*__sa_sigaction) __P((int, siginfo_t *, void *));
void (*__sa_sigaction) __P((int, struct __siginfo *,
void *));
} __sigaction_u; /* signal handler */
int sa_flags; /* see signal options below */
sigset_t sa_mask; /* signal mask to apply */
int sa_flags; /* see signal options below */
sigset_t sa_mask; /* signal mask to apply */
};
/* if SA_SIGINFO is set, sa_sigaction is to be used instead of sa_handler. */
@ -189,7 +199,7 @@ struct sigaction {
#define SA_USERTRAMP 0x0100 /* do not bounce off kernel's sigtramp */
#endif
#define NSIG 32
#define NSIG 32 /* number of old signals (counting 0) */
/* POSIX 1003.1b required values. */
#define SI_USER 0x10001
@ -211,12 +221,12 @@ typedef _BSD_SIZE_T_ size_t;
#endif
/*
* sigaltstack
* Structure used in sigaltstack call.
*/
typedef struct sigaltstack {
char *ss_sp; /* signal stack base */
unsigned int ss_size; /* signal stack length */
int ss_flags; /* SS_DISABLE and/or SS_ONSTACK */
char *ss_sp; /* signal stack base */
size_t ss_size; /* signal stack length */
int ss_flags; /* SS_DISABLE and/or SS_ONSTACK */
} stack_t;
#define SS_ONSTACK 0x0001 /* take signal on alternate stack */
@ -224,9 +234,7 @@ typedef struct sigaltstack {
#define MINSIGSTKSZ 8192 /* minimum allowable stack */
#define SIGSTKSZ (MINSIGSTKSZ + 32768) /* recommended stack size */
/*
* Suck in definition of ucontext_t
*/
/* Have enough typedefs for this now. XXX */
#include <sys/ucontext.h>
/*
@ -234,9 +242,9 @@ typedef struct sigaltstack {
* Signal vector "template" used in sigvec call.
*/
struct sigvec {
__sighandler_t *sv_handler; /* signal handler */
int sv_mask; /* signal mask to apply */
int sv_flags; /* see signal options below */
__sighandler_t *sv_handler; /* signal handler */
int sv_mask; /* signal mask to apply */
int sv_flags; /* see signal options below */
};
#define SV_ONSTACK SA_ONSTACK
@ -251,8 +259,8 @@ struct sigvec {
* Structure used in sigstack call.
*/
struct sigstack {
char *ss_sp; /* signal stack pointer */
int ss_onstack; /* current status */
char *ss_sp; /* signal stack pointer */
int ss_onstack; /* current status */
};
/*
@ -272,14 +280,16 @@ struct sigstack {
#define SIG_UNBLOCK 2 /* unblock specified signal set */
#define SIG_SETMASK 3 /* set specified signal set */
#ifndef _POSIX_SOURCE
struct sigevent {
int sigev_notify; /* Notification type */
int sigev_signo; /* Signal number */
union sigval sigev_value; /* Signal value */
int sigev_notify; /* Notification type */
int sigev_signo; /* Signal number */
union sigval sigev_value; /* Signal value */
};
#define SIGEV_NONE 0 /* No async notification */
#define SIGEV_SIGNAL 1 /* Generate a queued signal */
#endif
#endif /* !_ANSI_SOURCE */

View File

@ -44,22 +44,20 @@
#include <sys/cdefs.h>
#include <sys/_posix.h>
#include <sys/types.h>
#include <machine/signal.h> /* sig_atomic_t; trap codes; sigcontext */
/*
* sigset_t macros
* sigset_t macros.
*/
#define _SIG_WORDS 4
#define _SIG_MAXSIG 128
#define _SIG_IDX(sig) ((sig) - 1)
#define _SIG_WORD(sig) (_SIG_IDX(sig) >> 5)
#define _SIG_BIT(sig) (1 << (_SIG_IDX(sig) & 31))
#define _SIG_WORDS 4
#define _SIG_MAXSIG 128
#define _SIG_IDX(sig) ((sig) - 1)
#define _SIG_WORD(sig) (_SIG_IDX(sig) >> 5)
#define _SIG_BIT(sig) (1 << (_SIG_IDX(sig) & 31))
/*
* system defined signals
* System defined signals.
*/
#define SIGHUP 1 /* hangup */
#define SIGHUP 1 /* hangup */
#define SIGINT 2 /* interrupt */
#define SIGQUIT 3 /* quit */
#define SIGILL 4 /* illegal instr. (not reset when caught) */
@ -98,11 +96,11 @@
#define SIGXFSZ 25 /* exceeded file size limit */
#define SIGVTALRM 26 /* virtual time alarm */
#define SIGPROF 27 /* profiling time alarm */
#define SIGWINCH 28 /* window size changes */
#define SIGINFO 29 /* information request */
#define SIGWINCH 28 /* window size changes */
#define SIGINFO 29 /* information request */
#endif
#define SIGUSR1 30 /* user defined signal 1 */
#define SIGUSR2 31 /* user defined signal 2 */
#define SIGUSR1 30 /* user defined signal 1 */
#define SIGUSR2 31 /* user defined signal 2 */
/*-
* Type of a signal handling function.
@ -124,50 +122,62 @@ typedef void __sighandler_t __P((int));
#define SIG_DFL ((__sighandler_t *)0)
#define SIG_IGN ((__sighandler_t *)1)
#define SIG_HOLD ((__sighandler_t *)2)
#define SIG_HOLD ((__sighandler_t *)2)
#define SIG_ERR ((__sighandler_t *)-1)
#ifndef _POSIX_SOURCE
union sigval {
/* Members as suggested by Annex C of POSIX 1003.1b. */
int sigval_int;
void *sigval_ptr;
int sigval_int;
void *sigval_ptr;
};
typedef struct {
int si_signo; /* signal number */
int si_errno; /* errno association */
typedef struct __siginfo {
int si_signo; /* signal number */
int si_errno; /* errno association */
/*
* Cause of signal, one of the SI_ macros or signal-specific
* values, i.e. one of the FPE_... values for SIGFPE. This
* value is equivalent to the second argument to an old-style
* FreeBSD signal handler.
*/
int si_code; /* signal code */
pid_t si_pid; /* sending process */
uid_t si_uid; /* sender's ruid */
int si_status; /* exit value */
void *si_addr; /* faulting instruction */
union sigval si_value; /* signal value */
long si_band; /* band event for SIGPOLL */
int __spare__[7]; /* gimme some slack */
int si_code; /* signal code */
int si_pid; /* sending process */
unsigned int si_uid; /* sender's ruid */
int si_status; /* exit value */
void *si_addr; /* faulting instruction */
union sigval si_value; /* signal value */
long si_band; /* band event for SIGPOLL */
int __spare__[7]; /* gimme some slack */
} siginfo_t;
#endif
typedef struct {
typedef struct __sigset {
unsigned int __bits[_SIG_WORDS];
} sigset_t;
/*
* XXX - there are some nasty dependencies.
* Now that sigset_t has been defined we can
* include the MD structures.
*/
#include <machine/signal.h> /* sig_atomic_t; trap codes; sigcontext */
#if !defined(_ANSI_SOURCE)
struct __siginfo;
/*
* Signal vector "template" used in sigaction call.
*/
struct sigaction {
union {
void (*__sa_handler) __P((int));
void (*__sa_sigaction) __P((int, siginfo_t *, void *));
void (*__sa_sigaction) __P((int, struct __siginfo *,
void *));
} __sigaction_u; /* signal handler */
int sa_flags; /* see signal options below */
sigset_t sa_mask; /* signal mask to apply */
int sa_flags; /* see signal options below */
sigset_t sa_mask; /* signal mask to apply */
};
/* if SA_SIGINFO is set, sa_sigaction is to be used instead of sa_handler. */
@ -189,7 +199,7 @@ struct sigaction {
#define SA_USERTRAMP 0x0100 /* do not bounce off kernel's sigtramp */
#endif
#define NSIG 32
#define NSIG 32 /* number of old signals (counting 0) */
/* POSIX 1003.1b required values. */
#define SI_USER 0x10001
@ -211,12 +221,12 @@ typedef _BSD_SIZE_T_ size_t;
#endif
/*
* sigaltstack
* Structure used in sigaltstack call.
*/
typedef struct sigaltstack {
char *ss_sp; /* signal stack base */
unsigned int ss_size; /* signal stack length */
int ss_flags; /* SS_DISABLE and/or SS_ONSTACK */
char *ss_sp; /* signal stack base */
size_t ss_size; /* signal stack length */
int ss_flags; /* SS_DISABLE and/or SS_ONSTACK */
} stack_t;
#define SS_ONSTACK 0x0001 /* take signal on alternate stack */
@ -224,9 +234,7 @@ typedef struct sigaltstack {
#define MINSIGSTKSZ 8192 /* minimum allowable stack */
#define SIGSTKSZ (MINSIGSTKSZ + 32768) /* recommended stack size */
/*
* Suck in definition of ucontext_t
*/
/* Have enough typedefs for this now. XXX */
#include <sys/ucontext.h>
/*
@ -234,9 +242,9 @@ typedef struct sigaltstack {
* Signal vector "template" used in sigvec call.
*/
struct sigvec {
__sighandler_t *sv_handler; /* signal handler */
int sv_mask; /* signal mask to apply */
int sv_flags; /* see signal options below */
__sighandler_t *sv_handler; /* signal handler */
int sv_mask; /* signal mask to apply */
int sv_flags; /* see signal options below */
};
#define SV_ONSTACK SA_ONSTACK
@ -251,8 +259,8 @@ struct sigvec {
* Structure used in sigstack call.
*/
struct sigstack {
char *ss_sp; /* signal stack pointer */
int ss_onstack; /* current status */
char *ss_sp; /* signal stack pointer */
int ss_onstack; /* current status */
};
/*
@ -272,14 +280,16 @@ struct sigstack {
#define SIG_UNBLOCK 2 /* unblock specified signal set */
#define SIG_SETMASK 3 /* set specified signal set */
#ifndef _POSIX_SOURCE
struct sigevent {
int sigev_notify; /* Notification type */
int sigev_signo; /* Signal number */
union sigval sigev_value; /* Signal value */
int sigev_notify; /* Notification type */
int sigev_signo; /* Signal number */
union sigval sigev_value; /* Signal value */
};
#define SIGEV_NONE 0 /* No async notification */
#define SIGEV_SIGNAL 1 /* Generate a queued signal */
#endif
#endif /* !_ANSI_SOURCE */

View File

@ -29,16 +29,25 @@
*/
#ifndef _SYS_UCONTEXT_H_
#define _SYS_UCONTEXT_H_ 1
#define _SYS_UCONTEXT_H_
#include <machine/ucontext.h>
typedef struct __ucontext {
struct __ucontext *uc_link;
stack_t uc_stack;
sigset_t uc_sigmask;
mcontext_t uc_mcontext;
int __spare__[8];
/*
* Keep the order of the first three fields. Also,
* keep them the first to fields in the structure.
* This way we can have a union with struct
* sigcontext and ucontext_t. This allows us to
* support them both at the same time.
* note: the union is not defined, though.
*/
sigset_t uc_sigmask;
stack_t uc_stack;
mcontext_t uc_mcontext;
struct __ucontext_t *uc_link;
int __spare__[8];
} ucontext_t;
#endif /* _SYS_UCONTEXT_H_ */
#endif /* !_SYS_UCONTEXT_H_ */