OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [sh/] [kernel/] [signal.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* $Id: signal.c,v 1.1.1.1 2004-04-15 01:17:27 phoenix Exp $
2
 *
3
 *  linux/arch/sh/kernel/signal.c
4
 *
5
 *  Copyright (C) 1991, 1992  Linus Torvalds
6
 *
7
 *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
8
 *
9
 *  SuperH version:  Copyright (C) 1999, 2000  Niibe Yutaka & Kaz Kojima
10
 *
11
 */
12
 
13
#include <linux/sched.h>
14
#include <linux/mm.h>
15
#include <linux/smp.h>
16
#include <linux/smp_lock.h>
17
#include <linux/kernel.h>
18
#include <linux/signal.h>
19
#include <linux/errno.h>
20
#include <linux/wait.h>
21
#include <linux/ptrace.h>
22
#include <linux/unistd.h>
23
#include <linux/stddef.h>
24
#include <linux/personality.h>
25
#include <asm/ucontext.h>
26
#include <asm/uaccess.h>
27
#include <asm/pgtable.h>
28
 
29
#define DEBUG_SIG 0
30
 
31
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
32
 
33
asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset,
34
                         int from_syscall, unsigned long orig_r0);
35
 
36
int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
37
{
38
        if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
39
                return -EFAULT;
40
        if (from->si_code < 0)
41
                return __copy_to_user(to, from, sizeof(siginfo_t));
42
        else {
43
                int err;
44
 
45
                /* If you change siginfo_t structure, please be sure
46
                   this code is fixed accordingly.
47
                   It should never copy any pad contained in the structure
48
                   to avoid security leaks, but must copy the generic
49
                   3 ints plus the relevant union member.  */
50
                err = __put_user(from->si_signo, &to->si_signo);
51
                err |= __put_user(from->si_errno, &to->si_errno);
52
                err |= __put_user((short)from->si_code, &to->si_code);
53
                /* First 32bits of unions are always present.  */
54
                err |= __put_user(from->si_pid, &to->si_pid);
55
                switch (from->si_code >> 16) {
56
                case __SI_FAULT >> 16:
57
                        break;
58
                case __SI_CHLD >> 16:
59
                        err |= __put_user(from->si_utime, &to->si_utime);
60
                        err |= __put_user(from->si_stime, &to->si_stime);
61
                        err |= __put_user(from->si_status, &to->si_status);
62
                default:
63
                        err |= __put_user(from->si_uid, &to->si_uid);
64
                        break;
65
                /* case __SI_RT: This is not generated by the kernel as of now.  */
66
                }
67
                return err;
68
        }
69
}
70
 
71
/*
72
 * Atomically swap in the new signal mask, and wait for a signal.
73
 */
74
asmlinkage int
75
sys_sigsuspend(old_sigset_t mask,
76
               unsigned long r5, unsigned long r6, unsigned long r7,
77
               struct pt_regs regs)
78
{
79
        sigset_t saveset;
80
 
81
        mask &= _BLOCKABLE;
82
        spin_lock_irq(&current->sigmask_lock);
83
        saveset = current->blocked;
84
        siginitset(&current->blocked, mask);
85
        recalc_sigpending(current);
86
        spin_unlock_irq(&current->sigmask_lock);
87
 
88
        regs.regs[0] = -EINTR;
89
        while (1) {
90
                current->state = TASK_INTERRUPTIBLE;
91
                schedule();
92
                if (do_signal(&regs, &saveset, 0, 0))
93
                        return -EINTR;
94
        }
95
}
96
 
97
asmlinkage int
98
sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
99
                  unsigned long r6, unsigned long r7,
100
                  struct pt_regs regs)
101
{
102
        sigset_t saveset, newset;
103
 
104
        /* XXX: Don't preclude handling different sized sigset_t's.  */
105
        if (sigsetsize != sizeof(sigset_t))
106
                return -EINVAL;
107
 
108
        if (copy_from_user(&newset, unewset, sizeof(newset)))
109
                return -EFAULT;
110
        sigdelsetmask(&newset, ~_BLOCKABLE);
111
        spin_lock_irq(&current->sigmask_lock);
112
        saveset = current->blocked;
113
        current->blocked = newset;
114
        recalc_sigpending(current);
115
        spin_unlock_irq(&current->sigmask_lock);
116
 
117
        regs.regs[0] = -EINTR;
118
        while (1) {
119
                current->state = TASK_INTERRUPTIBLE;
120
                schedule();
121
                if (do_signal(&regs, &saveset, 0, 0))
122
                        return -EINTR;
123
        }
124
}
125
 
