This source file includes following definitions.
- osf_sigprocmask
- do_sigsuspend
- do_sigreturn
- setup_frame
- do_signal
1
2
3
4
5
6
7 #include <linux/sched.h>
8 #include <linux/kernel.h>
9 #include <linux/signal.h>
10 #include <linux/errno.h>
11 #include <linux/wait.h>
12 #include <linux/ptrace.h>
13 #include <linux/unistd.h>
14 #include <linux/mm.h>
15
16 #include <asm/bitops.h>
17 #include <asm/segment.h>
18
19 #define _S(nr) (1<<((nr)-1))
20 #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
21
22 asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
23 asmlinkage void ret_from_sys_call(void);
24 asmlinkage int do_signal(unsigned long, struct pt_regs *, struct switch_stack *,
25 unsigned long, unsigned long);
26 asmlinkage void imb(void);
27
28
29
30
31
32 asmlinkage unsigned long osf_sigprocmask(int how, unsigned long newmask)
33 {
34 unsigned long oldmask = current->blocked;
35
36 newmask &= _BLOCKABLE;
37 switch (how) {
38 case SIG_BLOCK:
39 current->blocked |= newmask;
40 return oldmask;
41 case SIG_UNBLOCK:
42 current->blocked &= ~newmask;
43 return oldmask;
44 case SIG_SETMASK:
45 current->blocked = newmask;
46 return oldmask;
47 }
48 return -EINVAL;
49 }
50
51
52
53
54 asmlinkage int do_sigsuspend(unsigned long mask, struct pt_regs * regs, struct switch_stack * sw)
55 {
56 unsigned long oldmask = current->blocked;
57 current->blocked = mask & _BLOCKABLE;
58 while (1) {
59 current->state = TASK_INTERRUPTIBLE;
60 schedule();
61 if (do_signal(oldmask,regs, sw, 0, 0))
62 return -EINTR;
63 }
64 }
65
66
67
68
69 asmlinkage void do_sigreturn(struct sigcontext_struct * sc,
70 struct pt_regs * regs, struct switch_stack * sw)
71 {
72 unsigned long mask;
73 int i;
74
75
76 if (verify_area(VERIFY_READ, sc, sizeof(*sc)))
77 do_exit(SIGSEGV);
78 if (get_fs_quad(&sc->sc_ps) != 8)
79 do_exit(SIGSEGV);
80 mask = get_fs_quad(&sc->sc_mask);
81 if (mask & ~_BLOCKABLE)
82 do_exit(SIGSEGV);
83
84
85 wrusp(get_fs_quad(sc->sc_regs+30));
86 regs->pc = get_fs_quad(&sc->sc_pc);
87 sw->r26 = (unsigned long) ret_from_sys_call;
88 current->blocked = mask;
89
90 regs->r0 = get_fs_quad(sc->sc_regs+0);
91 regs->r1 = get_fs_quad(sc->sc_regs+1);
92 regs->r2 = get_fs_quad(sc->sc_regs+2);
93 regs->r3 = get_fs_quad(sc->sc_regs+3);
94 regs->r4 = get_fs_quad(sc->sc_regs+4);
95 regs->r5 = get_fs_quad(sc->sc_regs+5);
96 regs->r6 = get_fs_quad(sc->sc_regs+6);
97 regs->r7 = get_fs_quad(sc->sc_regs+7);
98 regs->r8 = get_fs_quad(sc->sc_regs+8);
99 sw->r9 = get_fs_quad(sc->sc_regs+9);
100 sw->r10 = get_fs_quad(sc->sc_regs+10);
101 sw->r11 = get_fs_quad(sc->sc_regs+11);
102 sw->r12 = get_fs_quad(sc->sc_regs+12);
103 sw->r13 = get_fs_quad(sc->sc_regs+13);
104 sw->r14 = get_fs_quad(sc->sc_regs+14);
105 sw->r15 = get_fs_quad(sc->sc_regs+15);
106 regs->r16 = get_fs_quad(sc->sc_regs+16);
107 regs->r17 = get_fs_quad(sc->sc_regs+17);
108 regs->r18 = get_fs_quad(sc->sc_regs+18);
109 regs->r19 = get_fs_quad(sc->sc_regs+19);
110 regs->r20 = get_fs_quad(sc->sc_regs+20);
111 regs->r21 = get_fs_quad(sc->sc_regs+21);
112 regs->r22 = get_fs_quad(sc->sc_regs+22);
113 regs->r23 = get_fs_quad(sc->sc_regs+23);
114 regs->r24 = get_fs_quad(sc->sc_regs+24);
115 regs->r25 = get_fs_quad(sc->sc_regs+25);
116 regs->r26 = get_fs_quad(sc->sc_regs+26);
117 regs->r27 = get_fs_quad(sc->sc_regs+27);
118 regs->r28 = get_fs_quad(sc->sc_regs+28);
119 regs->gp = get_fs_quad(sc->sc_regs+29);
120 for (i = 0; i < 31; i++)
121 sw->fp[i] = get_fs_quad(sc->sc_fpregs+i);
122 }
123
124
125
126
127 static void setup_frame(struct sigaction * sa, struct sigcontext_struct ** fp, unsigned long pc,
128 struct pt_regs * regs, struct switch_stack * sw, int signr, unsigned long oldmask)
129 {
130 int i;
131 struct sigcontext_struct * sc;
132
133 sc = *fp;
134
135 sc--;
136 if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
137 do_exit(SIGSEGV);
138
139 put_fs_quad(oldmask, &sc->sc_mask);
140 put_fs_quad(8, &sc->sc_ps);
141 put_fs_quad(pc, &sc->sc_pc);
142 put_fs_quad((unsigned long)*fp, sc->sc_regs+30);
143
144 put_fs_quad(regs->r0 , sc->sc_regs+0);
145 put_fs_quad(regs->r1 , sc->sc_regs+1);
146 put_fs_quad(regs->r2 , sc->sc_regs+2);
147 put_fs_quad(regs->r3 , sc->sc_regs+3);
148 put_fs_quad(regs->r4 , sc->sc_regs+4);
149 put_fs_quad(regs->r5 , sc->sc_regs+5);
150 put_fs_quad(regs->r6 , sc->sc_regs+6);
151 put_fs_quad(regs->r7 , sc->sc_regs+7);
152 put_fs_quad(regs->r8 , sc->sc_regs+8);
153 put_fs_quad(sw->r9 , sc->sc_regs+9);
154 put_fs_quad(sw->r10 , sc->sc_regs+10);
155 put_fs_quad(sw->r11 , sc->sc_regs+11);
156 put_fs_quad(sw->r12 , sc->sc_regs+12);
157 put_fs_quad(sw->r13 , sc->sc_regs+13);
158 put_fs_quad(sw->r14 , sc->sc_regs+14);
159 put_fs_quad(sw->r15 , sc->sc_regs+15);
160 put_fs_quad(regs->r16, sc->sc_regs+16);
161 put_fs_quad(regs->r17, sc->sc_regs+17);
162 put_fs_quad(regs->r18, sc->sc_regs+18);
163 put_fs_quad(regs->r19, sc->sc_regs+19);
164 put_fs_quad(regs->r20, sc->sc_regs+20);
165 put_fs_quad(regs->r21, sc->sc_regs+21);
166 put_fs_quad(regs->r22, sc->sc_regs+22);
167 put_fs_quad(regs->r23, sc->sc_regs+23);
168 put_fs_quad(regs->r24, sc->sc_regs+24);
169 put_fs_quad(regs->r25, sc->sc_regs+25);
170 put_fs_quad(regs->r26, sc->sc_regs+26);
171 put_fs_quad(regs->r27, sc->sc_regs+27);
172 put_fs_quad(regs->r28, sc->sc_regs+28);
173 put_fs_quad(regs->gp , sc->sc_regs+29);
174 for (i = 0; i < 31; i++)
175 put_fs_quad(sw->fp[i], sc->sc_fpregs+i);
176
177
178
179
180
181
182
183
184
185
186 put_fs_quad(0x43ecf40047de0410, sc->sc_retcode+0);
187 put_fs_quad(0x0000000000000083, sc->sc_retcode+1);
188 regs->r26 = (unsigned long) sc->sc_retcode;
189 regs->r16 = signr;
190 *fp = sc;
191 }
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206 asmlinkage int do_signal(unsigned long oldmask,
207 struct pt_regs * regs,
208 struct switch_stack * sw,
209 unsigned long r0, unsigned long r19)
210 {
211 unsigned long mask = ~current->blocked;
212 unsigned long handler_signal = 0;
213 struct sigcontext_struct *frame = NULL;
214 unsigned long pc = 0;
215 unsigned long signr;
216 struct sigaction * sa;
217 extern ptrace_cancel_bpt (struct task_struct *child);
218
219 ptrace_cancel_bpt(current);
220
221 while ((signr = current->signal & mask) != 0) {
222 signr = ffz(~signr);
223 clear_bit(signr, ¤t->signal);
224 sa = current->sigaction + signr;
225 signr++;
226 if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
227 current->exit_code = signr;
228 current->state = TASK_STOPPED;
229 notify_parent(current);
230 schedule();
231 if (!(signr = current->exit_code))
232 continue;
233 current->exit_code = 0;
234 if (signr == SIGSTOP)
235 continue;
236 if (_S(signr) & current->blocked) {
237 current->signal |= _S(signr);
238 continue;
239 }
240 sa = current->sigaction + signr - 1;
241 }
242 if (sa->sa_handler == SIG_IGN) {
243 if (signr != SIGCHLD)
244 continue;
245
246 while (sys_waitpid(-1,NULL,WNOHANG) > 0)
247 ;
248 continue;
249 }
250 if (sa->sa_handler == SIG_DFL) {
251 if (current->pid == 1)
252 continue;
253 switch (signr) {
254 case SIGCONT: case SIGCHLD: case SIGWINCH:
255 continue;
256
257 case SIGSTOP: case SIGTSTP: case SIGTTIN: case SIGTTOU:
258 if (current->flags & PF_PTRACED)
259 continue;
260 current->state = TASK_STOPPED;
261 current->exit_code = signr;
262 if (!(current->p_pptr->sigaction[SIGCHLD-1].sa_flags &
263 SA_NOCLDSTOP))
264 notify_parent(current);
265 schedule();
266 continue;
267
268 case SIGQUIT: case SIGILL: case SIGTRAP:
269 case SIGABRT: case SIGFPE: case SIGSEGV:
270 if (current->binfmt && current->binfmt->core_dump) {
271 if (current->binfmt->core_dump(signr, regs))
272 signr |= 0x80;
273 }
274
275 default:
276 current->signal |= _S(signr & 0x7f);
277 do_exit(signr);
278 }
279 }
280
281
282
283 if (r0) {
284 if (regs->r0 == ERESTARTNOHAND ||
285 (regs->r0 == ERESTARTSYS && !(sa->sa_flags & SA_RESTART)))
286 regs->r0 = EINTR;
287 }
288 handler_signal |= 1 << (signr-1);
289 mask &= ~sa->sa_mask;
290 }
291 if (r0 &&
292 (regs->r0 == ERESTARTNOHAND ||
293 regs->r0 == ERESTARTSYS ||
294 regs->r0 == ERESTARTNOINTR)) {
295 regs->r0 = r0;
296 regs->r19 = r19;
297 regs->pc -= 4;
298 }
299 if (!handler_signal)
300 return 0;
301 pc = regs->pc;
302 frame = (struct sigcontext_struct *) rdusp();
303 signr = 1;
304 sa = current->sigaction;
305 for (mask = 1 ; mask ; sa++,signr++,mask += mask) {
306 if (mask > handler_signal)
307 break;
308 if (!(mask & handler_signal))
309 continue;
310 setup_frame(sa,&frame,pc,regs,sw,signr,oldmask);
311 pc = (unsigned long) sa->sa_handler;
312 regs->r27 = pc;
313 if (sa->sa_flags & SA_ONESHOT)
314 sa->sa_handler = NULL;
315 current->blocked |= sa->sa_mask;
316 oldmask |= sa->sa_mask;
317 }
318 imb();
319 wrusp((unsigned long) frame);
320 regs->pc = pc;
321 return 1;
322 }