Date: Thu, 22 Mar 2007 20:45:26 GMT From: Oleksandr Tymoshenko <gonzo@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 116363 for review Message-ID: <200703222045.l2MKjQdq020500@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=116363 Change 116363 by gonzo@gonzo_jeeves on 2007/03/22 20:44:55 o Add implementation of sendsig/sigreturn. o Add implementation of set_mcontext/get_mcontext. Affected files ... .. //depot/projects/mips2/src/sys/mips/mips/machdep.c#26 edit Differences ... ==== //depot/projects/mips2/src/sys/mips/mips/machdep.c#26 (text+ko) ==== @@ -38,12 +38,14 @@ #include <sys/bus.h> #include <sys/cpu.h> #include <sys/cons.h> +#include <sys/exec.h> #include <sys/ucontext.h> #include <sys/proc.h> #include <sys/kdb.h> #include <sys/ptrace.h> #include <sys/reboot.h> #include <sys/signalvar.h> +#include <sys/sysent.h> #include <sys/sysproto.h> #include <sys/user.h> @@ -63,7 +65,10 @@ #include <machine/locore.h> #include <machine/md_var.h> #include <machine/pte.h> +#include <machine/sigframe.h> #include <machine/tlb.h> +#include <machine/vmparam.h> + #ifdef DDB #include <ddb/ddb.h> @@ -89,7 +94,65 @@ void sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) { - panic("Signal is not implemented"); + 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; + int onstack; + int sig; + int code; + + onstack = sigonstack(td->td_frame->tf_regs[TF_SP]); + + sig = ksi->ksi_signo; + code = ksi->ksi_code; + + if ((td->td_flags & TDP_ALTSTACK) && + !(onstack) && + SIGISMEMBER(td->td_proc->p_sigacts->ps_sigonstack, sig)) { + fp = (void*)(td->td_sigstk.ss_sp + td->td_sigstk.ss_size); + td->td_sigstk.ss_flags |= SS_ONSTACK; + } else + fp = (void*)td->td_frame->tf_regs[TF_SP]; + + /* make room on the stack */ + fp--; + + /* make the stack aligned */ + fp = (struct sigframe *)((unsigned int)fp & ~8); + + /* Populate the siginfo frame. */ + frame.sf_si = ksi->ksi_info; + frame.sf_uc.uc_sigmask = *mask; + frame.sf_uc.uc_link = NULL; + frame.sf_uc.uc_flags = (td->td_pflags & TDP_ALTSTACK ) + ? ((onstack) ? SS_ONSTACK : 0) : SS_DISABLE; + 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, 0); + PROC_UNLOCK(td->td_proc); + mtx_unlock(&psp->ps_mtx); + if (copyout(&frame, (void*)fp, sizeof(frame)) != 0) + sigexit(td, SIGILL); + /* + * Build context to run handler in. We invoke the handler + * directly, only returning via the trampoline. Note the + * trampoline version numbers are coordinated with machine- + * dependent code in libc. + */ + + tf->tf_regs[TF_A0] = sig; + tf->tf_regs[TF_A1] = (int)&fp->sf_si; + tf->tf_regs[TF_A2] = (int)&fp->sf_uc; + tf->tf_regs[TF_A3] = (int)&fp->sf_uc; + tf->tf_regs[TF_EPC] = (int)catcher; + /* t9 should be set to entry point for PIC calls */ + tf->tf_regs[TF_T9] = (int)catcher; + tf->tf_regs[TF_SP] = (int)fp; + tf->tf_regs[TF_RA] = (int)(PS_STRINGS - *(p->p_sysent->sv_szsigcode)); + PROC_LOCK(td->td_proc); + mtx_lock(&psp->ps_mtx); } void @@ -196,14 +259,82 @@ int get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret) { - __asm __volatile("break"); + struct trapframe *tf = td->td_frame; + + /* Save register context. Dont copy R0 - it is always 0 */ + mcp->mc_regs[AST] = tf->tf_regs[TF_AST]; + /* V0, V1 */ + memcpy(&mcp->mc_regs[V0], &tf->tf_regs[TF_V0], + sizeof(__register_t) * 2); + /* A0 - A3 */ + memcpy(&mcp->mc_regs[A0], &tf->tf_regs[TF_A0], + sizeof(__register_t) * 4); + /* A4 - A7 */ + memcpy(&mcp->mc_regs[A4], &tf->tf_regs[TF_A4], + sizeof(__register_t) * 4); + /* T0 - T3 */ + memcpy(&mcp->mc_regs[T0], &tf->tf_regs[TF_T0], + sizeof(__register_t) * 4); + + /* S0 - S7 */ + memcpy(&mcp->mc_regs[S0], &tf->tf_regs[TF_S0], + sizeof(__register_t) * 8); + + mcp->mc_regs[T8] = tf->tf_regs[TF_T8]; + mcp->mc_regs[T9] = tf->tf_regs[TF_T9]; + mcp->mc_regs[GP] = tf->tf_regs[TF_GP]; + mcp->mc_regs[SP] = tf->tf_regs[TF_SP]; + mcp->mc_regs[S8] = tf->tf_regs[TF_S8]; + mcp->mc_regs[RA] = tf->tf_regs[TF_RA]; + + mcp->mc_sr = tf->tf_regs[TF_SR]; + mcp->mullo = tf->tf_regs[TF_MULLO]; + mcp->mulhi = tf->tf_regs[TF_MULHI]; + mcp->mc_pc = tf->tf_regs[TF_EPC]; + return (0); } int set_mcontext(struct thread *td, const mcontext_t *mcp) { - __asm __volatile("break"); + struct trapframe *tf = td->td_frame; + + /* Restore register context. Dont copy R0 - it is always 0 */ + tf->tf_regs[TF_AST] = mcp->mc_regs[AST]; + + /* V0, V1 */ + memcpy(&tf->tf_regs[TF_V0], &mcp->mc_regs[V0], + sizeof(__register_t) * 2); + /* A0 - A3 */ + memcpy(&tf->tf_regs[TF_A0], &mcp->mc_regs[A0], + sizeof(__register_t) * 4); + + /* A4 - A7 */ + memcpy(&tf->tf_regs[TF_A4], &mcp->mc_regs[A4], + sizeof(__register_t) * 4); + /* T0 - T3 */ + memcpy(&tf->tf_regs[TF_T0], &mcp->mc_regs[T0], + sizeof(__register_t) * 4); + + /* S0 - S7 */ + memcpy(&tf->tf_regs[TF_S0], &mcp->mc_regs[S0], + sizeof(__register_t) * 8); + + KASSERT(mcp->mc_regs[GP] != 0, ("GP == 0!")); + + tf->tf_regs[TF_T8] = mcp->mc_regs[T8]; + tf->tf_regs[TF_T9] = mcp->mc_regs[T9]; + tf->tf_regs[TF_GP] = mcp->mc_regs[GP]; + tf->tf_regs[TF_SP] = mcp->mc_regs[SP]; + tf->tf_regs[TF_S8] = mcp->mc_regs[S8]; + tf->tf_regs[TF_RA] = mcp->mc_regs[RA]; + + tf->tf_regs[TF_SR] = mcp->mc_sr; + tf->tf_regs[TF_MULLO] = mcp->mullo; + tf->tf_regs[TF_MULHI] = mcp->mulhi; + tf->tf_regs[TF_EPC] = mcp->mc_pc; + return (0); } @@ -367,8 +498,28 @@ const struct __ucontext *sigcntxp; } */ *uap; { - panic("sigreturn is not implemented\n"); - return (0); + struct proc *p = td->td_proc; + struct sigframe sf; + struct trapframe *tf; + + if (uap == NULL) + return (EFAULT); + + if (copyin(uap->sigcntxp, &sf, sizeof(sf))) + return (EFAULT); + + /* Restore register context. */ + tf = td->td_frame; + set_mcontext(td, &sf.sf_uc.uc_mcontext); + + /* 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); } void @@ -397,5 +548,5 @@ sysbeep(int pitch, int period) { - return (0); + return (0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200703222045.l2MKjQdq020500>