126
asmlinkage int
127
sys_sigaction(int sig, const struct old_sigaction *act,
128
              struct old_sigaction *oact)
129
{
130
        struct k_sigaction new_ka, old_ka;
131
        int ret;
132
 
133
        if (act) {
134
                old_sigset_t mask;
135
                if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
136
                    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
137
                    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
138
                        return -EFAULT;
139
                __get_user(new_ka.sa.sa_flags, &act->sa_flags);
140
                __get_user(mask, &act->sa_mask);
141
                siginitset(&new_ka.sa.sa_mask, mask);
142
        }
143
 
144
        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
145
 
146
        if (!ret && oact) {
147
                if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
148
                    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
149
                    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
150
                        return -EFAULT;
151
                __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
152
                __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
153
        }
154
 
155
        return ret;
156
}
157
 
158
asmlinkage int
159
sys_sigaltstack(const stack_t *uss, stack_t *uoss,
160
                unsigned long r6, unsigned long r7,
161
                struct pt_regs regs)
162
{
163
        return do_sigaltstack(uss, uoss, regs.regs[15]);
164
}
165
 
166
 
167
/*
168
 * Do a signal return; undo the signal stack.
169
 */
170
 
171
#define MOVW(n)  (0x9300|((n)-2))       /* Move mem word at PC+n to R3 */
172
#define TRAP16   0xc310                 /* Syscall w/no args (NR in R3) */
173
#define OR_R0_R0 0x200b                 /* or r0,r0 (insert to avoid hardware bug) */
174
 
175
struct sigframe
176
{
177
        struct sigcontext sc;
178
        unsigned long extramask[_NSIG_WORDS-1];
179
        u16 retcode[8];
180
};
181
 
182
struct rt_sigframe
183
{
184
        struct siginfo info;
185
        struct ucontext uc;
186
        u16 retcode[8];
187
};
188
 
189
#if defined(__SH4__)
190
static inline int restore_sigcontext_fpu(struct sigcontext *sc)
191
{
192
        struct task_struct *tsk = current;
193
 
194
        tsk->used_math = 1;
195
        return __copy_from_user(&tsk->thread.fpu.hard, &sc->sc_fpregs[0],
196
                                sizeof(long)*(16*2+2));
197
}
198
 
199
static inline int save_sigcontext_fpu(struct sigcontext *sc)
200
{
201
        struct task_struct *tsk = current;
202
 
203
        if (!tsk->used_math) {
204
                __put_user(0, &sc->sc_ownedfp);
205
                return 0;
206
        }
207
 
208
        __put_user(1, &sc->sc_ownedfp);
209
 
210
        /* This will cause a "finit" to be triggered by the next
211
           attempted FPU operation by the 'current' process.
212
           */
213
        tsk->used_math = 0;
214
 
215
        unlazy_fpu(tsk);
216
        return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.fpu.hard,
217
                              sizeof(long)*(16*2+2));
218
}
219
#endif
220
 
221
static int
222
restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
223
{
224
        unsigned int err = 0;
225
 
226
#define COPY(x)         err |= __get_user(regs->x, &sc->sc_##x)
227
        COPY(regs[0]);   COPY(regs[1]);
228
        COPY(regs[2]);  COPY(regs[3]);
229
        COPY(regs[4]);  COPY(regs[5]);
230
        COPY(regs[6]);  COPY(regs[7]);
231
        COPY(regs[8]);  COPY(regs[9]);
232
        COPY(regs[10]); COPY(regs[11]);
233
        COPY(regs[12]); COPY(regs[13]);
234
        COPY(regs[14]); COPY(regs[15]);
235
        COPY(gbr);      COPY(mach);
236
        COPY(macl);     COPY(pr);
237
        COPY(sr);       COPY(pc);
238
#undef COPY
239
 
240
#if defined(__SH4__)
241
        {
242
                int owned_fp;
243
                struct task_struct *tsk = current;
244
 
245
                regs->sr |= SR_FD; /* Release FPU */
246
                clear_fpu(tsk);
247
                current->used_math = 0;
248
                __get_user (owned_fp, &sc->sc_ownedfp);
249
                if (owned_fp)
250
                        err |= restore_sigcontext_fpu(sc);
251
        }
252
#endif
253
        return err;
254
}
255
 
