Annotation of coherent/b/STREAMS/coh.386/sig.c, revision 1.1.1.1

1.1       root        1: /* (lgl-
                      2:  *     The information contained herein is a trade secret of Mark Williams
                      3:  *     Company, and  is confidential information.  It is provided  under a
                      4:  *     license agreement,  and may be  copied or disclosed  only under the
                      5:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
                      6:  *     material without the express written authorization of Mark Williams
                      7:  *     Company or persuant to the license agreement is unlawful.
                      8:  *
                      9:  *     COHERENT Version 5.0
                     10:  *     Copyright (c) 1982, 1993.
                     11:  *     An unpublished work by Mark Williams Company, Chicago.
                     12:  *     All rights reserved.
                     13:  -lgl) */
                     14: /*
                     15:  * File:       coh.386/sig.c
                     16:  *
                     17:  * Purpose:    signal handling
                     18:  *
                     19:  * Revised: Tue May  4 11:59:15 1993 CDT
                     20:  */
                     21: 
                     22: /*
                     23:  * ----------------------------------------------------------------------
                     24:  * Includes.
                     25:  */
                     26: 
                     27: #include <common/_limits.h>
                     28: #include <common/_wait.h>
                     29: #include <common/_gregset.h>
                     30: #include <kernel/sigproc.h>
                     31: 
                     32: #include <sys/coherent.h>
                     33: #include <sys/errno.h>
                     34: #include <sys/ino.h>
                     35: #include <sys/inode.h>
                     36: #include <sys/io.h>
                     37: #include <sys/proc.h>
                     38: #include <sys/ptrace.h>
                     39: #include <sys/sched.h>
                     40: #include <sys/seg.h>
                     41: #include <sys/file.h>
                     42: #include <sys/core.h>
                     43: 
                     44: 
                     45: /*
                     46:  * ----------------------------------------------------------------------
                     47:  * Definitions.
                     48:  *     Constants.
                     49:  *     Macros with argument lists.
                     50:  *     Typedefs.
                     51:  *     Enums.
                     52:  */
                     53: 
                     54: /*
                     55:  * ----------------------------------------------------------------------
                     56:  * Functions.
                     57:  *     Import Functions.
                     58:  *     Export Functions.
                     59:  *     Local Functions.
                     60:  */
                     61: void   curr_check_signals();
                     62: int    ptset();
                     63: void   sendsig();
                     64: int    sigdump();
                     65: __sigfunc_t    usigsys();
                     66: 
                     67: static struct _fpstate * empack();
                     68: static int             ptret();
                     69: 
                     70: /*
                     71:  * ----------------------------------------------------------------------
                     72:  * Global Data.
                     73:  *     Import Variables.
                     74:  *     Export Variables.
                     75:  *     Local Variables.
                     76:  */
                     77: /*
                     78:  * Patchable variables.
                     79:  *
                     80:  * Patch DUMP_TEXT nonzero to make text segment show up in core files.
                     81:  * Patch DUMP_LIM set the upper limit in bytes of how much of a
                     82:  * segment is written to a core file.
                     83:  *
                     84:  * CATCH_SEGV can be patched to allow signal () to be used to catch the
                     85:  * SIGSEGV signal (). This is off by default because:
                     86:  *   i)        Experience has shown that kernel printf () messages being on by
                     87:  *     default is very useful for catching bugs.
                     88:  *  ii)        Certain extremely ill-behaved applications apparently catch SIGSEGV
                     89:  *     blindly as part of some catch-all behaviour, and when such faults
                     90:  *     happen have been known to loop generating kernel printf () output
                     91:  *     which bogs down the system unacceptably.
                     92:  * iii)        Turning the signal off to avoid ii) causes less actual disruption than
                     93:  *     leaving it on.
                     94:  * This only applies to the signal () interface; we assume that apps which are
                     95:  * smart enough to use sigset () or sigaction () also know what to do with
                     96:  * SIGSEGV.
                     97:  */
                     98: 
                     99: int    DUMP_TEXT = 0;
                    100: int    DUMP_LIM=512*1024;
                    101: int    CATCH_SEGV = 0;
                    102: 
                    103: /*
                    104:  * ----------------------------------------------------------------------
                    105:  * Code.
                    106:  */
                    107: 
                    108: /*
                    109:  * Or an entire signal mask into the "hold" mask.
                    110:  */
                    111: 
                    112: static void
                    113: sigMask (mask)
                    114: __sigset_t * mask;
                    115: {
                    116:        int             i;
                    117:        __sigmask_t   * loop = mask->_sigbits;
                    118:        __sigset_t      signal_mask;
                    119: 
                    120:        curr_signal_mask (NULL, & signal_mask);
                    121: 
                    122:        for (i = 0 ; i < __ARRAY_LENGTH (mask->_sigbits) ; i ++)
                    123:                signal_mask._sigbits [i] |= * loop ++;
                    124: 
                    125:        curr_signal_mask (& signal_mask, NULL);
                    126: }
                    127: 
                    128: 
                    129: /*
                    130:  * Set up the action to be taken on a signal.
                    131:  */
                    132: 
                    133: __sigfunc_t
                    134: usigsys (signal, func, regsetp)
                    135: unsigned       signal;
                    136: __sigfunc_t    func;
                    137: gregset_t     *        regsetp;
                    138: {
                    139:        int             sigtype;
                    140:        __sigmask_t     mask;
                    141:        __sigset_t      signal_mask;
                    142:        __sigaction_t   signal_action;
                    143: 
                    144:        sigtype = signal & ~ 0xFF;
                    145:        signal &= 0xFF;
                    146: 
                    147: #if 0
                    148:        T_HAL(8, printf("[%d]sig(%d, %x) ", SELF->p_pid, signal, func));
                    149: #endif
                    150: 
                    151:        /*
                    152:         * Check the passed signal number. SIGKILL and SIGSTOP are not allowed
                    153:         * to be caught.
                    154:         */
                    155: 
                    156:        /* Range check on 1-based signal number. */
                    157:        if (signal <= 0 || signal > NSIG || signal == SIGSTOP ||
                    158:            signal == SIGKILL) {
                    159:                u.u_error = EINVAL;
                    160:                return;
                    161:        }
                    162: 
                    163:        signal_action.sa_handler = func;
                    164:        signal_action.sa_flags = 0;
                    165:        __SIGSET_EMPTY (signal_action.sa_mask);
                    166:        func = 0;
                    167: 
                    168:        curr_signal_mask (NULL, & signal_mask);
                    169: 
                    170:        mask = __SIGSET_MASK (signal);
                    171: 
                    172:        switch (sigtype) {
                    173:        case SIGHOLD:
                    174:                __SIGSET_ADDMASK (signal_mask, signal, mask);
                    175:                break;
                    176: 
                    177:        case SIGRELSE:
                    178:                __SIGSET_CLRMASK (signal_mask, signal, mask);
                    179:                break;
                    180: 
                    181:        case SIGIGNORE:
                    182:                __SIGSET_CLRMASK (signal_mask, signal, mask);
                    183:                signal_action.sa_handler = SIG_IGN;
                    184:                curr_signal_action (signal, & signal_action, NULL);
                    185:                break;
                    186: 
                    187:        case 0:                         /* signal () */
                    188:                if (signal == SIGSEGV && CATCH_SEGV == 0) {
                    189:                        u.u_error = EINVAL;
                    190:                        return 0;
                    191:                }
                    192:                u.u_sigreturn = (__sigfunc_t) regsetp->_i386._edx;
                    193: 
                    194:                if (signal == SIGCHLD) {
                    195:                        /*
                    196:                         * With signal (), the argument implicitly mangles the
                    197:                         * SA_NOCLDWAIT flag. I have no idea whether the
                    198:                         * SA_NOCLDSTOP flag is also implicitly affected, but
                    199:                         * for now we leave it alone.
                    200:                         */
                    201: 
                    202:                        curr_signal_misc (__SF_NOCLDWAIT,
                    203:                                          signal_action.sa_handler ==
                    204:                                                SIG_IGN ? __SF_NOCLDWAIT : 0);
                    205:                }
                    206:                signal_action.sa_flags |= __SA_RESETHAND;
                    207:                curr_signal_action (signal, & signal_action, & signal_action);
                    208: 
                    209:                /*
                    210:                 * Using the signal () interface automatically causes a
                    211:                 * pending signal to be discarded.
                    212:                 */
                    213: 
                    214:                proc_unkill (SELF, signal);
                    215:                return signal_action.sa_handler;                
                    216: 
                    217:        case SIGSET:
                    218:                u.u_sigreturn = (__sigfunc_t) regsetp->_i386._edx;
                    219: 
                    220:                if (__SIGSET_TSTMASK (signal_mask, signal, mask))
                    221:                        func = SIG_HOLD;
                    222: 
                    223:                if (signal_action.sa_handler == SIG_HOLD) {
                    224: 
                    225:                        __SIGSET_ADDMASK (signal_mask, signal, mask);
                    226: 
                    227:                        if (func != SIG_HOLD) {
                    228:                                curr_signal_action (signal, NULL,
                    229:                                                    & signal_action);
                    230:                                func = signal_action.sa_handler;
                    231:                        }
                    232:                        break;
                    233:                }
                    234: 
                    235:                if (signal == SIGCHLD) {
                    236:                        /*
                    237:                         * With sigset (), the argument implicitly mangles the
                    238:                         * SA_NOCLDWAIT flag. I have no idea whether the
                    239:                         * SA_NOCLDSTOP flag is also implicitly affected, but
                    240:                         * for now we leave it alone.
                    241:                         */
                    242: 
                    243:                        curr_signal_misc (__SF_NOCLDWAIT,
                    244:                                          signal_action.sa_handler ==
                    245:                                                SIG_IGN ? __SF_NOCLDWAIT : 0);
                    246:                }
                    247:                __SIGSET_CLRMASK (signal_mask, signal, mask);
                    248:                __SIGSET_ADDMASK (signal_action.sa_mask, signal, mask);
                    249:                curr_signal_action (signal, & signal_action, & signal_action);
                    250: 
                    251:                if (func != SIG_HOLD)
                    252:                        func = signal_action.sa_handler;
                    253:                break;
                    254: 
                    255:        case SIGPAUSE:
                    256:                /*
                    257:                 * Like upause(), do a sleep on an event which never gets a
                    258:                 * wakeup. The sleep returns immediately if a signal was
                    259:                 * already holding.
                    260:                 */
                    261: 
                    262:                __SIGSET_CLRMASK (signal_mask, signal, mask);
                    263:                curr_signal_mask (& signal_mask, NULL);
                    264:                (void) x_sleep ((char *) & u, prilo, slpriSigCatch,
                    265:                                "sigpause");
                    266:                return 0;
                    267: 
                    268:        default:
                    269:                u.u_error = SIGSYS;
                    270:                return 0;
                    271:        }
                    272: 
                    273:        curr_signal_mask (& signal_mask, NULL);
                    274:        return func;
                    275: }
                    276: 
                    277: /*
                    278:  * Send a signal to the process `pp'. This function is only valid for use with
                    279:  * signals generated from user level with kill (), sigsend () or
                    280:  * sigsendset ().
                    281:  */
                    282: 
                    283: void
                    284: sendsig(sig, pp)
                    285: register unsigned sig;
                    286: register PROC *pp;
                    287: {
                    288:        __siginfo_t     siginfo;
                    289: 
                    290: #if 0
                    291:        T_HAL(8, if (sig == SIGINT) printf("[%d]gets int ", pp->p_pid));
                    292: #else
                    293:        T_HAL(8, printf ("[%d] sig=%d ", pp->p_pid, sig));
                    294: #endif
                    295: 
                    296:        siginfo.__si_signo = sig;
                    297:        siginfo.__si_code = 0;
                    298:        siginfo.__si_errno = 0;
                    299:        siginfo.__si_pid = SELF->p_pid;
                    300:        siginfo.__si_uid = SELF->p_uid;
                    301: 
                    302:        proc_send_signal (pp, & siginfo);
                    303: }
                    304: 
                    305: 
                    306: /*
                    307:  * Return signal number if we have a non ignored or delayed signal, else zero.
                    308:  */
                    309: 
                    310: int
                    311: nondsig()
                    312: {
                    313:        return curr_signal_pending ();
                    314: }
                    315: 
                    316: 
                    317: /*
                    318:  * If we have a signal that isn't ignored, activate it. The register set is
                    319:  * not "const" because the low-level trap code that uses it wants to modify
                    320:  * it.
                    321:  */
                    322: 
                    323: #if    __USE_PROTO__
                    324: void curr_check_signals (gregset_t * regsetp)
                    325: #else
                    326: void
                    327: curr_check_signals (regsetp)
                    328: gregset_t     *        regsetp;
                    329: #endif
                    330: {
                    331:        register int signum;
                    332:        int ptval;
                    333: 
                    334:        /*
                    335:         * Fetch an unprocessed signal.
                    336:         * Return if there are none.
                    337:         * The while() structure is only for traced processes.
                    338:         */
                    339:        while ((signum = curr_signal_pending ()) != 0) {
                    340:                __sigaction_t   signal_action;
                    341: 
                    342:                /*
                    343:                 * Reset the signal to indicate that it has been processed,
                    344:                 * and fetch the signal disposition.
                    345:                 */
                    346: 
                    347: got_signal:
                    348:                proc_unkill (SELF, signum);
                    349:                curr_signal_action (signum, NULL, & signal_action);
                    350: 
                    351:                /*
                    352:                 * Store the signal number in the u area.
                    353:                 * This is how a core dump records the death signal.
                    354:                 */
                    355:                u.u_signo = signum;
                    356: 
                    357:                /*
                    358:                 * If the signal is not defaulted, go run the requested
                    359:                 * function.
                    360:                 */
                    361: 
                    362:                if (signal_action.sa_handler != SIG_DFL) {
                    363:                        if (__xmode_286 (regsetp))
                    364:                                oldsigstart (signum, signal_action.sa_handler,
                    365:                                             regsetp);
                    366:                        else
                    367:                                msigstart (signum, signal_action.sa_handler,
                    368:                                           regsetp);
                    369: 
                    370:        /*
                    371:         * If the signal needs to be reset after delivery, do so. Note that
                    372:         * all signal-related activity goes though the defined function
                    373:         * interface; many subtle things may need to happen, so we let the
                    374:         * layering take care of it.
                    375:         */
                    376: 
                    377:                        if ((signal_action.sa_flags & __SA_RESETHAND) != 0) {
                    378:                                signal_action.sa_handler = SIG_DFL;
                    379:                                curr_signal_action (signum, & signal_action,
                    380:                                                    NULL);
                    381:                        } else
                    382:                                sigMask (& signal_action.sa_mask);
                    383: 
                    384:                        return;
                    385:                }
                    386: 
                    387:                /*
                    388:                 * msysgen() is a nop for COHERENT 4.0.  The comment in the
                    389:                 * assembly code is "Nothing useful to save".
                    390:                 */
                    391: 
                    392:                msysgen (u.u_sysgen);
                    393: 
                    394:                /*
                    395:                 * When a traced process is signaled, it may need to exchange
                    396:                 * data with its parent (via ptret).
                    397:                 */
                    398: 
                    399:                if ((SELF->p_flags & PFTRAC) != 0) {
                    400:                        SELF->p_flags |= PFWAIT;
                    401:                        ptval = ptret (regsetp);
                    402: 
                    403:                        T_HAL(0x10000, printf("ptret()=%x ", ptval));
                    404: 
                    405:                        SELF->p_flags &= ~ (PFWAIT | PFSTOP);
                    406: 
                    407:                        while ((signum = curr_signal_pending ()) != 0)
                    408:                                proc_unkill (SELF, signum);
                    409: 
                    410:                        if (ptval == 0)
                    411:                                /* see if another signal came in */
                    412:                                continue;
                    413: 
                    414:                        if ((signum = ptval) != SIGKILL)
                    415:                                goto got_signal;
                    416:                }
                    417: 
                    418:                /*
                    419:                 * Some signals cause a core file to be written.
                    420:                 */
                    421:                switch (signum) {
                    422:                case SIGQUIT:
                    423:                case SIGILL:
                    424:                case SIGTRAP:
                    425:                case SIGABRT:
                    426:                case SIGFPE:
                    427:                case SIGSEGV:
                    428:                case SIGSYS:
                    429:                        if (sigdump ())
                    430:                                signum |= __WCOREFLG;
                    431:                        break;
                    432:                }
                    433:                pexit (signum);
                    434:        }
                    435: }
                    436: 
                    437: /*
                    438:  * Create a dump of ourselves onto the file `core'.
                    439:  */
                    440: 
                    441: int
                    442: sigdump ()
                    443: {
                    444:        register INODE *ip;
                    445:        register SR *srp;
                    446:        register SEG * sp;
                    447:        register int n;
                    448:        register paddr_t ssize;
                    449:        extern  int     DUMP_LIM;
                    450:        struct ch_info chInfo;
                    451:        IO              io;
                    452:        struct direct   dir;
                    453: 
                    454:        if (SELF->p_flags & PFNDMP)
                    455:                return 0;
                    456: 
                    457:        /* Make the core with the real owners */
                    458:        schizo ();
                    459: 
                    460:        io.io_seg = IOSYS;
                    461:        io.io_flag = 0;
                    462:        if (ftoi ("core", 'c', & io, & dir)) {
                    463:                schizo ();
                    464:                return 0;
                    465:        }
                    466: 
                    467:        if ((ip = u.u_cdiri) == NULL) {
                    468:                if ((ip = imake (IFREG | 0644, 0, & io, & dir)) == NULL) {
                    469:                        schizo ();
                    470:                        return 0;
                    471:                }
                    472:        } else {
                    473:                if ((ip->i_mode & IFMT) != IFREG || iaccess (ip, IPW) == 0 ||
                    474:                    getment (ip->i_dev, 1) == NULL) {
                    475:                        idetach (ip);
                    476:                        schizo ();
                    477:                        return 0;
                    478:                }
                    479:                iclear (ip);
                    480:        }
                    481:        schizo ();
                    482:        u.u_error = 0;
                    483: 
                    484:        /* Write core file header */
                    485:        chInfo.ch_magic = CORE_MAGIC;
                    486:        chInfo.ch_info_len = sizeof (chInfo);
                    487:        chInfo.ch_uproc_offset = U_OFFSET;
                    488: 
                    489:        io.io_seek = 0;
                    490:        io.io_seg = IOSYS;
                    491:        io.io.vbase = & chInfo;
                    492:        io.io_ioc = sizeof (chInfo);
                    493:        io.io_flag = 0;
                    494: 
                    495:        iwrite (ip, & io);
                    496: 
                    497:        /*
                    498:         * Added to aid in kernel debugging - if DUMP_TEXT is nonzero,
                    499:         * dump the text segment (to see if it was corrupted) and set
                    500:         * the dump flag so that postmortem utilities will know that
                    501:         * text is present in the core file.
                    502:         */
                    503: 
                    504:        if (DUMP_TEXT)
                    505:                u.u_segl [SISTEXT].sr_flag |= SRFDUMP;
                    506: 
                    507:        for (srp = u.u_segl + 1 ; u.u_error == 0 && srp < u.u_segl + NUSEG ;
                    508:             srp ++) {
                    509: 
                    510:                if ((srp->sr_flag & SRFDUMP) == 0)
                    511:                        continue;
                    512: 
                    513:                /* Don't try to dump empty segments. */
                    514:                if ((sp = srp->sr_segp) == NULL) {
                    515:                        srp->sr_flag &= ~SRFDUMP;
                    516:                        continue;
                    517:                }
                    518: 
                    519:                /* Don't dump segments too big to dump. */
                    520:                if (sp->s_size > DUMP_LIM)
                    521:                        srp->sr_flag &= ~SRFDUMP;
                    522:        }
                    523: 
                    524:        /* Always dump the U segment. */
                    525:        u.u_segl [SIUSERP].sr_flag |= SRFDUMP;
                    526: 
                    527:        for (srp = u.u_segl ; u.u_error == 0 && srp < u.u_segl + NUSEG ;
                    528:             srp ++) {
                    529: 
                    530:                /* Only dump segments flagged for dumping. */
                    531:                if ((srp->sr_flag & SRFDUMP) == 0)
                    532:                        continue;
                    533: 
                    534:                sp = srp->sr_segp;
                    535: 
                    536:                ssize = sp->s_size;
                    537:                io.io_seg = IOPHY;
                    538:                io.io.pbase = MAPIO (sp->s_vmem, 0);
                    539:                io.io_flag = 0;
                    540:                sp->s_lrefc ++;
                    541:                while (u.u_error == 0 && ssize != 0) {
                    542:                        n = ssize > SCHUNK ? SCHUNK : ssize;
                    543:                        io.io_ioc = n;
                    544:                        iwrite (ip, & io);
                    545:                        io.io.pbase += n;
                    546:                        ssize -= (paddr_t) n;
                    547:                }
                    548:                sp->s_lrefc --;
                    549:        }
                    550:        idetach (ip);
                    551:        return u.u_error == 0;
                    552: }
                    553: 
                    554: /*
                    555:  * Send a ptrace command to the child.
                    556:  *
                    557:  * "pid" is child pid.
                    558:  */
                    559: 
                    560: int
                    561: ptset(req, pid, addr, data)
                    562: unsigned req;
                    563: int *addr;
                    564: {
                    565:        register PROC *pp;
                    566: 
                    567:        lock (pnxgate);
                    568:        for (pp = procq.p_nforw ; pp != & procq ; pp = pp->p_nforw)
                    569:                if (pp->p_pid == pid)
                    570:                        break;
                    571:        unlock (pnxgate);
                    572:        if (pp == & procq || (pp->p_flags & PFSTOP) == 0 ||
                    573:            pp->p_ppid != SELF->p_pid) {
                    574:                u.u_error = ESRCH;
                    575:                return;
                    576:        }
                    577: 
                    578:        lock (pts.pt_gate);
                    579:        pts.pt_req = req;
                    580:        pts.pt_pid = pid;
                    581:        pts.pt_addr = addr;
                    582:        pts.pt_data = data;
                    583:        pts.pt_errs = 0;
                    584:        pts.pt_rval = 0;
                    585:        pts.pt_busy = 1;
                    586: 
                    587:        wakeup ((char *) & pts.pt_req);
                    588: 
                    589:        while (pts.pt_busy) {
                    590:                x_sleep ((char *) & pts.pt_busy, primed, slpriSigCatch,
                    591:                         "ptrace");
                    592:                /* Send a ptrace command to the child.  */
                    593:        }
                    594: 
                    595:        u.u_error = pts.pt_errs;
                    596:        unlock (pts.pt_gate);
                    597:        return pts.pt_rval;
                    598: }
                    599: 
                    600: /*
                    601:  * This routine is called when a child that is being traced receives a signal
                    602:  * that is not caught or ignored.  It follows up on any requests by the parent
                    603:  * and returns when done.
                    604:  *
                    605:  * After ptrace handling done in this routine, a real or simulated signal
                    606:  * may need to be sent to the traced process.
                    607:  * Return a signal number to be sent to the child process, or 0 if none.
                    608:  */
                    609: 
                    610: static int
                    611: ptret (regsetp)
                    612: gregset_t     *        regsetp;
                    613: {
                    614:        extern void (*ndpKfrstor)();
                    615:        register PROC *pp;
                    616:        register PROC *pp1;
                    617:        register int sign;
                    618:        unsigned off;
                    619:        int doEmUnpack = 0;
                    620:        struct _fpstate * fstp = empack ();
                    621: 
                    622:        pp = SELF;
                    623: next:
                    624:        u.u_error = 0;
                    625:        if (pp->p_ppid == 1)
                    626:                return SIGKILL;
                    627:        sign = -1;
                    628: 
                    629:        /* wake up parent if it is sleeping */
                    630:        lock (pnxgate);
                    631:        pp1 = & procq;
                    632:        for (;;) {
                    633:                if ((pp1 = pp1->p_nforw) == & procq) {
                    634:                        sign = SIGKILL;
                    635:                        break;
                    636:                }
                    637:                if (pp1->p_pid != pp->p_ppid)
                    638:                        continue;
                    639:                if (ASLEEP (pp1))
                    640:                        wakeup ((char *) pp1);
                    641:                break;
                    642:        }
                    643:        unlock (pnxgate);
                    644: 
                    645:        while (sign < 0) {
                    646:                /* If no pending ptrace transaction for this process, sleep. */
                    647:                if (pts.pt_busy == 0 || pp->p_pid != pts.pt_pid) {
                    648:                        /*
                    649:                         * If a signal bit is set now, just exit - let
                    650:                         * actvsig() handle it next time through.
                    651:                         * Doing sleep and goto next will stick us in a loop
                    652:                         */
                    653: 
                    654:                        if (nondsig ())
                    655:                                return 0;
                    656:                        x_sleep ((char *) & pts.pt_req, primed,
                    657:                                 slpriSigCatch, "ptret");
                    658:                        goto next;
                    659:                }
                    660: 
                    661:                switch (pts.pt_req) {
                    662:                case PTRACE_RD_TXT:
                    663:                        if (__xmode_286 (regsetp)) {
                    664:                                pts.pt_rval = getuwd (NBPS + pts.pt_addr);
                    665:                                break;
                    666:                        }
                    667:                        /* Fall through for 386 mode processes. */
                    668: 
                    669:                case PTRACE_RD_DAT:
                    670:                        pts.pt_rval = getuwd (pts.pt_addr);
                    671:                        break;
                    672: 
                    673:                case PTRACE_RD_USR:
                    674:                        /* See ptrace.h for valid offsets. */
                    675:                        off = (unsigned) pts.pt_addr;
                    676:                        if (off & 3)
                    677:                                u.u_error = EINVAL;
                    678:                        else if (off < PTRACE_FP_CW) {
                    679:                                /* Reading CPU general register state */
                    680:                                if (off == PTRACE_SIG)
                    681:                                        pts.pt_rval = u.u_signo;
                    682:                                else
                    683:                                        pts.pt_rval =
                    684:                                                ((int *) regsetp) [off >> 2];
                    685:                        } else if (off < PTRACE_DR0) {
                    686:                                /*
                    687:                                 * Reading NDP state.
                    688:                                 * If NDP state not already saved, save it.
                    689:                                 * Fetch desired info.
                    690:                                 * Restore NDP state in case we will resume.
                    691:                                 */
                    692:                                if (rdNdpUser ()) {
                    693:                                        /* if using coprocessor */
                    694:                                        if (! rdNdpSaved ()) {
                    695:                                                ndpSave (& u.u_ndpCon);
                    696:                                                wrNdpSaved (1);
                    697:                                        }
                    698: pts.pt_rval = ((int *) & u.u_ndpCon) [(off - PTRACE_FP_CW) >> 2];
                    699:                                        ndpRestore (& u.u_ndpCon);
                    700:                                        wrNdpSaved (0);
                    701:                                } else if (fstp) {
                    702: pts.pt_rval = getuwd(((int *) fstp) + ((off - PTRACE_FP_CW) >> 2));
                    703:                                        /* if emulating */
                    704:                                } else { /* no ndp state to display */
                    705:                                        pts.pt_rval = 0;
                    706:                                        u.u_error = EFAULT;
                    707:                                }
                    708:                        } else /* Bad pseudo offset. */
                    709:                                u.u_error = EINVAL;
                    710:                        break;
                    711: 
                    712:                case PTRACE_WR_TXT:
                    713:                        if (__xmode_286 (regsetp)) {
                    714:                                putuwd (NBPS + pts.pt_addr, pts.pt_data);
                    715:                                break;
                    716:                        }
                    717:                        /* Fall through for 386 mode processes. */
                    718: 
                    719:                case PTRACE_WR_DAT:
                    720:                        putuwd (pts.pt_addr, pts.pt_data);
                    721:                        break;
                    722: 
                    723:                case PTRACE_WR_USR:
                    724:                        /* See ptrace.h for valid offsets. */
                    725:                        off = (unsigned) pts.pt_addr;
                    726: 
                    727:                        if (off & 3)
                    728:                                u.u_error = EINVAL;
                    729:                        else if (off < PTRACE_FP_CW) {
                    730:                                /* Writing CPU general register state */
                    731:                                if (off == PTRACE_SIG)
                    732:                                        u.u_error = EINVAL;
                    733:                                else
                    734:                                        ((int *) regsetp) [off >> 2] =
                    735:                                                pts.pt_data;
                    736:                        } else if (off < PTRACE_DR0) {
                    737:                                if (rdNdpUser ()) {
                    738:                                        /*
                    739:                                         * Writing NDP state.
                    740:                                         * If NDP state not already saved, save it.
                    741:                                         * Store desired info.
                    742:                                         * Restore NDP state in case we will resume.
                    743:                                         */
                    744:                                        if (! rdNdpSaved ()) {
                    745:                                                ndpSave (& u.u_ndpCon);
                    746:                                                wrNdpSaved (1);
                    747:                                        }
                    748: ((int *)&u.u_ndpCon)[(off - PTRACE_FP_CW)>>2] = pts.pt_data;
                    749:                                        ndpRestore (& u.u_ndpCon);
                    750:                                        wrNdpSaved (0);
                    751:                                } else if (fstp && ndpKfrstor) {
                    752: putuwd(((int *)fstp) + ((off - PTRACE_FP_CW)>>2), pts.pt_data);
                    753:                                        doEmUnpack = 1;
                    754:                                } else { /* No NDP state to modify. */
                    755:                                        u.u_error = EFAULT;
                    756:                                }
                    757:                        } else /* Bad pseudo offset. */
                    758:                                u.u_error = EINVAL;
                    759:                        break;
                    760: 
                    761:                case PTRACE_RESUME:
                    762:                        regsetp->_i386._eflags &= ~ MFTTB;
                    763:                        goto sig;
                    764: 
                    765:                case PTRACE_TERM:
                    766:                        sign = SIGKILL;
                    767:                        break;
                    768: 
                    769:                case PTRACE_SSTEP:
                    770:                        regsetp->_i386._eflags |= MFTTB;
                    771:                sig:
                    772:                        if (pts.pt_data < 0 || pts.pt_data > NSIG) {
                    773:                                u.u_error = EINVAL;
                    774:                                break;
                    775:                        }
                    776:                        sign = pts.pt_data;
                    777:                        break;
                    778: 
                    779:                default:
                    780:                        u.u_error = EINVAL;
                    781:                }
                    782: 
                    783:                if ((pts.pt_errs = u.u_error) == EFAULT)
                    784:                        pts.pt_errs = EINVAL;
                    785: 
                    786:                pts.pt_busy = 0;
                    787:                wakeup((char *) & pts.pt_busy);
                    788:        }
                    789:        if (doEmUnpack)
                    790:                (* ndpKfrstor) (fstp, & u.u_ndpCon);
                    791:        return sign;
                    792: }
                    793: 
                    794: /*
                    795:  * If using floating point emulator, make room on user stack and save
                    796:  * floating point context there.  Code elsewhere takes care of floating
                    797:  * point context if there is a coprocessor.
                    798:  *
                    799:  * Return the virtual address in user space of the context area, or
                    800:  * return NULL if not using FP emulation.
                    801:  */
                    802: 
                    803: static struct _fpstate *
                    804: empack (regsetp)
                    805: gregset_t     *        regsetp;
                    806: {
                    807:        int             sphi;
                    808:        struct _fpstate * ret;
                    809:        SEG           * segp = u.u_segl [SISTACK].sr_segp;
                    810:        extern void (*ndpKfsave)();
                    811:        unsigned long sw_old;
                    812: 
                    813:        /* If not emulating, do nothing */
                    814:        if (rdNdpUser () || ! rdEmTrapped () || ! ndpKfsave)
                    815:                return NULL;
                    816: 
                    817:        /*
                    818:         * Will copy at least u_sigreturn, _fpstackframe, and ndpFlags.
                    819:         * If using ndp, need room for an _fpstate.
                    820:         * If emulating, need room for an _fpemstate.
                    821:         */
                    822: 
                    823:        ret = (struct _fpstate *)
                    824:                (__xmode_286 (regsetp) ? regsetp->_i286._usp :
                    825:                                         regsetp->_i386._uesp) - 1;
                    826: 
                    827:        /* Add to user stack if necessary. */
                    828:        sphi = __xmode_286 (regsetp) ? ISP_286 : ISP_386;
                    829: 
                    830:        if (sphi - segp->s_size > (__ptr_arith_t) ret) {
                    831:                cseg_t        * pp;
                    832: 
                    833:                pp = c_extend (segp->s_vmem, btoc (segp->s_size));
                    834:                if (pp == 0) {
                    835:                        printf ("Empack failed.  cmd=%s  c_extend(%x,%x)=0 ",
                    836:                                u.u_comm, segp->s_vmem, btoc (segp->s_size));
                    837:                        return NULL;
                    838:                }
                    839: 
                    840:                segp->s_vmem = pp;
                    841:                segp->s_size += NBPC;
                    842:                if (sproto (0) == 0) {
                    843:                        printf ("Empack failed.  cmd=%s  sproto(0)=0 ",
                    844:                                u.u_comm);
                    845:                        return NULL;
                    846:                }
                    847: 
                    848:                segload ();
                    849:        }
                    850: 
                    851:        (* ndpKfsave) (& u.u_ndpCon, ret);
                    852:        sw_old = getuwd (& ret->sw);
                    853:        putuwd (& ret->status, sw_old);
                    854:        putuwd (& ret->sw, sw_old & 0x7f00);
                    855: 
                    856:        return ret;
                    857: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.