1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1991, 1992 Linus Torvalds 7 * Copyright (C) 1994 - 1999 Ralf Baechle 8 * Copyright (C) 1999 Silicon Graphics, Inc. 9 */ 10#include <linux/config.h> 11#include <linux/sched.h> 12#include <linux/mm.h> 13#include <linux/smp.h> 14#include <linux/smp_lock.h> 15#include <linux/kernel.h> 16#include <linux/personality.h> 17#include <linux/signal.h> 18#include <linux/errno.h> 19#include <linux/wait.h> 20#include <linux/unistd.h> 21 22#include <asm/asm.h> 23#include <asm/bitops.h> 24#include <asm/cpu.h> 25#include <asm/fpu.h> 26#include <asm/offset.h> 27#include <asm/pgalloc.h> 28#include <asm/ptrace.h> 29#include <asm/uaccess.h> 30#include <asm/ucontext.h> 31 32#define DEBUG_SIG 0 33 34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 35 36extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); 37 38extern asmlinkage void syscall_trace(void); 39 40int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) 41{ 42 if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) 43 return -EFAULT; 44 if (from->si_code < 0) 45 return __copy_to_user(to, from, sizeof(siginfo_t)); 46 else { 47 int err; 48 49 /* If you change siginfo_t structure, please be sure 50 this code is fixed accordingly. 51 It should never copy any pad contained in the structure 52 to avoid security leaks, but must copy the generic 53 3 ints plus the relevant union member. */ 54 err = __put_user(from->si_signo, &to->si_signo); 55 err |= __put_user(from->si_errno, &to->si_errno); 56 err |= __put_user((short)from->si_code, &to->si_code); 57 /* First 32bits of unions are always present. */ 58 err |= __put_user(from->si_pid, &to->si_pid); 59 switch (from->si_code >> 16) { 60 case __SI_FAULT >> 16: 61 break; 62 case __SI_CHLD >> 16: 63 err |= __put_user(from->si_utime, &to->si_utime); 64 err |= __put_user(from->si_stime, &to->si_stime); 65 err |= __put_user(from->si_status, &to->si_status); 66 default: 67 err |= __put_user(from->si_uid, &to->si_uid); 68 break; 69 /* case __SI_RT: This is not generated by the kernel as of now. */ 70 } 71 return err; 72 } 73} 74 75/* 76 * Atomically swap in the new signal mask, and wait for a signal. 77 */ 78save_static_function(sys_sigsuspend); 79static_unused int _sys_sigsuspend(struct pt_regs regs) 80{ 81 sigset_t *uset, saveset, newset; 82 83 uset = (sigset_t *) regs.regs[4]; 84 if (copy_from_user(&newset, uset, sizeof(sigset_t))) 85 return -EFAULT; 86 sigdelsetmask(&newset, ~_BLOCKABLE); 87 88 spin_lock_irq(¤t->sigmask_lock); 89 saveset = current->blocked; 90 current->blocked = newset; 91 recalc_sigpending(current); 92 spin_unlock_irq(¤t->sigmask_lock); 93 94 regs.regs[2] = EINTR; 95 regs.regs[7] = 1; 96 while (1) { 97 current->state = TASK_INTERRUPTIBLE; 98 schedule(); 99 if (do_signal(&saveset, ®s)) 100 return -EINTR; 101 } 102} 103 104save_static_function(sys_rt_sigsuspend); 105static_unused int _sys_rt_sigsuspend(struct pt_regs regs) 106{ 107 sigset_t *unewset, saveset, newset; 108 size_t sigsetsize; 109 110 sigsetsize = regs.regs[5]; 111 if (sigsetsize != sizeof(sigset_t)) 112 return -EINVAL; 113 114 unewset = (sigset_t *) regs.regs[4]; 115 if (copy_from_user(&newset, unewset, sizeof(newset))) 116 return -EFAULT; 117 sigdelsetmask(&newset, ~_BLOCKABLE); 118 119 spin_lock_irq(¤t->sigmask_lock); 120 saveset = current->blocked; 121 current->blocked = newset; 122 recalc_sigpending(current); 123 spin_unlock_irq(¤t->sigmask_lock); 124 125 regs.regs[2] = EINTR; 126 regs.regs[7] = 1; 127 while (1) { 128 current->state = TASK_INTERRUPTIBLE; 129 schedule(); 130 if (do_signal(&saveset, ®s)) 131 return -EINTR; 132 } 133} 134 135asmlinkage int sys_sigaction(int sig, const struct sigaction *act, 136 struct sigaction *oact) 137{ 138 struct k_sigaction new_ka, old_ka; 139 int ret; 140 int err = 0; 141 142 if (act) { 143 old_sigset_t mask; 144 145 if (!access_ok(VERIFY_READ, act, sizeof(*act))) 146 return -EFAULT; 147 err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler); 148 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); 149 err |= __get_user(mask, &act->sa_mask.sig[0]); 150 err |= __get_user(new_ka.sa.sa_restorer, &act->sa_restorer); 151 if (err) 152 return -EFAULT; 153 154 siginitset(&new_ka.sa.sa_mask, mask); 155 } 156 157 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 158 159 if (!ret && oact) { 160 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact))) 161 return -EFAULT; 162 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 163 err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler); 164 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig); 165 err |= __put_user(0, &oact->sa_mask.sig[1]); 166 err |= __put_user(0, &oact->sa_mask.sig[2]); 167 err |= __put_user(0, &oact->sa_mask.sig[3]); 168 err |= __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer); 169 if (err) 170 return -EFAULT; 171 } 172 173 return ret; 174} 175 176asmlinkage int sys_sigaltstack(struct pt_regs regs) 177{ 178 const stack_t *uss = (const stack_t *) regs.regs[4]; 179 stack_t *uoss = (stack_t *) regs.regs[5]; 180 unsigned long usp = regs.regs[29]; 181 182 return do_sigaltstack(uss, uoss, usp); 183} 184 185static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) 186{ 187 int err = 0; 188 u64 reg; 189 190 err |= __get_user(regs->cp0_epc, &sc->sc_pc); 191 192 err |= __get_user(reg, &sc->sc_mdhi); 193 regs->hi = (int) reg; 194 err |= __get_user(reg, &sc->sc_mdlo); 195 regs->lo = (int) reg; 196 197#define restore_gp_reg(i) do { \ 198 err |= __get_user(reg, &sc->sc_regs[i]); \ 199 regs->regs[i] = reg; \ 200} while(0) 201 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3); 202 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6); 203 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9); 204 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12); 205 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15); 206 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18); 207 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21); 208 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24); 209 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27); 210 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30); 211 restore_gp_reg(31); 212#undef restore_gp_reg 213 214 err |= __get_user(current->used_math, &sc->sc_used_math); 215 216 if (current->used_math) { 217 /* restore fpu context if we have used it before */ 218 own_fpu(); 219 err |= restore_fp_context(sc); 220 } else { 221 /* signal handler may have used FPU. Give it up. */ 222 loose_fpu(); 223 } 224 225 return err; 226} 227 228struct sigframe { 229 u32 sf_ass[4]; /* argument save space for o32 */ 230 u32 sf_code[2]; /* signal trampoline */ 231 struct sigcontext sf_sc; 232 sigset_t sf_mask; 233}; 234 235struct rt_sigframe { 236 u32 rs_ass[4]; /* argument save space for o32 */ 237 u32 rs_code[2]; /* signal trampoline */ 238 struct siginfo rs_info; 239 struct ucontext rs_uc; 240}; 241 242asmlinkage void sys_sigreturn(struct pt_regs regs) 243{ 244 struct sigframe *frame; 245 sigset_t blocked; 246 247 frame = (struct sigframe *) regs.regs[29]; 248 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 249 goto badframe; 250 if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked))) 251 goto badframe; 252 253 sigdelsetmask(&blocked, ~_BLOCKABLE); 254 spin_lock_irq(¤t->sigmask_lock); 255 current->blocked = blocked; 256 recalc_sigpending(current); 257 spin_unlock_irq(¤t->sigmask_lock); 258 259 if (restore_sigcontext(®s, &frame->sf_sc)) 260 goto badframe; 261 262 /* 263 * Don't let your children do this ... 264 */ 265 if (current->ptrace & PT_TRACESYS) 266 syscall_trace(); 267 __asm__ __volatile__( 268 "move\t$29, %0\n\t" 269 "j\tret_from_sys_call" 270 :/* no outputs */ 271 :"r" (®s)); 272 /* Unreached */ 273 274badframe: 275 force_sig(SIGSEGV, current); 276} 277 278asmlinkage void sys_rt_sigreturn(struct pt_regs regs) 279{ 280 struct rt_sigframe *frame; 281 sigset_t set; 282 stack_t st; 283 284 frame = (struct rt_sigframe *) regs.regs[29]; 285 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 286 goto badframe; 287 if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) 288 goto badframe; 289 290 sigdelsetmask(&set, ~_BLOCKABLE); 291 spin_lock_irq(¤t->sigmask_lock); 292 current->blocked = set; 293 recalc_sigpending(current); 294 spin_unlock_irq(¤t->sigmask_lock); 295 296 if (restore_sigcontext(®s, &frame->rs_uc.uc_mcontext)) 297 goto badframe; 298 299 if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st))) 300 goto badframe; 301 /* It is more difficult to avoid calling this function than to 302 call it and ignore errors. */ 303 do_sigaltstack(&st, NULL, regs.regs[29]); 304 305 /* 306 * Don't let your children do this ... 307 */ 308 __asm__ __volatile__( 309 "move\t$29, %0\n\t" 310 "j\tret_from_sys_call" 311 :/* no outputs */ 312 :"r" (®s)); 313 /* Unreached */ 314 315badframe: 316 force_sig(SIGSEGV, current); 317} 318 319static int inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) 320{ 321 int err = 0; 322 u64 reg; 323 324 reg = regs->cp0_epc; err |= __put_user(reg, &sc->sc_pc); 325 err |= __put_user(regs->cp0_status, &sc->sc_status); 326 327#define save_gp_reg(i) { \ 328 reg = regs->regs[i]; \ 329 err |= __put_user(reg, &sc->sc_regs[i]); \ 330} while(0) 331 reg = 0; err |= __put_user(reg, &sc->sc_regs[0]); 332 save_gp_reg(1); save_gp_reg(2); 333 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6); 334 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10); 335 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14); 336 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18); 337 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22); 338 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26); 339 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30); 340 save_gp_reg(31); 341#undef save_gp_reg 342 343 reg = regs->hi; err |= __put_user(reg, &sc->sc_mdhi); 344 reg = regs->lo; err |= __put_user(reg, &sc->sc_mdlo); 345 err |= __put_user(regs->cp0_cause, &sc->sc_cause); 346 err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); 347 348 err |= __put_user(current->used_math, &sc->sc_used_math); 349 350 if (!current->used_math) 351 goto out; 352 353 /* 354 * Save FPU state to signal context. Signal handler will "inherit" 355 * current FPU state. 356 */ 357 if (!is_fpu_owner()) { 358 own_fpu(); 359 restore_fp(current); 360 } 361 err |= save_fp_context(sc); 362 363out: 364 return err; 365} 366 367/* 368 * Determine which stack to use.. 369 */ 370static inline void * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, 371 size_t frame_size) 372{ 373 unsigned long sp; 374 375 /* Default to using normal stack */ 376 sp = regs->regs[29]; 377 378 /* 379 * FPU emulator may have it's own trampoline active just 380 * above the user stack, 16-bytes before the next lowest 381 * 16 byte boundary. Try to avoid trashing it. 382 */ 383 sp -= 32; 384 385 /* This is the X/Open sanctioned signal stack switching. */ 386 if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp)) 387 sp = current->sas_ss_sp + current->sas_ss_size; 388 389 return (void *)((sp - frame_size) & ALMASK); 390} 391 392static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs, 393 int signr, sigset_t *set) 394{ 395 struct sigframe *frame; 396 int err = 0; 397 398 frame = get_sigframe(ka, regs, sizeof(*frame)); 399 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) 400 goto give_sigsegv; 401 402 /* Set up to return from userspace. If provided, use a stub already 403 in userspace. */ 404 if (ka->sa.sa_flags & SA_RESTORER) 405 regs->regs[31] = (unsigned long) ka->sa.sa_restorer; 406 else { 407 /* 408 * Set up the return code ... 409 * 410 * li v0, __NR_sigreturn 411 * syscall 412 */ 413 err |= __put_user(0x24020000 + __NR_sigreturn, 414 frame->sf_code + 0); 415 err |= __put_user(0x0000000c , 416 frame->sf_code + 1); 417 flush_cache_sigtramp((unsigned long) frame->sf_code); 418 } 419 420 err |= setup_sigcontext(regs, &frame->sf_sc); 421 err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); 422 if (err) 423 goto give_sigsegv; 424 425 /* 426 * Arguments to signal handler: 427 * 428 * a0 = signal number 429 * a1 = 0 (should be cause) 430 * a2 = pointer to struct sigcontext 431 * 432 * $25 and c0_epc point to the signal handler, $29 points to the 433 * struct sigframe. 434 */ 435 regs->regs[ 4] = signr; 436 regs->regs[ 5] = 0; 437 regs->regs[ 6] = (unsigned long) &frame->sf_sc; 438 regs->regs[29] = (unsigned long) frame; 439 regs->regs[31] = (unsigned long) frame->sf_code; 440 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; 441 442#if DEBUG_SIG 443 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", 444 current->comm, current->pid, 445 frame, regs->cp0_epc, frame->sf_code); 446#endif 447 return; 448 449give_sigsegv: 450 if (signr == SIGSEGV) 451 ka->sa.sa_handler = SIG_DFL; 452 force_sig(SIGSEGV, current); 453} 454 455static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, 456 int signr, sigset_t *set, siginfo_t *info) 457{ 458 struct rt_sigframe *frame; 459 int err = 0; 460 461 frame = get_sigframe(ka, regs, sizeof(*frame)); 462 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) 463 goto give_sigsegv; 464 465 /* Set up to return from userspace. If provided, use a stub already 466 in userspace. */ 467 if (ka->sa.sa_flags & SA_RESTORER) 468 regs->regs[31] = (unsigned long) ka->sa.sa_restorer; 469 else { 470 /* 471 * Set up the return code ... 472 * 473 * li v0, __NR_rt_sigreturn 474 * syscall 475 */ 476 err |= __put_user(0x24020000 + __NR_rt_sigreturn, 477 frame->rs_code + 0); 478 err |= __put_user(0x0000000c , 479 frame->rs_code + 1); 480 flush_cache_sigtramp((unsigned long) frame->rs_code); 481 } 482 483 /* Create siginfo. */ 484 err |= copy_siginfo_to_user(&frame->rs_info, info); 485 486 /* Create the ucontext. */ 487 err |= __put_user(0, &frame->rs_uc.uc_flags); 488 err |= __put_user(0, &frame->rs_uc.uc_link); 489 err |= __put_user((void *)current->sas_ss_sp, 490 &frame->rs_uc.uc_stack.ss_sp); 491 err |= __put_user(sas_ss_flags(regs->regs[29]), 492 &frame->rs_uc.uc_stack.ss_flags); 493 err |= __put_user(current->sas_ss_size, 494 &frame->rs_uc.uc_stack.ss_size); 495 err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext); 496 err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set)); 497 498 if (err) 499 goto give_sigsegv; 500 501 /* 502 * Arguments to signal handler: 503 * 504 * a0 = signal number 505 * a1 = 0 (should be cause) 506 * a2 = pointer to ucontext 507 * 508 * $25 and c0_epc point to the signal handler, $29 points to 509 * the struct rt_sigframe. 510 */ 511 regs->regs[ 4] = signr; 512 regs->regs[ 5] = (unsigned long) &frame->rs_info; 513 regs->regs[ 6] = (unsigned long) &frame->rs_uc; 514 regs->regs[29] = (unsigned long) frame; 515 regs->regs[31] = (unsigned long) frame->rs_code; 516 regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; 517 518#if DEBUG_SIG 519 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", 520 current->comm, current->pid, 521 frame, regs->cp0_epc, frame->rs_code); 522#endif 523 return; 524 525give_sigsegv: 526 if (signr == SIGSEGV) 527 ka->sa.sa_handler = SIG_DFL; 528 force_sig(SIGSEGV, current); 529} 530 531static inline void handle_signal(unsigned long sig, struct k_sigaction *ka, 532 siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) 533{ 534 if (ka->sa.sa_flags & SA_SIGINFO) 535 setup_rt_frame(ka, regs, sig, oldset, info); 536 else 537 setup_frame(ka, regs, sig, oldset); 538 539 if (ka->sa.sa_flags & SA_ONESHOT) 540 ka->sa.sa_handler = SIG_DFL; 541 if (!(ka->sa.sa_flags & SA_NODEFER)) { 542 spin_lock_irq(¤t->sigmask_lock); 543 sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); 544 sigaddset(¤t->blocked,sig); 545 recalc_sigpending(current); 546 spin_unlock_irq(¤t->sigmask_lock); 547 } 548} 549 550static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) 551{ 552 switch(regs->regs[0]) { 553 case ERESTARTNOHAND: 554 regs->regs[2] = EINTR; 555 break; 556 case ERESTARTSYS: 557 if(!(ka->sa.sa_flags & SA_RESTART)) { 558 regs->regs[2] = EINTR; 559 break; 560 } 561 /* fallthrough */ 562 case ERESTARTNOINTR: /* Userland will reload $v0. */ 563 regs->regs[7] = regs->regs[26]; 564 regs->cp0_epc -= 8; 565 } 566 567 regs->regs[0] = 0; /* Don't deal with this again. */ 568} 569 570extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs); 571 572asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) 573{ 574 struct k_sigaction *ka; 575 siginfo_t info; 576 577#ifdef CONFIG_BINFMT_IRIX 578 if (current->personality != PER_LINUX) 579 return do_irix_signal(oldset, regs); 580#endif 581 582 if (!oldset) 583 oldset = ¤t->blocked; 584 585 for (;;) { 586 unsigned long signr; 587 588 spin_lock_irq(¤t->sigmask_lock); 589 signr = dequeue_signal(¤t->blocked, &info); 590 spin_unlock_irq(¤t->sigmask_lock); 591 592 if (!signr) 593 break; 594 595 if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { 596 /* Let the debugger run. */ 597 current->exit_code = signr; 598 current->state = TASK_STOPPED; 599 notify_parent(current, SIGCHLD); 600 schedule(); 601 602 /* We're back. Did the debugger cancel the sig? */ 603 if (!(signr = current->exit_code)) 604 continue; 605 current->exit_code = 0; 606 607 /* The debugger continued. Ignore SIGSTOP. */ 608 if (signr == SIGSTOP) 609 continue; 610 611 /* Update the siginfo structure. Is this good? */ 612 if (signr != info.si_signo) { 613 info.si_signo = signr; 614 info.si_errno = 0; 615 info.si_code = SI_USER; 616 info.si_pid = current->p_pptr->pid; 617 info.si_uid = current->p_pptr->uid; 618 } 619 620 /* If the (new) signal is now blocked, requeue it. */ 621 if (sigismember(¤t->blocked, signr)) { 622 send_sig_info(signr, &info, current); 623 continue; 624 } 625 } 626 627 ka = ¤t->sig->action[signr-1]; 628 if (ka->sa.sa_handler == SIG_IGN) { 629 if (signr != SIGCHLD) 630 continue; 631 /* Check for SIGCHLD: it's special. */ 632 while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0) 633 /* nothing */; 634 continue; 635 } 636 637 if (ka->sa.sa_handler == SIG_DFL) { 638 int exit_code = signr; 639 640 /* Init gets no signals it doesn't want. */ 641 if (current->pid == 1) 642 continue; 643 644 switch (signr) { 645 case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG: 646 continue; 647 648 case SIGTSTP: case SIGTTIN: case SIGTTOU: 649 if (is_orphaned_pgrp(current->pgrp)) 650 continue; 651 /* FALLTHRU */ 652 653 case SIGSTOP: 654 current->state = TASK_STOPPED; 655 current->exit_code = signr; 656 if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) 657 notify_parent(current, SIGCHLD); 658 schedule(); 659 continue; 660 661 case SIGQUIT: case SIGILL: case SIGTRAP: 662 case SIGABRT: case SIGFPE: case SIGSEGV: 663 case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: 664 if (do_coredump(signr, regs)) 665 exit_code |= 0x80; 666 /* FALLTHRU */ 667 668 default: 669 sig_exit(signr, exit_code, &info); 670 /* NOTREACHED */ 671 } 672 } 673 674 if (regs->regs[0]) 675 syscall_restart(regs, ka); 676 /* Whee! Actually deliver the signal. */ 677 handle_signal(signr, ka, &info, oldset, regs); 678 return 1; 679 } 680 681 /* 682 * Who's code doesn't conform to the restartable syscall convention 683 * dies here!!! The li instruction, a single machine instruction, 684 * must directly be followed by the syscall instruction. 685 */ 686 if (regs->regs[0]) { 687 if (regs->regs[2] == ERESTARTNOHAND || 688 regs->regs[2] == ERESTARTSYS || 689 regs->regs[2] == ERESTARTNOINTR) { 690 regs->regs[7] = regs->regs[26]; 691 regs->cp0_epc -= 8; 692 } 693 } 694 return 0; 695} 696