mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-21 15:45:02 +00:00
linux(4): Properly build argument list for the signal handler
Provide arguments 2 and 3 if signal handler installed with SA_SIGINFO. MFC after: 2 weeks
This commit is contained in:
parent
c30a767c6f
commit
109fd18ad9
@ -558,13 +558,14 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
|||||||
caddr_t sp;
|
caddr_t sp;
|
||||||
struct trapframe *regs;
|
struct trapframe *regs;
|
||||||
int sig, code;
|
int sig, code;
|
||||||
int oonstack;
|
int oonstack, issiginfo;
|
||||||
|
|
||||||
td = curthread;
|
td = curthread;
|
||||||
p = td->td_proc;
|
p = td->td_proc;
|
||||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||||
sig = linux_translate_traps(ksi->ksi_signo, ksi->ksi_trapno);
|
sig = linux_translate_traps(ksi->ksi_signo, ksi->ksi_trapno);
|
||||||
psp = p->p_sigacts;
|
psp = p->p_sigacts;
|
||||||
|
issiginfo = SIGISMEMBER(psp->ps_siginfo, sig);
|
||||||
code = ksi->ksi_code;
|
code = ksi->ksi_code;
|
||||||
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
mtx_assert(&psp->ps_mtx, MA_OWNED);
|
||||||
regs = td->td_frame;
|
regs = td->td_frame;
|
||||||
@ -616,22 +617,14 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
|||||||
/* Align to 16 bytes. */
|
/* Align to 16 bytes. */
|
||||||
sfp = (struct l_rt_sigframe *)((unsigned long)sp & ~0xFul);
|
sfp = (struct l_rt_sigframe *)((unsigned long)sp & ~0xFul);
|
||||||
|
|
||||||
/* Translate the signal. */
|
|
||||||
sig = bsd_to_linux_signal(sig);
|
|
||||||
|
|
||||||
/* Build the argument list for the signal handler. */
|
|
||||||
regs->tf_rdi = sig; /* arg 1 in %rdi */
|
|
||||||
regs->tf_rax = 0;
|
|
||||||
regs->tf_rsi = (register_t)&sfp->sf_si; /* arg 2 in %rsi */
|
|
||||||
regs->tf_rdx = (register_t)&sfp->sf_uc; /* arg 3 in %rdx */
|
|
||||||
regs->tf_rcx = (register_t)catcher;
|
|
||||||
|
|
||||||
/* Fill in POSIX parts. */
|
|
||||||
siginfo_to_lsiginfo(&ksi->ksi_info, &sf.sf_si, sig);
|
|
||||||
|
|
||||||
mtx_unlock(&psp->ps_mtx);
|
mtx_unlock(&psp->ps_mtx);
|
||||||
PROC_UNLOCK(p);
|
PROC_UNLOCK(p);
|
||||||
|
|
||||||
|
/* Translate the signal. */
|
||||||
|
sig = bsd_to_linux_signal(sig);
|
||||||
|
/* Fill in POSIX parts. */
|
||||||
|
siginfo_to_lsiginfo(&ksi->ksi_info, &sf.sf_si, sig);
|
||||||
|
|
||||||
/* Copy the sigframe out to the user's stack. */
|
/* Copy the sigframe out to the user's stack. */
|
||||||
if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
|
if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
|
||||||
uprintf("pid %d comm %s has trashed its stack, killing\n",
|
uprintf("pid %d comm %s has trashed its stack, killing\n",
|
||||||
@ -640,6 +633,17 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
|||||||
sigexit(td, SIGILL);
|
sigexit(td, SIGILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Build the argument list for the signal handler. */
|
||||||
|
regs->tf_rdi = sig; /* arg 1 in %rdi */
|
||||||
|
regs->tf_rax = 0;
|
||||||
|
if (issiginfo) {
|
||||||
|
regs->tf_rsi = (register_t)&sfp->sf_si; /* arg 2 in %rsi */
|
||||||
|
regs->tf_rdx = (register_t)&sfp->sf_uc; /* arg 3 in %rdx */
|
||||||
|
} else {
|
||||||
|
regs->tf_rsi = 0;
|
||||||
|
regs->tf_rdx = 0;
|
||||||
|
}
|
||||||
|
regs->tf_rcx = (register_t)catcher;
|
||||||
regs->tf_rsp = (long)sfp;
|
regs->tf_rsp = (long)sfp;
|
||||||
regs->tf_rip = linux_rt_sigcode;
|
regs->tf_rip = linux_rt_sigcode;
|
||||||
regs->tf_rflags &= ~(PSL_T | PSL_D);
|
regs->tf_rflags &= ~(PSL_T | PSL_D);
|
||||||
|
@ -430,7 +430,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
|||||||
ucontext_t uc;
|
ucontext_t uc;
|
||||||
uint8_t *scr;
|
uint8_t *scr;
|
||||||
struct sigacts *psp;
|
struct sigacts *psp;
|
||||||
int onstack, sig;
|
int onstack, sig, issiginfo;
|
||||||
|
|
||||||
td = curthread;
|
td = curthread;
|
||||||
p = td->td_proc;
|
p = td->td_proc;
|
||||||
@ -442,6 +442,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
|||||||
|
|
||||||
tf = td->td_frame;
|
tf = td->td_frame;
|
||||||
onstack = sigonstack(tf->tf_sp);
|
onstack = sigonstack(tf->tf_sp);
|
||||||
|
issiginfo = SIGISMEMBER(psp->ps_siginfo, sig);
|
||||||
|
|
||||||
CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm,
|
CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm,
|
||||||
catcher, sig);
|
catcher, sig);
|
||||||
@ -528,8 +529,13 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
|||||||
free(frame, M_LINUX);
|
free(frame, M_LINUX);
|
||||||
|
|
||||||
tf->tf_x[0]= sig;
|
tf->tf_x[0]= sig;
|
||||||
tf->tf_x[1] = (register_t)&fp->sf.sf_si;
|
if (issiginfo) {
|
||||||
tf->tf_x[2] = (register_t)&fp->sf.sf_uc;
|
tf->tf_x[1] = (register_t)&fp->sf.sf_si;
|
||||||
|
tf->tf_x[2] = (register_t)&fp->sf.sf_uc;
|
||||||
|
} else {
|
||||||
|
tf->tf_x[1] = 0;
|
||||||
|
tf->tf_x[2] = 0;
|
||||||
|
}
|
||||||
tf->tf_x[8] = (register_t)catcher;
|
tf->tf_x[8] = (register_t)catcher;
|
||||||
tf->tf_sp = (register_t)fp;
|
tf->tf_sp = (register_t)fp;
|
||||||
tf->tf_elr = (register_t)linux_vdso_sigcode;
|
tf->tf_elr = (register_t)linux_vdso_sigcode;
|
||||||
|
Loading…
Reference in New Issue
Block a user