diff options
author | cognet <cognet@FreeBSD.org> | 2004-09-23 22:12:28 +0000 |
---|---|---|
committer | cognet <cognet@FreeBSD.org> | 2004-09-23 22:12:28 +0000 |
commit | 556153cd0ce0abb482d25d01a6f9daf123657647 (patch) | |
tree | f194991de0afcb1bbc044d69b1fcfe281287c12f /sys/arm | |
parent | 2961849c001d8b4cf7c1a266e0242b3ec67e211f (diff) | |
download | FreeBSD-src-556153cd0ce0abb482d25d01a6f9daf123657647.zip FreeBSD-src-556153cd0ce0abb482d25d01a6f9daf123657647.tar.gz |
Implement sigreturn().
Diffstat (limited to 'sys/arm')
-rw-r--r-- | sys/arm/arm/machdep.c | 84 |
1 files changed, 63 insertions, 21 deletions
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index 8b23898..ccf81f3 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include <sys/bio.h> #include <sys/buf.h> #include <sys/exec.h> +#include <sys/sysent.h> #include <machine/reg.h> #include <machine/cpu.h> @@ -81,6 +82,7 @@ __FBSDID("$FreeBSD$"); #include <machine/machdep.h> #include <machine/metadata.h> #include <machine/armreg.h> +#include <machine/md_var.h> #define MDROOT_ADDR 0xd0400000 @@ -107,6 +109,7 @@ sendsig(catcher, sig, mask, code) u_long code; { struct thread *td = curthread; + struct proc *p = td->td_proc; struct trapframe *tf = td->td_frame; struct sigframe *fp, frame; struct sigacts *psp = td->td_proc->p_sigacts; @@ -117,7 +120,7 @@ sendsig(catcher, sig, mask, code) fp--; /* make the stack aligned */ - fp = (struct sigframe *)_ALIGN(fp); + fp = (struct sigframe *)STACKALIGN(fp); /* Populate the siginfo frame. */ frame.sf_si.si_signo = sig; frame.sf_si.si_code = code; @@ -125,6 +128,7 @@ sendsig(catcher, sig, mask, code) frame.sf_uc.uc_link = NULL; frame.sf_uc.uc_flags |= td->td_sigstk.ss_flags & SS_ONSTACK ? _UC_SETSTACK : _UC_CLRSTACK; + frame.sf_uc.uc_stack = td->td_sigstk; memset(&frame.sf_uc.uc_stack, 0, sizeof(frame.sf_uc.uc_stack)); get_mcontext(td, &frame.sf_uc.uc_mcontext, (uint32_t)&frame.sf_uc.uc_flags); @@ -147,6 +151,7 @@ sendsig(catcher, sig, mask, code) tf->tf_r5 = (int)&fp->sf_uc; tf->tf_pc = (int)catcher; tf->tf_usr_sp = (int)fp; + tf->tf_usr_lr = (int)(PS_STRINGS - *(p->p_sysent->sv_szsigcode)); if (onstack) td->td_sigstk.ss_flags |= SS_ONSTACK; PROC_LOCK(td->td_proc); @@ -267,7 +272,6 @@ set_regs(struct thread *td, struct reg *regs) tf->tf_pc = regs->r_pc; tf->tf_spsr &= ~PSR_FLAGS; tf->tf_spsr |= regs->r_cpsr & PSR_FLAGS; - while(1); return (0); } @@ -288,12 +292,6 @@ set_dbregs(struct thread *td, struct dbreg *regs) return (0); } -void -cpu_halt(void) -{ - cpu_reset(); -} - int ptrace_single_step(struct thread *td) { @@ -389,18 +387,6 @@ set_mcontext(struct thread *td, const mcontext_t *mcp) return (0); } -#ifdef COMPAT_FREEBSD4 -int -freebsd4_sigreturn(td, uap) - struct thread *td; - struct freebsd4_sigreturn_args /* { - const ucontext4 *sigcntxp; - } */ *uap; -{ - return (0); -} -#endif - /* * MPSAFE */ @@ -411,7 +397,63 @@ sigreturn(td, uap) const __ucontext *sigcntxp; } */ *uap; { - return (0); + struct proc *p = td->td_proc; + struct sigframe sf; + struct trapframe *tf; + int spsr; + + if (uap == NULL) + return (EFAULT); + if (copyin(uap->sigcntxp, &sf, sizeof(sf))) + 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]; + if ((spsr & PSR_MODE) != PSR_USR32_MODE || + (spsr & (I32_bit | F32_bit)) != 0) + return (EINVAL); + /* Restore register context. */ + tf = td->td_frame; + memcpy((register_t *)tf + 1, &sf.sf_uc.uc_mcontext, sizeof(*tf) - + 4 * sizeof(register_t)); +#if 0 + tf->tf_r0 = context.sc_r0; + tf->tf_r1 = context.sc_r1; + tf->tf_r2 = context.sc_r2; + tf->tf_r3 = context.sc_r3; + tf->tf_r4 = context.sc_r4; + tf->tf_r5 = context.sc_r5; + tf->tf_r6 = context.sc_r6; + tf->tf_r7 = context.sc_r7; + tf->tf_r8 = context.sc_r8; + tf->tf_r9 = context.sc_r9; + tf->tf_r10 = context.sc_r10; + tf->tf_r11 = context.sc_r11; + tf->tf_r12 = context.sc_r12; + tf->tf_usr_sp = context.sc_usr_sp; + tf->tf_usr_lr = context.sc_usr_lr; + tf->tf_svc_lr = context.sc_svc_lr; + tf->tf_pc = context.sc_pc; +#endif + tf->tf_pc = sf.sf_uc.uc_mcontext.__gregs[_REG_PC]; + tf->tf_spsr = spsr; + + /* Restore signal stack. */ + if (sf.sf_uc.uc_flags & _UC_SETSTACK) + td->td_sigstk.ss_flags |= SS_ONSTACK; + else + td->td_sigstk.ss_flags &= ~SS_ONSTACK; + + /* Restore signal mask. */ + PROC_LOCK(p); + td->td_sigmask = sf.sf_uc.uc_sigmask; + SIG_CANTMASK(td->td_sigmask); + signotify(td); + PROC_UNLOCK(p); + + return (EJUSTRETURN); } |