256
 
257
asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
258
                             unsigned long r6, unsigned long r7,
259
                             struct pt_regs regs)
260
{
261
        struct sigframe *frame = (struct sigframe *)regs.regs[15];
262
        sigset_t set;
263
 
264
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
265
                goto badframe;
266
 
267
        if (__get_user(set.sig[0], &frame->sc.oldmask)
268
            || (_NSIG_WORDS > 1
269
                && __copy_from_user(&set.sig[1], &frame->extramask,
270
                                    sizeof(frame->extramask))))
271
                goto badframe;
272
 
273
        sigdelsetmask(&set, ~_BLOCKABLE);
274
 
275
        spin_lock_irq(&current->sigmask_lock);
276
        current->blocked = set;
277
        recalc_sigpending(current);
278
        spin_unlock_irq(&current->sigmask_lock);
279
 
280
        if (restore_sigcontext(&regs, &frame->sc))
281
                goto badframe;
282
        return regs.regs[0];
283
 
284
badframe:
285
        force_sig(SIGSEGV, current);
286
        return 0;
287
}
288
 
289
asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
290
                                unsigned long r6, unsigned long r7,
291
                                struct pt_regs regs)
292
{
293
        struct rt_sigframe *frame = (struct rt_sigframe *)regs.regs[15];
294
        sigset_t set;
295
        stack_t st;
296
 
297
        if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
298
                goto badframe;
299
 
300
        if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
301
                goto badframe;
302
 
303
        sigdelsetmask(&set, ~_BLOCKABLE);
304
        spin_lock_irq(&current->sigmask_lock);
305
        current->blocked = set;
306
        recalc_sigpending(current);
307
        spin_unlock_irq(&current->sigmask_lock);
308
 
309
        if (restore_sigcontext(&regs, &frame->uc.uc_mcontext))
310
                goto badframe;
311
 
312
        if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
313
                goto badframe;
314
        /* It is more difficult to avoid calling this function than to
315
           call it and ignore errors.  */
316
        do_sigaltstack(&st, NULL, regs.regs[15]);
317
        return regs.regs[0];
318
 
319
badframe:
320
        force_sig(SIGSEGV, current);
321
        return 0;
322
}
323
 
324
/*
325
 * Set up a signal frame.
326
 */
327
 
328
static int
329
setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
330
                 unsigned long mask)
331
{
332
        int err = 0;
333
 
334
#define COPY(x)         err |= __put_user(regs->x, &sc->sc_##x)
335
        COPY(regs[0]);   COPY(regs[1]);
336
        COPY(regs[2]);  COPY(regs[3]);
337
        COPY(regs[4]);  COPY(regs[5]);
338
        COPY(regs[6]);  COPY(regs[7]);
339
        COPY(regs[8]);  COPY(regs[9]);
340
        COPY(regs[10]); COPY(regs[11]);
341
        COPY(regs[12]); COPY(regs[13]);
342
        COPY(regs[14]); COPY(regs[15]);
343
        COPY(gbr);      COPY(mach);
344
        COPY(macl);     COPY(pr);
345
        COPY(sr);       COPY(pc);
346
#undef COPY
347
 
348
#if defined(__SH4__)
349
        err |= save_sigcontext_fpu(sc);
350
#endif
351
 
352
        /* non-iBCS2 extensions.. */
353
        err |= __put_user(mask, &sc->oldmask);
354
 
355
        return err;
356
}
357
 
358
/*
359
 * Determine which stack to use..
360
 */
361
static inline void *
362
get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
363
{
364
        if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
365
                sp = current->sas_ss_sp + current->sas_ss_size;
366
 
367
        return (void *)((sp - frame_size) & -8ul);
368
}
369
 
370
static void setup_frame(int sig, struct k_sigaction *ka,
371
                        sigset_t *set, struct pt_regs *regs)
