Annotation of coherent/b/kernel/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: #include <sys/coherent.h>
                     27: #include <errno.h>
                     28: #include <sys/ino.h>
                     29: #include <sys/inode.h>
                     30: #include <sys/io.h>
                     31: #include <sys/proc.h>
                     32: #include <sys/ptrace.h>
                     33: #include <sys/sched.h>
                     34: #include <sys/seg.h>
                     35: #include <signal.h>
                     36: #include <sys/core.h>
                     37: 
                     38: /*
                     39:  * ----------------------------------------------------------------------
                     40:  * Definitions.
                     41:  *     Constants.
                     42:  *     Macros with argument lists.
                     43:  *     Typedefs.
                     44:  *     Enums.
                     45:  */
                     46: typedef void (*VFPTR)();       /* pointer to void function */
                     47: 
                     48: /*
                     49:  * ----------------------------------------------------------------------
                     50:  * Functions.
                     51:  *     Import Functions.
                     52:  *     Export Functions.
                     53:  *     Local Functions.
                     54:  */
                     55: int    actvsig();
                     56: int    nondsig();
                     57: int    ptret();
                     58: int    ptset();
                     59: void   sendsig();
                     60: void   sigDefault();
                     61: void   sigHold();
                     62: void   sigIgnore();
                     63: void   sigPause();
                     64: void   sigRelease();
                     65: int    sigSet();
                     66: int    sigdump();
                     67: int    usigsys();
                     68: 
                     69: static struct _fpstate * empack();
                     70: 
                     71: /*
                     72:  * ----------------------------------------------------------------------
                     73:  * Global Data.
                     74:  *     Import Variables.
                     75:  *     Export Variables.
                     76:  *     Local Variables.
                     77:  */
                     78: /*
                     79:  * Patchable variables.
                     80:  *
                     81:  * Patch DUMP_TEXT nonzero to make text segment show up in core files.
                     82:  * Patch DUMP_LIM set the upper limit in bytes of how much of a
                     83:  * segment is written to a core file.
                     84:  *
                     85:  * Patch CATCH_SEGV nonzero if you are trying to run software that was
                     86:  * written in blatant defiance of the SVID 2 caution that handling SIGSEGV
                     87:  * is nonportable and should not be assumed valid on all systems.
                     88:  */
                     89: int    DUMP_TEXT = 0;
                     90: int    DUMP_LIM=512*1024;
                     91: int    CATCH_SEGV = 0;
                     92: 
                     93: /*
                     94:  * ----------------------------------------------------------------------
                     95:  * Code.
                     96:  */
                     97: 
                     98: /*
                     99:  * Given 1-based signal number, ask whether a signal handler was
                    100:  * attached to the current process using sigset().  This allows
                    101:  * the kernel to process sigset() differently from signal(), as
                    102:  * required.
                    103:  *
                    104:  * return 1 if sigset(), 0 if not.
                    105:  */
                    106: int
                    107: sigSet(signal)
                    108: int signal;
                    109: {
                    110:        return (SELF->p_dsig & SIG_BIT(signal)) ? 1 : 0;
                    111: }
                    112: 
                    113: /*
                    114:  * Given 1-based signal number, ignore that signal in the current process.
                    115:  */
                    116: void
                    117: sigIgnore(signal)
                    118: int signal;
                    119: {
                    120:        int sigbit = SIG_BIT(signal);
                    121: 
                    122:        SELF->p_dfsig &= ~sigbit;       /* No longer defaulted.  */
                    123:        SELF->p_isig |= sigbit;         /* Mark signal as ignored.  */
                    124:        u.u_sfunc[signal - 1] = SIG_IGN;
                    125: }
                    126: 
                    127: /*
                    128:  * Given 1-based signal number, restore default handling for the current
                    129:  * process.
                    130:  *
                    131:  * There is some duplication of work done in sigAttach(), but sigDefault()
                    132:  * is also called from msig.c
                    133:  */
                    134: void
                    135: sigDefault(signal)
                    136: int signal;
                    137: {
                    138:        int sigbit = SIG_BIT(signal);
                    139: 
                    140:        SELF->p_dfsig |= sigbit;
                    141:        SELF->p_isig &= ~sigbit;
                    142:        u.u_sfunc[signal - 1] = SIG_DFL;
                    143: }
                    144: 
                    145: /*
                    146:  * Given 1-based signal number, hold that signal for the current process.
                    147:  */
                    148: void
                    149: sigHold(signal)
                    150: int signal;
                    151: {
                    152:        SELF->p_hsig |= SIG_BIT(signal);
                    153: }
                    154: 
                    155: /*
                    156:  * Given 1-based signal number, pause for that signal for the current process.
                    157:  */
                    158: void
                    159: sigPause(signal)
                    160: int signal;
                    161: {
                    162:        SELF->p_hsig &= ~SIG_BIT(signal);
                    163: 
                    164:        /*
                    165:         * Like upause(), do a sleep on an event which never gets a wakeup.
                    166:         * The sleep returns immediately if a signal was already holding.
                    167:         */
                    168:        x_sleep((char *)&u, prilo, slpriSigCatch, "sigpause");
                    169:        actvsig();
                    170: }
                    171: 
                    172: /*
                    173:  * Given 1-based signal number, release that signal for the current process.
                    174:  */
                    175: void
                    176: sigRelease(signal)
                    177: int signal;
                    178: {
                    179:        SELF->p_hsig &= ~SIG_BIT(signal);
                    180:        if (nondsig()) {
                    181:                actvsig();
                    182:        }
                    183: }
                    184: 
                    185: /*
                    186:  * Given 1-based signal number, a pointer to a signal-handling function,
                    187:  * and a flag, attach the signal handler to the current process.
                    188:  *
                    189:  * Function pointer "func" may take on special values SIG_DFL, SIG_IGN,
                    190:  * and, if "how" is SIGSET, SIG_HOLD.
                    191:  *
                    192:  * The flag "how" is 0 if attachment is via signal(), SIGSET if attachment
                    193:  * is via sigset().
                    194:  *
                    195:  * Return the previously attached signal handler, or SIG_HOLD if signals
                    196:  * were previously held.
                    197:  */
                    198: VFPTR
                    199: sigAttach(signal, func, how)
                    200: int signal;
                    201: VFPTR func;
                    202: int how;
                    203: {
                    204:        VFPTR retval;
                    205:        int sigbit = SIG_BIT(signal);
                    206: 
                    207:        /*
                    208:         * Set up the return value, which says what was previously
                    209:         * done with the given signal.
                    210:         */
                    211:        if (SELF->p_isig & sigbit)
                    212:                retval = (VFPTR)SIG_IGN;
                    213:        else if (SELF->p_hsig & sigbit)
                    214:                retval = (VFPTR)SIG_HOLD;
                    215:        else
                    216:                retval = u.u_sfunc[signal - 1];
                    217: 
                    218:        u.u_sigreturn = (VFPTR)(u.u_regl[EDX]);
                    219:        u.u_sfunc[signal - 1] = func;
                    220: 
                    221:        /*
                    222:         * Remove previous default, ignore, or hold status.
                    223:         */
                    224:        SELF->p_dfsig &= ~sigbit;
                    225:        SELF->p_isig &= ~sigbit;
                    226:        SELF->p_hsig &= ~sigbit;
                    227: 
                    228:        /*
                    229:         * Any pending signal is lost.
                    230:         */
                    231:        SELF->p_ssig &= ~sigbit;
                    232: 
                    233:        /*
                    234:         * Special cases for handler.
                    235:         */
                    236:        switch ((int)func) {
                    237:        case (int)SIG_DFL:
                    238:                sigDefault(signal);
                    239:                break;
                    240:        case (int)SIG_IGN:
                    241:                sigIgnore(signal);
                    242:                break;
                    243:        case (int)SIG_HOLD:
                    244:                sigHold(signal);
                    245:                break;
                    246:        }
                    247: 
                    248:        /*
                    249:         * Remember whether handler was attached with sigset() vs signal().
                    250:         */
                    251:        if (how == SIGSET)
                    252:                SELF->p_dsig |= sigbit;
                    253:        else
                    254:                SELF->p_dsig &= ~sigbit;
                    255: 
                    256:        return retval;
                    257: }
                    258: 
                    259: /*
                    260:  * Set up the action to be taken on a signal.
                    261:  */
                    262: int
                    263: usigsys(signal, func)
                    264: int    signal;
                    265: VFPTR func;
                    266: {
                    267:        int     sigtype;
                    268:        int     retval = 0;
                    269: 
                    270:        sigtype = signal & ~0xFF;
                    271:        signal &= 0xFF;
                    272: 
                    273:        T_HAL(8, if (signal == SIGINT)
                    274:          printf("[%d]sigint(%x, %x) ", SELF->p_pid, sigtype, func));
                    275: 
                    276:        /* Range check on 1-based signal number. */
                    277:        if (signal <= 0 || signal > NSIG) {
                    278:                u.u_error = EINVAL;
                    279:                return;
                    280:        }
                    281: 
                    282:        /*
                    283:         * Don't allow setting/holding/releasing some signals.
                    284:         *
                    285:         * NOTICE:  Ignoring SIGSEGV causes runaway user faults.
                    286:         * SVID Issue 2 says *don't* do signal(SIGSEGV,...)!!!
                    287:         */
                    288:        if (signal == SIGKILL) {
                    289:                u.u_error = EINVAL;
                    290:                return;
                    291:        }
                    292: 
                    293:        if (signal == SIGSEGV && CATCH_SEGV == 0) {
                    294:                u.u_error = EINVAL;
                    295:                return;
                    296:        }
                    297:         
                    298:        switch (sigtype) {
                    299:        case SIGHOLD:
                    300:                sigHold(signal);
                    301:                break;
                    302:        case SIGRELSE:
                    303:                sigRelease(signal);
                    304:                break;
                    305:        case SIGIGNORE:
                    306:                sigIgnore(signal);
                    307:                break;
                    308:        case 0:                         /* old system entry */
                    309:                retval = (int)sigAttach(signal, func, 0);
                    310:                break;
                    311:        case SIGSET:                    /* new system entry */
                    312:                retval = (int)sigAttach(signal, func, SIGSET);
                    313:                break;
                    314:        case SIGPAUSE:
                    315:                sigPause(signal);
                    316:                break;
                    317:        default:
                    318:                u.u_error = SIGSYS;
                    319:                break;
                    320:        }
                    321:        return retval;
                    322: }
                    323: 
                    324: /*
                    325:  * Send a signal to the process `pp'.
                    326:  * Return 1 if signal was sent.
                    327:  * Return 0 if signal was ignored.
                    328:  * The return value is of use to the trap handler.
                    329:  */
                    330: void
                    331: sendsig(sig, pp)
                    332: register unsigned sig;
                    333: register PROC *pp;
                    334: {
                    335:        register sig_t f;
                    336:        register int s;
                    337: 
                    338:        T_HAL(8, if (sig == SIGINT) printf("[%d]gets int ", pp->p_pid));
                    339: 
                    340:        /*
                    341:         * Convert the signal to a bit position.
                    342:         */
                    343:        f = SIG_BIT(sig);
                    344: 
                    345:        /*
                    346:         * If the signal is ignored, and is not SIGCLD, do nothing.
                    347:         */
                    348:        if ((pp->p_isig & f) && sig != SIGCLD) {
                    349:                goto sendSigDone;
                    350:        }
                    351: 
                    352:        /*
                    353:         * No further processing for delayed or held signals.
                    354:         */
                    355:        if ((pp->p_ssig & f) && (pp->p_hsig|pp->p_dsig) & f)
                    356:                goto sendSigDone;
                    357:        
                    358:        /*
                    359:         * Actually send the signal by flagging the needed bit.
                    360:         */
                    361:        pp->p_ssig |= f;
                    362: 
                    363:        /*
                    364:         * If the process is sleeping, wake it up so that
                    365:         * it can process this signal.
                    366:         */
                    367:        if (pp->p_state == PSSLSIG) {
                    368:                s = sphi();
                    369:                pp->p_lback->p_lforw = pp->p_lforw;
                    370:                pp->p_lforw->p_lback = pp->p_lback;
                    371: #ifndef _I386
                    372:                addu(pp->p_cval, (utimer-pp->p_lctim)*CVCLOCK);
                    373: #endif
                    374:                setrun(pp);
                    375:                spl(s);
                    376:        }
                    377: sendSigDone:
                    378:        return;
                    379: }
                    380: 
                    381: /*
                    382:  * Return signal number if we have a non ignored or delayed signal, else zero.
                    383:  */
                    384: int
                    385: nondsig()
                    386: {
                    387:        register PROC *pp;
                    388:        register sig_t mask;
                    389:        register int signo;
                    390: 
                    391:        pp = SELF;
                    392:        signo = 0;
                    393: 
                    394:        /*
                    395:         * Turn off all ignored signals except SIGCLD.
                    396:         */
                    397:        pp->p_ssig &= ~(pp->p_isig & ~SIG_BIT(SIGCLD));
                    398: 
                    399:        /*
                    400:         * If any signals have arrived, but which are not held,
                    401:         * figure out what they are.
                    402:         */
                    403:        if (pp->p_ssig&~pp->p_hsig) {
                    404:                /*
                    405:                 * There is at least one signal.  Extract its number
                    406:                 * from the signal bits.
                    407:                 */
                    408:                mask = (sig_t) 1;
                    409:                signo += 1;
                    410:                while (((pp->p_ssig&~pp->p_hsig) & mask) == 0) {
                    411:                        mask <<= 1;
                    412:                        signo += 1;
                    413:                }
                    414:        }
                    415:        return signo;
                    416: }
                    417: 
                    418: /*
                    419:  * If we have a signal that isn't ignored, activate it.
                    420:  */
                    421: int
                    422: actvsig()
                    423: {
                    424:        register int signum;
                    425:        register PROC *pp;
                    426:        register int (*func)();
                    427:        int ptval;
                    428: 
                    429:        /*
                    430:         * Fetch an unprocessed signal.
                    431:         * Return if there are none.
                    432:         * The while() structure is only for traced processes.
                    433:         */
                    434:        while (signum = nondsig()) {
                    435: 
                    436:                pp = SELF;
                    437: 
                    438:                /*
                    439:                 * Reset the signal to indicate that it has been processed.
                    440:                 * Bit table p_ssig uses 0-based signals, while signal.h
                    441:                 * lists 1-based signals.
                    442:                 */
                    443:                pp->p_ssig &= ~SIG_BIT(signum);
                    444: 
                    445:                /*
                    446:                 * Fetch the user function that goes with this signal.
                    447:                 * Function table u_sfunc uses 0-based signals, while signal.h
                    448:                 * lists 1-based signals.
                    449:                 */
                    450:                func = u.u_sfunc[signum-1];
                    451: 
                    452:                /*
                    453:                 * SIGCLD causes no work here if defaulted or ignored.
                    454:                 */
                    455:                if (signum == SIGCLD && (func == SIG_DFL || func == SIG_IGN))
                    456:                        return;
                    457: 
                    458:                /*
                    459:                 * Store the (1-based) signal number in the u area.
                    460:                 * This is how a core dump records the death signal.
                    461:                 */
                    462:                u.u_signo = signum;
                    463: 
                    464:                /*
                    465:                 * If the signal is not defaulted, go run the requested
                    466:                 * function.
                    467:                 */
                    468:                if (func != SIG_DFL) {
                    469:                        if (XMODE_286)
                    470:                                oldsigstart(signum, func);
                    471:                        else {
                    472:                                msigstart(signum, func);
                    473:                        }
                    474:                        return;
                    475:                }
                    476: 
                    477:                /*
                    478:                 * ASSERTION:  the signal being processed is SIG_DFL'd.
                    479:                 */
                    480: 
                    481:                /*
                    482:                 * msysgen() is a nop for COHERENT 4.0.  The comment in the
                    483:                 * assembly code is "Nothing useful to save".
                    484:                 */
                    485:                msysgen(u.u_sysgen);
                    486: 
                    487:                /*
                    488:                 * When a traced process is signaled, it may need to exchange
                    489:                 * data with its parent (via ptret).
                    490:                 */
                    491:                if (pp->p_flags&PFTRAC) {
                    492:                        pp->p_flags |= PFWAIT;
                    493:                        ptval = ptret();
                    494:                        T_HAL(0x10000, printf("ptret()=%x ", ptval));
                    495:                        pp->p_flags &= ~(PFWAIT|PFSTOP);
                    496:                        if (ptval == 0)
                    497:                                /* see if another signal came in */
                    498:                                continue;
                    499:                        else
                    500:                                signum = ptval;
                    501:                }
                    502: 
                    503:                /*
                    504:                 * Some signals cause a core file to be written.
                    505:                 */
                    506:                switch(signum) {
                    507:                case SIGQUIT:
                    508:                case SIGILL:
                    509:                case SIGTRAP:
                    510:                case SIGABRT:
                    511:                case SIGFPE:
                    512:                case SIGSEGV:
                    513:                case SIGSYS:
                    514:                        if (sigdump())
                    515:                                signum |= 0x80;
                    516:                        break;
                    517:                }
                    518:                pexit(signum);
                    519:        }
                    520: }
                    521: 
                    522: /*
                    523:  * Create a dump of ourselves onto the file `core'.
                    524:  */
                    525: int
                    526: sigdump()
                    527: {
                    528:        register INODE *ip;
                    529:        register SR *srp;
                    530:        register SEG * sp;
                    531:        register int n;
                    532:        register paddr_t ssize;
                    533:        extern  int     DUMP_LIM;
                    534:        struct ch_info chInfo;
                    535: 
                    536:        if (SELF->p_flags&PFNDMP)
                    537:                return (0);
                    538:        u.u_io.io_seg  = IOSYS;
                    539:        u.u_io.io_flag = 0;
                    540:        /* Make the core with the real owners */
                    541:        schizo();
                    542:        if (ftoi("core", 'c')) {
                    543:                schizo();
                    544:                return (0);
                    545:        }
                    546:        if ((ip=u.u_cdiri) == NULL) {
                    547:                if ((ip=imake(IFREG|0644, 0)) == NULL) {
                    548:                        schizo();
                    549:                        return (0);
                    550:                }
                    551:        } else {
                    552:                if ((ip->i_mode&IFMT)!=IFREG
                    553:                 || iaccess(ip, IPW)==0
                    554:                 || getment(ip->i_dev, 1)==NULL) {
                    555:                        idetach(ip);
                    556:                        schizo();
                    557:                        return (0);
                    558:                }
                    559:                iclear(ip);
                    560:        }
                    561:        schizo();
                    562:        u.u_error = 0;
                    563:        u.u_io.io_seek = 0;
                    564: 
                    565:        /* Write core file header */
                    566:        chInfo.ch_magic = CORE_MAGIC;
                    567:        chInfo.ch_info_len = sizeof(chInfo);
                    568:        chInfo.ch_uproc_offset = U_OFFSET;
                    569: 
                    570:        u.u_io.io_seg = IOSYS;
                    571:        u.u_io.io.vbase = &chInfo;
                    572:        u.u_io.io_ioc = sizeof(chInfo);
                    573:        u.u_io.io_flag = 0;
                    574: 
                    575:        sp->s_lrefc++;
                    576:        iwrite(ip, &u.u_io);
                    577:        sp->s_lrefc--;
                    578: 
                    579:        /*
                    580:         * Added to aid in kernel debugging - if DUMP_TEXT is nonzero,
                    581:         * dump the text segment (to see if it was corrupted) and set
                    582:         * the dump flag so that postmortem utilities will know that
                    583:         * text is present in the core file.
                    584:         */
                    585:        if (DUMP_TEXT)
                    586:                u.u_segl[SISTEXT].sr_flag |= SRFDUMP;
                    587: 
                    588:        for (srp=u.u_segl; u.u_error==0 && srp<&u.u_segl[NUSEG]; srp++) {
                    589: 
                    590:                if ((srp->sr_flag & SRFDUMP)==0)
                    591:                        continue;
                    592: 
                    593:                /* Don't try to dump empty segments. */
                    594:                if ((sp = srp->sr_segp)==NULL) {
                    595:                        srp->sr_flag &= ~SRFDUMP;
                    596:                        continue;
                    597:                }
                    598: 
                    599:                /* Don't dump segments too big to dump. */
                    600:                if (sp->s_size > DUMP_LIM)
                    601:                        srp->sr_flag &= ~SRFDUMP;
                    602:        }
                    603: 
                    604:        for (srp=u.u_segl; u.u_error==0 && srp<&u.u_segl[NUSEG]; srp++) {
                    605: 
                    606:                /* Only dump segments flagged for dumping. */
                    607:                if ((srp->sr_flag & SRFDUMP)==0)
                    608:                        continue;
                    609: 
                    610:                ssize = sp->s_size;
                    611:                u.u_io.io_seg = IOPHY;
                    612:                u.u_io.io.pbase = MAPIO(sp->s_vmem, 0);
                    613:                u.u_io.io_flag = 0;
                    614:                sp->s_lrefc++;
                    615:                while (u.u_error == 0 && ssize != 0) {
                    616:                        n = ssize > SCHUNK ? SCHUNK : ssize;
                    617:                        u.u_io.io_ioc = n;
                    618:                        iwrite(ip, &u.u_io);
                    619:                        u.u_io.io.pbase += n;
                    620:                        ssize -= (paddr_t)n;
                    621:                }
                    622:                sp->s_lrefc--;
                    623:        }
                    624:        idetach(ip);
                    625:        return (u.u_error==0);
                    626: }
                    627: 
                    628: /*
                    629:  * Send a ptrace command to the child.
                    630:  *
                    631:  * "pid" is child pid.
                    632:  */
                    633: int
                    634: ptset(req, pid, addr, data)
                    635: unsigned req;
                    636: int *addr;
                    637: {
                    638:        register PROC *pp;
                    639: 
                    640:        lock(pnxgate);
                    641:        for (pp=procq.p_nforw; pp!=&procq; pp=pp->p_nforw)
                    642:                if (pp->p_pid == pid)
                    643:                        break;
                    644:        unlock(pnxgate);
                    645:        if (pp==&procq || (pp->p_flags&PFSTOP)==0 || pp->p_ppid!=SELF->p_pid){
                    646:                u.u_error = ESRCH;
                    647:                return;
                    648:        }
                    649:        lock(pts.pt_gate);
                    650:        pts.pt_req = req;
                    651:        pts.pt_pid = pid;
                    652:        pts.pt_addr = addr;
                    653:        pts.pt_data = data;
                    654:        pts.pt_errs = 0;
                    655:        pts.pt_rval = 0;
                    656:        pts.pt_busy = 1;
                    657:        wakeup((char *)&pts.pt_req);
                    658:        while (pts.pt_busy) {
                    659:                x_sleep((char *)&pts.pt_busy, primed, slpriSigCatch, "ptrace");
                    660:                /* Send a ptrace command to the child.  */
                    661:        }
                    662:        u.u_error = pts.pt_errs;
                    663:        unlock(pts.pt_gate);
                    664:        return (pts.pt_rval);
                    665: }
                    666: 
                    667: /*
                    668:  * This routine is called when a child that is being traced receives a signal
                    669:  * that is not caught or ignored.  It follows up on any requests by the parent
                    670:  * and returns when done.
                    671:  *
                    672:  * After ptrace handling done in this routine, a real or simulated signal
                    673:  * may need to be sent to the traced process.
                    674:  * Return a signal number to be sent to the child process, or 0 if none.
                    675:  */
                    676: int
                    677: ptret()
                    678: {
                    679:        extern void (*ndpKfrstor)();
                    680:        register PROC *pp;
                    681:        register PROC *pp1;
                    682:        register int sign;
                    683:        unsigned off;
                    684:        int doEmUnpack = 0;
                    685: 
                    686:        struct _fpstate * fstp = empack();
                    687: 
                    688:        pp = SELF;
                    689: next:
                    690:        u.u_error = 0;
                    691:        if (pp->p_ppid == 1)
                    692:                return (SIGKILL);
                    693:        sign = -1;
                    694: 
                    695:        /* wake up parent if it is sleeping */
                    696:        lock(pnxgate);
                    697:        pp1 = &procq;
                    698:        for (;;) {
                    699:                if ((pp1=pp1->p_nforw) == &procq) {
                    700:                        sign = SIGKILL;
                    701:                        break;
                    702:                }
                    703:                if (pp1->p_pid != pp->p_ppid)
                    704:                        continue;
                    705:                if (ASLEEP(pp1))
                    706:                        wakeup((char *)pp1);
                    707:                break;
                    708:        }
                    709:        unlock(pnxgate);
                    710: 
                    711:        while (sign < 0) {
                    712:                /* If no pending ptrace transaction for this process, sleep. */
                    713:                if (pts.pt_busy==0 || pp->p_pid!=pts.pt_pid) {
                    714:                        /* If a signal bit is set now, just exit - let
                    715:                         * actvsig() handle it next time through.
                    716:                         * Doing sleep and goto next will stick us in a loop */
                    717:                        if (nondsig())
                    718:                                return 0;
                    719:                        x_sleep((char *)&pts.pt_req,
                    720:                          primed, slpriSigCatch, "ptret");
                    721:                        goto next;
                    722:                }
                    723:                switch (pts.pt_req) {
                    724:                case PTRACE_RD_TXT:
                    725:                        if (XMODE_286) {
                    726:                                pts.pt_rval = getuwd(NBPS+pts.pt_addr);
                    727:                                break;
                    728:                        }
                    729:                        /* Fall through for 386 mode processes. */
                    730:                case PTRACE_RD_DAT:
                    731:                        pts.pt_rval = getuwd(pts.pt_addr);
                    732:                        break;
                    733:                case PTRACE_RD_USR:
                    734:                        /* See ptrace.h for valid offsets. */
                    735:                        off = (unsigned)pts.pt_addr;
                    736:                        if (off & 3)
                    737:                                u.u_error = EINVAL;
                    738:                        else if (off < PTRACE_FP_CW) {
                    739:                                /* Reading CPU general register state */
                    740:                                if (off == PTRACE_SIG)
                    741:                                        pts.pt_rval = u.u_signo;
                    742:                                else
                    743:                                        pts.pt_rval = u.u_regl[off>>2];
                    744:                        } else if (off < PTRACE_DR0) {
                    745:                                /*
                    746:                                 * Reading NDP state.
                    747:                                 * If NDP state not already saved, save it.
                    748:                                 * Fetch desired info.
                    749:                                 * Restore NDP state in case we will resume.
                    750:                                 */
                    751:                                if (rdNdpUser()) {
                    752:                                        /* if using coprocessor */
                    753:                                        if (!rdNdpSaved()) {
                    754:                                                ndpSave(&u.u_ndpCon);
                    755:                                                wrNdpSaved(1);
                    756:                                        }
                    757: pts.pt_rval = ((int *)&u.u_ndpCon)[(off - PTRACE_FP_CW)>>2];
                    758:                                        ndpRestore(&u.u_ndpCon);
                    759:                                        wrNdpSaved(0);
                    760:                                } else if (fstp) {
                    761: pts.pt_rval = getuwd(((int *)fstp) + ((off - PTRACE_FP_CW)>>2));
                    762:                                        /* if emulating */
                    763:                                } else /* no ndp state to display */
                    764:                                        pts.pt_rval = 0;
                    765:                        } else
                    766:                                u.u_error = EINVAL;
                    767:                        break;
                    768:                case PTRACE_WR_TXT:
                    769:                        if (XMODE_286) {
                    770:                                putuwd(NBPS+pts.pt_addr, pts.pt_data);
                    771:                                break;
                    772:                        }
                    773:                        /* Fall through for 386 mode processes. */
                    774:                case PTRACE_WR_DAT:
                    775:                        putuwd(pts.pt_addr, pts.pt_data);
                    776:                        break;
                    777:                case PTRACE_WR_USR:
                    778:                        /* See ptrace.h for valid offsets. */
                    779:                        off = (unsigned)pts.pt_addr;
                    780: 
                    781:                        if (off & 3)
                    782:                                u.u_error = EINVAL;
                    783:                        else if (off < PTRACE_FP_CW) {
                    784:                                /* Writing CPU general register state */
                    785:                                if (off == PTRACE_SIG)
                    786:                                        u.u_error = EINVAL;
                    787:                                else
                    788:                                        u.u_regl[off>>2] = pts.pt_data;
                    789:                        } else if (off < PTRACE_DR0) {
                    790:                                if (rdNdpUser()) {
                    791:                                        /*
                    792:                                         * Writing NDP state.
                    793:                                         * If NDP state not already saved, save it.
                    794:                                         * Store desired info.
                    795:                                         * Restore NDP state in case we will resume.
                    796:                                         */
                    797:                                        if (!rdNdpSaved()) {
                    798:                                                ndpSave(&u.u_ndpCon);
                    799:                                                wrNdpSaved(1);
                    800:                                        }
                    801: ((int *)&u.u_ndpCon)[(off - PTRACE_FP_CW)>>2] = pts.pt_data;
                    802:                                        ndpRestore(&u.u_ndpCon);
                    803:                                        wrNdpSaved(0);
                    804:                                } else if (fstp && ndpKfrstor) {
                    805: putuwd(((int *)fstp) + ((off - PTRACE_FP_CW)>>2), pts.pt_data);
                    806:                                        doEmUnpack = 1;
                    807:                                }
                    808:                        } else
                    809:                                u.u_error = EINVAL;
                    810:                        break;
                    811:                case PTRACE_RESUME:
                    812:                        u.u_regl[EFL] &= ~MFTTB;
                    813:                        goto sig;
                    814:                case PTRACE_TERM:
                    815:                        sign = SIGKILL;
                    816:                        break;
                    817:                case PTRACE_SSTEP:
                    818:                        u.u_regl[EFL] |= MFTTB;
                    819:                sig:
                    820:                        if (pts.pt_data<0 || pts.pt_data>NSIG) {
                    821:                                u.u_error = EINVAL;
                    822:                                break;
                    823:                        }
                    824:                        sign = pts.pt_data;
                    825:                        if (pts.pt_addr != SIG_IGN) {
                    826:                                u.u_regl[EIP] = (int)pts.pt_addr;
                    827:                        }
                    828:                        break;
                    829:                default:
                    830:                        u.u_error = EINVAL;
                    831:                }
                    832:                if ((pts.pt_errs=u.u_error) == EFAULT)
                    833:                        pts.pt_errs = EINVAL;
                    834:                pts.pt_busy = 0;
                    835:                wakeup((char *)&pts.pt_busy);
                    836:        }
                    837:        if (doEmUnpack)
                    838:                (*ndpKfrstor)(fstp, &u.u_ndpCon);
                    839:        return (sign);
                    840: }
                    841: 
                    842: /*
                    843:  * If using floating point emulator, make room on user stack and save
                    844:  * floating point context there.  Code elsewhere takes care of floating
                    845:  * point context if there is a coprocessor.
                    846:  *
                    847:  * Return the virtual address in user space of the context area, or
                    848:  * return NULL if not using FP emulation.
                    849:  */
                    850: static struct _fpstate *
                    851: empack()
                    852: {
                    853:        int uesp;
                    854:        int sphi, splo;
                    855:        SEG * segp;
                    856:        cseg_t * pp;
                    857:        struct _fpstate * ret = NULL;
                    858:        extern void (*ndpKfsave)();
                    859:        unsigned long sw_old;
                    860: 
                    861:        /* If not emulating, do nothing */
                    862:        if (rdNdpUser() || !rdEmTrapped() || !ndpKfsave)
                    863:                return NULL;
                    864: 
                    865:        /*
                    866:         * Will copy at least u_sigreturn, _fpstackframe, and ndpFlags.
                    867:         * If using ndp, need room for an _fpstate.
                    868:         * If emulating, need room for an _fpemstate.
                    869:         */
                    870:        uesp = u.u_regl[UESP] - sizeof(struct _fpstate);
                    871: 
                    872:        /* Add to user stack if necessary. */
                    873:        segp = u.u_segl[SISTACK].sr_segp;
                    874:        sphi = (XMODE_286) ? ISP_286 : ISP_386;
                    875:        splo = sphi - segp->s_size;
                    876: 
                    877:        if (splo > uesp) {
                    878:                pp = c_extend(segp->s_vmem, btoc(segp->s_size));
                    879:                if (pp==0) {
                    880:                        printf("Empack failed.  cmd=%s  c_extend(%x,%x)=0 ",
                    881:                          u.u_comm, segp->s_vmem, btoc(segp->s_size));
                    882:                        return NULL;
                    883:                }
                    884: 
                    885:                segp->s_vmem = pp;
                    886:                segp->s_size += NBPC;
                    887:                if (sproto(0)==0) {
                    888:                        printf("Empack failed.  cmd=%s  sproto(0)=0 ",
                    889:                          u.u_comm);
                    890:                        return NULL;
                    891:                }
                    892: 
                    893:                segload();
                    894:        }
                    895: 
                    896:        ret = (struct _fpstate *)uesp;
                    897:        (*ndpKfsave)(&u.u_ndpCon, uesp);
                    898:        sw_old = getuwd(&ret->sw);
                    899:        putuwd(&ret->status, sw_old);
                    900:        putuwd(&ret->sw, sw_old & 0x7f00);
                    901: 
                    902:        return ret;
                    903: }

unix.superglobalmegacorp.com

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