|
|
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.