372
{
373
        struct sigframe *frame;
374
        int err = 0;
375
        int signal;
376
 
377
        frame = get_sigframe(ka, regs->regs[15], sizeof(*frame));
378
 
379
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
380
                goto give_sigsegv;
381
 
382
        signal = current->exec_domain
383
                && current->exec_domain->signal_invmap
384
                && sig < 32
385
                ? current->exec_domain->signal_invmap[sig]
386
                : sig;
387
 
388
        err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
389
 
390
        if (_NSIG_WORDS > 1) {
391
                err |= __copy_to_user(frame->extramask, &set->sig[1],
392
                                      sizeof(frame->extramask));
393
        }
394
 
395
        /* Set up to return from userspace.  If provided, use a stub
396
           already in userspace.  */
397
        if (ka->sa.sa_flags & SA_RESTORER) {
398
                regs->pr = (unsigned long) ka->sa.sa_restorer;
399
        } else {
400
                /* Generate return code (system call to sigreturn) */
401
                err |= __put_user(MOVW(7), &frame->retcode[0]);
402
                err |= __put_user(TRAP16, &frame->retcode[1]);
403
                err |= __put_user(OR_R0_R0, &frame->retcode[2]);
404
                err |= __put_user(OR_R0_R0, &frame->retcode[3]);
405
                err |= __put_user(OR_R0_R0, &frame->retcode[4]);
406
                err |= __put_user(OR_R0_R0, &frame->retcode[5]);
407
                err |= __put_user(OR_R0_R0, &frame->retcode[6]);
408
                err |= __put_user((__NR_sigreturn), &frame->retcode[7]);
409
                regs->pr = (unsigned long) frame->retcode;
410
        }
411
 
412
        if (err)
413
                goto give_sigsegv;
414
 
415
        /* Set up registers for signal handler */
416
        regs->regs[15] = (unsigned long) frame;
417
        regs->regs[4] = signal; /* Arg for signal handler */
418
        regs->regs[5] = 0;
419
        regs->regs[6] = (unsigned long) &frame->sc;
420
        regs->pc = (unsigned long) ka->sa.sa_handler;
421
 
422
        set_fs(USER_DS);
423
 
424
#if DEBUG_SIG
425
        printk("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
426
                current->comm, current->pid, frame, regs->pc, regs->pr);
427
#endif
428
 
429
        flush_cache_sigtramp(regs->pr);
430
        if ((-regs->pr & (L1_CACHE_BYTES-1)) < sizeof(frame->retcode))
431
                flush_cache_sigtramp(regs->pr + L1_CACHE_BYTES);
432
        return;
433
 
434
give_sigsegv:
435
        if (sig == SIGSEGV)
436
                ka->sa.sa_handler = SIG_DFL;
437
        force_sig(SIGSEGV, current);
438
}
439
 
440
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
441
                           sigset_t *set, struct pt_regs *regs)
