Annotation of coherent/b/STREAMS/coh.386/sig.c, revision 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.