mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-10 14:02:43 +00:00
1. Change prototype of trapsignal and sendsig to use ksiginfo_t *, most
changes in MD code are trivial, before this change, trapsignal and sendsig use discrete parameters, now they uses member fields of ksiginfo_t structure. For sendsig, this change allows us to pass POSIX realtime signal value to user code. 2. Remove cpu_thread_siginfo, it is no longer needed because we now always generate ksiginfo_t data and feed it to libpthread. 3. Add p_sigqueue to proc structure to hold shared signals which were blocked by all threads in the proc. 4. Add td_sigqueue to thread structure to hold all signals delivered to thread. 5. i386 and amd64 now return POSIX standard si_code, other arches will be fixed. 6. In this sigqueue implementation, pending signal set is kept as before, an extra siginfo list holds additional siginfo_t data for signals. kernel code uses psignal() still behavior as before, it won't be failed even under memory pressure, only exception is when deleting a signal, we should call sigqueue_delete to remove signal from sigqueue but not SIGDELSET. Current there is no kernel code will deliver a signal with additional data, so kernel should be as stable as before, a ksiginfo can carry more information, for example, allow signal to be delivered but throw away siginfo data if memory is not enough. SIGKILL and SIGSTOP have fast path in sigqueue_add, because they can not be caught or masked. The sigqueue() syscall allows user code to queue a signal to target process, if resource is unavailable, EAGAIN will be returned as specification said. Just before thread exits, signal queue memory will be freed by sigqueue_flush. Current, all signals are allowed to be queued, not only realtime signals. Earlier patch reviewed by: jhb, deischen Tested on: i386, amd64
This commit is contained in:
parent
de90a634cb
commit
9104847f21
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=151316
@ -211,11 +211,10 @@ vm_offset_t phys_avail[10];
|
||||
#define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2)
|
||||
|
||||
#ifdef COMPAT_43
|
||||
void osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code);
|
||||
void osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
|
||||
#endif
|
||||
#ifdef COMPAT_FREEBSD4
|
||||
static void freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask,
|
||||
u_long code);
|
||||
static void freebsd4_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
|
||||
#endif
|
||||
|
||||
static void get_fpcontext(struct thread *td, mcontext_t *mcp);
|
||||
@ -1107,7 +1106,7 @@ DELAY(int n)
|
||||
*/
|
||||
#ifdef COMPAT_43
|
||||
void
|
||||
osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
osendsig(sig_t catcher, ksiginfo_t *kp, sigset_t *mask)
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
@ -1115,10 +1114,14 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
struct trapframe *frame;
|
||||
struct sigacts *psp;
|
||||
int oonstack, fsize, rndfsize;
|
||||
int sig;
|
||||
int code;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = kp->ksi_signo;
|
||||
code = kp->ksi_code;
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
|
||||
@ -1177,7 +1180,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
/* Fill in POSIX parts */
|
||||
ksi.si_signo = sig;
|
||||
ksi.si_code = code;
|
||||
ksi.si_value.sigval_ptr = NULL; /* XXX */
|
||||
ksi.si_value = kp->ksi_value;
|
||||
|
||||
/*
|
||||
* copy the frame out to userland.
|
||||
@ -1212,7 +1215,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
|
||||
#ifdef COMPAT_FREEBSD4
|
||||
static void
|
||||
freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
freebsd4_sendsig(sig_t catcher, ksiginfo_t *kp, sigset_t *mask)
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
@ -1220,10 +1223,14 @@ freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
struct sigacts *psp;
|
||||
struct sigframe4 sf, *sfp;
|
||||
int oonstack, rndfsize;
|
||||
int sig;
|
||||
int code;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = kp->ksi_signo;
|
||||
code = kp->ksi_code;
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
|
||||
@ -1308,9 +1315,7 @@ freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
frame->tf_regs[FRAME_A1] = (u_int64_t)&(sfp->sf_si);
|
||||
|
||||
/* Fill in POSIX parts */
|
||||
sf.sf_si.si_signo = sig;
|
||||
sf.sf_si.si_code = code;
|
||||
sf.sf_si.si_addr = (void*)frame->tf_regs[FRAME_TRAPARG_A0];
|
||||
sf.sf_si = kp->ksi_info;
|
||||
}
|
||||
else
|
||||
frame->tf_regs[FRAME_A1] = code;
|
||||
@ -1323,7 +1328,7 @@ freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
#endif /* COMPAT_FREEBSD4 */
|
||||
|
||||
void
|
||||
sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
sendsig(sig_t catcher, ksiginfo_t *kp, sigset_t *mask)
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
@ -1331,21 +1336,25 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
struct sigacts *psp;
|
||||
struct sigframe sf, *sfp;
|
||||
int oonstack, rndfsize;
|
||||
int sig;
|
||||
int code;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = kp->ksi_signo;
|
||||
code = kp->ksi_code;
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
#ifdef COMPAT_FREEBSD4
|
||||
if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
|
||||
freebsd4_sendsig(catcher, sig, mask, code);
|
||||
freebsd4_sendsig(catcher, kp, mask);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef COMPAT_43
|
||||
if (SIGISMEMBER(psp->ps_osigset, sig)) {
|
||||
osendsig(catcher, sig, mask, code);
|
||||
osendsig(catcher, kp, mask);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -1432,9 +1441,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
frame->tf_regs[FRAME_A1] = (u_int64_t)&(sfp->sf_si);
|
||||
|
||||
/* Fill in POSIX parts */
|
||||
sf.sf_si.si_signo = sig;
|
||||
sf.sf_si.si_code = code;
|
||||
sf.sf_si.si_addr = (void*)frame->tf_regs[FRAME_TRAPARG_A0];
|
||||
sf.sf_si = kp->ksi_info;
|
||||
}
|
||||
else
|
||||
frame->tf_regs[FRAME_A1] = code;
|
||||
@ -1445,25 +1452,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
alpha_pal_wrusp((unsigned long)sfp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build siginfo_t for SA thread
|
||||
*/
|
||||
void
|
||||
cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
|
||||
bzero(si, sizeof(*si));
|
||||
si->si_signo = sig;
|
||||
si->si_code = code;
|
||||
/* XXXKSE fill other fields */
|
||||
}
|
||||
|
||||
/*
|
||||
* System call to cleanup state after a signal
|
||||
* has been taken. Reset signal mask and
|
||||
|
@ -264,6 +264,7 @@ trap(a0, a1, a2, entry, framep)
|
||||
#ifdef SMP
|
||||
register_t s;
|
||||
#endif
|
||||
ksiginfo_t ksi;
|
||||
|
||||
/*
|
||||
* Find our per-cpu globals.
|
||||
@ -585,7 +586,12 @@ trap(a0, a1, a2, entry, framep)
|
||||
framep->tf_regs[FRAME_TRAPARG_A0] = a0;
|
||||
framep->tf_regs[FRAME_TRAPARG_A1] = a1;
|
||||
framep->tf_regs[FRAME_TRAPARG_A2] = a2;
|
||||
trapsignal(td, i, ucode);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = i;
|
||||
ksi.ksi_code = ucode; /* XXX, Should be POSIX si_code */
|
||||
ksi.ksi_addr = (void *)a0;
|
||||
trapsignal(td, &ksi);
|
||||
|
||||
out:
|
||||
if (user) {
|
||||
framep->tf_regs[FRAME_SP] = alpha_pal_rdusp();
|
||||
|
@ -77,7 +77,7 @@ MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
|
||||
|
||||
SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler);
|
||||
|
||||
void osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code);
|
||||
void osendsig(sig_t catcher, ksiginfo_t *kp, sigset_t *mask);
|
||||
|
||||
static int elf_linux_fixup(register_t **stack_base,
|
||||
struct image_params *iparams);
|
||||
|
@ -459,7 +459,7 @@ osf1_kill(td, uap)
|
||||
*/
|
||||
|
||||
void
|
||||
osf1_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
osf1_sendsig(sig_t catcher, ksiginfo_t *kp, sigset_t *mask)
|
||||
{
|
||||
int fsize, oonstack, rndfsize;
|
||||
struct thread *td;
|
||||
@ -467,10 +467,14 @@ osf1_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
osiginfo_t *sip, ksi;
|
||||
struct trapframe *frame;
|
||||
struct sigacts *psp;
|
||||
int sig;
|
||||
int code;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = kp->ksi_signo;
|
||||
code = kp->ksi_code;
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
|
||||
@ -526,7 +530,7 @@ osf1_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
/* Fill in POSIX parts */
|
||||
ksi.si_signo = sig;
|
||||
ksi.si_code = code;
|
||||
ksi.si_value.sigval_ptr = NULL; /* XXX */
|
||||
ksi.si_value = kp->ksi_value;
|
||||
|
||||
/*
|
||||
* copy the frame out to userland.
|
||||
|
@ -61,7 +61,7 @@ void bsd_to_osf1_sigaltstack(const struct sigaltstack *, struct osf1_sigaltstack
|
||||
void bsd_to_osf1_sigset(const sigset_t *, osf1_sigset_t *);
|
||||
void osf1_to_bsd_sigaltstack(const struct osf1_sigaltstack *, struct sigaltstack *);
|
||||
void osf1_to_bsd_sigset(const osf1_sigset_t *, sigset_t *);
|
||||
void osf1_sendsig(sig_t, int , sigset_t *, u_long );
|
||||
void osf1_sendsig(sig_t, struct ksiginfo *, sigset_t *);
|
||||
|
||||
|
||||
#endif /* !_OSF1_SIGNAL_H */
|
||||
|
@ -237,11 +237,7 @@ cpu_startup(dummy)
|
||||
* specified pc, psl.
|
||||
*/
|
||||
void
|
||||
sendsig(catcher, sig, mask, code)
|
||||
sig_t catcher;
|
||||
int sig;
|
||||
sigset_t *mask;
|
||||
u_long code;
|
||||
sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
struct sigframe sf, *sfp;
|
||||
struct proc *p;
|
||||
@ -250,10 +246,12 @@ sendsig(catcher, sig, mask, code)
|
||||
char *sp;
|
||||
struct trapframe *regs;
|
||||
int oonstack;
|
||||
int sig;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = ksi->ksi_signo;
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
regs = td->td_frame;
|
||||
@ -297,13 +295,13 @@ sendsig(catcher, sig, mask, code)
|
||||
sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
|
||||
|
||||
/* Fill in POSIX parts */
|
||||
sf.sf_si.si_signo = sig;
|
||||
sf.sf_si.si_code = code;
|
||||
regs->tf_rcx = regs->tf_addr; /* arg 4 in %rcx */
|
||||
sf.sf_si = ksi->ksi_info;
|
||||
sf.sf_si.si_signo = sig; /* maybe a translated signal */
|
||||
regs->tf_rcx = (register_t)ksi->ksi_addr; /* arg 4 in %rcx */
|
||||
} else {
|
||||
/* Old FreeBSD-style arguments. */
|
||||
regs->tf_rsi = code; /* arg 2 in %rsi */
|
||||
regs->tf_rcx = regs->tf_addr; /* arg 4 in %rcx */
|
||||
regs->tf_rsi = ksi->ksi_code; /* arg 2 in %rsi */
|
||||
regs->tf_rcx = (register_t)ksi->ksi_addr; /* arg 4 in %rcx */
|
||||
sf.sf_ahu.sf_handler = catcher;
|
||||
}
|
||||
mtx_unlock(&psp->ps_mtx);
|
||||
@ -328,28 +326,6 @@ sendsig(catcher, sig, mask, code)
|
||||
mtx_lock(&psp->ps_mtx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build siginfo_t for SA thread
|
||||
*/
|
||||
void
|
||||
cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
struct trapframe *regs;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
regs = td->td_frame;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
|
||||
bzero(si, sizeof(*si));
|
||||
si->si_signo = sig;
|
||||
si->si_code = code;
|
||||
si->si_addr = (void *)regs->tf_addr;
|
||||
/* XXXKSE fill other fields */
|
||||
}
|
||||
|
||||
/*
|
||||
* System call to cleanup state after a signal
|
||||
* has been taken. Reset signal mask and
|
||||
@ -374,6 +350,7 @@ sigreturn(td, uap)
|
||||
const ucontext_t *ucp;
|
||||
long rflags;
|
||||
int cs, error, ret;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
error = copyin(uap->sigcntxp, &uc, sizeof(uc));
|
||||
if (error != 0)
|
||||
@ -407,7 +384,12 @@ sigreturn(td, uap)
|
||||
cs = ucp->uc_mcontext.mc_cs;
|
||||
if (!CS_SECURE(cs)) {
|
||||
printf("sigreturn: cs = 0x%x\n", cs);
|
||||
trapsignal(td, SIGBUS, T_PROTFLT);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_trapno = T_PROTFLT;
|
||||
ksi.ksi_addr = (void *)regs->tf_rip;
|
||||
trapsignal(td, &ksi);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
|
@ -161,6 +161,8 @@ trap(frame)
|
||||
struct proc *p = td->td_proc;
|
||||
u_int sticks = 0;
|
||||
int i = 0, ucode = 0, type, code;
|
||||
register_t addr = 0;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
PCPU_LAZY_INC(cnt.v_trap);
|
||||
type = frame.tf_trapno;
|
||||
@ -241,13 +243,14 @@ trap(frame)
|
||||
|
||||
sticks = td->td_sticks;
|
||||
td->td_frame = &frame;
|
||||
addr = frame.tf_rip;
|
||||
if (td->td_ucred != p->p_ucred)
|
||||
cred_update_thread(td);
|
||||
|
||||
switch (type) {
|
||||
case T_PRIVINFLT: /* privileged instruction fault */
|
||||
ucode = type;
|
||||
i = SIGILL;
|
||||
ucode = ILL_PRVOPC;
|
||||
break;
|
||||
|
||||
case T_BPTFLT: /* bpt instruction fault */
|
||||
@ -255,6 +258,7 @@ trap(frame)
|
||||
enable_intr();
|
||||
frame.tf_rflags &= ~PSL_T;
|
||||
i = SIGTRAP;
|
||||
ucode = (type == T_TRCTRAP ? TRAP_TRACE : TRAP_BRKPT);
|
||||
break;
|
||||
|
||||
case T_ARITHTRAP: /* arithmetic trap */
|
||||
@ -265,16 +269,26 @@ trap(frame)
|
||||
break;
|
||||
|
||||
case T_PROTFLT: /* general protection fault */
|
||||
i = SIGBUS;
|
||||
ucode = BUS_OBJERR;
|
||||
break;
|
||||
case T_STKFLT: /* stack fault */
|
||||
case T_SEGNPFLT: /* segment not present fault */
|
||||
i = SIGBUS;
|
||||
ucode = BUS_ADRERR;
|
||||
break;
|
||||
case T_TSSFLT: /* invalid TSS fault */
|
||||
i = SIGBUS;
|
||||
ucode = BUS_OBJERR;
|
||||
break;
|
||||
case T_DOUBLEFLT: /* double fault */
|
||||
default:
|
||||
ucode = code + BUS_SEGM_FAULT ;
|
||||
i = SIGBUS;
|
||||
ucode = BUS_OBJERR;
|
||||
break;
|
||||
|
||||
case T_PAGEFLT: /* page fault */
|
||||
addr = frame.tf_addr;
|
||||
if (td->td_pflags & TDP_SA)
|
||||
thread_user_enter(td);
|
||||
i = trap_pfault(&frame, TRUE);
|
||||
@ -283,7 +297,12 @@ trap(frame)
|
||||
if (i == 0)
|
||||
goto user;
|
||||
|
||||
ucode = T_PAGEFLT;
|
||||
if (i == SIGSEGV)
|
||||
ucode = SEGV_MAPERR;
|
||||
else {
|
||||
i = SIGSEGV; /* XXX hack */
|
||||
ucode = SEGV_ACCERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case T_DIVIDE: /* integer divide fault */
|
||||
@ -326,12 +345,14 @@ trap(frame)
|
||||
/* transparent fault (due to context switch "late") */
|
||||
if (fpudna())
|
||||
goto userout;
|
||||
i = SIGFPE;
|
||||
ucode = FPE_FPU_NP_TRAP;
|
||||
printf("pid %d killed due to lack of floating point\n",
|
||||
p->p_pid);
|
||||
i = SIGKILL;
|
||||
ucode = 0;
|
||||
break;
|
||||
|
||||
case T_FPOPFLT: /* FPU operand fetch fault */
|
||||
ucode = T_FPOPFLT;
|
||||
ucode = ILL_COPROC;
|
||||
i = SIGILL;
|
||||
break;
|
||||
|
||||
@ -472,7 +493,12 @@ trap(frame)
|
||||
if (*p->p_sysent->sv_transtrap)
|
||||
i = (*p->p_sysent->sv_transtrap)(i, type);
|
||||
|
||||
trapsignal(td, i, ucode);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = i;
|
||||
ksi.ksi_code = ucode;
|
||||
ksi.ksi_trapno = type;
|
||||
ksi.ksi_addr = (void *)addr;
|
||||
trapsignal(td, &ksi);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (type <= MAX_TRAP_MSG) {
|
||||
@ -696,6 +722,7 @@ syscall(frame)
|
||||
register_t *argp;
|
||||
u_int code;
|
||||
int reg, regcnt;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
/*
|
||||
* note: PCPU_LAZY_INC() can only be used if we can afford
|
||||
@ -826,7 +853,12 @@ syscall(frame)
|
||||
*/
|
||||
if (orig_tf_rflags & PSL_T) {
|
||||
frame.tf_rflags &= ~PSL_T;
|
||||
trapsignal(td, SIGTRAP, 0);
|
||||
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGTRAP;
|
||||
ksi.ksi_code = TRAP_TRACE;
|
||||
ksi.ksi_addr = (void *)frame.tf_rip;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -79,7 +79,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/cpufunc.h>
|
||||
|
||||
#ifdef COMPAT_FREEBSD4
|
||||
static void freebsd4_ia32_sendsig(sig_t, int, sigset_t *, u_long);
|
||||
static void freebsd4_ia32_sendsig(sig_t, ksiginfo_t *, sigset_t *);
|
||||
#endif
|
||||
static void ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp);
|
||||
static int ia32_set_fpcontext(struct thread *td, const struct ia32_mcontext *mcp);
|
||||
@ -295,18 +295,23 @@ freebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap)
|
||||
*/
|
||||
#ifdef COMPAT_FREEBSD4
|
||||
static void
|
||||
freebsd4_ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
struct ia32_sigframe4 sf, *sfp;
|
||||
struct ia32_siginfo siginfo;
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
struct sigacts *psp;
|
||||
struct trapframe *regs;
|
||||
int oonstack;
|
||||
int sig;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
siginfo_to_ia32siginfo(&ksi->ksi_info, &siginfo);
|
||||
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = siginfo.si_signo;
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
regs = td->td_frame;
|
||||
@ -362,13 +367,12 @@ freebsd4_ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
|
||||
|
||||
/* Fill in POSIX parts */
|
||||
sf.sf_si = siginfo;
|
||||
sf.sf_si.si_signo = sig;
|
||||
sf.sf_si.si_code = code;
|
||||
sf.sf_si.si_addr = regs->tf_addr;
|
||||
} else {
|
||||
/* Old FreeBSD-style arguments. */
|
||||
sf.sf_siginfo = code;
|
||||
sf.sf_addr = regs->tf_addr;
|
||||
sf.sf_siginfo = siginfo.si_code;
|
||||
sf.sf_addr = (u_int32_t)siginfo.si_addr;
|
||||
sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
|
||||
}
|
||||
mtx_unlock(&psp->ps_mtx);
|
||||
@ -400,23 +404,27 @@ freebsd4_ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
#endif /* COMPAT_FREEBSD4 */
|
||||
|
||||
void
|
||||
ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
struct ia32_sigframe sf, *sfp;
|
||||
struct ia32_siginfo siginfo;
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
struct sigacts *psp;
|
||||
char *sp;
|
||||
struct trapframe *regs;
|
||||
int oonstack;
|
||||
int sig;
|
||||
|
||||
siginfo_to_ia32siginfo(&ksi->ksi_info, &siginfo);
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = siginfo.si_signo;
|
||||
psp = p->p_sigacts;
|
||||
#ifdef COMPAT_FREEBSD4
|
||||
if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
|
||||
freebsd4_ia32_sendsig(catcher, sig, mask, code);
|
||||
freebsd4_ia32_sendsig(catcher, ksi, mask);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -479,13 +487,12 @@ ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
|
||||
|
||||
/* Fill in POSIX parts */
|
||||
sf.sf_si = siginfo;
|
||||
sf.sf_si.si_signo = sig;
|
||||
sf.sf_si.si_code = code;
|
||||
sf.sf_si.si_addr = regs->tf_addr;
|
||||
} else {
|
||||
/* Old FreeBSD-style arguments. */
|
||||
sf.sf_siginfo = code;
|
||||
sf.sf_addr = regs->tf_addr;
|
||||
sf.sf_siginfo = siginfo.si_code;
|
||||
sf.sf_addr = (u_int32_t)siginfo.si_addr;
|
||||
sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
|
||||
}
|
||||
mtx_unlock(&psp->ps_mtx);
|
||||
@ -540,6 +547,7 @@ freebsd4_freebsd32_sigreturn(td, uap)
|
||||
struct trapframe *regs;
|
||||
const struct ia32_ucontext4 *ucp;
|
||||
int cs, eflags, error;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
error = copyin(uap->sigcntxp, &uc, sizeof(uc));
|
||||
if (error != 0)
|
||||
@ -573,7 +581,12 @@ freebsd4_freebsd32_sigreturn(td, uap)
|
||||
cs = ucp->uc_mcontext.mc_cs;
|
||||
if (!CS_SECURE(cs)) {
|
||||
printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
|
||||
trapsignal(td, SIGBUS, T_PROTFLT);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_trapno = T_PROTFLT;
|
||||
ksi.ksi_addr = (void *)regs->tf_rip;
|
||||
trapsignal(td, &ksi);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
@ -617,6 +630,7 @@ freebsd32_sigreturn(td, uap)
|
||||
struct trapframe *regs;
|
||||
const struct ia32_ucontext *ucp;
|
||||
int cs, eflags, error, ret;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
error = copyin(uap->sigcntxp, &uc, sizeof(uc));
|
||||
if (error != 0)
|
||||
@ -650,7 +664,12 @@ freebsd32_sigreturn(td, uap)
|
||||
cs = ucp->uc_mcontext.mc_cs;
|
||||
if (!CS_SECURE(cs)) {
|
||||
printf("sigreturn: cs = 0x%x\n", cs);
|
||||
trapsignal(td, SIGBUS, T_PROTFLT);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_trapno = T_PROTFLT;
|
||||
ksi.ksi_addr = (void *)regs->tf_rip;
|
||||
trapsignal(td, &ksi);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
@ -722,3 +741,18 @@ ia32_setregs(td, entry, stack, ps_strings)
|
||||
pcb->pcb_flags |= PCB_FULLCTX;
|
||||
td->td_retval[1] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
siginfo_to_ia32siginfo(siginfo_t *src, struct ia32_siginfo *dst)
|
||||
{
|
||||
dst->si_signo = src->si_signo;
|
||||
dst->si_errno = src->si_errno;
|
||||
dst->si_code = src->si_code;
|
||||
dst->si_pid = src->si_pid;
|
||||
dst->si_uid = src->si_uid;
|
||||
dst->si_status = src->si_status;
|
||||
dst->si_addr = dst->si_addr;
|
||||
dst->si_value.sigval_int = src->si_value.sigval_int;
|
||||
dst->si_band = src->si_band;
|
||||
dst->__spare__[0] = src->si_trapno;
|
||||
}
|
||||
|
@ -101,6 +101,7 @@ ia32_syscall(struct trapframe frame)
|
||||
u_int32_t args[8];
|
||||
u_int64_t args64[8];
|
||||
u_int code;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
/*
|
||||
* note: PCPU_LAZY_INC() can only be used if we can afford
|
||||
@ -227,7 +228,11 @@ ia32_syscall(struct trapframe frame)
|
||||
*/
|
||||
if (orig_tf_rflags & PSL_T) {
|
||||
frame.tf_rflags &= ~PSL_T;
|
||||
trapsignal(td, SIGTRAP, 0);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGTRAP;
|
||||
ksi.ksi_code = TRAP_TRACE;
|
||||
ksi.ksi_addr = (void *)frame.tf_rip;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -120,8 +120,7 @@ static int elf_linux_fixup(register_t **stack_base,
|
||||
static register_t *linux_copyout_strings(struct image_params *imgp);
|
||||
static void linux_prepsyscall(struct trapframe *tf, int *args, u_int *code,
|
||||
caddr_t *params);
|
||||
static void linux_sendsig(sig_t catcher, int sig, sigset_t *mask,
|
||||
u_long code);
|
||||
static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
|
||||
static void exec_linux_setregs(struct thread *td, u_long entry,
|
||||
u_long stack, u_long ps_strings);
|
||||
static void linux32_fixlimits(struct image_params *imgp);
|
||||
@ -275,7 +274,7 @@ extern int _ucodesel, _ucode32sel, _udatasel;
|
||||
extern unsigned long linux_sznonrtsigcode;
|
||||
|
||||
static void
|
||||
linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
struct thread *td = curthread;
|
||||
struct proc *p = td->td_proc;
|
||||
@ -283,7 +282,11 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
struct trapframe *regs;
|
||||
struct l_rt_sigframe *fp, frame;
|
||||
int oonstack;
|
||||
|
||||
int sig;
|
||||
int code;
|
||||
|
||||
sig = ksi->ksi_signo;
|
||||
code = ksi->ksi_code;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
@ -323,7 +326,7 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
/* Fill in POSIX parts */
|
||||
frame.sf_si.lsi_signo = sig;
|
||||
frame.sf_si.lsi_code = code;
|
||||
frame.sf_si.lsi_addr = PTROUT(regs->tf_err);
|
||||
frame.sf_si.lsi_addr = PTROUT(ksi->ksi_addr);
|
||||
|
||||
/*
|
||||
* Build the signal context to be used by sigreturn.
|
||||
@ -411,7 +414,7 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
* specified pc, psl.
|
||||
*/
|
||||
static void
|
||||
linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
struct thread *td = curthread;
|
||||
struct proc *p = td->td_proc;
|
||||
@ -420,13 +423,16 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
struct l_sigframe *fp, frame;
|
||||
l_sigset_t lmask;
|
||||
int oonstack, i;
|
||||
int sig, code;
|
||||
|
||||
sig = ksi->ksi_signo;
|
||||
code = ksi->ksi_code;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
if (SIGISMEMBER(psp->ps_siginfo, sig)) {
|
||||
/* Signal handler installed with SA_SIGINFO. */
|
||||
linux_rt_sendsig(catcher, sig, mask, code);
|
||||
linux_rt_sendsig(catcher, ksi, mask);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -534,6 +540,7 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
|
||||
struct trapframe *regs;
|
||||
l_sigset_t lmask;
|
||||
int eflags, i;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
regs = td->td_frame;
|
||||
|
||||
@ -574,7 +581,12 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
|
||||
*/
|
||||
#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
|
||||
if (!CS_SECURE(frame.sf_sc.sc_cs)) {
|
||||
trapsignal(td, SIGBUS, T_PROTFLT);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_trapno = T_PROTFLT;
|
||||
ksi.ksi_addr = (void *)regs->tf_rip;
|
||||
trapsignal(td, &ksi);
|
||||
return(EINVAL);
|
||||
}
|
||||
|
||||
@ -627,6 +639,7 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
|
||||
stack_t ss;
|
||||
struct trapframe *regs;
|
||||
int eflags;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
regs = td->td_frame;
|
||||
|
||||
@ -669,7 +682,12 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
|
||||
*/
|
||||
#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
|
||||
if (!CS_SECURE(context->sc_cs)) {
|
||||
trapsignal(td, SIGBUS, T_PROTFLT);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_trapno = T_PROTFLT;
|
||||
ksi.ksi_addr = (void *)regs->tf_rip;
|
||||
trapsignal(td, &ksi);
|
||||
return(EINVAL);
|
||||
}
|
||||
|
||||
|
@ -101,11 +101,10 @@ int _min_memcpy_size = 0;
|
||||
int _min_bzero_size = 0;
|
||||
|
||||
void
|
||||
sendsig(catcher, sig, mask, code)
|
||||
sendsig(catcher, ksi, mask)
|
||||
sig_t catcher;
|
||||
int sig;
|
||||
ksiginfo_t *ksi;
|
||||
sigset_t *mask;
|
||||
u_long code;
|
||||
{
|
||||
struct thread *td = curthread;
|
||||
struct proc *p = td->td_proc;
|
||||
@ -113,9 +112,13 @@ sendsig(catcher, sig, mask, code)
|
||||
struct sigframe *fp, frame;
|
||||
struct sigacts *psp = td->td_proc->p_sigacts;
|
||||
int onstack;
|
||||
int sig;
|
||||
int code;
|
||||
|
||||
onstack = sigonstack(td->td_frame->tf_usr_sp);
|
||||
|
||||
sig = ksi->ksi_signo;
|
||||
code = ksi->ksi_code;
|
||||
if ((td->td_flags & TDP_ALTSTACK) &&
|
||||
!(onstack) &&
|
||||
SIGISMEMBER(td->td_proc->p_sigacts->ps_sigonstack, sig)) {
|
||||
@ -130,8 +133,7 @@ sendsig(catcher, sig, mask, code)
|
||||
/* make the stack aligned */
|
||||
fp = (struct sigframe *)STACKALIGN(fp);
|
||||
/* Populate the siginfo frame. */
|
||||
frame.sf_si.si_signo = sig;
|
||||
frame.sf_si.si_code = code;
|
||||
frame.sf_si = ksi->ksi_info;
|
||||
frame.sf_uc.uc_sigmask = *mask;
|
||||
frame.sf_uc.uc_link = NULL;
|
||||
frame.sf_uc.uc_flags = (td->td_pflags & TDP_ALTSTACK )
|
||||
@ -435,17 +437,6 @@ exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
|
||||
tf->tf_spsr = PSR_USR32_MODE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build siginfo_t for SA thread
|
||||
*/
|
||||
void
|
||||
cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
|
||||
{
|
||||
bzero(si, sizeof(*si));
|
||||
si->si_signo = sig;
|
||||
si->si_code = code;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get machine context.
|
||||
*/
|
||||
|
@ -184,8 +184,12 @@ static const struct data_abort data_aborts[] = {
|
||||
static __inline void
|
||||
call_trapsignal(struct thread *td, int sig, u_long code)
|
||||
{
|
||||
ksiginfo_t ksi;
|
||||
|
||||
trapsignal(td, sig, code);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = sig;
|
||||
ksi.ksi_code = (int)code;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
@ -875,7 +879,7 @@ syscall(struct thread *td, trapframe_t *frame, u_int32_t insn)
|
||||
nap = 4;
|
||||
break;
|
||||
default:
|
||||
trapsignal(td, SIGILL, 0);
|
||||
call_trapsignal(td, SIGILL, 0);
|
||||
userret(td, frame, td->td_sticks);
|
||||
return;
|
||||
}
|
||||
@ -993,7 +997,7 @@ swi_handler(trapframe_t *frame)
|
||||
* don't take an alignment fault trying to read the opcode.
|
||||
*/
|
||||
if (__predict_false(((frame->tf_pc - INSN_SIZE) & 3) != 0)) {
|
||||
trapsignal(td, SIGILL, 0);
|
||||
call_trapsignal(td, SIGILL, 0);
|
||||
userret(td, frame, td->td_sticks);
|
||||
return;
|
||||
}
|
||||
|
@ -134,11 +134,17 @@ static int
|
||||
gdb_trapper(u_int addr, u_int insn, struct trapframe *frame, int code)
|
||||
{
|
||||
struct thread *td;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
td = (curthread == NULL) ? &thread0 : curthread;
|
||||
|
||||
if (insn == GDB_BREAKPOINT || insn == GDB5_BREAKPOINT) {
|
||||
if (code == FAULT_USER) {
|
||||
trapsignal(td, SIGTRAP, 0);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGTRAP;
|
||||
ksi.ksi_code = TRAP_BRKPT;
|
||||
ksi.ksi_addr = (u_int32_t *)addr;
|
||||
trapsignal(td, &ksi);
|
||||
return 0;
|
||||
}
|
||||
#if 0
|
||||
@ -179,6 +185,7 @@ undefinedinstruction(trapframe_t *frame)
|
||||
#ifdef VERBOSE_ARM32
|
||||
int s;
|
||||
#endif
|
||||
ksiginfo_t ksi;
|
||||
|
||||
/* Enable interrupts if they were enabled before the exception. */
|
||||
if (!(frame->tf_spsr & I32_bit))
|
||||
@ -200,7 +207,11 @@ undefinedinstruction(trapframe_t *frame)
|
||||
* don't take an alignment fault trying to read the opcode.
|
||||
*/
|
||||
if (__predict_false((fault_pc & 3) != 0)) {
|
||||
trapsignal(td, SIGILL, 0);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGILL;
|
||||
ksi.ksi_code = ILL_ILLADR;
|
||||
ksi.ksi_addr = (u_int32_t *)(intptr_t) fault_pc;
|
||||
trapsignal(td, &ksi);
|
||||
userret(td, frame, 0);
|
||||
return;
|
||||
}
|
||||
@ -256,7 +267,11 @@ undefinedinstruction(trapframe_t *frame)
|
||||
|
||||
if (uh == NULL && (fault_code & FAULT_USER)) {
|
||||
/* Fault has not been handled */
|
||||
trapsignal(td, SIGILL, 0);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGILL;
|
||||
ksi.ksi_code = ILL_ILLOPC;
|
||||
ksi.ksi_addr = (u_int32_t *)(intptr_t) fault_pc;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
|
||||
if ((fault_code & FAULT_USER) == 0) {
|
||||
|
@ -199,10 +199,12 @@ struct ia32_sigframe3 {
|
||||
};
|
||||
#endif
|
||||
|
||||
struct ksiginfo;
|
||||
extern char ia32_sigcode[];
|
||||
extern char freebsd4_ia32_sigcode[];
|
||||
extern int sz_ia32_sigcode;
|
||||
extern int sz_freebsd4_ia32_sigcode;
|
||||
extern void ia32_sendsig(sig_t, int, sigset_t *, u_long);
|
||||
extern void ia32_sendsig(sig_t, struct ksiginfo *, sigset_t *);
|
||||
extern void ia32_setregs(struct thread *td, u_long entry, u_long stack,
|
||||
u_long ps_strings);
|
||||
extern void siginfo_to_ia32siginfo(siginfo_t *src, struct ia32_siginfo *dst);
|
||||
|
@ -862,7 +862,7 @@ linux_wait4(struct thread *td, struct linux_wait4_args *args)
|
||||
|
||||
p = td->td_proc;
|
||||
PROC_LOCK(p);
|
||||
SIGDELSET(p->p_siglist, SIGCHLD);
|
||||
sigqueue_delete(&p->p_sigqueue, SIGCHLD);
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
if (args->status) {
|
||||
|
@ -133,10 +133,12 @@ struct svr4_sigaltstack {
|
||||
|
||||
#define SVR4_MINSIGSTKSZ 8192
|
||||
|
||||
struct ksiginfo;
|
||||
|
||||
void bsd_to_svr4_sigaltstack(const struct sigaltstack *, struct svr4_sigaltstack *);
|
||||
void bsd_to_svr4_sigset(const sigset_t *, svr4_sigset_t *);
|
||||
void svr4_to_bsd_sigaltstack(const struct svr4_sigaltstack *, struct sigaltstack *);
|
||||
void svr4_to_bsd_sigset(const svr4_sigset_t *, sigset_t *);
|
||||
void svr4_sendsig(sig_t, int, sigset_t *, u_long);
|
||||
void svr4_sendsig(sig_t, struct ksiginfo *, sigset_t *);
|
||||
|
||||
#endif /* !_SVR4_SIGNAL_H_ */
|
||||
|
@ -215,7 +215,7 @@ procfs_control(struct thread *td, struct proc *p, int op)
|
||||
p->p_flag &= ~P_TRACED;
|
||||
|
||||
/* remove pending SIGTRAP, else the process will die */
|
||||
SIGDELSET(p->p_siglist, SIGTRAP);
|
||||
sigqueue_delete_proc(p, SIGTRAP);
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
/* give process back to original parent */
|
||||
|
@ -171,11 +171,10 @@ u_int basemem;
|
||||
int cold = 1;
|
||||
|
||||
#ifdef COMPAT_43
|
||||
static void osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code);
|
||||
static void osendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask);
|
||||
#endif
|
||||
#ifdef COMPAT_FREEBSD4
|
||||
static void freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask,
|
||||
u_long code);
|
||||
static void freebsd4_sendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask);
|
||||
#endif
|
||||
|
||||
long Maxmem = 0;
|
||||
@ -261,22 +260,20 @@ cpu_startup(dummy)
|
||||
*/
|
||||
#ifdef COMPAT_43
|
||||
static void
|
||||
osendsig(catcher, sig, mask, code)
|
||||
sig_t catcher;
|
||||
int sig;
|
||||
sigset_t *mask;
|
||||
u_long code;
|
||||
osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
struct osigframe sf, *fp;
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
struct sigacts *psp;
|
||||
struct trapframe *regs;
|
||||
int sig;
|
||||
int oonstack;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = ksi->ksi_signo;
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
regs = td->td_frame;
|
||||
@ -304,12 +301,12 @@ osendsig(catcher, sig, mask, code)
|
||||
/* Signal handler installed with SA_SIGINFO. */
|
||||
sf.sf_arg2 = (register_t)&fp->sf_siginfo;
|
||||
sf.sf_siginfo.si_signo = sig;
|
||||
sf.sf_siginfo.si_code = code;
|
||||
sf.sf_siginfo.si_code = ksi->ksi_code;
|
||||
sf.sf_ahu.sf_action = (__osiginfohandler_t *)catcher;
|
||||
} else {
|
||||
/* Old FreeBSD-style arguments. */
|
||||
sf.sf_arg2 = code;
|
||||
sf.sf_addr = regs->tf_err;
|
||||
sf.sf_arg2 = ksi->ksi_code;
|
||||
sf.sf_addr = (register_t)ksi->ksi_addr;
|
||||
sf.sf_ahu.sf_handler = catcher;
|
||||
}
|
||||
mtx_unlock(&psp->ps_mtx);
|
||||
@ -391,22 +388,20 @@ osendsig(catcher, sig, mask, code)
|
||||
|
||||
#ifdef COMPAT_FREEBSD4
|
||||
static void
|
||||
freebsd4_sendsig(catcher, sig, mask, code)
|
||||
sig_t catcher;
|
||||
int sig;
|
||||
sigset_t *mask;
|
||||
u_long code;
|
||||
freebsd4_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
struct sigframe4 sf, *sfp;
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
struct sigacts *psp;
|
||||
struct trapframe *regs;
|
||||
int sig;
|
||||
int oonstack;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = ksi->ksi_signo;
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
regs = td->td_frame;
|
||||
@ -447,12 +442,12 @@ freebsd4_sendsig(catcher, sig, mask, code)
|
||||
|
||||
/* Fill in POSIX parts */
|
||||
sf.sf_si.si_signo = sig;
|
||||
sf.sf_si.si_code = code;
|
||||
sf.sf_si.si_addr = (void *)regs->tf_err;
|
||||
sf.sf_si.si_code = ksi->ksi_code;
|
||||
sf.sf_si.si_addr = ksi->ksi_addr;
|
||||
} else {
|
||||
/* Old FreeBSD-style arguments. */
|
||||
sf.sf_siginfo = code;
|
||||
sf.sf_addr = regs->tf_err;
|
||||
sf.sf_siginfo = ksi->ksi_code;
|
||||
sf.sf_addr = (register_t)ksi->ksi_addr;
|
||||
sf.sf_ahu.sf_handler = catcher;
|
||||
}
|
||||
mtx_unlock(&psp->ps_mtx);
|
||||
@ -512,11 +507,7 @@ freebsd4_sendsig(catcher, sig, mask, code)
|
||||
#endif /* COMPAT_FREEBSD4 */
|
||||
|
||||
void
|
||||
sendsig(catcher, sig, mask, code)
|
||||
sig_t catcher;
|
||||
int sig;
|
||||
sigset_t *mask;
|
||||
u_long code;
|
||||
sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
struct sigframe sf, *sfp;
|
||||
struct proc *p;
|
||||
@ -524,22 +515,24 @@ sendsig(catcher, sig, mask, code)
|
||||
struct sigacts *psp;
|
||||
char *sp;
|
||||
struct trapframe *regs;
|
||||
int sig;
|
||||
int oonstack;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = ksi->ksi_signo;
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
#ifdef COMPAT_FREEBSD4
|
||||
if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
|
||||
freebsd4_sendsig(catcher, sig, mask, code);
|
||||
freebsd4_sendsig(catcher, ksi, mask);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef COMPAT_43
|
||||
if (SIGISMEMBER(psp->ps_osigset, sig)) {
|
||||
osendsig(catcher, sig, mask, code);
|
||||
osendsig(catcher, ksi, mask);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -585,13 +578,12 @@ sendsig(catcher, sig, mask, code)
|
||||
sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
|
||||
|
||||
/* Fill in POSIX parts */
|
||||
sf.sf_si.si_signo = sig;
|
||||
sf.sf_si.si_code = code;
|
||||
sf.sf_si.si_addr = (void *)regs->tf_err;
|
||||
sf.sf_si = ksi->ksi_info;
|
||||
sf.sf_si.si_signo = sig; /* maybe a translated signal */
|
||||
} else {
|
||||
/* Old FreeBSD-style arguments. */
|
||||
sf.sf_siginfo = code;
|
||||
sf.sf_addr = regs->tf_err;
|
||||
sf.sf_siginfo = ksi->ksi_code;
|
||||
sf.sf_addr = (register_t)ksi->ksi_addr;
|
||||
sf.sf_ahu.sf_handler = catcher;
|
||||
}
|
||||
mtx_unlock(&psp->ps_mtx);
|
||||
@ -649,26 +641,6 @@ sendsig(catcher, sig, mask, code)
|
||||
mtx_lock(&psp->ps_mtx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build siginfo_t for SA thread
|
||||
*/
|
||||
void
|
||||
cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
|
||||
bzero(si, sizeof(*si));
|
||||
si->si_signo = sig;
|
||||
si->si_code = code;
|
||||
si->si_addr = (void *)td->td_frame->tf_err;
|
||||
/* XXXKSE fill other fields */
|
||||
}
|
||||
|
||||
/*
|
||||
* System call to cleanup state after a signal
|
||||
* has been taken. Reset signal mask and
|
||||
@ -693,6 +665,7 @@ osigreturn(td, uap)
|
||||
struct osigcontext *scp;
|
||||
struct proc *p = td->td_proc;
|
||||
int eflags, error;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
regs = td->td_frame;
|
||||
error = copyin(uap->sigcntxp, &sc, sizeof(sc));
|
||||
@ -715,8 +688,13 @@ osigreturn(td, uap)
|
||||
return (EINVAL);
|
||||
|
||||
/* Go back to user mode if both flags are set. */
|
||||
if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
|
||||
trapsignal(td, SIGBUS, 0);
|
||||
if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) {
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_addr = (void *)regs->tf_eip;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
|
||||
if (vm86->vm86_has_vme) {
|
||||
eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
|
||||
@ -757,7 +735,12 @@ osigreturn(td, uap)
|
||||
* other selectors, invalid %eip's and invalid %esp's.
|
||||
*/
|
||||
if (!CS_SECURE(scp->sc_cs)) {
|
||||
trapsignal(td, SIGBUS, T_PROTFLT);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_trapno = T_PROTFLT;
|
||||
ksi.ksi_addr = (void *)regs->tf_eip;
|
||||
trapsignal(td, &ksi);
|
||||
return (EINVAL);
|
||||
}
|
||||
regs->tf_ds = scp->sc_ds;
|
||||
@ -811,6 +794,7 @@ freebsd4_sigreturn(td, uap)
|
||||
struct trapframe *regs;
|
||||
const struct ucontext4 *ucp;
|
||||
int cs, eflags, error;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
error = copyin(uap->sigcntxp, &uc, sizeof(uc));
|
||||
if (error != 0)
|
||||
@ -833,9 +817,13 @@ freebsd4_sigreturn(td, uap)
|
||||
return (EINVAL);
|
||||
|
||||
/* Go back to user mode if both flags are set. */
|
||||
if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
|
||||
trapsignal(td, SIGBUS, 0);
|
||||
|
||||
if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) {
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_addr = (void *)regs->tf_eip;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
if (vm86->vm86_has_vme) {
|
||||
eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
|
||||
(eflags & VME_USERCHANGE) | PSL_VM;
|
||||
@ -880,7 +868,12 @@ freebsd4_sigreturn(td, uap)
|
||||
cs = ucp->uc_mcontext.mc_cs;
|
||||
if (!CS_SECURE(cs)) {
|
||||
printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
|
||||
trapsignal(td, SIGBUS, T_PROTFLT);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_trapno = T_PROTFLT;
|
||||
ksi.ksi_addr = (void *)regs->tf_eip;
|
||||
trapsignal(td, &ksi);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
@ -918,6 +911,7 @@ sigreturn(td, uap)
|
||||
struct trapframe *regs;
|
||||
const ucontext_t *ucp;
|
||||
int cs, eflags, error, ret;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
error = copyin(uap->sigcntxp, &uc, sizeof(uc));
|
||||
if (error != 0)
|
||||
@ -940,8 +934,13 @@ sigreturn(td, uap)
|
||||
return (EINVAL);
|
||||
|
||||
/* Go back to user mode if both flags are set. */
|
||||
if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
|
||||
trapsignal(td, SIGBUS, 0);
|
||||
if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) {
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_addr = (void *)regs->tf_eip;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
|
||||
if (vm86->vm86_has_vme) {
|
||||
eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
|
||||
@ -987,7 +986,12 @@ sigreturn(td, uap)
|
||||
cs = ucp->uc_mcontext.mc_cs;
|
||||
if (!CS_SECURE(cs)) {
|
||||
printf("sigreturn: cs = 0x%x\n", cs);
|
||||
trapsignal(td, SIGBUS, T_PROTFLT);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_trapno = T_PROTFLT;
|
||||
ksi.ksi_addr = (void *)regs->tf_eip;
|
||||
trapsignal(td, &ksi);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,9 @@ trap(frame)
|
||||
struct proc *p = td->td_proc;
|
||||
u_int sticks = 0;
|
||||
int i = 0, ucode = 0, type, code;
|
||||
register_t addr = 0;
|
||||
vm_offset_t eva;
|
||||
ksiginfo_t ksi;
|
||||
#ifdef POWERFAIL_NMI
|
||||
static int lastalert = 0;
|
||||
#endif
|
||||
@ -274,13 +276,14 @@ trap(frame)
|
||||
|
||||
sticks = td->td_sticks;
|
||||
td->td_frame = &frame;
|
||||
addr = frame.tf_eip;
|
||||
if (td->td_ucred != p->p_ucred)
|
||||
cred_update_thread(td);
|
||||
|
||||
switch (type) {
|
||||
case T_PRIVINFLT: /* privileged instruction fault */
|
||||
ucode = type;
|
||||
i = SIGILL;
|
||||
ucode = ILL_PRVOPC;
|
||||
break;
|
||||
|
||||
case T_BPTFLT: /* bpt instruction fault */
|
||||
@ -288,6 +291,7 @@ trap(frame)
|
||||
enable_intr();
|
||||
frame.tf_eflags &= ~PSL_T;
|
||||
i = SIGTRAP;
|
||||
ucode = (type == T_TRCTRAP ? TRAP_TRACE : TRAP_BRKPT);
|
||||
break;
|
||||
|
||||
case T_ARITHTRAP: /* arithmetic trap */
|
||||
@ -296,7 +300,7 @@ trap(frame)
|
||||
if (ucode == -1)
|
||||
goto userout;
|
||||
#else
|
||||
ucode = code;
|
||||
ucode = 0;
|
||||
#endif
|
||||
i = SIGFPE;
|
||||
break;
|
||||
@ -314,14 +318,21 @@ trap(frame)
|
||||
goto user;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
i = SIGBUS;
|
||||
ucode = (type == T_PROTFLT) ? BUS_OBJERR : BUS_ADRERR;
|
||||
break;
|
||||
case T_SEGNPFLT: /* segment not present fault */
|
||||
i = SIGBUS;
|
||||
ucode = BUS_ADRERR;
|
||||
break;
|
||||
case T_TSSFLT: /* invalid TSS fault */
|
||||
i = SIGBUS;
|
||||
ucode = BUS_OBJERR;
|
||||
break;
|
||||
case T_DOUBLEFLT: /* double fault */
|
||||
default:
|
||||
ucode = code + BUS_SEGM_FAULT ;
|
||||
i = SIGBUS;
|
||||
ucode = BUS_OBJERR;
|
||||
break;
|
||||
|
||||
case T_PAGEFLT: /* page fault */
|
||||
@ -339,7 +350,7 @@ trap(frame)
|
||||
type = frame.tf_trapno = T_PRIVINFLT;
|
||||
|
||||
/* Proceed as in that case. */
|
||||
ucode = type;
|
||||
ucode = ILL_PRVOPC;
|
||||
i = SIGILL;
|
||||
break;
|
||||
}
|
||||
@ -349,7 +360,13 @@ trap(frame)
|
||||
if (i == 0)
|
||||
goto user;
|
||||
|
||||
ucode = T_PAGEFLT;
|
||||
if (i == SIGSEGV)
|
||||
ucode = SEGV_MAPERR;
|
||||
else {
|
||||
i = SIGSEGV; /* XXX hack */
|
||||
ucode = SEGV_ACCERR;
|
||||
}
|
||||
addr = eva;
|
||||
break;
|
||||
|
||||
case T_DIVIDE: /* integer divide fault */
|
||||
@ -408,12 +425,14 @@ trap(frame)
|
||||
if (npxdna())
|
||||
goto userout;
|
||||
#endif
|
||||
i = SIGFPE;
|
||||
ucode = FPE_FPU_NP_TRAP;
|
||||
printf("pid %d killed due to lack of floating point\n",
|
||||
p->p_pid);
|
||||
i = SIGKILL;
|
||||
ucode = 0;
|
||||
break;
|
||||
|
||||
case T_FPOPFLT: /* FPU operand fetch fault */
|
||||
ucode = T_FPOPFLT;
|
||||
ucode = ILL_COPROC;
|
||||
i = SIGILL;
|
||||
break;
|
||||
|
||||
@ -634,7 +653,12 @@ trap(frame)
|
||||
if (*p->p_sysent->sv_transtrap)
|
||||
i = (*p->p_sysent->sv_transtrap)(i, type);
|
||||
|
||||
trapsignal(td, i, ucode);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = i;
|
||||
ksi.ksi_code = ucode;
|
||||
ksi.ksi_addr = (void *)addr;
|
||||
ksi.ksi_trapno = type;
|
||||
trapsignal(td, &ksi);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (type <= MAX_TRAP_MSG) {
|
||||
@ -879,6 +903,7 @@ syscall(frame)
|
||||
int narg;
|
||||
int args[8];
|
||||
u_int code;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
/*
|
||||
* note: PCPU_LAZY_INC() can only be used if we can afford
|
||||
@ -1017,7 +1042,11 @@ syscall(frame)
|
||||
*/
|
||||
if ((orig_tf_eflags & PSL_T) && !(orig_tf_eflags & PSL_VM)) {
|
||||
frame.tf_eflags &= ~PSL_T;
|
||||
trapsignal(td, SIGTRAP, 0);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGTRAP;
|
||||
ksi.ksi_code = TRAP_TRACE;
|
||||
ksi.ksi_addr = (void *)frame.tf_eip;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -107,8 +107,7 @@ static int elf_linux_fixup(register_t **stack_base,
|
||||
struct image_params *iparams);
|
||||
static void linux_prepsyscall(struct trapframe *tf, int *args, u_int *code,
|
||||
caddr_t *params);
|
||||
static void linux_sendsig(sig_t catcher, int sig, sigset_t *mask,
|
||||
u_long code);
|
||||
static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
|
||||
static void exec_linux_setregs(struct thread *td, u_long entry,
|
||||
u_long stack, u_long ps_strings);
|
||||
|
||||
@ -267,15 +266,18 @@ extern int _ucodesel, _udatasel;
|
||||
extern unsigned long linux_sznonrtsigcode;
|
||||
|
||||
static void
|
||||
linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
struct thread *td = curthread;
|
||||
struct proc *p = td->td_proc;
|
||||
struct sigacts *psp;
|
||||
struct trapframe *regs;
|
||||
struct l_rt_sigframe *fp, frame;
|
||||
int sig, code;
|
||||
int oonstack;
|
||||
|
||||
sig = ksi->ksi_signo;
|
||||
code = ksi->ksi_code;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
@ -315,7 +317,7 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
/* Fill in POSIX parts */
|
||||
frame.sf_si.lsi_signo = sig;
|
||||
frame.sf_si.lsi_code = code;
|
||||
frame.sf_si.lsi_addr = (void *)regs->tf_err;
|
||||
frame.sf_si.lsi_addr = ksi->ksi_addr;
|
||||
|
||||
/*
|
||||
* Build the signal context to be used by sigreturn.
|
||||
@ -400,7 +402,7 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
* specified pc, psl.
|
||||
*/
|
||||
static void
|
||||
linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
struct thread *td = curthread;
|
||||
struct proc *p = td->td_proc;
|
||||
@ -408,17 +410,19 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
struct trapframe *regs;
|
||||
struct l_sigframe *fp, frame;
|
||||
l_sigset_t lmask;
|
||||
int sig, code;
|
||||
int oonstack, i;
|
||||
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
psp = p->p_sigacts;
|
||||
sig = ksi->ksi_signo;
|
||||
code = ksi->ksi_code;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
if (SIGISMEMBER(psp->ps_siginfo, sig)) {
|
||||
/* Signal handler installed with SA_SIGINFO. */
|
||||
linux_rt_sendsig(catcher, sig, mask, code);
|
||||
linux_rt_sendsig(catcher, ksi, mask);
|
||||
return;
|
||||
}
|
||||
|
||||
regs = td->td_frame;
|
||||
oonstack = sigonstack(regs->tf_esp);
|
||||
|
||||
@ -475,7 +479,7 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
frame.sf_sc.sc_esp_at_signal = regs->tf_esp;
|
||||
frame.sf_sc.sc_ss = regs->tf_ss;
|
||||
frame.sf_sc.sc_err = regs->tf_err;
|
||||
frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(code);
|
||||
frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(ksi->ksi_trapno);
|
||||
|
||||
for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
|
||||
frame.sf_extramask[i] = lmask.__bits[i+1];
|
||||
@ -522,6 +526,7 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
|
||||
struct trapframe *regs;
|
||||
l_sigset_t lmask;
|
||||
int eflags, i;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
regs = td->td_frame;
|
||||
|
||||
@ -562,7 +567,12 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
|
||||
*/
|
||||
#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
|
||||
if (!CS_SECURE(frame.sf_sc.sc_cs)) {
|
||||
trapsignal(td, SIGBUS, T_PROTFLT);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_trapno = T_PROTFLT;
|
||||
ksi.ksi_addr = (void *)regs->tf_eip;
|
||||
trapsignal(td, &ksi);
|
||||
return(EINVAL);
|
||||
}
|
||||
|
||||
@ -618,6 +628,7 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
|
||||
stack_t ss;
|
||||
struct trapframe *regs;
|
||||
int eflags;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
regs = td->td_frame;
|
||||
|
||||
@ -660,7 +671,12 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
|
||||
*/
|
||||
#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
|
||||
if (!CS_SECURE(context->sc_cs)) {
|
||||
trapsignal(td, SIGBUS, T_PROTFLT);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_trapno = T_PROTFLT;
|
||||
ksi.ksi_addr = (void *)regs->tf_eip;
|
||||
trapsignal(td, &ksi);
|
||||
return(EINVAL);
|
||||
}
|
||||
|
||||
|
@ -411,11 +411,10 @@ svr4_getsiginfo(si, sig, code, addr)
|
||||
* will return to the user pc, psl.
|
||||
*/
|
||||
void
|
||||
svr4_sendsig(catcher, sig, mask, code)
|
||||
svr4_sendsig(catcher, ksi, mask)
|
||||
sig_t catcher;
|
||||
int sig;
|
||||
ksiginfo_t ksi;
|
||||
sigset_t *mask;
|
||||
u_long code;
|
||||
{
|
||||
register struct thread *td = curthread;
|
||||
struct proc *p = td->td_proc;
|
||||
@ -423,11 +422,15 @@ svr4_sendsig(catcher, sig, mask, code)
|
||||
struct svr4_sigframe *fp, frame;
|
||||
struct sigacts *psp;
|
||||
int oonstack;
|
||||
int sig;
|
||||
int code;
|
||||
|
||||
#if defined(DEBUG_SVR4)
|
||||
printf("svr4_sendsig(%d)\n", sig);
|
||||
#endif
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = ksi->ksi_signo;
|
||||
code = ksi->ksi_trapno; /* use trap No. */
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
|
||||
|
@ -98,9 +98,9 @@ int sz_ia32_sigcode = sizeof(ia32_sigcode);
|
||||
* sendsig() means that at least untrapped signals will work.
|
||||
*/
|
||||
void
|
||||
ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
sendsig(catcher, sig, mask, code);
|
||||
sendsig(catcher, ksi, mask);
|
||||
}
|
||||
|
||||
#ifdef COMPAT_FREEBSD4
|
||||
|
@ -61,6 +61,7 @@ ia32_syscall(struct trapframe *tf)
|
||||
register_t eflags;
|
||||
u_int code;
|
||||
int error, i, narg;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
PCPU_LAZY_INC(cnt.v_syscall);
|
||||
|
||||
@ -168,7 +169,11 @@ ia32_syscall(struct trapframe *tf)
|
||||
*/
|
||||
if ((eflags & PSL_T) && !(eflags & PSL_VM)) {
|
||||
ia64_set_eflag(ia64_get_eflag() & ~PSL_T);
|
||||
trapsignal(td, SIGTRAP, 0);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGTRAP;
|
||||
ksi.ksi_code = TRAP_TRACE;
|
||||
ksi.ksi_addr = (void *)tf->tf_special.iip;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
|
||||
#ifdef KTRACE
|
||||
@ -201,6 +206,7 @@ ia32_trap(int vector, struct trapframe *tf)
|
||||
uint64_t ucode;
|
||||
int sig;
|
||||
u_int sticks;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
KASSERT(TRAPF_USERMODE(tf), ("%s: In kernel mode???", __func__));
|
||||
|
||||
@ -284,7 +290,11 @@ ia32_trap(int vector, struct trapframe *tf)
|
||||
|
||||
KASSERT(sig != 0, ("%s: signal not set", __func__));
|
||||
|
||||
trapsignal(td, sig, ucode);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = sig;
|
||||
ksi.ksi_code = (int)ucode; /* XXX */
|
||||
/* ksi.ksi_addr */
|
||||
trapsignal(td, &ksi);
|
||||
|
||||
out:
|
||||
userret(td, tf, sticks);
|
||||
|
@ -878,7 +878,7 @@ DELAY(int n)
|
||||
* Send an interrupt (signal) to a process.
|
||||
*/
|
||||
void
|
||||
sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
@ -887,10 +887,14 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
struct sigframe sf, *sfp;
|
||||
u_int64_t sbs, sp;
|
||||
int oonstack;
|
||||
int sig;
|
||||
u_long code;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = ksi->ksi_signo;
|
||||
code = ksi->ksi_code;
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
tf = td->td_frame;
|
||||
@ -926,8 +930,12 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
|
||||
/* Fill in the siginfo structure for POSIX handlers. */
|
||||
if (SIGISMEMBER(psp->ps_siginfo, sig)) {
|
||||
sf.sf_si = ksi->ksi_info;
|
||||
sf.sf_si.si_signo = sig;
|
||||
sf.sf_si.si_code = code;
|
||||
/*
|
||||
* XXX this shouldn't be here after code in trap.c
|
||||
* is fixed
|
||||
*/
|
||||
sf.sf_si.si_addr = (void*)tf->tf_special.ifa;
|
||||
code = (u_int64_t)&sfp->sf_si;
|
||||
}
|
||||
@ -978,25 +986,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
mtx_lock(&psp->ps_mtx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build siginfo_t for SA thread
|
||||
*/
|
||||
void
|
||||
cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
|
||||
bzero(si, sizeof(*si));
|
||||
si->si_signo = sig;
|
||||
si->si_code = code;
|
||||
/* XXXKSE fill other fields */
|
||||
}
|
||||
|
||||
/*
|
||||
* System call to cleanup state after a signal
|
||||
* has been taken. Reset signal mask and
|
||||
|
@ -361,6 +361,7 @@ trap(int vector, struct trapframe *tf)
|
||||
uint64_t ucode;
|
||||
int error, sig, user;
|
||||
u_int sticks;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
user = TRAPF_USERMODE(tf) ? 1 : 0;
|
||||
|
||||
@ -869,7 +870,10 @@ trap(int vector, struct trapframe *tf)
|
||||
if (print_usertrap)
|
||||
printtrap(vector, tf, 1, user);
|
||||
|
||||
trapsignal(td, sig, ucode);
|
||||
ksiginfo_init(&ksi);
|
||||
ksi.ksi_signo = sig;
|
||||
ksi.ksi_code = ucode;
|
||||
trapsignal(td, &ksi);
|
||||
|
||||
out:
|
||||
if (user) {
|
||||
|
@ -485,4 +485,5 @@ struct sysent sysent[] = {
|
||||
{ SYF_MPSAFE | AS(auditctl_args), (sy_call_t *)lkmressys, AUE_NULL }, /* 453 = auditctl */
|
||||
{ SYF_MPSAFE | AS(_umtx_op_args), (sy_call_t *)_umtx_op, AUE_NULL }, /* 454 = _umtx_op */
|
||||
{ SYF_MPSAFE | AS(thr_new_args), (sy_call_t *)thr_new, AUE_NULL }, /* 455 = thr_new */
|
||||
{ SYF_MPSAFE | AS(sigqueue_args), (sy_call_t *)sigqueue, AUE_NULL }, /* 456 = sigqueue */
|
||||
};
|
||||
|
@ -666,7 +666,7 @@ do_execve(td, args, mac_p)
|
||||
* single thread mode.
|
||||
*/
|
||||
if (p->p_flag & P_TRACED)
|
||||
tdsignal(td, SIGTRAP, SIGTARGET_TD);
|
||||
tdsignal(td, SIGTRAP, NULL, SIGTARGET_TD);
|
||||
|
||||
/* clear "fork but no exec" flag, as we _are_ execing */
|
||||
p->p_acflag &= ~AFORK;
|
||||
|
@ -207,8 +207,8 @@ exit1(struct thread *td, int rv)
|
||||
PROC_LOCK(p);
|
||||
stopprofclock(p);
|
||||
p->p_flag &= ~(P_TRACED | P_PPWAIT);
|
||||
SIGEMPTYSET(p->p_siglist);
|
||||
SIGEMPTYSET(td->td_siglist);
|
||||
sigqueue_flush(&p->p_sigqueue);
|
||||
sigqueue_flush(&td->td_sigqueue);
|
||||
|
||||
/*
|
||||
* Stop the real interval timer. If the handler is currently
|
||||
|
@ -210,7 +210,7 @@ kse_thr_interrupt(struct thread *td, struct kse_thr_interrupt_args *uap)
|
||||
if (uap->data > 0) {
|
||||
td2->td_flags &= ~TDF_INTERRUPT;
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
tdsignal(td2, (int)uap->data, SIGTARGET_TD);
|
||||
tdsignal(td2, (int)uap->data, NULL, SIGTARGET_TD);
|
||||
} else {
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
}
|
||||
@ -342,6 +342,7 @@ kse_exit(struct thread *td, struct kse_exit_args *uap)
|
||||
PROC_LOCK(p);
|
||||
if (error)
|
||||
psignal(p, SIGSEGV);
|
||||
sigqueue_flush(&td->td_sigqueue);
|
||||
mtx_lock_spin(&sched_lock);
|
||||
upcall_remove(td);
|
||||
if (p->p_numthreads != 1) {
|
||||
@ -697,8 +698,8 @@ kse_create(struct thread *td, struct kse_create_args *uap)
|
||||
* SA threading will make a special thread to handle them.
|
||||
*/
|
||||
if (first && sa) {
|
||||
SIGSETOR(p->p_siglist, td->td_siglist);
|
||||
SIGEMPTYSET(td->td_siglist);
|
||||
sigqueue_move_set(&td->td_sigqueue, &p->p_sigqueue,
|
||||
&td->td_sigqueue.sq_signals);
|
||||
SIGFILLSET(td->td_sigmask);
|
||||
SIG_CANTMASK(td->td_sigmask);
|
||||
}
|
||||
@ -1094,10 +1095,9 @@ thread_schedule_upcall(struct thread *td, struct kse_upcall *ku)
|
||||
* debugged.
|
||||
*/
|
||||
void
|
||||
thread_signal_add(struct thread *td, int sig)
|
||||
thread_signal_add(struct thread *td, ksiginfo_t *ksi)
|
||||
{
|
||||
struct proc *p;
|
||||
siginfo_t siginfo;
|
||||
struct sigacts *ps;
|
||||
int error;
|
||||
|
||||
@ -1106,11 +1106,11 @@ thread_signal_add(struct thread *td, int sig)
|
||||
ps = p->p_sigacts;
|
||||
mtx_assert(&ps->ps_mtx, MA_OWNED);
|
||||
|
||||
cpu_thread_siginfo(sig, 0, &siginfo);
|
||||
mtx_unlock(&ps->ps_mtx);
|
||||
SIGADDSET(td->td_sigmask, sig);
|
||||
SIGADDSET(td->td_sigmask, ksi->ksi_signo);
|
||||
PROC_UNLOCK(p);
|
||||
error = copyout(&siginfo, &td->td_mailbox->tm_syncsig, sizeof(siginfo));
|
||||
error = copyout(&ksi->ksi_info, &td->td_mailbox->tm_syncsig,
|
||||
sizeof(siginfo_t));
|
||||
if (error) {
|
||||
PROC_LOCK(p);
|
||||
sigexit(td, SIGSEGV);
|
||||
@ -1315,6 +1315,7 @@ thread_userret(struct thread *td, struct trapframe *frame)
|
||||
wakeup(&kg->kg_completed);
|
||||
WITNESS_WARN(WARN_PANIC, &p->p_mtx.mtx_object,
|
||||
"thread exiting in userret");
|
||||
sigqueue_flush(&td->td_sigqueue);
|
||||
mtx_lock_spin(&sched_lock);
|
||||
thread_stopped(p);
|
||||
thread_exit();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -279,6 +279,7 @@ thr_exit(struct thread *td, struct thr_exit_args *uap)
|
||||
suword((void *)uap->state, 1);
|
||||
|
||||
PROC_LOCK(p);
|
||||
sigqueue_flush(&td->td_sigqueue);
|
||||
mtx_lock_spin(&sched_lock);
|
||||
|
||||
/*
|
||||
@ -319,7 +320,7 @@ thr_kill(struct thread *td, struct thr_kill_args *uap)
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
tdsignal(ttd, uap->sig, SIGTARGET_TD);
|
||||
tdsignal(ttd, uap->sig, NULL, SIGTARGET_TD);
|
||||
out:
|
||||
PROC_UNLOCK(p);
|
||||
return (error);
|
||||
|
@ -277,6 +277,7 @@ proc_linkup(struct proc *p, struct ksegrp *kg, struct thread *td)
|
||||
TAILQ_INIT(&p->p_ksegrps); /* all ksegrps in proc */
|
||||
TAILQ_INIT(&p->p_threads); /* all threads in proc */
|
||||
TAILQ_INIT(&p->p_suspended); /* Threads suspended */
|
||||
sigqueue_init(&p->p_sigqueue, p);
|
||||
p->p_numksegrps = 0;
|
||||
p->p_numthreads = 0;
|
||||
|
||||
@ -454,6 +455,7 @@ thread_exit(void)
|
||||
KASSERT(kg != NULL, ("thread exiting without a kse group"));
|
||||
CTR3(KTR_PROC, "thread_exit: thread %p (pid %ld, %s)", td,
|
||||
(long)p->p_pid, p->p_comm);
|
||||
KASSERT(TAILQ_EMPTY(&td->td_sigqueue.sq_list), ("signal pending"));
|
||||
|
||||
if (td->td_standin != NULL) {
|
||||
/*
|
||||
@ -625,6 +627,7 @@ thread_link(struct thread *td, struct ksegrp *kg)
|
||||
td->td_kflags = 0;
|
||||
|
||||
LIST_INIT(&td->td_contested);
|
||||
sigqueue_init(&td->td_sigqueue, p);
|
||||
callout_init(&td->td_slpcallout, CALLOUT_MPSAFE);
|
||||
TAILQ_INSERT_HEAD(&p->p_threads, td, td_plist);
|
||||
TAILQ_INSERT_HEAD(&kg->kg_threads, td, td_kglist);
|
||||
@ -875,6 +878,10 @@ thread_suspend_check(int return_instead)
|
||||
(p->p_flag & P_SINGLE_BOUNDARY) && return_instead)
|
||||
return (1);
|
||||
|
||||
/* If thread will exit, flush its pending signals */
|
||||
if ((p->p_flag & P_SINGLE_EXIT) && (p->p_singlethread != td))
|
||||
sigqueue_flush(&td->td_sigqueue);
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
thread_stopped(p);
|
||||
/*
|
||||
|
@ -155,6 +155,7 @@ ast(struct trapframe *framep)
|
||||
int sig;
|
||||
#if defined(DEV_NPX) && !defined(SMP)
|
||||
int ucode;
|
||||
ksiginfo_t ksi;
|
||||
#endif
|
||||
|
||||
td = curthread;
|
||||
@ -217,7 +218,10 @@ ast(struct trapframe *framep)
|
||||
PCB_NPXTRAP);
|
||||
ucode = npxtrap();
|
||||
if (ucode != -1) {
|
||||
trapsignal(td, SIGFPE, ucode);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGFPE;
|
||||
ksi.ksi_code = ucode;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -793,6 +793,6 @@
|
||||
long id, void *uaddr, void *uaddr2); }
|
||||
455 AUE_NULL MSTD { int thr_new(struct thr_param *param, \
|
||||
int param_size); }
|
||||
|
||||
456 AUE_NULL MSTD { int sigqueue(pid_t pid, int signum, void *value); }
|
||||
; Please copy any additions and changes to the following compatability tables:
|
||||
; sys/compat/freebsd32/syscalls.master
|
||||
|
@ -177,11 +177,10 @@ SYSCTL_INT(_machdep, OID_AUTO, ispc98, CTLFLAG_RD, &ispc98, 0, "");
|
||||
int cold = 1;
|
||||
|
||||
#ifdef COMPAT_43
|
||||
static void osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code);
|
||||
static void osendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask);
|
||||
#endif
|
||||
#ifdef COMPAT_FREEBSD4
|
||||
static void freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask,
|
||||
u_long code);
|
||||
static void freebsd4_sendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask)
|
||||
#endif
|
||||
|
||||
long Maxmem = 0;
|
||||
@ -267,11 +266,7 @@ cpu_startup(dummy)
|
||||
*/
|
||||
#ifdef COMPAT_43
|
||||
static void
|
||||
osendsig(catcher, sig, mask, code)
|
||||
sig_t catcher;
|
||||
int sig;
|
||||
sigset_t *mask;
|
||||
u_long code;
|
||||
osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
struct osigframe sf, *fp;
|
||||
struct proc *p;
|
||||
@ -279,10 +274,14 @@ osendsig(catcher, sig, mask, code)
|
||||
struct sigacts *psp;
|
||||
struct trapframe *regs;
|
||||
int oonstack;
|
||||
int sig;
|
||||
int code;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = ksi->ksi_signo;
|
||||
code = ksi->ksi_code;
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
regs = td->td_frame;
|
||||
@ -311,6 +310,7 @@ osendsig(catcher, sig, mask, code)
|
||||
sf.sf_arg2 = (register_t)&fp->sf_siginfo;
|
||||
sf.sf_siginfo.si_signo = sig;
|
||||
sf.sf_siginfo.si_code = code;
|
||||
sf.sf_siginfo.sf_value = ksi->ksi_value;
|
||||
sf.sf_ahu.sf_action = (__osiginfohandler_t *)catcher;
|
||||
} else {
|
||||
/* Old FreeBSD-style arguments. */
|
||||
@ -721,8 +721,13 @@ osigreturn(td, uap)
|
||||
return (EINVAL);
|
||||
|
||||
/* Go back to user mode if both flags are set. */
|
||||
if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
|
||||
trapsignal(td, SIGBUS, 0);
|
||||
if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) {
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_addr = (void *)regs->tf_eip;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
|
||||
if (vm86->vm86_has_vme) {
|
||||
eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
|
||||
@ -763,7 +768,12 @@ osigreturn(td, uap)
|
||||
* other selectors, invalid %eip's and invalid %esp's.
|
||||
*/
|
||||
if (!CS_SECURE(scp->sc_cs)) {
|
||||
trapsignal(td, SIGBUS, T_PROTFLT);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_trapno = T_PROTFLT;
|
||||
ksi.ksi_addr = (void *)regs->tf_eip;
|
||||
trapsignal(td, &ksi);
|
||||
return (EINVAL);
|
||||
}
|
||||
regs->tf_ds = scp->sc_ds;
|
||||
@ -839,8 +849,13 @@ freebsd4_sigreturn(td, uap)
|
||||
return (EINVAL);
|
||||
|
||||
/* Go back to user mode if both flags are set. */
|
||||
if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
|
||||
trapsignal(td, SIGBUS, 0);
|
||||
if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) {
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_addr = (void *)regs->tf_eip;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
|
||||
if (vm86->vm86_has_vme) {
|
||||
eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
|
||||
@ -886,7 +901,12 @@ freebsd4_sigreturn(td, uap)
|
||||
cs = ucp->uc_mcontext.mc_cs;
|
||||
if (!CS_SECURE(cs)) {
|
||||
printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
|
||||
trapsignal(td, SIGBUS, T_PROTFLT);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_trapno = T_PROTFLT;
|
||||
ksi.ksi_addr = (void *)regs->tf_eip;
|
||||
trapsignal(td, &ksi);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
@ -946,8 +966,13 @@ sigreturn(td, uap)
|
||||
return (EINVAL);
|
||||
|
||||
/* Go back to user mode if both flags are set. */
|
||||
if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
|
||||
trapsignal(td, SIGBUS, 0);
|
||||
if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) {
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_addr = (void *)regs->tf_eip;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
|
||||
if (vm86->vm86_has_vme) {
|
||||
eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
|
||||
@ -993,7 +1018,12 @@ sigreturn(td, uap)
|
||||
cs = ucp->uc_mcontext.mc_cs;
|
||||
if (!CS_SECURE(cs)) {
|
||||
printf("sigreturn: cs = 0x%x\n", cs);
|
||||
trapsignal(td, SIGBUS, T_PROTFLT);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = SIGBUS;
|
||||
ksi.ksi_code = BUS_OBJERR;
|
||||
ksi.ksi_trapno = T_PROTFLT;
|
||||
ksi.ksi_addr = (void *)regs->tf_eip;
|
||||
trapsignal(td, &ksi);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
|
@ -432,7 +432,7 @@ bzero(void *buf, size_t len)
|
||||
}
|
||||
|
||||
void
|
||||
sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
struct trapframe *tf;
|
||||
struct sigframe *sfp;
|
||||
@ -441,10 +441,14 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
struct thread *td;
|
||||
struct proc *p;
|
||||
int oonstack, rndfsize;
|
||||
int sig;
|
||||
int code;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = ksi->ksi_signo;
|
||||
code = ksi->ksi_code;
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
tf = td->td_frame;
|
||||
@ -512,9 +516,9 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
/*
|
||||
* Fill siginfo structure.
|
||||
*/
|
||||
sf.sf_si = ksi->ksi_info;
|
||||
sf.sf_si.si_signo = sig;
|
||||
sf.sf_si.si_code = code;
|
||||
sf.sf_si.si_addr = (void *)tf->srr0;
|
||||
sf.sf_si.si_addr = (void *)tf->srr0; /* XXX */
|
||||
} else {
|
||||
/* Old FreeBSD-style arguments. */
|
||||
tf->fixreg[FIRSTARG+1] = code;
|
||||
@ -543,25 +547,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
mtx_lock(&psp->ps_mtx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build siginfo_t for SA thread
|
||||
*/
|
||||
void
|
||||
cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
|
||||
bzero(si, sizeof(*si));
|
||||
si->si_signo = sig;
|
||||
si->si_code = code;
|
||||
/* XXXKSE fill other fields */
|
||||
}
|
||||
|
||||
int
|
||||
sigreturn(struct thread *td, struct sigreturn_args *uap)
|
||||
{
|
||||
|
@ -144,6 +144,7 @@ trap(struct trapframe *frame)
|
||||
struct proc *p;
|
||||
int sig, type, user;
|
||||
u_int sticks, ucode;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
PCPU_LAZY_INC(cnt.v_trap);
|
||||
|
||||
@ -254,7 +255,12 @@ trap(struct trapframe *frame)
|
||||
if (sig != 0) {
|
||||
if (p->p_sysent->sv_transtrap != NULL)
|
||||
sig = (p->p_sysent->sv_transtrap)(sig, type);
|
||||
trapsignal(td, sig, ucode);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = sig;
|
||||
ksi.ksi_code = (int) ucode; /* XXX, not POSIX */
|
||||
/* ksi.ksi_addr = ? */
|
||||
ksi.ksi_trapno = type;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
|
||||
userret(td, frame, sticks);
|
||||
|
@ -432,7 +432,7 @@ bzero(void *buf, size_t len)
|
||||
}
|
||||
|
||||
void
|
||||
sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
struct trapframe *tf;
|
||||
struct sigframe *sfp;
|
||||
@ -441,10 +441,14 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
struct thread *td;
|
||||
struct proc *p;
|
||||
int oonstack, rndfsize;
|
||||
int sig;
|
||||
int code;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = ksi->ksi_signo;
|
||||
code = ksi->ksi_code;
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
tf = td->td_frame;
|
||||
@ -512,9 +516,9 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
/*
|
||||
* Fill siginfo structure.
|
||||
*/
|
||||
sf.sf_si = ksi->ksi_info;
|
||||
sf.sf_si.si_signo = sig;
|
||||
sf.sf_si.si_code = code;
|
||||
sf.sf_si.si_addr = (void *)tf->srr0;
|
||||
sf.sf_si.si_addr = (void *)tf->srr0; /* XXX */
|
||||
} else {
|
||||
/* Old FreeBSD-style arguments. */
|
||||
tf->fixreg[FIRSTARG+1] = code;
|
||||
@ -543,25 +547,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
mtx_lock(&psp->ps_mtx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build siginfo_t for SA thread
|
||||
*/
|
||||
void
|
||||
cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
|
||||
bzero(si, sizeof(*si));
|
||||
si->si_signo = sig;
|
||||
si->si_code = code;
|
||||
/* XXXKSE fill other fields */
|
||||
}
|
||||
|
||||
int
|
||||
sigreturn(struct thread *td, struct sigreturn_args *uap)
|
||||
{
|
||||
|
@ -144,6 +144,7 @@ trap(struct trapframe *frame)
|
||||
struct proc *p;
|
||||
int sig, type, user;
|
||||
u_int sticks, ucode;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
PCPU_LAZY_INC(cnt.v_trap);
|
||||
|
||||
@ -254,7 +255,12 @@ trap(struct trapframe *frame)
|
||||
if (sig != 0) {
|
||||
if (p->p_sysent->sv_transtrap != NULL)
|
||||
sig = (p->p_sysent->sv_transtrap)(sig, type);
|
||||
trapsignal(td, sig, ucode);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = sig;
|
||||
ksi.ksi_code = (int) ucode; /* XXX, not POSIX */
|
||||
/* ksi.ksi_addr = ? */
|
||||
ksi.ksi_trapno = type;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
|
||||
userret(td, frame, sticks);
|
||||
|
@ -447,7 +447,7 @@ set_openfirm_callback(ofw_vec_t *vec)
|
||||
}
|
||||
|
||||
void
|
||||
sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
||||
{
|
||||
struct trapframe *tf;
|
||||
struct sigframe *sfp;
|
||||
@ -458,11 +458,15 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
struct proc *p;
|
||||
int oonstack;
|
||||
u_long sp;
|
||||
int sig;
|
||||
int code;
|
||||
|
||||
oonstack = 0;
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
sig = ksi->ksi_signo;
|
||||
code = ksi->ksi_code;
|
||||
psp = p->p_sigacts;
|
||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||
tf = td->td_frame;
|
||||
@ -513,9 +517,8 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
tf->tf_out[2] = (register_t)&sfp->sf_uc;
|
||||
tf->tf_out[4] = (register_t)catcher;
|
||||
/* Fill siginfo structure. */
|
||||
sf.sf_si.si_signo = sig;
|
||||
sf.sf_si.si_code = code;
|
||||
sf.sf_si.si_addr = (void *)tf->tf_sfar;
|
||||
sf.sf_si = ksi->ksi_info;
|
||||
sf.sf_si.si_addr = (void *)tf->tf_sfar; /* XXX */
|
||||
|
||||
/* Copy the sigframe out to the user's stack. */
|
||||
if (rwindow_save(td) != 0 || copyout(&sf, sfp, sizeof(*sfp)) != 0 ||
|
||||
@ -541,25 +544,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
mtx_lock(&psp->ps_mtx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build siginfo_t for SA thread
|
||||
*/
|
||||
void
|
||||
cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *td;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
|
||||
bzero(si, sizeof(*si));
|
||||
si->si_signo = sig;
|
||||
si->si_code = code;
|
||||
/* XXXKSE fill other fields */
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
struct sigreturn_args {
|
||||
ucontext_t *ucp;
|
||||
|
@ -233,6 +233,7 @@ trap(struct trapframe *tf)
|
||||
u_int sticks;
|
||||
int error;
|
||||
int sig;
|
||||
ksiginfo_t ksi;
|
||||
|
||||
td = PCPU_GET(curthread);
|
||||
|
||||
@ -284,7 +285,12 @@ trap(struct trapframe *tf)
|
||||
if (debugger_on_signal &&
|
||||
(sig == 4 || sig == 10 || sig == 11))
|
||||
kdb_enter("trapsig");
|
||||
trapsignal(td, sig, tf->tf_type);
|
||||
ksiginfo_init_trap(&ksi);
|
||||
ksi.ksi_signo = sig;
|
||||
ksi.ksi_code = (int)tf->tf_type; /* XXX not POSIX */
|
||||
/* ksi.ksi_addr = ? */
|
||||
ksi.ksi_trap = (int)tf->tf_type;
|
||||
trapsignal(td, &ksi);
|
||||
}
|
||||
|
||||
userret(td, tf, sticks);
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include <sys/runq.h>
|
||||
#include <sys/sigio.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/signalvar.h>
|
||||
#ifndef _KERNEL
|
||||
#include <sys/time.h> /* For structs itimerval, timeval. */
|
||||
#else
|
||||
@ -253,6 +254,8 @@ struct thread {
|
||||
struct turnstile *td_turnstile; /* (k) Associated turnstile. */
|
||||
struct umtx_q *td_umtxq; /* (c?) Link for when we're blocked. */
|
||||
lwpid_t td_tid; /* (b) Thread ID. */
|
||||
sigqueue_t td_sigqueue; /* (c) Sigs arrived, not delivered. */
|
||||
#define td_siglist td_sigqueue.sq_signals
|
||||
|
||||
/* Cleared during fork1() or thread_schedule_upcall(). */
|
||||
#define td_startzero td_flags
|
||||
@ -283,7 +286,6 @@ struct thread {
|
||||
int td_intrval; /* (j) Return value of TDF_INTERRUPT. */
|
||||
sigset_t td_oldsigmask; /* (k) Saved mask from pre sigpause. */
|
||||
sigset_t td_sigmask; /* (c) Current signal mask. */
|
||||
sigset_t td_siglist; /* (c) Sigs arrived, not delivered. */
|
||||
volatile u_int td_generation; /* (k) For detection of preemption */
|
||||
stack_t td_sigstk; /* (k) Stack ptr and on-stack flag. */
|
||||
int td_kflags; /* (c) Flags for KSE threading. */
|
||||
@ -544,6 +546,8 @@ struct proc {
|
||||
LIST_ENTRY(proc) p_sibling; /* (e) List of sibling processes. */
|
||||
LIST_HEAD(, proc) p_children; /* (e) Pointer to list of children. */
|
||||
struct mtx p_mtx; /* (n) Lock for this struct. */
|
||||
sigqueue_t p_sigqueue; /* (c) Sigs not delivered to a td. */
|
||||
#define p_siglist p_sigqueue.sq_signals
|
||||
|
||||
/* The following fields are all zeroed upon creation in fork. */
|
||||
#define p_startzero p_oppid
|
||||
@ -559,7 +563,6 @@ struct proc {
|
||||
struct vnode *p_tracevp; /* (c + o) Trace to vnode. */
|
||||
struct ucred *p_tracecred; /* (o) Credentials to trace with. */
|
||||
struct vnode *p_textvp; /* (b) Vnode of executable. */
|
||||
sigset_t p_siglist; /* (c) Sigs not delivered to a td. */
|
||||
char p_lock; /* (c) Proclock (prevent swap) count. */
|
||||
struct sigiolst p_sigiolst; /* (c) List of sigio sources. */
|
||||
int p_sigparent; /* (c) Signal to parent on exit. */
|
||||
@ -576,6 +579,7 @@ struct proc {
|
||||
struct thread *p_xthread; /* (c) Trap thread */
|
||||
int p_boundary_count;/* (c) Num threads at user boundary */
|
||||
struct ksegrp *p_procscopegrp;
|
||||
int p_pendingcnt; /* how many signals are pending */
|
||||
/* End area that is zeroed on creation. */
|
||||
#define p_endzero p_magic
|
||||
|
||||
@ -908,7 +912,6 @@ int cpu_set_user_tls(struct thread *, void *tls_base);
|
||||
void cpu_thread_clean(struct thread *);
|
||||
void cpu_thread_exit(struct thread *);
|
||||
void cpu_thread_setup(struct thread *td);
|
||||
void cpu_thread_siginfo(int sig, u_long code, siginfo_t *si);
|
||||
void cpu_thread_swapin(struct thread *);
|
||||
void cpu_thread_swapout(struct thread *);
|
||||
void ksegrp_link(struct ksegrp *kg, struct proc *p);
|
||||
@ -921,7 +924,7 @@ void thread_free(struct thread *td);
|
||||
void thread_link(struct thread *td, struct ksegrp *kg);
|
||||
void thread_reap(void);
|
||||
struct thread *thread_schedule_upcall(struct thread *td, struct kse_upcall *ku);
|
||||
void thread_signal_add(struct thread *td, int sig);
|
||||
void thread_signal_add(struct thread *td, ksiginfo_t *);
|
||||
int thread_single(int how);
|
||||
void thread_single_end(void);
|
||||
int thread_sleep_check(struct thread *td);
|
||||
|
@ -219,6 +219,16 @@ typedef struct ksiginfo {
|
||||
/* bits for ksi_flags */
|
||||
#define KSI_TRAP 0x01 /* Generated by trap. */
|
||||
|
||||
typedef struct sigqueue {
|
||||
sigset_t sq_signals;
|
||||
TAILQ_HEAD(, ksiginfo) sq_list;
|
||||
struct proc *sq_proc;
|
||||
int sq_flags;
|
||||
} sigqueue_t;
|
||||
|
||||
/* Flags for ksi_flags */
|
||||
#define SQ_INIT 0x01
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/*
|
||||
@ -299,6 +309,7 @@ void pgsigio(struct sigio **, int signum, int checkctty);
|
||||
void pgsignal(struct pgrp *pgrp, int sig, int checkctty);
|
||||
void postsig(int sig);
|
||||
void psignal(struct proc *p, int sig);
|
||||
int psignal_info(struct proc *p, ksiginfo_t *ksi);
|
||||
struct sigacts *sigacts_alloc(void);
|
||||
void sigacts_copy(struct sigacts *dest, struct sigacts *src);
|
||||
void sigacts_free(struct sigacts *ps);
|
||||
@ -308,14 +319,27 @@ void sigexit(struct thread *td, int signum) __dead2;
|
||||
int sig_ffs(sigset_t *set);
|
||||
void siginit(struct proc *p);
|
||||
void signotify(struct thread *td);
|
||||
void tdsignal(struct thread *td, int sig, sigtarget_t target);
|
||||
void trapsignal(struct thread *td, int sig, u_long code);
|
||||
int tdsignal(struct thread *td, int sig, ksiginfo_t *ksi,
|
||||
sigtarget_t target);
|
||||
void trapsignal(struct thread *td, ksiginfo_t *);
|
||||
int ptracestop(struct thread *td, int sig);
|
||||
void sigqueue_init(struct sigqueue *queue, struct proc *p);
|
||||
void sigqueue_flush(struct sigqueue *queue);
|
||||
void sigqueue_delete_proc(struct proc *p, int sig);
|
||||
void sigqueue_delete_set(struct sigqueue *queue, sigset_t *set);
|
||||
void sigqueue_delete(struct sigqueue *queue, int sig);
|
||||
void sigqueue_move_set(struct sigqueue *src, sigqueue_t *dst, sigset_t *);
|
||||
int sigqueue_get(struct sigqueue *queue, int sig, ksiginfo_t *info);
|
||||
int sigqueue_add(struct sigqueue *queue, int sig, ksiginfo_t *info);
|
||||
void sigqueue_collect_set(struct sigqueue *queue, sigset_t *set);
|
||||
void sigqueue_move(struct sigqueue *, struct sigqueue *, int sig);
|
||||
void sigqueue_delete_set_proc(struct proc *, sigset_t *);
|
||||
void sigqueue_delete_stopmask_proc(struct proc *);
|
||||
|
||||
/*
|
||||
* Machine-dependent functions:
|
||||
*/
|
||||
void sendsig(sig_t action, int sig, sigset_t *retmask, u_long code);
|
||||
void sendsig(sig_t, ksiginfo_t *, sigset_t *retmask);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <bsm/audit.h>
|
||||
|
||||
struct thread;
|
||||
struct ksiginfo;
|
||||
|
||||
typedef int sy_call_t(struct thread *, void *);
|
||||
|
||||
@ -64,8 +65,8 @@ struct sysentvec {
|
||||
/* translate trap-to-signal mapping */
|
||||
int (*sv_fixup)(register_t **, struct image_params *);
|
||||
/* stack fixup function */
|
||||
void (*sv_sendsig)(void (*)(int), int, struct __sigset *,
|
||||
u_long); /* send signal */
|
||||
void (*sv_sendsig)(void (*)(int), struct ksiginfo *, struct __sigset *);
|
||||
/* send signal */
|
||||
char *sv_sigcode; /* start of sigtramp code */
|
||||
int *sv_szsigcode; /* size of sigtramp code */
|
||||
void (*sv_prepsyscall)(struct trapframe *, int *, u_int *,
|
||||
|
Loading…
Reference in New Issue
Block a user