442
{
443
        struct rt_sigframe *frame;
444
        int err = 0;
445
        int signal;
446
 
447
        frame = get_sigframe(ka, regs->regs[15], sizeof(*frame));
448
 
449
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
450
                goto give_sigsegv;
451
 
452
        signal = current->exec_domain
453
                && current->exec_domain->signal_invmap
454
                && sig < 32
455
                ? current->exec_domain->signal_invmap[sig]
456
                : sig;
457
 
458
        err |= copy_siginfo_to_user(&frame->info, info);
459
 
460
        /* Create the ucontext.  */
461
        err |= __put_user(0, &frame->uc.uc_flags);
462
        err |= __put_user(0, &frame->uc.uc_link);
463
        err |= __put_user((void *)current->sas_ss_sp,
464
                          &frame->uc.uc_stack.ss_sp);
465
        err |= __put_user(sas_ss_flags(regs->regs[15]),
466
                          &frame->uc.uc_stack.ss_flags);
467
        err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
468
        err |= setup_sigcontext(&frame->uc.uc_mcontext,
469
                                regs, set->sig[0]);
470
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
471
 
472
        /* Set up to return from userspace.  If provided, use a stub
473
           already in userspace.  */
474
        if (ka->sa.sa_flags & SA_RESTORER) {
475
                regs->pr = (unsigned long) ka->sa.sa_restorer;
476
        } else {
477
                /* Generate return code (system call to rt_sigreturn) */
478
                err |= __put_user(MOVW(7), &frame->retcode[0]);
479
                err |= __put_user(TRAP16, &frame->retcode[1]);
480
                err |= __put_user(OR_R0_R0, &frame->retcode[2]);
481
                err |= __put_user(OR_R0_R0, &frame->retcode[3]);
482
                err |= __put_user(OR_R0_R0, &frame->retcode[4]);
483
                err |= __put_user(OR_R0_R0, &frame->retcode[5]);
484
                err |= __put_user(OR_R0_R0, &frame->retcode[6]);
485
                err |= __put_user((__NR_rt_sigreturn), &frame->retcode[7]);
486
                regs->pr = (unsigned long) frame->retcode;
487
        }
488
 
489
        if (err)
490
                goto give_sigsegv;
491
 
492
        /* Set up registers (SP, PC, and args) for signal handler */
493
        regs->regs[15] = (unsigned long) frame;         /* Stack pointer */
494
        regs->regs[4] = signal;                         /* Arg1 (signal) */
495
        regs->regs[5] = (unsigned long)&frame->info;    /* Arg2 (siginfo) */
496
        regs->regs[6] = (unsigned long)&frame->uc;      /* Arg3 (context) */
497
        regs->pc = (unsigned long) ka->sa.sa_handler;   /* Program counter */
498
 
499
        set_fs(USER_DS);
500
 
501
#if DEBUG_SIG
502
        printk("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
503
                current->comm, current->pid, frame, regs->pc, regs->pr);
504
#endif
505
 
506
        flush_cache_sigtramp(regs->pr);
507
        if ((-regs->pr & (L1_CACHE_BYTES-1)) < sizeof(frame->retcode))
508
                flush_cache_sigtramp(regs->pr + L1_CACHE_BYTES);
509
        return;
510
 
511
give_sigsegv:
512
        if (sig == SIGSEGV)
513
                ka->sa.sa_handler = SIG_DFL;
514
        force_sig(SIGSEGV, current);
515
}
516
 
517
/*
518
 * OK, we're invoking a handler
519
 */
520
 
521
static void
522
handle_signal(unsigned long sig, struct k_sigaction *ka,
523
              siginfo_t *info, sigset_t *oldset, struct pt_regs *regs,
524
              int from_syscall, unsigned long orig_r0)
525
{
526
        /* Are we from a system call? */
527
        if (from_syscall) {
528
                /* If so, check system call restarting.. */
529
                switch (regs->regs[0]) {
530
                        case -ERESTARTNOHAND:
531
                                regs->regs[0] = -EINTR;
532
                                break;
533
 
534
                        case -ERESTARTSYS:
535
                                if (!(ka->sa.sa_flags & SA_RESTART)) {
536
                                        regs->regs[0] = -EINTR;
537
                                        break;
538
                                }
539
                        /* fallthrough */
540
                        case -ERESTARTNOINTR:
541
                                regs->regs[0] = orig_r0;
542
                                regs->pc -= 2;
543
                }
544
        } else {
545
                /* gUSA handling */
546
                if (regs->regs[15] >= 0xc0000000) {
547
                        int offset = (int)regs->regs[15];
548
 
549
                        /* Reset stack pointer: clear critical region mark */
550
                        regs->regs[15] = regs->regs[1];
551
                        if (regs->pc < regs->regs[0])
552
                                /* Go to rewind point #1 */
553
                                regs->pc = regs->regs[0] + offset - 2;
554
                }
555
        }
556
 
557
        /* Set up the stack frame */
558
        if (ka->sa.sa_flags & SA_SIGINFO)
559
                setup_rt_frame(sig, ka, info, oldset, regs);
560
        else
561
                setup_frame(sig, ka, oldset, regs);
562
 
563
        if (ka->sa.sa_flags & SA_ONESHOT)
564
                ka->sa.sa_handler = SIG_DFL;
565
 
566
        if (!(ka->sa.sa_flags & SA_NODEFER)) {
567
                spin_lock_irq(&current->sigmask_lock);
568
                sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
569
                sigaddset(&current->blocked,sig);
570
                recalc_sigpending(current);
571
                spin_unlock_irq(&current->sigmask_lock);
572
        }
573
}
574
 
575
/*
576
 * Note that 'init' is a special process: it doesn't get signals it doesn't
577
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
578
 * mistake.
579
 *
580
 * Note that we go through the signals twice: once to check the signals that
581
 * the kernel can handle, and then we build all the user-level signal handling
582
 * stack-frames in one go after that.
583
 */
