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