Annotation of src/sys/arch/powerpc/powerpc/compat_16_machdep.c, Revision 1.4.2.3
1.4.2.3 ! skrll 1: /* $NetBSD: compat_16_machdep.c,v 1.4.2.2 2004/09/18 14:39:19 skrll Exp $ */
1.4.2.2 skrll 2:
3: /*
4: * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5: * Copyright (C) 1995, 1996 TooLs GmbH.
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by TooLs GmbH.
19: * 4. The name of TooLs GmbH may not be used to endorse or promote products
20: * derived from this software without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25: * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32: */
33:
34: #include <sys/cdefs.h>
1.4.2.3 ! skrll 35: __KERNEL_RCSID(0, "$NetBSD: compat_16_machdep.c,v 1.4.2.2 2004/09/18 14:39:19 skrll Exp $");
1.4.2.2 skrll 36:
37: #include "opt_compat_netbsd.h"
38: #include "opt_altivec.h"
39: #include "opt_ppcarch.h"
40:
41: #include <sys/param.h>
42: #include <sys/mount.h>
43: #include <sys/proc.h>
44: #include <sys/sa.h>
45: #include <sys/savar.h>
46: #include <sys/syscallargs.h>
47: #include <sys/systm.h>
48: #include <sys/ucontext.h>
49: #include <sys/user.h>
50:
51: #include <machine/fpu.h>
52:
53: /*
54: * Send a signal to process.
55: */
56: void
57: sendsig_sigcontext(int sig, const sigset_t *mask, u_long code)
58: {
59: struct lwp *l = curlwp;
60: struct proc *p = l->l_proc;
61: struct sigacts *ps = p->p_sigacts;
62: struct sigcontext *fp, frame;
63: struct trapframe *tf;
64: struct utrapframe *utf = &frame.sc_frame;
65: int onstack;
66: sig_t catcher = SIGACTION(p, sig).sa_handler;
67:
68: tf = trapframe(l);
69:
70: /* Do we need to jump onto the signal stack? */
71: onstack =
72: (p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
73: (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
74:
75: /* Allocate space for the signal handler context. */
76: if (onstack)
77: fp = (struct sigcontext *)((caddr_t)p->p_sigctx.ps_sigstk.ss_sp +
78: p->p_sigctx.ps_sigstk.ss_size);
79: else
80: fp = (struct sigcontext *)tf->fixreg[1];
81: fp = (struct sigcontext *)((uintptr_t)(fp - 1) & ~0xf);
82:
83: /* Save register context. */
84: memcpy(utf->fixreg, tf->fixreg, sizeof(utf->fixreg));
85: utf->lr = tf->lr;
86: utf->cr = tf->cr;
87: utf->xer = tf->xer;
88: utf->ctr = tf->ctr;
89: utf->srr0 = tf->srr0;
90: utf->srr1 = tf->srr1 & PSL_USERSRR1;
91: #ifdef PPC_HAVE_FPU
92: utf->srr1 |= l->l_addr->u_pcb.pcb_flags & (PCB_FE0|PCB_FE1);
93: #endif
94: #ifdef ALTIVEC
95: utf->srr1 |= l->l_addr->u_pcb.pcb_flags & PCB_ALTIVEC ? PSL_VEC : 0;
96: #endif
97: #ifdef PPC_OEA
98: utf->vrsave = tf->tf_xtra[TF_VRSAVE];
99: utf->mq = tf->tf_xtra[TF_MQ];
100: #endif
101:
102: /* Save signal stack. */
103: frame.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK;
104:
105: /* Save signal mask. */
106: frame.sc_mask = *mask;
107:
108: #ifdef COMPAT_13
109: /*
110: * XXX We always have to save an old style signal mask because
111: * XXX we might be delivering a signal to a process which will
112: * XXX escape from the signal in a non-standard way and invoke
113: * XXX sigreturn() directly.
114: */
115: native_sigset_to_sigset13(mask, &frame.__sc_mask13);
116: #endif
117:
118: if (copyout(&frame, fp, sizeof frame) != 0) {
119: /*
120: * Process has trashed its stack; give it an illegal
121: * instructoin to halt it in its tracks.
122: */
123: sigexit(l, SIGILL);
124: /* NOTREACHED */
125: }
126:
127: /*
128: * Build context to run handler in. Note the trampoline version
129: * numbers are coordinated with machine-dependent code in libc.
130: */
131: switch (ps->sa_sigdesc[sig].sd_vers) {
132: #if 1 /* COMPAT_16 */
133: case 0: /* legacy on-stack sigtramp */
134: tf->fixreg[1] = (register_t)fp;
135: tf->lr = (register_t)catcher;
136: tf->fixreg[3] = (register_t)sig;
137: tf->fixreg[4] = (register_t)code;
138: tf->fixreg[5] = (register_t)fp;
139: tf->srr0 = (register_t)p->p_sigctx.ps_sigcode;
140: break;
141: #endif /* COMPAT_16 */
142:
143: case 1:
144: tf->fixreg[1] = (register_t)fp;
145: tf->lr = (register_t)catcher;
146: tf->fixreg[3] = (register_t)sig;
147: tf->fixreg[4] = (register_t)code;
148: tf->fixreg[5] = (register_t)fp;
149: tf->srr0 = (register_t)ps->sa_sigdesc[sig].sd_tramp;
150: break;
151:
152: default:
153: /* Don't know what trampoline version; kill it. */
154: sigexit(l, SIGILL);
155: }
156:
157: /* Remember that we're now on the signal stack. */
158: if (onstack)
159: p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
160: }
161:
162: /*
163: * System call to cleanup state after a signal handler returns.
164: */
165: int
166: compat_16_sys___sigreturn14(struct lwp *l, void *v, register_t *retval)
167: {
168: struct compat_16_sys___sigreturn14_args /* {
169: syscallarg(struct sigcontext *) sigcntxp;
170: } */ *uap = v;
171: struct proc *p = l->l_proc;
172: struct sigcontext sc;
173: struct trapframe *tf;
174: struct utrapframe * const utf = &sc.sc_frame;
175: int error;
176:
177: /*
178: * The trampoline hands us the context.
179: * It is unsafe to keep track of it ourselves, in the event that a
180: * program jumps out of a signal hander.
181: */
182: if ((error = copyin(SCARG(uap, sigcntxp), &sc, sizeof sc)) != 0)
183: return (error);
184:
185: /* Restore the register context. */
186: tf = trapframe(l);
187:
188: /*
189: * Make sure SRR1 hasn't been maliciously tampered with.
190: */
191: if (!PSL_USEROK_P(sc.sc_frame.srr1))
192: return (EINVAL);
193:
194: /* Restore register context. */
195: memcpy(tf->fixreg, utf->fixreg, sizeof(tf->fixreg));
196: tf->lr = utf->lr;
197: tf->cr = utf->cr;
198: tf->xer = utf->xer;
199: tf->ctr = utf->ctr;
200: tf->srr0 = utf->srr0;
201: tf->srr1 = utf->srr1;
202: #ifdef PPC_HAVE_FPU
203: l->l_addr->u_pcb.pcb_flags &= ~(PCB_FE0|PCB_FE1);
204: l->l_addr->u_pcb.pcb_flags |= utf->srr1 & (PCB_FE0|PCB_FE1);
205: #endif
206: #ifdef PPC_OEA
207: tf->tf_xtra[TF_VRSAVE] = utf->vrsave;
208: tf->tf_xtra[TF_MQ] = utf->mq;
209: #endif
210:
211: /* Restore signal stack. */
212: if (sc.sc_onstack & SS_ONSTACK)
213: p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
214: else
215: p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK;
216:
217: /* Restore signal mask. */
218: (void) sigprocmask1(p, SIG_SETMASK, &sc.sc_mask, 0);
219:
220: return (EJUSTRETURN);
221: }
CVSweb <webmaster@jp.NetBSD.org>