Add a per-signal flag to mark handlers registered with osigaction, so we
can provide the correct context to each signal handler. Fix broken sigsuspend(): don't use p_oldsigmask as a flag, use SAS_OLDMASK as we did before the linuxthreads support merge (submitted by bde). Move ps_sigstk from to p_sigacts to the main proc structure since signal stack should not be shared among threads. Move SAS_OLDMASK and SAS_ALTSTACK flags from sigacts::ps_flags to proc::p_flag. Move PS_NOCLDSTOP and PS_NOCLDWAIT flags from proc::p_flag to procsig::ps_flag. Reviewed by: marcel, jdp, bde
This commit is contained in:
parent
456b2f8063
commit
645682fd40
@ -1172,7 +1172,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
int oonstack, fsize, rndfsize;
|
||||
|
||||
frame = p->p_md.md_tf;
|
||||
oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
|
||||
oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
|
||||
fsize = sizeof ksi;
|
||||
rndfsize = ((fsize + 15) / 16) * 16;
|
||||
|
||||
@ -1183,11 +1183,11 @@ osendsig(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) && !oonstack &&
|
||||
if ((p->p_flag & P_ALTSTACK) && !oonstack &&
|
||||
SIGISMEMBER(psp->ps_sigonstack, sig)) {
|
||||
sip = (osiginfo_t *)((caddr_t)psp->ps_sigstk.ss_sp +
|
||||
psp->ps_sigstk.ss_size - rndfsize);
|
||||
psp->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
sip = (osiginfo_t *)((caddr_t)p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - rndfsize);
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
} else
|
||||
sip = (osiginfo_t *)(alpha_pal_rdusp() - rndfsize);
|
||||
|
||||
@ -1265,29 +1265,26 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
void
|
||||
sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
{
|
||||
struct proc *p;
|
||||
struct proc *p = curproc;
|
||||
struct trapframe *frame;
|
||||
struct sigacts *psp;
|
||||
struct sigacts *psp = p->p_sigacts;
|
||||
struct sigframe sf, *sfp;
|
||||
int onstack, rndfsize;
|
||||
int oonstack, rndfsize;
|
||||
|
||||
p = curproc;
|
||||
|
||||
if ((p->p_flag & P_NEWSIGSET) == 0) {
|
||||
if (SIGISMEMBER(psp->ps_osigset, sig)) {
|
||||
osendsig(catcher, sig, mask, code);
|
||||
return;
|
||||
}
|
||||
|
||||
frame = p->p_md.md_tf;
|
||||
psp = p->p_sigacts;
|
||||
onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
|
||||
oonstack = (p->p_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_onstack = onstack;
|
||||
sf.sf_uc.uc_stack = p->p_sigstk;
|
||||
sf.sf_uc.uc_mcontext.mc_onstack = oonstack;
|
||||
|
||||
fill_regs(p, (struct reg *)sf.sf_uc.uc_mcontext.mc_regs);
|
||||
sf.sf_uc.uc_mcontext.mc_regs[R_SP] = alpha_pal_rdusp();
|
||||
@ -1308,11 +1305,11 @@ 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 && !onstack &&
|
||||
if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack &&
|
||||
SIGISMEMBER(psp->ps_sigonstack, sig)) {
|
||||
sfp = (struct sigframe *)((caddr_t)psp->ps_sigstk.ss_sp +
|
||||
psp->ps_sigstk.ss_size - rndfsize);
|
||||
psp->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
sfp = (struct sigframe *)((caddr_t)p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - rndfsize);
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
} else
|
||||
sfp = (struct sigframe *)(alpha_pal_rdusp() - rndfsize);
|
||||
|
||||
@ -1438,20 +1435,16 @@ osigreturn(struct proc *p,
|
||||
* Restore the user-supplied information
|
||||
*/
|
||||
if (ksc.sc_onstack)
|
||||
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
else
|
||||
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
|
||||
/*
|
||||
* longjmp is still implemented by calling osigreturn. The new
|
||||
* sigmask is stored in sc_reserved, sc_mask is only used for
|
||||
* backward compatibility.
|
||||
*/
|
||||
if ((p->p_flag & P_NEWSIGSET) == 0) {
|
||||
OSIG2SIG(ksc.sc_mask, p->p_sigmask);
|
||||
}
|
||||
else
|
||||
p->p_sigmask = *((sigset_t *)(&ksc.sc_reserved[0]));
|
||||
SIGSETOLD(p->p_sigmask, ksc.sc_mask);
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
|
||||
set_regs(p, (struct reg *)ksc.sc_regs);
|
||||
@ -1480,11 +1473,10 @@ sigreturn(struct proc *p,
|
||||
struct pcb *pcb;
|
||||
unsigned long val;
|
||||
|
||||
if (((struct osigcontext*)uap->sigcntxp)->sc_regs[R_ZERO] == 0xACEDBADE)
|
||||
return osigreturn(p, (struct osigreturn_args *)uap);
|
||||
|
||||
ucp = uap->sigcntxp;
|
||||
|
||||
if ((p->p_flag & P_NEWSIGSET) == 0)
|
||||
return (osigreturn(p, (struct osigreturn_args *)uap));
|
||||
|
||||
pcb = &p->p_addr->u_pcb;
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -1514,9 +1506,9 @@ sigreturn(struct proc *p,
|
||||
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;
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
else
|
||||
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
|
||||
p->p_sigmask = uc.uc_sigmask;
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
|
@ -198,7 +198,7 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
int oonstack;
|
||||
|
||||
regs = p->p_md.md_regs;
|
||||
oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
|
||||
oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Linux-emul(%ld): linux_sendsig(%p, %d, %p, %lu)\n",
|
||||
@ -207,11 +207,11 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
/*
|
||||
* Allocate space for the signal handler context.
|
||||
*/
|
||||
if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
|
||||
if ((p->p_flag & P_ALTSTACK) && !oonstack &&
|
||||
SIGISMEMBER(psp->ps_sigonstack, sig)) {
|
||||
fp = (struct linux_sigframe *)(psp->ps_sigstk.ss_sp +
|
||||
psp->ps_sigstk.ss_size - sizeof(struct linux_sigframe));
|
||||
psp->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
fp = (struct linux_sigframe *)(p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - sizeof(struct linux_sigframe));
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
} else {
|
||||
fp = (struct linux_sigframe *)regs->tf_esp - 1;
|
||||
}
|
||||
@ -287,6 +287,7 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
regs->tf_ds = _udatasel;
|
||||
regs->tf_es = _udatasel;
|
||||
regs->tf_fs = _udatasel;
|
||||
load_gs(_udatasel);
|
||||
regs->tf_ss = _udatasel;
|
||||
}
|
||||
|
||||
@ -354,12 +355,9 @@ linux_sigreturn(p, args)
|
||||
return(EINVAL);
|
||||
}
|
||||
|
||||
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
SIGEMPTYSET(p->p_sigmask);
|
||||
p->p_sigmask.__bits[0] = context.sc_mask;
|
||||
SIGDELSET(p->p_sigmask, SIGKILL);
|
||||
SIGDELSET(p->p_sigmask, SIGCONT);
|
||||
SIGDELSET(p->p_sigmask, SIGSTOP);
|
||||
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
SIGSETOLD(p->p_sigmask, context.sc_mask);
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
|
||||
/*
|
||||
* Restore signal context.
|
||||
|
@ -148,8 +148,18 @@ main()
|
||||
printf("#define\tTF_EFLAGS %#x\n", OS(trapframe, tf_eflags));
|
||||
|
||||
printf("#define\tSIGF_HANDLER %#x\n", OS(sigframe, sf_ahu.sf_handler));
|
||||
printf("#define\tSIGF_SC %#x\n", OS(osigframe, sf_siginfo.si_sc));
|
||||
printf("#define\tSIGF_UC %#x\n", OS(sigframe, sf_uc));
|
||||
|
||||
printf("#define\tSC_PS %#x\n", OS(osigcontext, sc_ps));
|
||||
printf("#define\tSC_FS %#x\n", OS(osigcontext, sc_fs));
|
||||
printf("#define\tSC_GS %#x\n", OS(osigcontext, sc_gs));
|
||||
printf("#define\tSC_TRAPNO %#x\n", OS(osigcontext, sc_trapno));
|
||||
|
||||
printf("#define\tUC_EFLAGS %#x\n",
|
||||
OS(__ucontext, uc_mcontext.mc_eflags));
|
||||
printf("#define\tUC_GS %#x\n", OS(__ucontext, uc_mcontext.mc_gs));
|
||||
|
||||
printf("#define\tB_READ %#x\n", B_READ);
|
||||
printf("#define\tENOENT %d\n", ENOENT);
|
||||
printf("#define\tEFAULT %d\n", EFAULT);
|
||||
|
@ -417,19 +417,39 @@ NON_GPROF_ENTRY(sigcode)
|
||||
call SIGF_HANDLER(%esp) /* call signal handler */
|
||||
lea SIGF_UC(%esp),%eax /* get ucontext_t */
|
||||
pushl %eax
|
||||
movl $SYS_osigreturn,%eax
|
||||
testl $PSL_VM,UC_EFLAGS(%eax)
|
||||
jne 9f
|
||||
movl UC_GS(%eax),%gs /* restore %gs */
|
||||
9:
|
||||
movl $SYS_sigreturn,%eax
|
||||
pushl %eax /* junk to fake return addr. */
|
||||
int $0x80 /* enter kernel with args */
|
||||
/* on stack */
|
||||
1:
|
||||
jmp 1b
|
||||
0: jmp 0b
|
||||
|
||||
ALIGN_TEXT
|
||||
_osigcode:
|
||||
call SIGF_HANDLER(%esp) /* call signal handler */
|
||||
lea SIGF_SC(%esp),%eax /* get sigcontext */
|
||||
pushl %eax
|
||||
testl $PSL_VM,SC_PS(%eax)
|
||||
jne 9f
|
||||
movl SC_GS(%eax),%gs /* restore %gs */
|
||||
9:
|
||||
movl $0x01d516,SC_TRAPNO(%eax) /* magic: 0ldSiG */
|
||||
movl $SYS_sigreturn,%eax
|
||||
pushl %eax /* junk to fake return addr. */
|
||||
int $0x80 /* enter kernel with args */
|
||||
0: jmp 0b
|
||||
|
||||
ALIGN_TEXT
|
||||
_esigcode:
|
||||
|
||||
.data
|
||||
.globl _szsigcode
|
||||
.globl _szsigcode, _oszsigcode
|
||||
_szsigcode:
|
||||
.long _esigcode-_sigcode
|
||||
_oszsigcode:
|
||||
.long _esigcode-_osigcode
|
||||
.text
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -417,19 +417,39 @@ NON_GPROF_ENTRY(sigcode)
|
||||
call SIGF_HANDLER(%esp) /* call signal handler */
|
||||
lea SIGF_UC(%esp),%eax /* get ucontext_t */
|
||||
pushl %eax
|
||||
movl $SYS_osigreturn,%eax
|
||||
testl $PSL_VM,UC_EFLAGS(%eax)
|
||||
jne 9f
|
||||
movl UC_GS(%eax),%gs /* restore %gs */
|
||||
9:
|
||||
movl $SYS_sigreturn,%eax
|
||||
pushl %eax /* junk to fake return addr. */
|
||||
int $0x80 /* enter kernel with args */
|
||||
/* on stack */
|
||||
1:
|
||||
jmp 1b
|
||||
0: jmp 0b
|
||||
|
||||
ALIGN_TEXT
|
||||
_osigcode:
|
||||
call SIGF_HANDLER(%esp) /* call signal handler */
|
||||
lea SIGF_SC(%esp),%eax /* get sigcontext */
|
||||
pushl %eax
|
||||
testl $PSL_VM,SC_PS(%eax)
|
||||
jne 9f
|
||||
movl SC_GS(%eax),%gs /* restore %gs */
|
||||
9:
|
||||
movl $0x01d516,SC_TRAPNO(%eax) /* magic: 0ldSiG */
|
||||
movl $SYS_sigreturn,%eax
|
||||
pushl %eax /* junk to fake return addr. */
|
||||
int $0x80 /* enter kernel with args */
|
||||
0: jmp 0b
|
||||
|
||||
ALIGN_TEXT
|
||||
_esigcode:
|
||||
|
||||
.data
|
||||
.globl _szsigcode
|
||||
.globl _szsigcode, _oszsigcode
|
||||
_szsigcode:
|
||||
.long _esigcode-_sigcode
|
||||
_oszsigcode:
|
||||
.long _esigcode-_osigcode
|
||||
.text
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -483,14 +483,14 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
int oonstack;
|
||||
|
||||
regs = p->p_md.md_regs;
|
||||
oonstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
|
||||
oonstack = (p->p_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
|
||||
|
||||
/* Allocate and validate space for the signal handler context. */
|
||||
if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
|
||||
if ((p->p_flag & P_ALTSTACK) && !oonstack &&
|
||||
SIGISMEMBER(psp->ps_sigonstack, sig)) {
|
||||
fp = (struct osigframe *)(psp->ps_sigstk.ss_sp +
|
||||
psp->ps_sigstk.ss_size - sizeof(struct osigframe));
|
||||
psp->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
fp = (struct osigframe *)(p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - sizeof(struct osigframe));
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
}
|
||||
else
|
||||
fp = (struct osigframe *)regs->tf_esp - 1;
|
||||
@ -594,7 +594,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
}
|
||||
|
||||
regs->tf_esp = (int)fp;
|
||||
regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
|
||||
regs->tf_eip = PS_STRINGS - oszsigcode;
|
||||
regs->tf_cs = _ucodesel;
|
||||
regs->tf_ds = _udatasel;
|
||||
regs->tf_es = _udatasel;
|
||||
@ -610,37 +610,34 @@ sendsig(catcher, sig, mask, code)
|
||||
sigset_t *mask;
|
||||
u_long code;
|
||||
{
|
||||
struct proc *p;
|
||||
struct proc *p = curproc;
|
||||
struct trapframe *regs;
|
||||
struct sigacts *psp;
|
||||
struct sigacts *psp = p->p_sigacts;
|
||||
struct sigframe sf, *sfp;
|
||||
int onstack;
|
||||
int oonstack;
|
||||
|
||||
p = curproc;
|
||||
|
||||
if ((p->p_flag & P_NEWSIGSET) == 0) {
|
||||
if (SIGISMEMBER(psp->ps_osigset, sig)) {
|
||||
osendsig(catcher, sig, mask, code);
|
||||
return;
|
||||
}
|
||||
|
||||
regs = p->p_md.md_regs;
|
||||
psp = p->p_sigacts;
|
||||
onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
|
||||
oonstack = (p->p_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_stack = p->p_sigstk;
|
||||
sf.sf_uc.uc_mcontext.mc_onstack = oonstack;
|
||||
sf.sf_uc.uc_mcontext.mc_gs = rgs();
|
||||
bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(struct trapframe));
|
||||
|
||||
/* Allocate and validate space for the signal handler context. */
|
||||
if ((psp->ps_flags & SAS_ALTSTACK) != 0 && !onstack &&
|
||||
if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack &&
|
||||
SIGISMEMBER(psp->ps_sigonstack, sig)) {
|
||||
sfp = (struct sigframe *)(psp->ps_sigstk.ss_sp +
|
||||
psp->ps_sigstk.ss_size - sizeof(struct sigframe));
|
||||
psp->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
sfp = (struct sigframe *)(p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - sizeof(struct sigframe));
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
}
|
||||
else
|
||||
sfp = (struct sigframe *)regs->tf_esp - 1;
|
||||
@ -770,9 +767,6 @@ osigreturn(p, uap)
|
||||
register struct trapframe *regs = p->p_md.md_regs;
|
||||
int eflags;
|
||||
|
||||
if ((p->p_flag & P_NEWSIGSET) != 0)
|
||||
return sigreturn(p, (struct sigreturn_args *)uap);
|
||||
|
||||
scp = uap->sigcntxp;
|
||||
|
||||
if (useracc((caddr_t)scp, sizeof (struct osigcontext), B_WRITE) == 0)
|
||||
@ -841,10 +835,6 @@ osigreturn(p, uap)
|
||||
regs->tf_ds = scp->sc_ds;
|
||||
regs->tf_es = scp->sc_es;
|
||||
regs->tf_fs = scp->sc_fs;
|
||||
if (load_gs_param(scp->sc_gs)) {
|
||||
trapsignal(p, SIGBUS, T_SEGNPFLT);
|
||||
return (EFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
/* restore scratch registers */
|
||||
@ -859,11 +849,11 @@ osigreturn(p, uap)
|
||||
regs->tf_isp = scp->sc_isp;
|
||||
|
||||
if (scp->sc_onstack & 01)
|
||||
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
else
|
||||
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
|
||||
OSIG2SIG(scp->sc_mask, p->p_sigmask);
|
||||
SIGSETOLD(p->p_sigmask, scp->sc_mask);
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
regs->tf_ebp = scp->sc_fp;
|
||||
regs->tf_esp = scp->sc_sp;
|
||||
@ -883,7 +873,8 @@ sigreturn(p, uap)
|
||||
ucontext_t *ucp;
|
||||
int cs, eflags;
|
||||
|
||||
p->p_flag |= P_NEWSIGSET;
|
||||
if (((struct osigcontext *)uap->sigcntxp)->sc_trapno == 0x01d516)
|
||||
return osigreturn(p, (struct osigreturn_args *)uap);
|
||||
|
||||
regs = p->p_md.md_regs;
|
||||
ucp = uap->sigcntxp;
|
||||
@ -956,16 +947,12 @@ sigreturn(p, uap)
|
||||
return(EINVAL);
|
||||
}
|
||||
bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(struct trapframe));
|
||||
if (load_gs_param(ucp->uc_mcontext.mc_gs)) {
|
||||
trapsignal(p, SIGBUS, T_SEGNPFLT);
|
||||
return (EFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
if (ucp->uc_mcontext.mc_onstack & 1)
|
||||
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
else
|
||||
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
|
||||
p->p_sigmask = ucp->uc_sigmask;
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
|
@ -1586,21 +1586,6 @@ ENTRY(load_cr4)
|
||||
movl %eax,%cr4
|
||||
ret
|
||||
|
||||
/* int load_gs_param(caddr_t gs) */
|
||||
ENTRY(load_gs_param)
|
||||
movl _curpcb,%ecx
|
||||
movl $load_gs_param_fault,PCB_ONFAULT(%ecx)
|
||||
movl 4(%esp),%eax
|
||||
movl %eax,%gs
|
||||
xor %eax,%eax
|
||||
movl %eax,PCB_ONFAULT(%ecx)
|
||||
ret
|
||||
load_gs_param_fault:
|
||||
movl _curpcb,%ecx
|
||||
movl $0,PCB_ONFAULT(%ecx)
|
||||
movl $EFAULT,%eax
|
||||
ret
|
||||
|
||||
/*****************************************************************************/
|
||||
/* setjump, longjump */
|
||||
/*****************************************************************************/
|
||||
|
@ -1586,21 +1586,6 @@ ENTRY(load_cr4)
|
||||
movl %eax,%cr4
|
||||
ret
|
||||
|
||||
/* int load_gs_param(caddr_t gs) */
|
||||
ENTRY(load_gs_param)
|
||||
movl _curpcb,%ecx
|
||||
movl $load_gs_param_fault,PCB_ONFAULT(%ecx)
|
||||
movl 4(%esp),%eax
|
||||
movl %eax,%gs
|
||||
xor %eax,%eax
|
||||
movl %eax,PCB_ONFAULT(%ecx)
|
||||
ret
|
||||
load_gs_param_fault:
|
||||
movl _curpcb,%ecx
|
||||
movl $0,PCB_ONFAULT(%ecx)
|
||||
movl $EFAULT,%eax
|
||||
ret
|
||||
|
||||
/*****************************************************************************/
|
||||
/* setjump, longjump */
|
||||
/*****************************************************************************/
|
||||
|
@ -58,7 +58,7 @@ extern void (*netisrs[32]) __P((void));
|
||||
extern int nfs_diskless_valid;
|
||||
extern void (*ovbcopy_vector) __P((const void *from, void *to, size_t len));
|
||||
extern char sigcode[];
|
||||
extern int szsigcode;
|
||||
extern int szsigcode, oszsigcode;
|
||||
|
||||
typedef void alias_for_inthand_t __P((u_int cs, u_int ef, u_int esp, u_int ss));
|
||||
struct proc;
|
||||
@ -91,7 +91,6 @@ int i586_copyout __P((const void *kaddr, void *udaddr, size_t len));
|
||||
void i686_pagezero __P((void *addr));
|
||||
int is_physical_memory __P((vm_offset_t addr));
|
||||
u_long kvtop __P((void *addr));
|
||||
int load_gs_param __P((u_int sel));
|
||||
void setidt __P((int idx, alias_for_inthand_t *func, int typ, int dpl,
|
||||
int selec));
|
||||
void swi_vm __P((void));
|
||||
|
@ -31,8 +31,6 @@
|
||||
#ifndef _MACHINE_UCONTEXT_H_
|
||||
#define _MACHINE_UCONTEXT_H_
|
||||
|
||||
#include <machine/frame.h>
|
||||
|
||||
typedef struct __mcontext {
|
||||
/*
|
||||
* The first 20 fields must match the definition of
|
||||
|
@ -602,7 +602,7 @@ svr4_sys_context(p, uap)
|
||||
case 0:
|
||||
DPRINTF(("getcontext(%p)\n", uap->uc));
|
||||
svr4_getcontext(p, &uc, &p->p_sigmask,
|
||||
p->p_sigacts->ps_sigstk.ss_flags & SS_ONSTACK);
|
||||
p->p_sigstk.ss_flags & SS_ONSTACK);
|
||||
return copyout(&uc, uap->uc, sizeof(uc));
|
||||
|
||||
case 1:
|
||||
|
@ -148,8 +148,18 @@ main()
|
||||
printf("#define\tTF_EFLAGS %#x\n", OS(trapframe, tf_eflags));
|
||||
|
||||
printf("#define\tSIGF_HANDLER %#x\n", OS(sigframe, sf_ahu.sf_handler));
|
||||
printf("#define\tSIGF_SC %#x\n", OS(osigframe, sf_siginfo.si_sc));
|
||||
printf("#define\tSIGF_UC %#x\n", OS(sigframe, sf_uc));
|
||||
|
||||
printf("#define\tSC_PS %#x\n", OS(osigcontext, sc_ps));
|
||||
printf("#define\tSC_FS %#x\n", OS(osigcontext, sc_fs));
|
||||
printf("#define\tSC_GS %#x\n", OS(osigcontext, sc_gs));
|
||||
printf("#define\tSC_TRAPNO %#x\n", OS(osigcontext, sc_trapno));
|
||||
|
||||
printf("#define\tUC_EFLAGS %#x\n",
|
||||
OS(__ucontext, uc_mcontext.mc_eflags));
|
||||
printf("#define\tUC_GS %#x\n", OS(__ucontext, uc_mcontext.mc_gs));
|
||||
|
||||
printf("#define\tB_READ %#x\n", B_READ);
|
||||
printf("#define\tENOENT %d\n", ENOENT);
|
||||
printf("#define\tEFAULT %d\n", EFAULT);
|
||||
|
@ -417,19 +417,39 @@ NON_GPROF_ENTRY(sigcode)
|
||||
call SIGF_HANDLER(%esp) /* call signal handler */
|
||||
lea SIGF_UC(%esp),%eax /* get ucontext_t */
|
||||
pushl %eax
|
||||
movl $SYS_osigreturn,%eax
|
||||
testl $PSL_VM,UC_EFLAGS(%eax)
|
||||
jne 9f
|
||||
movl UC_GS(%eax),%gs /* restore %gs */
|
||||
9:
|
||||
movl $SYS_sigreturn,%eax
|
||||
pushl %eax /* junk to fake return addr. */
|
||||
int $0x80 /* enter kernel with args */
|
||||
/* on stack */
|
||||
1:
|
||||
jmp 1b
|
||||
0: jmp 0b
|
||||
|
||||
ALIGN_TEXT
|
||||
_osigcode:
|
||||
call SIGF_HANDLER(%esp) /* call signal handler */
|
||||
lea SIGF_SC(%esp),%eax /* get sigcontext */
|
||||
pushl %eax
|
||||
testl $PSL_VM,SC_PS(%eax)
|
||||
jne 9f
|
||||
movl SC_GS(%eax),%gs /* restore %gs */
|
||||
9:
|
||||
movl $0x01d516,SC_TRAPNO(%eax) /* magic: 0ldSiG */
|
||||
movl $SYS_sigreturn,%eax
|
||||
pushl %eax /* junk to fake return addr. */
|
||||
int $0x80 /* enter kernel with args */
|
||||
0: jmp 0b
|
||||
|
||||
ALIGN_TEXT
|
||||
_esigcode:
|
||||
|
||||
.data
|
||||
.globl _szsigcode
|
||||
.globl _szsigcode, _oszsigcode
|
||||
_szsigcode:
|
||||
.long _esigcode-_sigcode
|
||||
_oszsigcode:
|
||||
.long _esigcode-_osigcode
|
||||
.text
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -483,14 +483,14 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
int oonstack;
|
||||
|
||||
regs = p->p_md.md_regs;
|
||||
oonstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
|
||||
oonstack = (p->p_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
|
||||
|
||||
/* Allocate and validate space for the signal handler context. */
|
||||
if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
|
||||
if ((p->p_flag & P_ALTSTACK) && !oonstack &&
|
||||
SIGISMEMBER(psp->ps_sigonstack, sig)) {
|
||||
fp = (struct osigframe *)(psp->ps_sigstk.ss_sp +
|
||||
psp->ps_sigstk.ss_size - sizeof(struct osigframe));
|
||||
psp->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
fp = (struct osigframe *)(p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - sizeof(struct osigframe));
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
}
|
||||
else
|
||||
fp = (struct osigframe *)regs->tf_esp - 1;
|
||||
@ -594,7 +594,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
}
|
||||
|
||||
regs->tf_esp = (int)fp;
|
||||
regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
|
||||
regs->tf_eip = PS_STRINGS - oszsigcode;
|
||||
regs->tf_cs = _ucodesel;
|
||||
regs->tf_ds = _udatasel;
|
||||
regs->tf_es = _udatasel;
|
||||
@ -610,37 +610,34 @@ sendsig(catcher, sig, mask, code)
|
||||
sigset_t *mask;
|
||||
u_long code;
|
||||
{
|
||||
struct proc *p;
|
||||
struct proc *p = curproc;
|
||||
struct trapframe *regs;
|
||||
struct sigacts *psp;
|
||||
struct sigacts *psp = p->p_sigacts;
|
||||
struct sigframe sf, *sfp;
|
||||
int onstack;
|
||||
int oonstack;
|
||||
|
||||
p = curproc;
|
||||
|
||||
if ((p->p_flag & P_NEWSIGSET) == 0) {
|
||||
if (SIGISMEMBER(psp->ps_osigset, sig)) {
|
||||
osendsig(catcher, sig, mask, code);
|
||||
return;
|
||||
}
|
||||
|
||||
regs = p->p_md.md_regs;
|
||||
psp = p->p_sigacts;
|
||||
onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
|
||||
oonstack = (p->p_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_stack = p->p_sigstk;
|
||||
sf.sf_uc.uc_mcontext.mc_onstack = oonstack;
|
||||
sf.sf_uc.uc_mcontext.mc_gs = rgs();
|
||||
bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(struct trapframe));
|
||||
|
||||
/* Allocate and validate space for the signal handler context. */
|
||||
if ((psp->ps_flags & SAS_ALTSTACK) != 0 && !onstack &&
|
||||
if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack &&
|
||||
SIGISMEMBER(psp->ps_sigonstack, sig)) {
|
||||
sfp = (struct sigframe *)(psp->ps_sigstk.ss_sp +
|
||||
psp->ps_sigstk.ss_size - sizeof(struct sigframe));
|
||||
psp->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
sfp = (struct sigframe *)(p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - sizeof(struct sigframe));
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
}
|
||||
else
|
||||
sfp = (struct sigframe *)regs->tf_esp - 1;
|
||||
@ -770,9 +767,6 @@ osigreturn(p, uap)
|
||||
register struct trapframe *regs = p->p_md.md_regs;
|
||||
int eflags;
|
||||
|
||||
if ((p->p_flag & P_NEWSIGSET) != 0)
|
||||
return sigreturn(p, (struct sigreturn_args *)uap);
|
||||
|
||||
scp = uap->sigcntxp;
|
||||
|
||||
if (useracc((caddr_t)scp, sizeof (struct osigcontext), B_WRITE) == 0)
|
||||
@ -841,10 +835,6 @@ osigreturn(p, uap)
|
||||
regs->tf_ds = scp->sc_ds;
|
||||
regs->tf_es = scp->sc_es;
|
||||
regs->tf_fs = scp->sc_fs;
|
||||
if (load_gs_param(scp->sc_gs)) {
|
||||
trapsignal(p, SIGBUS, T_SEGNPFLT);
|
||||
return (EFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
/* restore scratch registers */
|
||||
@ -859,11 +849,11 @@ osigreturn(p, uap)
|
||||
regs->tf_isp = scp->sc_isp;
|
||||
|
||||
if (scp->sc_onstack & 01)
|
||||
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
else
|
||||
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
|
||||
OSIG2SIG(scp->sc_mask, p->p_sigmask);
|
||||
SIGSETOLD(p->p_sigmask, scp->sc_mask);
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
regs->tf_ebp = scp->sc_fp;
|
||||
regs->tf_esp = scp->sc_sp;
|
||||
@ -883,7 +873,8 @@ sigreturn(p, uap)
|
||||
ucontext_t *ucp;
|
||||
int cs, eflags;
|
||||
|
||||
p->p_flag |= P_NEWSIGSET;
|
||||
if (((struct osigcontext *)uap->sigcntxp)->sc_trapno == 0x01d516)
|
||||
return osigreturn(p, (struct osigreturn_args *)uap);
|
||||
|
||||
regs = p->p_md.md_regs;
|
||||
ucp = uap->sigcntxp;
|
||||
@ -956,16 +947,12 @@ sigreturn(p, uap)
|
||||
return(EINVAL);
|
||||
}
|
||||
bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(struct trapframe));
|
||||
if (load_gs_param(ucp->uc_mcontext.mc_gs)) {
|
||||
trapsignal(p, SIGBUS, T_SEGNPFLT);
|
||||
return (EFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
if (ucp->uc_mcontext.mc_onstack & 1)
|
||||
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
else
|
||||
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
|
||||
p->p_sigmask = ucp->uc_sigmask;
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
|
@ -1586,21 +1586,6 @@ ENTRY(load_cr4)
|
||||
movl %eax,%cr4
|
||||
ret
|
||||
|
||||
/* int load_gs_param(caddr_t gs) */
|
||||
ENTRY(load_gs_param)
|
||||
movl _curpcb,%ecx
|
||||
movl $load_gs_param_fault,PCB_ONFAULT(%ecx)
|
||||
movl 4(%esp),%eax
|
||||
movl %eax,%gs
|
||||
xor %eax,%eax
|
||||
movl %eax,PCB_ONFAULT(%ecx)
|
||||
ret
|
||||
load_gs_param_fault:
|
||||
movl _curpcb,%ecx
|
||||
movl $0,PCB_ONFAULT(%ecx)
|
||||
movl $EFAULT,%eax
|
||||
ret
|
||||
|
||||
/*****************************************************************************/
|
||||
/* setjump, longjump */
|
||||
/*****************************************************************************/
|
||||
|
@ -258,6 +258,7 @@
|
||||
#define _normalize_nuo normalize_nuo
|
||||
#define _npx_intr npx_intr
|
||||
#define _npxsave npxsave
|
||||
#define _oszsigcode oszsigcode
|
||||
#define _ovbcopy_vector ovbcopy_vector
|
||||
#define _panic panic
|
||||
#define _pc98_system_parameter pc98_system_parameter
|
||||
|
@ -58,7 +58,7 @@ extern void (*netisrs[32]) __P((void));
|
||||
extern int nfs_diskless_valid;
|
||||
extern void (*ovbcopy_vector) __P((const void *from, void *to, size_t len));
|
||||
extern char sigcode[];
|
||||
extern int szsigcode;
|
||||
extern int szsigcode, oszsigcode;
|
||||
|
||||
typedef void alias_for_inthand_t __P((u_int cs, u_int ef, u_int esp, u_int ss));
|
||||
struct proc;
|
||||
@ -91,7 +91,6 @@ int i586_copyout __P((const void *kaddr, void *udaddr, size_t len));
|
||||
void i686_pagezero __P((void *addr));
|
||||
int is_physical_memory __P((vm_offset_t addr));
|
||||
u_long kvtop __P((void *addr));
|
||||
int load_gs_param __P((u_int sel));
|
||||
void setidt __P((int idx, alias_for_inthand_t *func, int typ, int dpl,
|
||||
int selec));
|
||||
void swi_vm __P((void));
|
||||
|
@ -31,8 +31,6 @@
|
||||
#ifndef _MACHINE_UCONTEXT_H_
|
||||
#define _MACHINE_UCONTEXT_H_
|
||||
|
||||
#include <machine/frame.h>
|
||||
|
||||
typedef struct __mcontext {
|
||||
/*
|
||||
* The first 20 fields must match the definition of
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#include "linux_assym.h" /* system definitions */
|
||||
#include <machine/asmacros.h> /* miscellaneous asm macros */
|
||||
|
||||
@ -6,12 +8,11 @@
|
||||
NON_GPROF_ENTRY(linux_sigcode)
|
||||
call LINUX_SIGF_HANDLER(%esp)
|
||||
leal LINUX_SIGF_SC(%esp),%ebx /* linux scp */
|
||||
movl LINUX_SC_GS(%ebx),%edx
|
||||
movl %dx,%gs
|
||||
movl LINUX_SC_GS(%ebx),%gs
|
||||
push %eax /* fake ret addr */
|
||||
movl $LINUX_SYS_linux_sigreturn,%eax /* linux_sigreturn() */
|
||||
int $0x80 /* enter kernel with args on stack */
|
||||
hlt /* never gets here */
|
||||
int $0x80 /* enter kernel with args */
|
||||
0: jmp 0b
|
||||
ALIGN_TEXT
|
||||
_linux_esigcode:
|
||||
|
||||
|
@ -198,7 +198,7 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
int oonstack;
|
||||
|
||||
regs = p->p_md.md_regs;
|
||||
oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
|
||||
oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Linux-emul(%ld): linux_sendsig(%p, %d, %p, %lu)\n",
|
||||
@ -207,11 +207,11 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
/*
|
||||
* Allocate space for the signal handler context.
|
||||
*/
|
||||
if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
|
||||
if ((p->p_flag & P_ALTSTACK) && !oonstack &&
|
||||
SIGISMEMBER(psp->ps_sigonstack, sig)) {
|
||||
fp = (struct linux_sigframe *)(psp->ps_sigstk.ss_sp +
|
||||
psp->ps_sigstk.ss_size - sizeof(struct linux_sigframe));
|
||||
psp->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
fp = (struct linux_sigframe *)(p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - sizeof(struct linux_sigframe));
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
} else {
|
||||
fp = (struct linux_sigframe *)regs->tf_esp - 1;
|
||||
}
|
||||
@ -287,6 +287,7 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
regs->tf_ds = _udatasel;
|
||||
regs->tf_es = _udatasel;
|
||||
regs->tf_fs = _udatasel;
|
||||
load_gs(_udatasel);
|
||||
regs->tf_ss = _udatasel;
|
||||
}
|
||||
|
||||
@ -354,12 +355,9 @@ linux_sigreturn(p, args)
|
||||
return(EINVAL);
|
||||
}
|
||||
|
||||
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
SIGEMPTYSET(p->p_sigmask);
|
||||
p->p_sigmask.__bits[0] = context.sc_mask;
|
||||
SIGDELSET(p->p_sigmask, SIGKILL);
|
||||
SIGDELSET(p->p_sigmask, SIGCONT);
|
||||
SIGDELSET(p->p_sigmask, SIGSTOP);
|
||||
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
SIGSETOLD(p->p_sigmask, context.sc_mask);
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
|
||||
/*
|
||||
* Restore signal context.
|
||||
|
@ -9,20 +9,16 @@ NON_GPROF_ENTRY(svr4_sigcode)
|
||||
call SVR4_SIGF_HANDLER(%esp)
|
||||
leal SVR4_SIGF_UC(%esp),%eax # ucp (the call may have clobbered the
|
||||
# copy at SIGF_UCP(%esp))
|
||||
#if defined(NOTYET)
|
||||
#ifdef VM86
|
||||
testl $PSL_VM,SVR4_UC_EFLAGS(%eax)
|
||||
jnz 1f
|
||||
#endif
|
||||
#endif
|
||||
movl SVR4_UC_GS(%eax),%edx
|
||||
movl %dx,%gs
|
||||
1: pushl %eax # fake return address
|
||||
pushl $1 # pointer to ucontext
|
||||
movl SVR4_UC_GS(%eax),%gs
|
||||
1: pushl %eax # pointer to ucontext
|
||||
pushl $1 # set context
|
||||
movl $_svr4_sys_context,%eax
|
||||
int $0x80 # enter kernel with args on stack
|
||||
movl $exit,%eax
|
||||
int $0x80 # exit if sigreturn fails
|
||||
0: jmp 0b
|
||||
|
||||
ALIGN_TEXT
|
||||
svr4_esigcode:
|
||||
|
@ -112,7 +112,7 @@ svr4_getcontext(p, uc, mask, oonstack)
|
||||
struct svr4_sigaltstack *s = &uc->uc_stack;
|
||||
#ifdef DONE_MORE_SIGALTSTACK_WORK
|
||||
struct sigacts *psp = p->p_sigacts;
|
||||
struct sigaltstack *sf = &psp->ps_sigstk;
|
||||
struct sigaltstack *sf = &p->p_sigstk;
|
||||
#endif
|
||||
|
||||
memset(uc, 0, sizeof(struct svr4_ucontext));
|
||||
@ -199,7 +199,7 @@ svr4_setcontext(p, uc)
|
||||
register struct trapframe *tf;
|
||||
svr4_greg_t *r = uc->uc_mcontext.greg;
|
||||
struct svr4_sigaltstack *s = &uc->uc_stack;
|
||||
struct sigaltstack *sf = &psp->ps_sigstk;
|
||||
struct sigaltstack *sf = &p->p_sigstk;
|
||||
sigset_t mask;
|
||||
|
||||
/*
|
||||
@ -276,8 +276,8 @@ svr4_setcontext(p, uc)
|
||||
*/
|
||||
if (uc->uc_flags & SVR4_UC_SIGMASK) {
|
||||
svr4_to_bsd_sigset(&uc->uc_sigmask, &mask);
|
||||
SIG_CANTMASK(mask);
|
||||
p->p_sigmask = mask;
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
}
|
||||
|
||||
return 0; /*EJUSTRETURN;*/
|
||||
@ -401,16 +401,16 @@ svr4_sendsig(catcher, sig, mask, code)
|
||||
int oonstack;
|
||||
|
||||
tf = p->p_md.md_regs;
|
||||
oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
|
||||
oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
|
||||
|
||||
/*
|
||||
* Allocate space for the signal handler context.
|
||||
*/
|
||||
if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
|
||||
if ((p->p_flag & P_ALTSTACK) && !oonstack &&
|
||||
SIGISMEMBER(psp->ps_sigonstack, sig)) {
|
||||
fp = (struct svr4_sigframe *)((caddr_t)psp->ps_sigstk.ss_sp +
|
||||
psp->ps_sigstk.ss_size - sizeof(struct svr4_sigframe));
|
||||
psp->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
fp = (struct svr4_sigframe *)((caddr_t)p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - sizeof(struct svr4_sigframe));
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
} else {
|
||||
fp = (struct svr4_sigframe *)tf->tf_esp - 1;
|
||||
}
|
||||
@ -466,6 +466,7 @@ svr4_sendsig(catcher, sig, mask, code)
|
||||
tf->tf_ds = _udatasel;
|
||||
tf->tf_es = _udatasel;
|
||||
tf->tf_fs = _udatasel;
|
||||
load_gs(_udatasel);
|
||||
tf->tf_ss = _udatasel;
|
||||
#endif
|
||||
}
|
||||
|
@ -307,11 +307,11 @@ exit1(p, rv)
|
||||
switchticks = ticks;
|
||||
|
||||
/*
|
||||
* Notify parent that we're gone. If parent has the P_NOCLDWAIT
|
||||
* Notify parent that we're gone. If parent has the PS_NOCLDWAIT
|
||||
* flag set, notify process 1 instead (and hope it will handle
|
||||
* this situation).
|
||||
*/
|
||||
if (p->p_pptr->p_procsig->ps_flag & P_NOCLDWAIT) {
|
||||
if (p->p_pptr->p_procsig->ps_flag & PS_NOCLDWAIT) {
|
||||
struct proc *pp = p->p_pptr;
|
||||
proc_reparent(p, initproc);
|
||||
/*
|
||||
|
@ -76,7 +76,8 @@ kthread_create(void (*func)(void *), void *arg,
|
||||
*newpp = p2;
|
||||
|
||||
/* this is a non-swapped system process */
|
||||
p2->p_flag |= P_INMEM | P_SYSTEM | P_NOCLDWAIT;
|
||||
p2->p_flag |= P_INMEM | P_SYSTEM;
|
||||
p2->p_procsig->ps_flag |= PS_NOCLDWAIT;
|
||||
PHOLD(p2);
|
||||
|
||||
/* set up arg0 for 'ps', et al */
|
||||
|
@ -71,9 +71,9 @@ static int sigprop __P((int sig));
|
||||
static int sig_ffs __P((sigset_t *set));
|
||||
static int killpg1 __P((struct proc *cp, int sig, int pgid, int all));
|
||||
static int do_sigaction __P((struct proc *p, int sig, struct sigaction *act,
|
||||
struct sigaction *oact));
|
||||
struct sigaction *oact, int old));
|
||||
static int do_sigprocmask __P((struct proc *p, int how, sigset_t *set,
|
||||
sigset_t *oset));
|
||||
sigset_t *oset, int old));
|
||||
static void stop __P((struct proc *));
|
||||
static char *expand_name __P((const char *, uid_t, pid_t));
|
||||
static int coredump __P((struct proc *));
|
||||
@ -180,10 +180,11 @@ extern __inline int sig_ffs(sigset_t *set)
|
||||
* osigaction
|
||||
*/
|
||||
static int
|
||||
do_sigaction(p, sig, act, oact)
|
||||
do_sigaction(p, sig, act, oact, old)
|
||||
struct proc *p;
|
||||
register int sig;
|
||||
struct sigaction *act, *oact;
|
||||
int old;
|
||||
{
|
||||
register struct sigacts *ps = p->p_sigacts;
|
||||
|
||||
@ -204,9 +205,9 @@ do_sigaction(p, sig, act, oact)
|
||||
oact->sa_flags |= SA_NODEFER;
|
||||
if (SIGISMEMBER(ps->ps_siginfo, sig))
|
||||
oact->sa_flags |= SA_SIGINFO;
|
||||
if (sig == SIGCHLD && p->p_procsig->ps_flag & P_NOCLDSTOP)
|
||||
if (sig == SIGCHLD && p->p_procsig->ps_flag & PS_NOCLDSTOP)
|
||||
oact->sa_flags |= SA_NOCLDSTOP;
|
||||
if (sig == SIGCHLD && p->p_procsig->ps_flag & P_NOCLDWAIT)
|
||||
if (sig == SIGCHLD && p->p_procsig->ps_flag & PS_NOCLDWAIT)
|
||||
oact->sa_flags |= SA_NOCLDWAIT;
|
||||
}
|
||||
if (act) {
|
||||
@ -254,9 +255,9 @@ do_sigaction(p, sig, act, oact)
|
||||
#endif
|
||||
if (sig == SIGCHLD) {
|
||||
if (act->sa_flags & SA_NOCLDSTOP)
|
||||
p->p_procsig->ps_flag |= P_NOCLDSTOP;
|
||||
p->p_procsig->ps_flag |= PS_NOCLDSTOP;
|
||||
else
|
||||
p->p_procsig->ps_flag &= ~P_NOCLDSTOP;
|
||||
p->p_procsig->ps_flag &= ~PS_NOCLDSTOP;
|
||||
if (act->sa_flags & SA_NOCLDWAIT) {
|
||||
/*
|
||||
* Paranoia: since SA_NOCLDWAIT is implemented
|
||||
@ -265,11 +266,11 @@ do_sigaction(p, sig, act, oact)
|
||||
* is forbidden to set SA_NOCLDWAIT.
|
||||
*/
|
||||
if (p->p_pid == 1)
|
||||
p->p_procsig->ps_flag &= ~P_NOCLDWAIT;
|
||||
p->p_procsig->ps_flag &= ~PS_NOCLDWAIT;
|
||||
else
|
||||
p->p_procsig->ps_flag |= P_NOCLDWAIT;
|
||||
p->p_procsig->ps_flag |= PS_NOCLDWAIT;
|
||||
} else
|
||||
p->p_procsig->ps_flag &= ~P_NOCLDWAIT;
|
||||
p->p_procsig->ps_flag &= ~PS_NOCLDWAIT;
|
||||
}
|
||||
/*
|
||||
* Set bit in p_sigignore for signals that are set to SIG_IGN,
|
||||
@ -286,14 +287,18 @@ do_sigaction(p, sig, act, oact)
|
||||
/* easier in psignal */
|
||||
SIGADDSET(p->p_sigignore, sig);
|
||||
SIGDELSET(p->p_sigcatch, sig);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
SIGDELSET(p->p_sigignore, sig);
|
||||
if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL)
|
||||
SIGDELSET(p->p_sigcatch, sig);
|
||||
else
|
||||
SIGADDSET(p->p_sigcatch, sig);
|
||||
}
|
||||
if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_IGN ||
|
||||
ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL || !old)
|
||||
SIGDELSET(ps->ps_osigset, sig);
|
||||
else
|
||||
SIGADDSET(ps->ps_osigset, sig);
|
||||
|
||||
(void) spl0();
|
||||
}
|
||||
@ -317,8 +322,6 @@ sigaction(p, uap)
|
||||
register struct sigaction *actp, *oactp;
|
||||
int error;
|
||||
|
||||
p->p_flag |= P_NEWSIGSET;
|
||||
|
||||
actp = (uap->act) ? &act : NULL;
|
||||
oactp = (uap->oact) ? &oact : NULL;
|
||||
if (actp) {
|
||||
@ -327,7 +330,7 @@ sigaction(p, uap)
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
error = do_sigaction(p, uap->sig, actp, oactp);
|
||||
error = do_sigaction(p, uap->sig, actp, oactp, 0);
|
||||
if (oactp && !error) {
|
||||
error = copyout((caddr_t)oactp, (caddr_t)uap->oact,
|
||||
sizeof(oact));
|
||||
@ -363,7 +366,7 @@ osigaction(p, uap)
|
||||
nsap->sa_flags = sa.sa_flags;
|
||||
OSIG2SIG(sa.sa_mask, nsap->sa_mask);
|
||||
}
|
||||
error = do_sigaction(p, uap->signum, nsap, osap);
|
||||
error = do_sigaction(p, uap->signum, nsap, osap, 1);
|
||||
if (osap && !error) {
|
||||
sa.sa_handler = osap->sa_handler;
|
||||
sa.sa_flags = osap->sa_flags;
|
||||
@ -417,14 +420,13 @@ execsigs(p)
|
||||
* Reset stack state to the user stack.
|
||||
* Clear set of signals caught on the signal stack.
|
||||
*/
|
||||
ps->ps_sigstk.ss_flags = SS_DISABLE;
|
||||
ps->ps_sigstk.ss_size = 0;
|
||||
ps->ps_sigstk.ss_sp = 0;
|
||||
ps->ps_flags = 0;
|
||||
p->p_sigstk.ss_flags = SS_DISABLE;
|
||||
p->p_sigstk.ss_size = 0;
|
||||
p->p_sigstk.ss_sp = 0;
|
||||
/*
|
||||
* Reset no zombies if child dies flag as Solaris does.
|
||||
*/
|
||||
p->p_procsig->ps_flag &= ~P_NOCLDWAIT;
|
||||
p->p_procsig->ps_flag &= ~PS_NOCLDWAIT;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -434,10 +436,11 @@ execsigs(p)
|
||||
* the library stub does the rest.
|
||||
*/
|
||||
static int
|
||||
do_sigprocmask(p, how, set, oset)
|
||||
do_sigprocmask(p, how, set, oset, old)
|
||||
struct proc *p;
|
||||
int how;
|
||||
sigset_t *set, *oset;
|
||||
int old;
|
||||
{
|
||||
int error;
|
||||
|
||||
@ -449,15 +452,18 @@ do_sigprocmask(p, how, set, oset)
|
||||
(void) splhigh();
|
||||
switch (how) {
|
||||
case SIG_BLOCK:
|
||||
SIG_CANTMASK(*set);
|
||||
SIGSETOR(p->p_sigmask, *set);
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
break;
|
||||
case SIG_UNBLOCK:
|
||||
SIGSETNAND(p->p_sigmask, *set);
|
||||
break;
|
||||
case SIG_SETMASK:
|
||||
p->p_sigmask = *set;
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
SIG_CANTMASK(*set);
|
||||
if (old)
|
||||
SIGSETLO(p->p_sigmask, *set);
|
||||
else
|
||||
p->p_sigmask = *set;
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
@ -492,7 +498,7 @@ sigprocmask(p, uap)
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
error = do_sigprocmask(p, uap->how, setp, osetp);
|
||||
error = do_sigprocmask(p, uap->how, setp, osetp, 0);
|
||||
if (osetp && !error) {
|
||||
error = copyout((caddr_t)osetp, (caddr_t)uap->oset,
|
||||
sizeof(oset));
|
||||
@ -515,7 +521,7 @@ osigprocmask(p, uap)
|
||||
int error;
|
||||
|
||||
OSIG2SIG(uap->mask, set);
|
||||
error = do_sigprocmask(p, uap->how, &set, &oset);
|
||||
error = do_sigprocmask(p, uap->how, &set, &oset, 1);
|
||||
SIG2OSIG(oset, p->p_retval[0]);
|
||||
return (error);
|
||||
}
|
||||
@ -588,7 +594,7 @@ osigvec(p, uap)
|
||||
nsap->sa_flags |= SA_USERTRAMP;
|
||||
#endif
|
||||
}
|
||||
error = do_sigaction(p, uap->signum, nsap, osap);
|
||||
error = do_sigaction(p, uap->signum, nsap, osap, 1);
|
||||
if (osap && !error) {
|
||||
vec.sv_handler = osap->sa_handler;
|
||||
SIG2OSIG(osap->sa_mask, vec.sv_mask);
|
||||
@ -640,7 +646,7 @@ osigsetmask(p, uap)
|
||||
SIG_CANTMASK(set);
|
||||
(void) splhigh();
|
||||
SIG2OSIG(p->p_sigmask, p->p_retval[0]);
|
||||
p->p_sigmask = set;
|
||||
SIGSETLO(p->p_sigmask, set);
|
||||
(void) spl0();
|
||||
return (0);
|
||||
}
|
||||
@ -671,15 +677,17 @@ sigsuspend(p, uap)
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* When returning from sigpause, we want
|
||||
* When returning from sigsuspend, we want
|
||||
* the old mask to be restored after the
|
||||
* signal handler has finished. Thus, we
|
||||
* save it here and mark the sigacts structure
|
||||
* to indicate this.
|
||||
*/
|
||||
p->p_oldsigmask = p->p_sigmask;
|
||||
p->p_flag |= P_OLDMASK;
|
||||
|
||||
SIG_CANTMASK(mask);
|
||||
p->p_sigmask = mask;
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
while (tsleep((caddr_t) ps, PPAUSE|PCATCH, "pause", 0) == 0)
|
||||
/* void */;
|
||||
/* always return EINTR rather than ERESTART... */
|
||||
@ -697,14 +705,15 @@ osigsuspend(p, uap)
|
||||
register struct proc *p;
|
||||
struct osigsuspend_args *uap;
|
||||
{
|
||||
sigset_t set;
|
||||
sigset_t mask;
|
||||
register struct sigacts *ps = p->p_sigacts;
|
||||
|
||||
OSIG2SIG(uap->mask, set);
|
||||
SIG_CANTMASK(set);
|
||||
p->p_oldsigmask = p->p_sigmask;
|
||||
p->p_sigmask = set;
|
||||
while (tsleep((caddr_t) ps, PPAUSE|PCATCH, "pause", 0) == 0)
|
||||
p->p_flag |= P_OLDMASK;
|
||||
OSIG2SIG(uap->mask, mask);
|
||||
SIG_CANTMASK(mask);
|
||||
SIGSETLO(p->p_sigmask, mask);
|
||||
while (tsleep((caddr_t) ps, PPAUSE|PCATCH, "opause", 0) == 0)
|
||||
/* void */;
|
||||
/* always return EINTR rather than ERESTART... */
|
||||
return (EINTR);
|
||||
@ -724,21 +733,19 @@ osigstack(p, uap)
|
||||
register struct osigstack_args *uap;
|
||||
{
|
||||
struct sigstack ss;
|
||||
struct sigacts *psp;
|
||||
int error = 0;
|
||||
|
||||
psp = p->p_sigacts;
|
||||
ss.ss_sp = psp->ps_sigstk.ss_sp;
|
||||
ss.ss_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
|
||||
ss.ss_sp = p->p_sigstk.ss_sp;
|
||||
ss.ss_onstack = p->p_sigstk.ss_flags & SS_ONSTACK;
|
||||
if (uap->oss && (error = copyout((caddr_t)&ss, (caddr_t)uap->oss,
|
||||
sizeof (struct sigstack))))
|
||||
return (error);
|
||||
if (uap->nss && (error = copyin((caddr_t)uap->nss, (caddr_t)&ss,
|
||||
sizeof (ss))) == 0) {
|
||||
psp->ps_sigstk.ss_sp = ss.ss_sp;
|
||||
psp->ps_sigstk.ss_size = 0;
|
||||
psp->ps_sigstk.ss_flags |= ss.ss_onstack & SS_ONSTACK;
|
||||
psp->ps_flags |= SAS_ALTSTACK;
|
||||
p->p_sigstk.ss_sp = ss.ss_sp;
|
||||
p->p_sigstk.ss_size = 0;
|
||||
p->p_sigstk.ss_flags |= ss.ss_onstack & SS_ONSTACK;
|
||||
p->p_flag |= P_ALTSTACK;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
@ -756,14 +763,12 @@ sigaltstack(p, uap)
|
||||
struct proc *p;
|
||||
register struct sigaltstack_args *uap;
|
||||
{
|
||||
struct sigacts *psp;
|
||||
stack_t ss;
|
||||
int error;
|
||||
|
||||
psp = p->p_sigacts;
|
||||
if ((psp->ps_flags & SAS_ALTSTACK) == 0)
|
||||
psp->ps_sigstk.ss_flags |= SS_DISABLE;
|
||||
if (uap->oss && (error = copyout((caddr_t)&psp->ps_sigstk,
|
||||
if ((p->p_flag & P_ALTSTACK) == 0)
|
||||
p->p_sigstk.ss_flags |= SS_DISABLE;
|
||||
if (uap->oss && (error = copyout((caddr_t)&p->p_sigstk,
|
||||
(caddr_t)uap->oss, sizeof (stack_t))))
|
||||
return (error);
|
||||
if (uap->ss == 0)
|
||||
@ -771,16 +776,16 @@ sigaltstack(p, uap)
|
||||
if ((error = copyin((caddr_t)uap->ss, (caddr_t)&ss, sizeof (ss))))
|
||||
return (error);
|
||||
if (ss.ss_flags & SS_DISABLE) {
|
||||
if (psp->ps_sigstk.ss_flags & SS_ONSTACK)
|
||||
if (p->p_sigstk.ss_flags & SS_ONSTACK)
|
||||
return (EINVAL);
|
||||
psp->ps_flags &= ~SAS_ALTSTACK;
|
||||
psp->ps_sigstk.ss_flags = ss.ss_flags;
|
||||
p->p_flag &= ~P_ALTSTACK;
|
||||
p->p_sigstk.ss_flags = ss.ss_flags;
|
||||
return (0);
|
||||
}
|
||||
if (ss.ss_size < MINSIGSTKSZ)
|
||||
return (ENOMEM);
|
||||
psp->ps_flags |= SAS_ALTSTACK;
|
||||
psp->ps_sigstk = ss;
|
||||
p->p_flag |= P_ALTSTACK;
|
||||
p->p_sigstk = ss;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1093,7 +1098,7 @@ psignal(p, sig)
|
||||
goto out;
|
||||
SIGDELSET(p->p_siglist, sig);
|
||||
p->p_xstat = sig;
|
||||
if ((p->p_pptr->p_procsig->ps_flag & P_NOCLDSTOP) == 0)
|
||||
if ((p->p_pptr->p_procsig->ps_flag & PS_NOCLDSTOP) == 0)
|
||||
psignal(p->p_pptr, SIGCHLD);
|
||||
stop(p);
|
||||
goto out;
|
||||
@ -1300,7 +1305,7 @@ issignal(p)
|
||||
break; /* == ignore */
|
||||
p->p_xstat = sig;
|
||||
stop(p);
|
||||
if ((p->p_pptr->p_procsig->ps_flag & P_NOCLDSTOP) == 0)
|
||||
if ((p->p_pptr->p_procsig->ps_flag & PS_NOCLDSTOP) == 0)
|
||||
psignal(p->p_pptr, SIGCHLD);
|
||||
mi_switch();
|
||||
break;
|
||||
@ -1372,8 +1377,7 @@ postsig(sig)
|
||||
action = ps->ps_sigact[_SIG_IDX(sig)];
|
||||
#ifdef KTRACE
|
||||
if (KTRPOINT(p, KTR_PSIG))
|
||||
ktrpsig(p->p_tracep,
|
||||
sig, action, SIGNOTEMPTY(p->p_oldsigmask) ?
|
||||
ktrpsig(p->p_tracep, sig, action, p->p_flag & P_OLDMASK ?
|
||||
&p->p_oldsigmask : &p->p_sigmask, 0);
|
||||
#endif
|
||||
STOPEVENT(p, S_SIG, sig);
|
||||
@ -1393,17 +1397,17 @@ postsig(sig)
|
||||
("postsig action"));
|
||||
/*
|
||||
* Set the new mask value and also defer further
|
||||
* occurences of this signal.
|
||||
* occurrences of this signal.
|
||||
*
|
||||
* Special case: user has done a sigpause. Here the
|
||||
* Special case: user has done a sigsuspend. Here the
|
||||
* current mask is not of interest, but rather the
|
||||
* mask from before the sigpause is what we want
|
||||
* mask from before the sigsuspend is what we want
|
||||
* restored after the signal processing is completed.
|
||||
*/
|
||||
(void) splhigh();
|
||||
if (SIGNOTEMPTY(p->p_oldsigmask)) {
|
||||
if (p->p_flag & P_OLDMASK) {
|
||||
returnmask = p->p_oldsigmask;
|
||||
SIGEMPTYSET(p->p_oldsigmask);
|
||||
p->p_flag &= ~P_OLDMASK;
|
||||
} else
|
||||
returnmask = p->p_sigmask;
|
||||
|
||||
|
@ -496,14 +496,14 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
int oonstack;
|
||||
|
||||
regs = p->p_md.md_regs;
|
||||
oonstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
|
||||
oonstack = (p->p_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
|
||||
|
||||
/* Allocate and validate space for the signal handler context. */
|
||||
if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
|
||||
if ((p->p_flag & P_ALTSTACK) && !oonstack &&
|
||||
SIGISMEMBER(psp->ps_sigonstack, sig)) {
|
||||
fp = (struct osigframe *)(psp->ps_sigstk.ss_sp +
|
||||
psp->ps_sigstk.ss_size - sizeof(struct osigframe));
|
||||
psp->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
fp = (struct osigframe *)(p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - sizeof(struct osigframe));
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
}
|
||||
else
|
||||
fp = (struct osigframe *)regs->tf_esp - 1;
|
||||
@ -546,11 +546,10 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
else {
|
||||
/* Old FreeBSD-style arguments. */
|
||||
sf.sf_arg2 = code;
|
||||
sf.sf_addr = (char *)regs->tf_err;
|
||||
sf.sf_ahu.sf_handler = catcher;
|
||||
}
|
||||
|
||||
sf.sf_addr = (char *) regs->tf_err;
|
||||
|
||||
/* save scratch registers */
|
||||
sf.sf_siginfo.si_sc.sc_eax = regs->tf_eax;
|
||||
sf.sf_siginfo.si_sc.sc_ebx = regs->tf_ebx;
|
||||
@ -608,7 +607,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
}
|
||||
|
||||
regs->tf_esp = (int)fp;
|
||||
regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
|
||||
regs->tf_eip = PS_STRINGS - oszsigcode;
|
||||
regs->tf_cs = _ucodesel;
|
||||
regs->tf_ds = _udatasel;
|
||||
regs->tf_es = _udatasel;
|
||||
@ -624,37 +623,34 @@ sendsig(catcher, sig, mask, code)
|
||||
sigset_t *mask;
|
||||
u_long code;
|
||||
{
|
||||
struct proc *p;
|
||||
struct proc *p = curproc;
|
||||
struct trapframe *regs;
|
||||
struct sigacts *psp;
|
||||
struct sigacts *psp = p->p_sigacts;
|
||||
struct sigframe sf, *sfp;
|
||||
int onstack;
|
||||
int oonstack;
|
||||
|
||||
p = curproc;
|
||||
|
||||
if ((p->p_flag & P_NEWSIGSET) == 0) {
|
||||
if (SIGISMEMBER(psp->ps_osigset, sig)) {
|
||||
osendsig(catcher, sig, mask, code);
|
||||
return;
|
||||
}
|
||||
|
||||
regs = p->p_md.md_regs;
|
||||
psp = p->p_sigacts;
|
||||
onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
|
||||
oonstack = (p->p_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_stack = p->p_sigstk;
|
||||
sf.sf_uc.uc_mcontext.mc_onstack = oonstack;
|
||||
sf.sf_uc.uc_mcontext.mc_gs = rgs();
|
||||
bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(struct trapframe));
|
||||
|
||||
/* Allocate and validate space for the signal handler context. */
|
||||
if ((psp->ps_flags & SAS_ALTSTACK) != 0 && !onstack &&
|
||||
if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack &&
|
||||
SIGISMEMBER(psp->ps_sigonstack, sig)) {
|
||||
sfp = (struct sigframe *)(psp->ps_sigstk.ss_sp +
|
||||
psp->ps_sigstk.ss_size - sizeof(struct sigframe));
|
||||
psp->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
sfp = (struct sigframe *)(p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - sizeof(struct sigframe));
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
}
|
||||
else
|
||||
sfp = (struct sigframe *)regs->tf_esp - 1;
|
||||
@ -703,6 +699,7 @@ sendsig(catcher, sig, mask, code)
|
||||
else {
|
||||
/* Old FreeBSD-style arguments. */
|
||||
sf.sf_siginfo = code;
|
||||
sf.sf_addr = (char *)regs->tf_err;
|
||||
sf.sf_ahu.sf_handler = catcher;
|
||||
}
|
||||
|
||||
@ -783,9 +780,6 @@ osigreturn(p, uap)
|
||||
register struct trapframe *regs = p->p_md.md_regs;
|
||||
int eflags;
|
||||
|
||||
if ((p->p_flag & P_NEWSIGSET) != 0)
|
||||
return sigreturn(p, (struct sigreturn_args *)uap);
|
||||
|
||||
scp = uap->sigcntxp;
|
||||
|
||||
if (useracc((caddr_t)scp, sizeof (struct osigcontext), B_WRITE) == 0)
|
||||
@ -854,10 +848,6 @@ osigreturn(p, uap)
|
||||
regs->tf_ds = scp->sc_ds;
|
||||
regs->tf_es = scp->sc_es;
|
||||
regs->tf_fs = scp->sc_fs;
|
||||
if (load_gs_param(scp->sc_gs)) {
|
||||
trapsignal(p, SIGBUS, T_SEGNPFLT);
|
||||
return (EFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
/* restore scratch registers */
|
||||
@ -872,11 +862,11 @@ osigreturn(p, uap)
|
||||
regs->tf_isp = scp->sc_isp;
|
||||
|
||||
if (scp->sc_onstack & 01)
|
||||
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
else
|
||||
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
|
||||
OSIG2SIG(scp->sc_mask, p->p_sigmask);
|
||||
SIGSETOLD(p->p_sigmask, scp->sc_mask);
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
regs->tf_ebp = scp->sc_fp;
|
||||
regs->tf_esp = scp->sc_sp;
|
||||
@ -896,7 +886,8 @@ sigreturn(p, uap)
|
||||
ucontext_t *ucp;
|
||||
int cs, eflags;
|
||||
|
||||
p->p_flag |= P_NEWSIGSET;
|
||||
if (((struct osigcontext *)uap->sigcntxp)->sc_trapno == 0x01d516)
|
||||
return osigreturn(p, (struct osigreturn_args *)uap);
|
||||
|
||||
regs = p->p_md.md_regs;
|
||||
ucp = uap->sigcntxp;
|
||||
@ -969,16 +960,12 @@ sigreturn(p, uap)
|
||||
return(EINVAL);
|
||||
}
|
||||
bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(struct trapframe));
|
||||
if (load_gs_param(ucp->uc_mcontext.mc_gs)) {
|
||||
trapsignal(p, SIGBUS, T_SEGNPFLT);
|
||||
return (EFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
if (ucp->uc_mcontext.mc_onstack & 1)
|
||||
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
else
|
||||
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
|
||||
p->p_sigmask = ucp->uc_sigmask;
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
|
@ -496,14 +496,14 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
int oonstack;
|
||||
|
||||
regs = p->p_md.md_regs;
|
||||
oonstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
|
||||
oonstack = (p->p_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
|
||||
|
||||
/* Allocate and validate space for the signal handler context. */
|
||||
if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
|
||||
if ((p->p_flag & P_ALTSTACK) && !oonstack &&
|
||||
SIGISMEMBER(psp->ps_sigonstack, sig)) {
|
||||
fp = (struct osigframe *)(psp->ps_sigstk.ss_sp +
|
||||
psp->ps_sigstk.ss_size - sizeof(struct osigframe));
|
||||
psp->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
fp = (struct osigframe *)(p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - sizeof(struct osigframe));
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
}
|
||||
else
|
||||
fp = (struct osigframe *)regs->tf_esp - 1;
|
||||
@ -546,11 +546,10 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
else {
|
||||
/* Old FreeBSD-style arguments. */
|
||||
sf.sf_arg2 = code;
|
||||
sf.sf_addr = (char *)regs->tf_err;
|
||||
sf.sf_ahu.sf_handler = catcher;
|
||||
}
|
||||
|
||||
sf.sf_addr = (char *) regs->tf_err;
|
||||
|
||||
/* save scratch registers */
|
||||
sf.sf_siginfo.si_sc.sc_eax = regs->tf_eax;
|
||||
sf.sf_siginfo.si_sc.sc_ebx = regs->tf_ebx;
|
||||
@ -608,7 +607,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
}
|
||||
|
||||
regs->tf_esp = (int)fp;
|
||||
regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
|
||||
regs->tf_eip = PS_STRINGS - oszsigcode;
|
||||
regs->tf_cs = _ucodesel;
|
||||
regs->tf_ds = _udatasel;
|
||||
regs->tf_es = _udatasel;
|
||||
@ -624,37 +623,34 @@ sendsig(catcher, sig, mask, code)
|
||||
sigset_t *mask;
|
||||
u_long code;
|
||||
{
|
||||
struct proc *p;
|
||||
struct proc *p = curproc;
|
||||
struct trapframe *regs;
|
||||
struct sigacts *psp;
|
||||
struct sigacts *psp = p->p_sigacts;
|
||||
struct sigframe sf, *sfp;
|
||||
int onstack;
|
||||
int oonstack;
|
||||
|
||||
p = curproc;
|
||||
|
||||
if ((p->p_flag & P_NEWSIGSET) == 0) {
|
||||
if (SIGISMEMBER(psp->ps_osigset, sig)) {
|
||||
osendsig(catcher, sig, mask, code);
|
||||
return;
|
||||
}
|
||||
|
||||
regs = p->p_md.md_regs;
|
||||
psp = p->p_sigacts;
|
||||
onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
|
||||
oonstack = (p->p_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_stack = p->p_sigstk;
|
||||
sf.sf_uc.uc_mcontext.mc_onstack = oonstack;
|
||||
sf.sf_uc.uc_mcontext.mc_gs = rgs();
|
||||
bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(struct trapframe));
|
||||
|
||||
/* Allocate and validate space for the signal handler context. */
|
||||
if ((psp->ps_flags & SAS_ALTSTACK) != 0 && !onstack &&
|
||||
if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack &&
|
||||
SIGISMEMBER(psp->ps_sigonstack, sig)) {
|
||||
sfp = (struct sigframe *)(psp->ps_sigstk.ss_sp +
|
||||
psp->ps_sigstk.ss_size - sizeof(struct sigframe));
|
||||
psp->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
sfp = (struct sigframe *)(p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - sizeof(struct sigframe));
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
}
|
||||
else
|
||||
sfp = (struct sigframe *)regs->tf_esp - 1;
|
||||
@ -703,6 +699,7 @@ sendsig(catcher, sig, mask, code)
|
||||
else {
|
||||
/* Old FreeBSD-style arguments. */
|
||||
sf.sf_siginfo = code;
|
||||
sf.sf_addr = (char *)regs->tf_err;
|
||||
sf.sf_ahu.sf_handler = catcher;
|
||||
}
|
||||
|
||||
@ -783,9 +780,6 @@ osigreturn(p, uap)
|
||||
register struct trapframe *regs = p->p_md.md_regs;
|
||||
int eflags;
|
||||
|
||||
if ((p->p_flag & P_NEWSIGSET) != 0)
|
||||
return sigreturn(p, (struct sigreturn_args *)uap);
|
||||
|
||||
scp = uap->sigcntxp;
|
||||
|
||||
if (useracc((caddr_t)scp, sizeof (struct osigcontext), B_WRITE) == 0)
|
||||
@ -854,10 +848,6 @@ osigreturn(p, uap)
|
||||
regs->tf_ds = scp->sc_ds;
|
||||
regs->tf_es = scp->sc_es;
|
||||
regs->tf_fs = scp->sc_fs;
|
||||
if (load_gs_param(scp->sc_gs)) {
|
||||
trapsignal(p, SIGBUS, T_SEGNPFLT);
|
||||
return (EFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
/* restore scratch registers */
|
||||
@ -872,11 +862,11 @@ osigreturn(p, uap)
|
||||
regs->tf_isp = scp->sc_isp;
|
||||
|
||||
if (scp->sc_onstack & 01)
|
||||
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
else
|
||||
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
|
||||
OSIG2SIG(scp->sc_mask, p->p_sigmask);
|
||||
SIGSETOLD(p->p_sigmask, scp->sc_mask);
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
regs->tf_ebp = scp->sc_fp;
|
||||
regs->tf_esp = scp->sc_sp;
|
||||
@ -896,7 +886,8 @@ sigreturn(p, uap)
|
||||
ucontext_t *ucp;
|
||||
int cs, eflags;
|
||||
|
||||
p->p_flag |= P_NEWSIGSET;
|
||||
if (((struct osigcontext *)uap->sigcntxp)->sc_trapno == 0x01d516)
|
||||
return osigreturn(p, (struct osigreturn_args *)uap);
|
||||
|
||||
regs = p->p_md.md_regs;
|
||||
ucp = uap->sigcntxp;
|
||||
@ -969,16 +960,12 @@ sigreturn(p, uap)
|
||||
return(EINVAL);
|
||||
}
|
||||
bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(struct trapframe));
|
||||
if (load_gs_param(ucp->uc_mcontext.mc_gs)) {
|
||||
trapsignal(p, SIGBUS, T_SEGNPFLT);
|
||||
return (EFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
if (ucp->uc_mcontext.mc_onstack & 1)
|
||||
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags |= SS_ONSTACK;
|
||||
else
|
||||
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
|
||||
p->p_sigmask = ucp->uc_sigmask;
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
|
@ -602,7 +602,7 @@ svr4_sys_context(p, uap)
|
||||
case 0:
|
||||
DPRINTF(("getcontext(%p)\n", uap->uc));
|
||||
svr4_getcontext(p, &uc, &p->p_sigmask,
|
||||
p->p_sigacts->ps_sigstk.ss_flags & SS_ONSTACK);
|
||||
p->p_sigstk.ss_flags & SS_ONSTACK);
|
||||
return copyout(&uc, uap->uc, sizeof(uc));
|
||||
|
||||
case 1:
|
||||
|
@ -85,6 +85,9 @@ struct procsig {
|
||||
int ps_refcnt;
|
||||
};
|
||||
|
||||
#define PS_NOCLDWAIT 0x0001 /* No zombies if child dies */
|
||||
#define PS_NOCLDSTOP 0x0002 /* No SIGCHLD when children stop. */
|
||||
|
||||
/*
|
||||
* pasleep structure, used by asleep() syscall to hold requested priority
|
||||
* and timeout values for await().
|
||||
@ -197,6 +200,7 @@ struct proc {
|
||||
#define p_startcopy p_sigmask
|
||||
|
||||
sigset_t p_sigmask; /* Current signal mask. */
|
||||
stack_t p_sigstk; /* sp & on stack state variable */
|
||||
u_char p_priority; /* Process priority. */
|
||||
u_char p_usrpri; /* User-priority based on p_cpu and p_nice. */
|
||||
char p_nice; /* Process "nice" value. */
|
||||
@ -240,7 +244,6 @@ struct proc {
|
||||
#define P_ADVLOCK 0x00001 /* Process may hold a POSIX advisory lock. */
|
||||
#define P_CONTROLT 0x00002 /* Has a controlling terminal. */
|
||||
#define P_INMEM 0x00004 /* Loaded into memory. */
|
||||
#define P_NOCLDSTOP 0x00008 /* No SIGCHLD when children stop. */
|
||||
#define P_PPWAIT 0x00010 /* Parent is waiting for child to exec/exit. */
|
||||
#define P_PROFIL 0x00020 /* Has started profiling. */
|
||||
#define P_SELECT 0x00040 /* Selecting; wakeup/waiting danger. */
|
||||
@ -264,14 +267,14 @@ struct proc {
|
||||
#define P_SWAPINREQ 0x80000 /* Swapin request due to wakeup */
|
||||
|
||||
/* Marked a kernel thread */
|
||||
#define P_BUFEXHAUST 0x100000 /* dirty buffers flush is in progress */
|
||||
#define P_KTHREADP 0x200000 /* Process is really a kernel thread */
|
||||
#define P_BUFEXHAUST 0x100000 /* dirty buffers flush is in progress */
|
||||
#define P_KTHREADP 0x200000 /* Process is really a kernel thread */
|
||||
|
||||
#define P_NOCLDWAIT 0x400000 /* No zombies if child dies */
|
||||
#define P_DEADLKTREAT 0x800000 /* lock aquisition - deadlock treatment */
|
||||
#define P_DEADLKTREAT 0x800000 /* lock aquisition - deadlock treatment */
|
||||
|
||||
#define P_JAILED 0x1000000 /* Process is in jail */
|
||||
#define P_NEWSIGSET 0x2000000 /* Process uses new sigset_t */
|
||||
#define P_JAILED 0x1000000 /* Process is in jail */
|
||||
#define P_OLDMASK 0x2000000 /* need to restore mask before pause */
|
||||
#define P_ALTSTACK 0x4000000 /* have alternate signal stack */
|
||||
|
||||
/*
|
||||
* MOVE TO ucred.h?
|
||||
|
@ -59,15 +59,9 @@ struct sigacts {
|
||||
sigset_t ps_sigreset; /* signals that reset when caught */
|
||||
sigset_t ps_signodefer; /* signals not masked while handled */
|
||||
sigset_t ps_siginfo; /* signals that want SA_SIGINFO args */
|
||||
int ps_flags; /* signal flags, below */
|
||||
stack_t ps_sigstk; /* sp & on stack state variable */
|
||||
sigset_t ps_usertramp; /* SunOS compat; libc sigtramp XXX */
|
||||
sigset_t ps_osigset; /* signals that use osigset_t */
|
||||
};
|
||||
|
||||
/* signal flags */
|
||||
#define SAS_OLDMASK 0x01 /* need to restore mask before pause */
|
||||
#define SAS_ALTSTACK 0x02 /* have alternate signal stack */
|
||||
|
||||
/*
|
||||
* Compatibility
|
||||
*/
|
||||
@ -154,6 +148,9 @@ typedef void __osiginfohandler_t __P((int, osiginfo_t *, void *));
|
||||
(set1).__bits[__i] &= ~(set2).__bits[__i]; \
|
||||
} while (0)
|
||||
|
||||
#define SIGSETLO(set1, set2) ((set1).__bits[0] = (set2).__bits[0])
|
||||
#define SIGSETOLD(set, oset) ((set).__bits[0] = (oset))
|
||||
|
||||
#define SIG_CANTMASK(set) \
|
||||
SIGDELSET(set, SIGKILL), SIGDELSET(set, SIGSTOP)
|
||||
|
||||
|
@ -45,7 +45,7 @@ typedef struct __ucontext {
|
||||
sigset_t uc_sigmask;
|
||||
mcontext_t uc_mcontext;
|
||||
|
||||
struct __ucontext_t *uc_link;
|
||||
struct __ucontext *uc_link;
|
||||
stack_t uc_stack;
|
||||
int __spare__[8];
|
||||
} ucontext_t;
|
||||
|
Loading…
x
Reference in New Issue
Block a user