Annotation of sys/arch/i386/i386/svr4_machdep.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: svr4_machdep.c,v 1.25 2006/12/29 13:04:37 pedro Exp $ */
2: /* $NetBSD: svr4_machdep.c,v 1.24 1996/05/03 19:42:26 christos Exp $ */
3:
4: /*
5: * Copyright (c) 1994 Christos Zoulas
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. The name of the author may not be used to endorse or promote products
17: * derived from this software without specific prior written permission
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29: */
30:
31: #include <sys/param.h>
32: #include <sys/systm.h>
33: #include <sys/namei.h>
34: #include <sys/proc.h>
35: #include <sys/user.h>
36: #include <sys/filedesc.h>
37: #include <sys/ioctl.h>
38: #include <sys/mount.h>
39: #include <sys/kernel.h>
40: #include <sys/signal.h>
41: #include <sys/signalvar.h>
42: #include <sys/malloc.h>
43:
44: #include <sys/syscallargs.h>
45: #include <compat/svr4/svr4_types.h>
46: #include <compat/svr4/svr4_ucontext.h>
47: #include <compat/svr4/svr4_syscallargs.h>
48: #include <compat/svr4/svr4_util.h>
49:
50: #include <machine/cpu.h>
51: #include <machine/cpufunc.h>
52: #include <machine/psl.h>
53: #include <machine/reg.h>
54: #include <machine/specialreg.h>
55: #include <machine/sysarch.h>
56: #include <machine/vm86.h>
57: #include <machine/svr4_machdep.h>
58:
59: static void svr4_getsiginfo(union svr4_siginfo *, int, u_long, int, caddr_t);
60:
61: void
62: svr4_getcontext(struct proc *p, struct svr4_ucontext *uc, int mask,
63: int oonstack)
64: {
65: struct trapframe *tf = p->p_md.md_regs;
66: struct sigacts *psp = p->p_sigacts;
67: svr4_greg_t *r = uc->uc_mcontext.greg;
68: struct svr4_sigaltstack *s = &uc->uc_stack;
69: struct sigaltstack *sf = &psp->ps_sigstk;
70:
71: bzero(uc, sizeof(struct svr4_ucontext));
72:
73: /*
74: * Set the general purpose registers
75: */
76: #ifdef VM86
77: if (tf->tf_eflags & PSL_VM) {
78: r[SVR4_X86_GS] = tf->tf_vm86_gs;
79: r[SVR4_X86_FS] = tf->tf_vm86_fs;
80: r[SVR4_X86_ES] = tf->tf_vm86_es;
81: r[SVR4_X86_DS] = tf->tf_vm86_ds;
82: r[SVR4_X86_EFL] = get_vflags(p);
83: } else
84: #endif
85: {
86: r[SVR4_X86_FS] = tf->tf_fs;
87: r[SVR4_X86_GS] = tf->tf_gs;
88: r[SVR4_X86_ES] = tf->tf_es;
89: r[SVR4_X86_DS] = tf->tf_ds;
90: r[SVR4_X86_EFL] = tf->tf_eflags;
91: }
92: r[SVR4_X86_EDI] = tf->tf_edi;
93: r[SVR4_X86_ESI] = tf->tf_esi;
94: r[SVR4_X86_EBP] = tf->tf_ebp;
95: r[SVR4_X86_ESP] = tf->tf_esp;
96: r[SVR4_X86_EBX] = tf->tf_ebx;
97: r[SVR4_X86_EDX] = tf->tf_edx;
98: r[SVR4_X86_ECX] = tf->tf_ecx;
99: r[SVR4_X86_EAX] = tf->tf_eax;
100: r[SVR4_X86_TRAPNO] = 0;
101: r[SVR4_X86_ERR] = 0;
102: r[SVR4_X86_EIP] = tf->tf_eip;
103: r[SVR4_X86_CS] = tf->tf_cs;
104: r[SVR4_X86_UESP] = 0;
105: r[SVR4_X86_SS] = tf->tf_ss;
106:
107: /*
108: * Set the signal stack
109: */
110: bsd_to_svr4_sigaltstack(sf, s);
111:
112: /*
113: * Set the signal mask
114: */
115: bsd_to_svr4_sigset(&mask, &uc->uc_sigmask);
116:
117: /*
118: * Set the flags
119: */
120: uc->uc_flags = SVR4_UC_ALL;
121: }
122:
123:
124: /*
125: * Set to ucontext specified.
126: * has been taken. Reset signal mask and
127: * stack state from context.
128: * Return to previous pc and psl as specified by
129: * context left by sendsig. Check carefully to
130: * make sure that the user has not modified the
131: * psl to gain improper privileges or to cause
132: * a machine fault.
133: */
134: int
135: svr4_setcontext(struct proc *p, struct svr4_ucontext *uc)
136: {
137: struct sigacts *psp = p->p_sigacts;
138: struct trapframe *tf;
139: svr4_greg_t *r = uc->uc_mcontext.greg;
140: struct svr4_sigaltstack *s = &uc->uc_stack;
141: struct sigaltstack *sf = &psp->ps_sigstk;
142: int mask;
143:
144: /*
145: * XXX:
146: * Should we check the value of flags to determine what to restore?
147: * What to do with uc_link?
148: * What to do with floating point stuff?
149: * Should we bother with the rest of the registers that we
150: * set to 0 right now?
151: */
152:
153: tf = p->p_md.md_regs;
154:
155: /*
156: * Restore register context.
157: */
158: #ifdef VM86
159: if (r[SVR4_X86_EFL] & PSL_VM) {
160: tf->tf_vm86_gs = r[SVR4_X86_GS];
161: tf->tf_vm86_fs = r[SVR4_X86_FS];
162: tf->tf_vm86_es = r[SVR4_X86_ES];
163: tf->tf_vm86_ds = r[SVR4_X86_DS];
164: set_vflags(p, r[SVR4_X86_EFL]);
165: } else
166: #endif
167: {
168: /*
169: * Check for security violations. If we're returning to
170: * protected mode, the CPU will validate the segment registers
171: * automatically and generate a trap on violations. We handle
172: * the trap, rather than doing all of the checking here.
173: */
174: if (((r[SVR4_X86_EFL] ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 ||
175: !USERMODE(r[SVR4_X86_CS], r[SVR4_X86_EFL]))
176: return (EINVAL);
177:
178: tf->tf_fs = r[SVR4_X86_FS];
179: tf->tf_gs = r[SVR4_X86_GS];
180: tf->tf_es = r[SVR4_X86_ES];
181: tf->tf_ds = r[SVR4_X86_DS];
182: tf->tf_eflags = r[SVR4_X86_EFL];
183: }
184: tf->tf_edi = r[SVR4_X86_EDI];
185: tf->tf_esi = r[SVR4_X86_ESI];
186: tf->tf_ebp = r[SVR4_X86_EBP];
187: tf->tf_ebx = r[SVR4_X86_EBX];
188: tf->tf_edx = r[SVR4_X86_EDX];
189: tf->tf_ecx = r[SVR4_X86_ECX];
190: tf->tf_eax = r[SVR4_X86_EAX];
191: tf->tf_eip = r[SVR4_X86_EIP];
192: tf->tf_cs = r[SVR4_X86_CS];
193: tf->tf_ss = r[SVR4_X86_SS];
194: tf->tf_esp = r[SVR4_X86_ESP];
195:
196: /*
197: * restore signal stack
198: */
199: svr4_to_bsd_sigaltstack(s, sf);
200:
201: /*
202: * restore signal mask
203: */
204: svr4_to_bsd_sigset(&uc->uc_sigmask, &mask);
205: p->p_sigmask = mask & ~sigcantmask;
206:
207: return EJUSTRETURN;
208: }
209:
210:
211: static void
212: svr4_getsiginfo(union svr4_siginfo *si, int sig, u_long code, int type,
213: caddr_t addr)
214: {
215: si->svr4_si_signo = bsd_to_svr4_sig[sig];
216: si->svr4_si_errno = 0;
217: si->svr4_si_addr = addr;
218:
219: si->svr4_si_code = 0;
220: si->svr4_si_trap = 0;
221:
222: switch (sig) {
223: case SIGSEGV:
224: switch (type) {
225: case SEGV_ACCERR:
226: si->svr4_si_code = SVR4_SEGV_ACCERR;
227: si->svr4_si_trap = SVR4_T_PROTFLT;
228: break;
229: case SEGV_MAPERR:
230: si->svr4_si_code = SVR4_SEGV_MAPERR;
231: si->svr4_si_trap = SVR4_T_SEGNPFLT;
232: break;
233: }
234: break;
235: case SIGBUS:
236: switch (type) {
237: case BUS_ADRALN:
238: si->svr4_si_code = SVR4_BUS_ADRALN;
239: si->svr4_si_trap = SVR4_T_ALIGNFLT;
240: break;
241: }
242: break;
243: case SIGTRAP:
244: switch (type) {
245: case TRAP_BRKPT:
246: si->svr4_si_code = SVR4_TRAP_BRKPT;
247: si->svr4_si_trap = SVR4_T_BPTFLT;
248: break;
249: case TRAP_TRACE:
250: si->svr4_si_code = SVR4_TRAP_TRACE;
251: si->svr4_si_trap = SVR4_T_TRCTRAP;
252: break;
253: }
254: break;
255: case SIGEMT:
256: switch (type) {
257: }
258: break;
259: case SIGILL:
260: switch (type) {
261: case ILL_PRVOPC:
262: si->svr4_si_code = SVR4_ILL_PRVOPC;
263: si->svr4_si_trap = SVR4_T_PRIVINFLT;
264: break;
265: case ILL_BADSTK:
266: si->svr4_si_code = SVR4_ILL_BADSTK;
267: si->svr4_si_trap = SVR4_T_STKFLT;
268: break;
269: }
270: break;
271: case SIGFPE:
272: switch (type) {
273: case FPE_INTOVF:
274: si->svr4_si_code = SVR4_FPE_INTOVF;
275: si->svr4_si_trap = SVR4_T_DIVIDE;
276: break;
277: case FPE_FLTDIV:
278: si->svr4_si_code = SVR4_FPE_FLTDIV;
279: si->svr4_si_trap = SVR4_T_DIVIDE;
280: break;
281: case FPE_FLTOVF:
282: si->svr4_si_code = SVR4_FPE_FLTOVF;
283: si->svr4_si_trap = SVR4_T_DIVIDE;
284: break;
285: case FPE_FLTSUB:
286: si->svr4_si_code = SVR4_FPE_FLTSUB;
287: si->svr4_si_trap = SVR4_T_BOUND;
288: break;
289: case FPE_FLTINV:
290: si->svr4_si_code = SVR4_FPE_FLTINV;
291: si->svr4_si_trap = SVR4_T_FPOPFLT;
292: break;
293: }
294: break;
295: }
296: }
297:
298:
299: /*
300: * Send an interrupt to process.
301: *
302: * Stack is set up to allow sigcode stored
303: * in u. to call routine. After the handler is
304: * done svr4 will call setcontext for us
305: * with the user context we just set up, and we
306: * will return to the user pc, psl.
307: */
308: void
309: svr4_sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
310: union sigval val)
311: {
312: struct proc *p = curproc;
313: struct trapframe *tf;
314: struct svr4_sigframe *fp, frame;
315: struct sigacts *psp = p->p_sigacts;
316: int oonstack;
317:
318: tf = p->p_md.md_regs;
319: oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
320:
321: /*
322: * Allocate space for the signal handler context.
323: */
324: if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
325: (psp->ps_sigonstack & sigmask(sig))) {
326: fp = (struct svr4_sigframe *)((char *)psp->ps_sigstk.ss_sp +
327: psp->ps_sigstk.ss_size - sizeof(struct svr4_sigframe));
328: psp->ps_sigstk.ss_flags |= SS_ONSTACK;
329: } else {
330: fp = (struct svr4_sigframe *)tf->tf_esp - 1;
331: }
332:
333: /*
334: * Build the argument list for the signal handler.
335: * Notes:
336: * - we always build the whole argument list, even when we
337: * don't need to [when SA_SIGINFO is not set, we don't need
338: * to pass all sf_si and sf_uc]
339: * - we don't pass the correct signal address [we need to
340: * modify many kernel files to enable that]
341: */
342:
343: svr4_getcontext(p, &frame.sf_uc, mask, oonstack);
344: svr4_getsiginfo(&frame.sf_si, sig, code, type, val.sival_ptr);
345:
346: frame.sf_signum = frame.sf_si.svr4_si_signo;
347: frame.sf_sip = &fp->sf_si;
348: frame.sf_ucp = &fp->sf_uc;
349: frame.sf_handler = catcher;
350: #ifdef DEBUG_SVR4
351: printf("sig = %d, sip %p, ucp = %p, handler = %p\n",
352: frame.sf_signum, frame.sf_sip, frame.sf_ucp, frame.sf_handler);
353: #endif
354:
355: if (copyout(&frame, fp, sizeof(frame)) != 0) {
356: /*
357: * Process has trashed its stack; give it an illegal
358: * instruction to halt it in its tracks.
359: */
360: sigexit(p, SIGILL);
361: /* NOTREACHED */
362: }
363:
364: /*
365: * Build context to run handler in.
366: */
367: tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
368: tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
369: tf->tf_eip = p->p_sigcode;
370: tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
371: tf->tf_eflags &= ~(PSL_T|PSL_VM|PSL_AC);
372: tf->tf_esp = (int)fp;
373: tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
374: }
375:
376:
377: /*
378: * sysi86
379: */
380: int
381: svr4_sys_sysarch(struct proc *p, void *v, register_t *retval)
382: {
383: struct svr4_sys_sysarch_args *uap = v;
384: int error;
385: #ifdef USER_LDT
386: caddr_t sg = stackgap_init(p->p_emul);
387: #endif
388: *retval = 0; /* XXX: What to do */
389:
390: switch (SCARG(uap, op)) {
391: case SVR4_SYSARCH_FPHW:
392: return 0;
393:
394: case SVR4_SYSARCH_DSCR:
395: #ifdef USER_LDT
396: if (user_ldt_enable == 0)
397: return (ENOSYS);
398: else {
399: struct i386_set_ldt_args sa, *sap;
400: struct sys_sysarch_args ua;
401:
402: struct svr4_ssd ssd;
403: union descriptor bsd;
404:
405: if ((error = copyin(SCARG(uap, a1), &ssd,
406: sizeof(ssd))) != 0) {
407: printf("Cannot copy arg1\n");
408: return error;
409: }
410:
411: printf("s=%x, b=%x, l=%x, a1=%x a2=%x\n",
412: ssd.selector, ssd.base, ssd.limit,
413: ssd.access1, ssd.access2);
414:
415: /* We can only set ldt's for now. */
416: if (!ISLDT(ssd.selector)) {
417: printf("Not an ldt\n");
418: return EPERM;
419: }
420:
421: /* Oh, well we don't cleanup either */
422: if (ssd.access1 == 0)
423: return 0;
424:
425: bsd.sd.sd_lobase = ssd.base & 0xffffff;
426: bsd.sd.sd_hibase = (ssd.base >> 24) & 0xff;
427:
428: bsd.sd.sd_lolimit = ssd.limit & 0xffff;
429: bsd.sd.sd_hilimit = (ssd.limit >> 16) & 0xf;
430:
431: bsd.sd.sd_type = ssd.access1 & 0x1f;
432: bsd.sd.sd_dpl = (ssd.access1 >> 5) & 0x3;
433: bsd.sd.sd_p = (ssd.access1 >> 7) & 0x1;
434:
435: bsd.sd.sd_xx = ssd.access2 & 0x3;
436: bsd.sd.sd_def32 = (ssd.access2 >> 2) & 0x1;
437: bsd.sd.sd_gran = (ssd.access2 >> 3)& 0x1;
438:
439: sa.start = IDXSEL(ssd.selector);
440: sa.desc = stackgap_alloc(&sg, sizeof(union descriptor));
441: sa.num = 1;
442: sap = stackgap_alloc(&sg,
443: sizeof(struct i386_set_ldt_args));
444:
445: if ((error = copyout(&sa, sap, sizeof(sa))) != 0) {
446: printf("Cannot copyout args\n");
447: return error;
448: }
449:
450: SCARG(&ua, op) = I386_SET_LDT;
451: SCARG(&ua, parms) = (char *) sap;
452:
453: if ((error = copyout(&bsd, sa.desc, sizeof(bsd))) != 0) {
454: printf("Cannot copyout desc\n");
455: return error;
456: }
457:
458: return sys_sysarch(p, &ua, retval);
459: }
460: #endif
461: case SVR4_SYSARCH_GOSF:
462: {
463: /* just as SCO Openserver 5.0 says */
464: char features[] = {1,1,1,1,1,1,1,1,2,1,1,1};
465:
466: if ((error = copyout(features, SCARG(uap, a1),
467: sizeof(features))) != 0) {
468: printf("Cannot copyout vector\n");
469: return error;
470: }
471:
472: return 0;
473: }
474:
475: default:
476: printf("svr4_sysarch(%d), a1 %p\n", SCARG(uap, op),
477: SCARG(uap, a1));
478: return 0;
479: }
480: }
CVSweb