summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2014-03-07 20:32:45 +0000
committerian <ian@FreeBSD.org>2014-03-07 20:32:45 +0000
commit11fd7cf2992306c8b382554217a88bdaa49099d3 (patch)
tree29b44efe9cb713920b6197f229d26a5650c93ae5 /sys/arm
parentaf733395cb04047ceb619741a607753867cc37a1 (diff)
downloadFreeBSD-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.c2
-rw-r--r--sys/arm/arm/locore.S1
-rw-r--r--sys/arm/arm/machdep.c12
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);
}
OpenPOWER on IntegriCloud