diff options
author | ian <ian@FreeBSD.org> | 2014-03-07 20:32:45 +0000 |
---|---|---|
committer | ian <ian@FreeBSD.org> | 2014-03-07 20:32:45 +0000 |
commit | 11fd7cf2992306c8b382554217a88bdaa49099d3 (patch) | |
tree | 29b44efe9cb713920b6197f229d26a5650c93ae5 /sys/arm | |
parent | af733395cb04047ceb619741a607753867cc37a1 (diff) | |
download | FreeBSD-src-11fd7cf2992306c8b382554217a88bdaa49099d3.zip FreeBSD-src-11fd7cf2992306c8b382554217a88bdaa49099d3.tar.gz |
Fix the arm sys_sigreturn(): its argument is a struct ucontext, not a
struct sigframe containing the struct ucontext.
The signal trampoline return code on the other hand DOES have just a
struct sigframe on the stack to work with, so have it get a pointer to
the ucontext out of there to pass along to sys_sigreturn.
In other words, make everything work right whether sys_sigreturn is
invoked from the trampoline or from userland code calling sigreturn(2).
Submitted by: Takashi Komatsu <komatsu.taka@jp.panasonic.com>
Reviewed by: cognet
Diffstat (limited to 'sys/arm')
-rw-r--r-- | sys/arm/arm/genassym.c | 2 | ||||
-rw-r--r-- | sys/arm/arm/locore.S | 1 | ||||
-rw-r--r-- | sys/arm/arm/machdep.c | 12 |
3 files changed, 8 insertions, 7 deletions
diff --git a/sys/arm/arm/genassym.c b/sys/arm/arm/genassym.c index 029529a..e38733b 100644 --- a/sys/arm/arm/genassym.c +++ b/sys/arm/arm/genassym.c @@ -109,6 +109,8 @@ ASSYM(TF_PC, offsetof(struct trapframe, tf_pc)); ASSYM(P_PID, offsetof(struct proc, p_pid)); ASSYM(P_FLAG, offsetof(struct proc, p_flag)); +ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc)); + #ifdef ARM_TP_ADDRESS ASSYM(ARM_TP_ADDRESS, ARM_TP_ADDRESS); ASSYM(ARM_RAS_START, ARM_RAS_START); diff --git a/sys/arm/arm/locore.S b/sys/arm/arm/locore.S index 364d19e..90eeeaf 100644 --- a/sys/arm/arm/locore.S +++ b/sys/arm/arm/locore.S @@ -557,6 +557,7 @@ END(abort) ENTRY_NP(sigcode) mov r0, sp + add r0, r0, #SIGF_UC /* * Call the sigreturn system call. diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index 68f4318..35f1432 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -742,28 +742,26 @@ sys_sigreturn(td, uap) const struct __ucontext *sigcntxp; } */ *uap; { - struct sigframe sf; - struct trapframe *tf; + ucontext_t uc; int spsr; if (uap == NULL) return (EFAULT); - if (copyin(uap->sigcntxp, &sf, sizeof(sf))) + if (copyin(uap->sigcntxp, &uc, sizeof(uc))) return (EFAULT); /* * Make sure the processor mode has not been tampered with and * interrupts have not been disabled. */ - spsr = sf.sf_uc.uc_mcontext.__gregs[_REG_CPSR]; + spsr = uc.uc_mcontext.__gregs[_REG_CPSR]; if ((spsr & PSR_MODE) != PSR_USR32_MODE || (spsr & (I32_bit | F32_bit)) != 0) return (EINVAL); /* Restore register context. */ - tf = td->td_frame; - set_mcontext(td, &sf.sf_uc.uc_mcontext); + set_mcontext(td, &uc.uc_mcontext); /* Restore signal mask. */ - kern_sigprocmask(td, SIG_SETMASK, &sf.sf_uc.uc_sigmask, NULL, 0); + kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); return (EJUSTRETURN); } |