[BACK]Return to svr4_machdep.c CVS log [TXT][DIR] Up to [local] / sys / arch / i386 / i386

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