Annotation of coherent/b/STREAMS/i386/msig.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * i386/msig.c
        !             3:  *
        !             4:  * signal handler start and return
        !             5:  *
        !             6:  * Revised: Tue May 11 14:24:00 1993 CDT
        !             7:  */
        !             8: 
        !             9: /*
        !            10:  * ----------------------------------------------------------------------
        !            11:  * Includes.
        !            12:  */
        !            13: 
        !            14: #include <common/_gregset.h>
        !            15: #include <kernel/sigproc.h>
        !            16: #include <sys/debug.h>
        !            17: 
        !            18: #include <sys/coherent.h>
        !            19: 
        !            20: /*
        !            21:  * ----------------------------------------------------------------------
        !            22:  * Definitions.
        !            23:  *     Constants.
        !            24:  *     Macros with argument lists.
        !            25:  *     Typedefs.
        !            26:  *     Enums.
        !            27:  */
        !            28: 
        !            29: /*
        !            30:  * ----------------------------------------------------------------------
        !            31:  * Functions.
        !            32:  *     Import Functions.
        !            33:  *     Export Functions.
        !            34:  *     Local Functions.
        !            35:  */
        !            36: void   msigend();
        !            37: void   msigstart();
        !            38: 
        !            39: /*
        !            40:  * ----------------------------------------------------------------------
        !            41:  * Global Data.
        !            42:  *     Import Variables.
        !            43:  *     Export Variables.
        !            44:  *     Local Variables.
        !            45:  */
        !            46: extern void    (*ndpKfsave)();
        !            47: extern void    (*ndpKfrstor)();
        !            48: 
        !            49: /*
        !            50:  * ----------------------------------------------------------------------
        !            51:  * Code.
        !            52:  */
        !            53: 
        !            54: /*
        !            55:  * msigstart(signum, func)
        !            56:  *
        !            57:  * signum is 1-based signal number
        !            58:  * func points to signal handler in user text, which is the address of a
        !            59:  *     real handler and not a cookie such as SIG_DFL.
        !            60:  *
        !            61:  * This routine will set up the stack as shown before entering the user
        !            62:  * signal handler:
        !            63:  *
        !            64:  *     ndp/emulator context (struct _fpstate or struct _fpemstate or absent)
        !            65:  *     ndp/emulator flags
        !            66:  *     previous signal mask
        !            67:  *     fpstackframe:
        !            68:  *             wsp (Weitek context pointer - always null, but part of BCS)
        !            69:  *             fpsp (floating point context pointer, possibly null)
        !            70:  *             CPU register set (SS+1 long registers)
        !            71:  *             1-based signal number (user can overwrite this one)
        !            72:  *     u.u_sigreturn (in place of user return address)
        !            73:  */
        !            74: 
        !            75: /*
        !            76:  * A special define for signal stack arithmetic:
        !            77:  * Will copy at least u_sigreturn, _fpstackframe, previous mask, and ndpFlags.
        !            78:  * Note that _fpstackframe is an iBCS2 anomaly, not present in the ABI; below
        !            79:  * we define a structure with similar data and identical structure up to a
        !            80:  * point.
        !            81:  */
        !            82: 
        !            83: struct basic_signal_frame {
        !            84:        ulong_t         sf_sigreturn;
        !            85:        struct _fpstackframe _thank_you_intel;
        !            86: 
        !            87:        /*
        !            88:         * From this point on is not subject to iBCS2.
        !            89:         */
        !            90: 
        !            91:        __sigset_t      sf_signal_mask;
        !            92:        ulong_t         sf_ndpflags;
        !            93: };
        !            94: #define        sf_signo        _thank_you_intel.signo
        !            95: #define        sf_regset       _thank_you_intel.regs [0]
        !            96: #define        sf_fpsp         _thank_you_intel.fpsp
        !            97: #define        sf_weitekp      _thank_you_intel.wsp
        !            98: 
        !            99: /*
        !           100:  * Be careful! sf_regset yields something not quite the right size!
        !           101:  */
        !           102: #define        SF_REGSET(rs)   (* (gregset_t *) & (rs).sf_regset)
        !           103: 
        !           104: void
        !           105: msigstart(signum, func, regsetp)
        !           106: __sigfunc_t    func;
        !           107: gregset_t     *        regsetp;
        !           108: {
        !           109:        register int uesp;
        !           110:        int sphi, splo;
        !           111:        SEG * segp;
        !           112:        cseg_t * pp;
        !           113:        int sigArea;    /* number of bytes written to user's stack */
        !           114:        struct _fpstate * fpsp;
        !           115:        struct basic_signal_frame
        !           116:                        signal_frame;
        !           117: 
        !           118:        /*
        !           119:         * The following is all highly specific to i386 tasks. Also, check
        !           120:         * that our notion of general-register set matches the iBCS2 cookies.
        !           121:         */
        !           122: 
        !           123:        ASSERT (__xmode_286 (regsetp) == 0);
        !           124:        ASSERT ((SS + 1) * sizeof (long) == sizeof (gregset_t));
        !           125: 
        !           126:        /*
        !           127:         * Will copy at least u_sigreturn, _fpstackframe, and ndpFlags.
        !           128:         * If using ndp, need room for an _fpstate.
        !           129:         * If emulating, need room for an _fpemstate.
        !           130:         * Fp context is immediately above regular signal context.
        !           131:         */
        !           132: 
        !           133:        sigArea = sizeof (signal_frame);
        !           134:        uesp = regsetp->_i386._uesp;
        !           135: 
        !           136:        if (rdNdpUser () || rdEmTrapped ()) {
        !           137:                fpsp = (struct _fpstate *) uesp - 1;
        !           138:                sigArea += sizeof (struct _fpstate);
        !           139:        } else
        !           140:                fpsp = 0;
        !           141: 
        !           142:        uesp -= sigArea;
        !           143: 
        !           144:        /* Add to user stack if necessary. */
        !           145:        segp = u.u_segl[SISTACK].sr_segp;
        !           146:        sphi = ISP_386;
        !           147:        splo = sphi - segp->s_size;
        !           148: 
        !           149:        if (splo > uesp) {
        !           150:                pp = c_extend(segp->s_vmem, btoc(segp->s_size));
        !           151:                if (pp==0) {
        !           152:                        printf("Signal failed.  cmd=%s  c_extend(%x,%x)=0 ",
        !           153:                          u.u_comm, segp->s_vmem, btoc(segp->s_size));
        !           154:                        return;
        !           155:                }
        !           156: 
        !           157:                segp->s_vmem = pp;
        !           158:                segp->s_size += NBPC;
        !           159:                if (sproto(0)==0) {
        !           160:                        printf("Signal failed.  cmd=%s  sproto(0)=0 ",
        !           161:                          u.u_comm);
        !           162:                        return;
        !           163:                }
        !           164: 
        !           165:                segload();
        !           166:        }
        !           167: 
        !           168:        /*
        !           169:         * Build signal stack frame locally and copy as a group.
        !           170:         */
        !           171: 
        !           172:        curr_signal_mask (NULL, & signal_frame.sf_signal_mask);
        !           173: 
        !           174:        signal_frame.sf_weitekp = 0;
        !           175:        signal_frame.sf_fpsp = fpsp;
        !           176: 
        !           177:        SF_REGSET (signal_frame) = * regsetp;
        !           178:        signal_frame.sf_signo = signum;
        !           179:        signal_frame.sf_sigreturn = u.u_sigreturn;
        !           180: 
        !           181:        /*
        !           182:         * Turn off single-stepping, and set up user registers.
        !           183:         */
        !           184: 
        !           185:        regsetp->_i386._eflags &= ~ MFTTB;
        !           186:        regsetp->_i386._eip = func;
        !           187:        regsetp->_i386._uesp = uesp;
        !           188: 
        !           189:        /*
        !           190:         * We are about to enter a signal handling function for the process.
        !           191:         * If current process is using ndp
        !           192:         *   copy ndp state and related flags into signal handler stack
        !           193:         *   mark the process as not using ndp
        !           194:         *   arm EM traps in case signal handler uses ndp
        !           195:         * Else if process is using emulator
        !           196:         *   copy emulator state and flags into signal handler stack
        !           197:         *   mark the process as not using emulator
        !           198:         * Else
        !           199:         *   put ndp/emulator flags on stack
        !           200:         */
        !           201: 
        !           202:        if (rdNdpUser ()) {
        !           203:                /* if ndp state not saved yet for this process, save it now */
        !           204:                if (! rdNdpSaved ()) {
        !           205:                        ndpSave (& u.u_ndpCon);
        !           206:                        wrNdpSaved (1);
        !           207:                }
        !           208: 
        !           209:                signal_frame.sf_ndpflags = u.u_ndpFlags;
        !           210: 
        !           211:                kucopy (& u.u_ndpCon, fpsp, sizeof (struct _fpstate));
        !           212:                ndpDetach ();
        !           213: 
        !           214:                wrNdpUser (0);
        !           215:                wrNdpSaved (0);
        !           216:                ndpEmTraps (1);
        !           217:        } else {
        !           218:                signal_frame.sf_ndpflags = u.u_ndpFlags;
        !           219: 
        !           220:                if (rdEmTrapped()) {
        !           221:                        if (ndpKfsave) {
        !           222:                                unsigned long sw_old;
        !           223: 
        !           224:                                (* ndpKfsave) (& u.u_ndpCon, fpsp);
        !           225:                                sw_old = getuwd (& fpsp->sw);
        !           226:                                putuwd (& fpsp->status, sw_old);
        !           227:                                putuwd (& fpsp->sw, sw_old & 0x7f00);
        !           228:                        }
        !           229:                        wrEmTrapped(0);
        !           230:                }
        !           231:        }
        !           232: 
        !           233:        if (kucopy (& signal_frame, uesp, sizeof (signal_frame)) !=
        !           234:                        sizeof (signal_frame)) {
        !           235:                printf ("Could not build signal frame!\n");
        !           236:                return;
        !           237:        }
        !           238: }
        !           239: 
        !           240: void
        !           241: msigend (regset)
        !           242: gregset_t      regset;
        !           243: {
        !           244:        int savedNdpFlags;
        !           245:        int sigNdpUser;
        !           246:        int             temp;
        !           247:        __sigset_t      signal_mask;
        !           248:        struct basic_signal_frame
        !           249:                      * signal_framep;
        !           250: 
        !           251:        /*
        !           252:         * Retrieved saved signal mask and ndp flags; note that the sigreturn
        !           253:         * and signo members of the signal frame have vanished.
        !           254:         */
        !           255: 
        !           256:        signal_framep = (struct basic_signal_frame *) (regset._i386._uesp -
        !           257:                                                       2 * sizeof (ulong_t));
        !           258:        ASSERT (getuwd (& signal_framep->sf_weitekp) == 0);
        !           259: 
        !           260:        temp = ukcopy (& signal_framep->sf_signal_mask, & signal_mask,
        !           261:                       sizeof (signal_mask));
        !           262:        ASSERT (temp == sizeof (signal_mask));
        !           263: 
        !           264:        curr_signal_mask (& signal_mask, NULL);
        !           265: 
        !           266:        savedNdpFlags = getuwd (& signal_framep->sf_ndpflags);
        !           267: 
        !           268:        sigNdpUser = rdNdpUser ();
        !           269:        u.u_ndpFlags = savedNdpFlags;
        !           270: 
        !           271:        /*
        !           272:         * We are about to leave a signal handling function for this process.
        !           273:         * If signal function for this process was using ndp
        !           274:         * And main process was *not* using ndp
        !           275:         *   Detach signal function from ndp
        !           276:         *   Restore current EM to its pre-signal value.
        !           277:         * If main process *was* using ndp
        !           278:         *   restore its ndp state and make it ndp owner again.
        !           279:         * If main process was using emulator
        !           280:         *   restore emulator state.
        !           281:         */
        !           282:        if (sigNdpUser && !rdNdpUser()) {
        !           283:                ndpDetach();
        !           284:                ndpEmTraps(1);
        !           285:        }
        !           286: 
        !           287:        if (rdNdpUser()) {
        !           288:                ndpEmTraps(0);
        !           289: 
        !           290:                ASSERT (signal_framep + 1 == getuwd (& signal_framep->sf_fpsp));
        !           291:                temp = ukcopy (signal_framep + 1, & u.u_ndpCon,
        !           292:                               sizeof (struct _fpstate));
        !           293:                ASSERT (temp == sizeof (struct _fpstate));
        !           294: 
        !           295:                ndpRestore (& u.u_ndpCon);
        !           296:                wrNdpSaved (0);
        !           297:                ndpMine();
        !           298:        } else if (rdEmTrapped () && ndpKfrstor)
        !           299:                (* ndpKfrstor) (signal_framep + 1, & u.u_ndpCon);
        !           300: 
        !           301:        /* Restore user process state to pre-signal values */
        !           302: 
        !           303:        temp = ukcopy (& signal_framep->sf_regset, & regset, sizeof (regset));
        !           304:        ASSERT (temp == (SS + 1) * sizeof (long));
        !           305: }

unix.superglobalmegacorp.com

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