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