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
This commit is contained in:
parent
af733395cb
commit
11fd7cf299
@ -109,6 +109,8 @@ ASSYM(TF_PC, offsetof(struct trapframe, tf_pc));
|
|||||||
ASSYM(P_PID, offsetof(struct proc, p_pid));
|
ASSYM(P_PID, offsetof(struct proc, p_pid));
|
||||||
ASSYM(P_FLAG, offsetof(struct proc, p_flag));
|
ASSYM(P_FLAG, offsetof(struct proc, p_flag));
|
||||||
|
|
||||||
|
ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc));
|
||||||
|
|
||||||
#ifdef ARM_TP_ADDRESS
|
#ifdef ARM_TP_ADDRESS
|
||||||
ASSYM(ARM_TP_ADDRESS, ARM_TP_ADDRESS);
|
ASSYM(ARM_TP_ADDRESS, ARM_TP_ADDRESS);
|
||||||
ASSYM(ARM_RAS_START, ARM_RAS_START);
|
ASSYM(ARM_RAS_START, ARM_RAS_START);
|
||||||
|
@ -557,6 +557,7 @@ END(abort)
|
|||||||
|
|
||||||
ENTRY_NP(sigcode)
|
ENTRY_NP(sigcode)
|
||||||
mov r0, sp
|
mov r0, sp
|
||||||
|
add r0, r0, #SIGF_UC
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call the sigreturn system call.
|
* Call the sigreturn system call.
|
||||||
|
@ -742,28 +742,26 @@ sys_sigreturn(td, uap)
|
|||||||
const struct __ucontext *sigcntxp;
|
const struct __ucontext *sigcntxp;
|
||||||
} */ *uap;
|
} */ *uap;
|
||||||
{
|
{
|
||||||
struct sigframe sf;
|
ucontext_t uc;
|
||||||
struct trapframe *tf;
|
|
||||||
int spsr;
|
int spsr;
|
||||||
|
|
||||||
if (uap == NULL)
|
if (uap == NULL)
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
if (copyin(uap->sigcntxp, &sf, sizeof(sf)))
|
if (copyin(uap->sigcntxp, &uc, sizeof(uc)))
|
||||||
return (EFAULT);
|
return (EFAULT);
|
||||||
/*
|
/*
|
||||||
* Make sure the processor mode has not been tampered with and
|
* Make sure the processor mode has not been tampered with and
|
||||||
* interrupts have not been disabled.
|
* 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 ||
|
if ((spsr & PSR_MODE) != PSR_USR32_MODE ||
|
||||||
(spsr & (I32_bit | F32_bit)) != 0)
|
(spsr & (I32_bit | F32_bit)) != 0)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
/* Restore register context. */
|
/* Restore register context. */
|
||||||
tf = td->td_frame;
|
set_mcontext(td, &uc.uc_mcontext);
|
||||||
set_mcontext(td, &sf.sf_uc.uc_mcontext);
|
|
||||||
|
|
||||||
/* Restore signal mask. */
|
/* 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);
|
return (EJUSTRETURN);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user