Annotation of coherent/b/kernel/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: #include <sys/coherent.h>
                     14: 
                     15: /*
                     16:  * ----------------------------------------------------------------------
                     17:  * Definitions.
                     18:  *     Constants.
                     19:  *     Macros with argument lists.
                     20:  *     Typedefs.
                     21:  *     Enums.
                     22:  */
                     23: 
                     24: /*
                     25:  * ----------------------------------------------------------------------
                     26:  * Functions.
                     27:  *     Import Functions.
                     28:  *     Export Functions.
                     29:  *     Local Functions.
                     30:  */
                     31: void   msigend();
                     32: void   msigstart();
                     33: 
                     34: /*
                     35:  * ----------------------------------------------------------------------
                     36:  * Global Data.
                     37:  *     Import Variables.
                     38:  *     Export Variables.
                     39:  *     Local Variables.
                     40:  */
                     41: extern void    (*ndpKfsave)();
                     42: extern void    (*ndpKfrstor)();
                     43: 
                     44: /*
                     45:  * ----------------------------------------------------------------------
                     46:  * Code.
                     47:  */
                     48: 
                     49: /*
                     50:  * msigstart(signum, func)
                     51:  *
                     52:  * signum is 1-based signal number
                     53:  * func points to signal handler in user text,
                     54:  *   or func is magic value (SIG_DFL, etc.)
                     55:  *
                     56:  * This routine will set up the stack as shown before entering the user
                     57:  * signal handler:
                     58:  *
                     59:  *     ndp/emulator context (struct _fpstate or struct _fpemstate or absent)
                     60:  *     ndp/emulator flags
                     61:  *     fpstackframe:
                     62:  *             wsp (Weitek context pointer - always null, but part of BCS)
                     63:  *             fpsp (floating point context pointer, possibly null)
                     64:  *             CPU register set (SS+1 long registers)
                     65:  *             1-based signal number
                     66:  *     u.u_sigreturn (in place of user return address)
                     67:  */
                     68: 
                     69: /*
                     70:  * A special define for signal stack arithmetic:
                     71:  * Will copy at least u_sigreturn, _fpstackframe, and ndpFlags.
                     72:  */
                     73: #define SIG_AREA_BASE  (sizeof(struct _fpstackframe) + 2 * sizeof(long))
                     74: 
                     75: void
                     76: msigstart(signum, func)
                     77: {
                     78:        register int uesp;
                     79:        int sphi, splo;
                     80:        SEG * segp;
                     81:        cseg_t * pp;
                     82:        int sigArea;    /* number of bytes written to user's stack */
                     83:        struct _fpstate * fpsp;
                     84: 
                     85:        /*
                     86:         * If signal handler was attached with sigset(), temporarily
                     87:         * hold further instances of the same signal.
                     88:         * Otherwise, signal handler was attached with signal(), so
                     89:         * unless at a breakpoint, we detach it and restore SIG_DFL handling.
                     90:         */
                     91:        if (sigSet(signum))
                     92:                sigHold(signum);
                     93:        else if (signum != SIGTRAP)
                     94:                sigDefault(signum);
                     95: 
                     96:        /*
                     97:         * Will copy at least u_sigreturn, _fpstackframe, and ndpFlags.
                     98:         * If using ndp, need room for an _fpstate.
                     99:         * If emulating, need room for an _fpemstate.
                    100:         */
                    101:        sigArea = SIG_AREA_BASE;
                    102:        if (rdNdpUser() || rdEmTrapped())
                    103:                sigArea += sizeof(struct _fpstate);
                    104:        uesp = u.u_regl[UESP] - sigArea;
                    105: 
                    106:        /* Add to user stack if necessary. */
                    107:        segp = u.u_segl[SISTACK].sr_segp;
                    108:        sphi = (XMODE_286) ? ISP_286 : ISP_386;
                    109:        splo = sphi - segp->s_size;
                    110: 
                    111:        if (splo > uesp) {
                    112:                pp = c_extend(segp->s_vmem, btoc(segp->s_size));
                    113:                if (pp==0) {
                    114:                        printf("Signal failed.  cmd=%s  c_extend(%x,%x)=0 ",
                    115:                          u.u_comm, segp->s_vmem, btoc(segp->s_size));
                    116:                        return;
                    117:                }
                    118: 
                    119:                segp->s_vmem = pp;
                    120:                segp->s_size += NBPC;
                    121:                if (sproto(0)==0) {
                    122:                        printf("Signal failed.  cmd=%s  sproto(0)=0 ",
                    123:                          u.u_comm);
                    124:                        return;
                    125:                }
                    126: 
                    127:                segload();
                    128:        }
                    129: 
                    130:        /*
                    131:         * Set the ndp/emulator context pointer fpsp.
                    132:         * Fp context is immediately above SIG_AREA_BASE.
                    133:         */
                    134:        if (rdNdpUser() || rdEmTrapped())
                    135:                fpsp = (struct _fpstate *)(uesp + SIG_AREA_BASE);
                    136:        else
                    137:                fpsp = 0;
                    138: 
                    139:        /*
                    140:         * Write fpsp and wsp (Weitek state pointer always null).
                    141:         */
                    142:        putuwd(uesp + (SS+3) * sizeof(long), fpsp);
                    143:        putuwd(uesp + (SS+4) * sizeof(long), 0);
                    144: 
                    145:        kucopy(u.u_regl, uesp + 2*sizeof(long), (SS+1) * sizeof(long));
                    146:        putuwd(uesp+sizeof(long), signum);
                    147:        putuwd(uesp, u.u_sigreturn);
                    148:        u.u_regl[EFL] &= ~MFTTB;
                    149:        u.u_regl[EIP] = func;
                    150:        u.u_regl[UESP] = uesp;
                    151: 
                    152:        /*
                    153:         * We are about to enter a signal handling function for the process.
                    154:         * If current process is using ndp
                    155:         *   copy ndp state and related flags into signal handler stack
                    156:         *   mark the process as not using ndp
                    157:         *   arm EM traps in case signal handler uses ndp
                    158:         * Else if process is using emulator
                    159:         *   copy emulator state and flags into signal handler stack
                    160:         *   mark the process as not using emulator
                    161:         * Else
                    162:         *   put ndp/emulator flags on stack
                    163:         */
                    164:        if (rdNdpUser()) {
                    165:                /* if ndp state not saved yet for this process, save it now */
                    166:                if (!rdNdpSaved()) {
                    167:                        ndpSave(&u.u_ndpCon);
                    168:                        wrNdpSaved(1);
                    169:                }
                    170: 
                    171:                putuwd(uesp + (SS+5) * sizeof(long), u.u_ndpFlags);
                    172: 
                    173:                kucopy(&u.u_ndpCon, fpsp, sizeof(struct _fpstate));
                    174:                ndpDetach();
                    175: 
                    176:                wrNdpUser(0);
                    177:                wrNdpSaved(0);
                    178:                ndpEmTraps(1);
                    179:        } else if (rdEmTrapped()) {
                    180:                putuwd(uesp + (SS+5) * sizeof(long), u.u_ndpFlags);
                    181:                if (ndpKfsave) {
                    182:                        unsigned long sw_old;
                    183:                        (*ndpKfsave)(&u.u_ndpCon, fpsp);
                    184:                        sw_old = getuwd(&fpsp->sw);
                    185:                        putuwd(&fpsp->status, sw_old);
                    186:                        putuwd(&fpsp->sw, sw_old & 0x7f00);
                    187:                }
                    188:                wrEmTrapped(0);
                    189:        } else {
                    190:                putuwd(uesp + (SS+5) * sizeof(long), u.u_ndpFlags);
                    191:        }
                    192: }
                    193: 
                    194: void
                    195: msigend(gs, fs, es, ds, edi, esi, ebp, esp, ebx, edx, ecx, eax, trapno, err,
                    196:   eip, cs, efl, uesp, ss)
                    197: {
                    198:        register int signo;
                    199:        register PROC *pp = SELF;
                    200:        int savedNdpFlags;
                    201:        int sigNdpUser;
                    202: 
                    203:        u.u_regl = &gs;
                    204: 
                    205:        /*
                    206:         * BOGUS - assumes nothing clobbers user stack.
                    207:         * There is a small probability that the u_sigreturn code,
                    208:         * which is
                    209:         *      add     $4,%esp
                    210:         *      lcall   $0xf,$0
                    211:         * might get a signal hit between the first and second instructions.
                    212:         * This will clobber the value being fetched to signo.
                    213:         */
                    214:        signo = getuwd(uesp-sizeof(long)); 
                    215: 
                    216:        savedNdpFlags = getuwd(uesp + (SS+3) * sizeof(long));
                    217: 
                    218:        sigNdpUser = rdNdpUser();
                    219:        u.u_ndpFlags = savedNdpFlags;
                    220: 
                    221:        /*
                    222:         * We are about to leave a signal handling function for this process.
                    223:         * If signal function for this process was using ndp
                    224:         * And main process was *not* using ndp
                    225:         *   Detach signal function from ndp
                    226:         *   Restore current EM to its pre-signal value.
                    227:         * If main process *was* using ndp
                    228:         *   restore its ndp state and make it ndp owner again.
                    229:         * If main process was using emulator
                    230:         *   restore emulator state.
                    231:         */
                    232:        if (sigNdpUser && !rdNdpUser()) {
                    233:                ndpDetach();
                    234:                ndpEmTraps(1);
                    235:        }
                    236: 
                    237:        if (rdNdpUser()) {
                    238:                ndpEmTraps(0);
                    239:                ukcopy(uesp + (SS+4)*sizeof(long), &u.u_ndpCon,
                    240:                  sizeof(struct _fpstate));
                    241:                ndpRestore(&u.u_ndpCon);
                    242:                wrNdpSaved(0);
                    243:                ndpMine();
                    244:        } else if (rdEmTrapped()) {
                    245:                if (ndpKfrstor)
                    246:                        (*ndpKfrstor)(uesp + (SS+4)*sizeof(long), &u.u_ndpCon);
                    247:        }
                    248: 
                    249:        /* Restore process state to pre-signal values. */
                    250:        ukcopy(uesp, u.u_regl, (SS+1) * sizeof(long));
                    251: 
                    252:        /*
                    253:         * If the signal has been sigset simulate a sigrelse(signal).
                    254:         *
                    255:         * As per S5, if the user's signal handler tries to do a sighold,
                    256:         * it will be ignored.
                    257:         */
                    258:        sigRelease(signo);
                    259: }

unix.superglobalmegacorp.com

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