Annotation of coherent/b/STREAMS/i386/msig.c, revision 1.1.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.