|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.