Skip site navigation (1)Skip section navigation (2)
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>