584
int do_signal(struct pt_regs *regs, sigset_t *oldset,
585
              int from_syscall, unsigned long orig_r0)
586
{
587
        siginfo_t info;
588
        struct k_sigaction *ka;
589
 
590
        /*
591
         * We want the common case to go fast, which
592
         * is why we may in certain cases get here from
593
         * kernel mode. Just return without doing anything
594
         * if so.
595
         */
596
        if (!user_mode(regs))
597
                return 1;
598
 
599
        if (!oldset)
600
                oldset = &current->blocked;
601
 
602
        for (;;) {
603
                unsigned long signr;
604
 
605
                spin_lock_irq(&current->sigmask_lock);
606
                signr = dequeue_signal(&current->blocked, &info);
607
                spin_unlock_irq(&current->sigmask_lock);
608
 
609
                if (!signr)
610
                        break;
611
 
612
                if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
613
                        /* Let the debugger run.  */
614
                        current->exit_code = signr;
615
                        current->state = TASK_STOPPED;
616
                        notify_parent(current, SIGCHLD);
617
                        schedule();
618
 
619
                        /* We're back.  Did the debugger cancel the sig?  */
620
                        if (!(signr = current->exit_code))
621
                                continue;
622
                        current->exit_code = 0;
623
 
624
                        /* The debugger continued.  Ignore SIGSTOP.  */
625
                        if (signr == SIGSTOP)
626
                                continue;
627
 
628
                        /* Update the siginfo structure.  Is this good?  */
629
                        if (signr != info.si_signo) {
630
                                info.si_signo = signr;
631
                                info.si_errno = 0;
632
                                info.si_code = SI_USER;
633
                                info.si_pid = current->p_pptr->pid;
634
                                info.si_uid = current->p_pptr->uid;
635
                        }
636
 
637
                        /* If the (new) signal is now blocked, requeue it.  */
638
                        if (sigismember(&current->blocked, signr)) {
639
                                send_sig_info(signr, &info, current);
640
                                continue;
641
                        }
642
                }
643
 
644
                ka = &current->sig->action[signr-1];
645
                if (ka->sa.sa_handler == SIG_IGN) {
646
                        if (signr != SIGCHLD)
647
                                continue;
648
                        /* Check for SIGCHLD: it's special.  */
649
                        while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
650
                                /* nothing */;
651
                        continue;
652
                }
653
 
654
                if (ka->sa.sa_handler == SIG_DFL) {
655
                        int exit_code = signr;
656
 
657
                        /* Init gets no signals it doesn't want.  */
658
                        if (current->pid == 1)
659
                                continue;
660
 
661
                        switch (signr) {
662
                        case SIGCONT: case SIGCHLD: case SIGWINCH:
663
                                continue;
664
 
665
                        case SIGTSTP: case SIGTTIN: case SIGTTOU:
666
                                if (is_orphaned_pgrp(current->pgrp))
667
                                        continue;
668
                                /* FALLTHRU */
669
 
670
                        case SIGSTOP:
671
                                current->state = TASK_STOPPED;
672
                                current->exit_code = signr;
673
                                if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
674
                                        notify_parent(current, SIGCHLD);
675
                                schedule();
676
                                continue;
677
 
678
                        case SIGQUIT: case SIGILL: case SIGTRAP:
679
                        case SIGABRT: case SIGFPE: case SIGSEGV:
680
                        case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
681
                                if (do_coredump(signr, regs))
682
                                        exit_code |= 0x80;
683
                                /* FALLTHRU */
684
 
685
                        default:
686
                                sig_exit(signr, exit_code, &info);
687
                                /* NOTREACHED */
688
                        }
689
                }
690
 
691
                /* Whee!  Actually deliver the signal.  */
692
                handle_signal(signr, ka, &info, oldset, regs,
693
                              from_syscall, orig_r0);
694
                return 1;
695
        }
696
 
697
        /* Did we come from a system call? */
698
        if (from_syscall) {
699
                /* Restart the system call - no handlers present */
700
                if (regs->regs[0] == -ERESTARTNOHAND ||
701
                    regs->regs[0] == -ERESTARTSYS ||
702
                    regs->regs[0] == -ERESTARTNOINTR) {
703
                        regs->regs[0] = orig_r0;
704
                        regs->pc -= 2;
705
                }
706
        }
707
        return 0;
708
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.