ia32_signal.c (150631) | ia32_signal.c (151316) |
---|---|
1/*- 2 * Copyright (c) 2003 Peter Wemm 3 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * William Jolitz. 8 * --- 18 unchanged lines hidden (view full) --- 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003 Peter Wemm 3 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * William Jolitz. 8 * --- 18 unchanged lines hidden (view full) --- 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#include <sys/cdefs.h> |
35__FBSDID("$FreeBSD: head/sys/amd64/ia32/ia32_signal.c 150631 2005-09-27 18:04:20Z peter $"); | 35__FBSDID("$FreeBSD: head/sys/amd64/ia32/ia32_signal.c 151316 2005-10-14 12:43:47Z davidxu $"); |
36 37#include "opt_compat.h" 38 39#include <sys/param.h> 40#include <sys/exec.h> 41#include <sys/fcntl.h> 42#include <sys/imgact.h> 43#include <sys/kernel.h> --- 30 unchanged lines hidden (view full) --- 74#include <machine/segments.h> 75#include <machine/specialreg.h> 76#include <machine/frame.h> 77#include <machine/md_var.h> 78#include <machine/pcb.h> 79#include <machine/cpufunc.h> 80 81#ifdef COMPAT_FREEBSD4 | 36 37#include "opt_compat.h" 38 39#include <sys/param.h> 40#include <sys/exec.h> 41#include <sys/fcntl.h> 42#include <sys/imgact.h> 43#include <sys/kernel.h> --- 30 unchanged lines hidden (view full) --- 74#include <machine/segments.h> 75#include <machine/specialreg.h> 76#include <machine/frame.h> 77#include <machine/md_var.h> 78#include <machine/pcb.h> 79#include <machine/cpufunc.h> 80 81#ifdef COMPAT_FREEBSD4 |
82static void freebsd4_ia32_sendsig(sig_t, int, sigset_t *, u_long); | 82static void freebsd4_ia32_sendsig(sig_t, ksiginfo_t *, sigset_t *); |
83#endif 84static void ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp); 85static int ia32_set_fpcontext(struct thread *td, const struct ia32_mcontext *mcp); 86 87extern int _ucode32sel, _udatasel; 88 89#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL) 90#define EFL_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) --- 199 unchanged lines hidden (view full) --- 290 * at top to call routine, followed by kcall 291 * to sigreturn routine below. After sigreturn 292 * resets the signal mask, the stack, and the 293 * frame pointer, it returns to the user 294 * specified pc, psl. 295 */ 296#ifdef COMPAT_FREEBSD4 297static void | 83#endif 84static void ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp); 85static int ia32_set_fpcontext(struct thread *td, const struct ia32_mcontext *mcp); 86 87extern int _ucode32sel, _udatasel; 88 89#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL) 90#define EFL_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) --- 199 unchanged lines hidden (view full) --- 290 * at top to call routine, followed by kcall 291 * to sigreturn routine below. After sigreturn 292 * resets the signal mask, the stack, and the 293 * frame pointer, it returns to the user 294 * specified pc, psl. 295 */ 296#ifdef COMPAT_FREEBSD4 297static void |
298freebsd4_ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) | 298freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) |
299{ 300 struct ia32_sigframe4 sf, *sfp; | 299{ 300 struct ia32_sigframe4 sf, *sfp; |
301 struct ia32_siginfo siginfo; |
|
301 struct proc *p; 302 struct thread *td; 303 struct sigacts *psp; 304 struct trapframe *regs; 305 int oonstack; | 302 struct proc *p; 303 struct thread *td; 304 struct sigacts *psp; 305 struct trapframe *regs; 306 int oonstack; |
307 int sig; |
|
306 307 td = curthread; 308 p = td->td_proc; | 308 309 td = curthread; 310 p = td->td_proc; |
311 siginfo_to_ia32siginfo(&ksi->ksi_info, &siginfo); 312 |
|
309 PROC_LOCK_ASSERT(p, MA_OWNED); | 313 PROC_LOCK_ASSERT(p, MA_OWNED); |
314 sig = siginfo.si_signo; |
|
310 psp = p->p_sigacts; 311 mtx_assert(&psp->ps_mtx, MA_OWNED); 312 regs = td->td_frame; 313 oonstack = sigonstack(regs->tf_rsp); 314 315 /* Save user context. */ 316 bzero(&sf, sizeof(sf)); 317 sf.sf_uc.uc_sigmask = *mask; --- 39 unchanged lines hidden (view full) --- 357 sf.sf_signum = sig; 358 sf.sf_ucontext = (register_t)&sfp->sf_uc; 359 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 360 /* Signal handler installed with SA_SIGINFO. */ 361 sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si; 362 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 363 364 /* Fill in POSIX parts */ | 315 psp = p->p_sigacts; 316 mtx_assert(&psp->ps_mtx, MA_OWNED); 317 regs = td->td_frame; 318 oonstack = sigonstack(regs->tf_rsp); 319 320 /* Save user context. */ 321 bzero(&sf, sizeof(sf)); 322 sf.sf_uc.uc_sigmask = *mask; --- 39 unchanged lines hidden (view full) --- 362 sf.sf_signum = sig; 363 sf.sf_ucontext = (register_t)&sfp->sf_uc; 364 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 365 /* Signal handler installed with SA_SIGINFO. */ 366 sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si; 367 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 368 369 /* Fill in POSIX parts */ |
370 sf.sf_si = siginfo; |
|
365 sf.sf_si.si_signo = sig; | 371 sf.sf_si.si_signo = sig; |
366 sf.sf_si.si_code = code; 367 sf.sf_si.si_addr = regs->tf_addr; | |
368 } else { 369 /* Old FreeBSD-style arguments. */ | 372 } else { 373 /* Old FreeBSD-style arguments. */ |
370 sf.sf_siginfo = code; 371 sf.sf_addr = regs->tf_addr; | 374 sf.sf_siginfo = siginfo.si_code; 375 sf.sf_addr = (u_int32_t)siginfo.si_addr; |
372 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 373 } 374 mtx_unlock(&psp->ps_mtx); 375 376 /* 377 * Copy the sigframe out to the user's stack. 378 */ 379 if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { --- 15 unchanged lines hidden (view full) --- 395 td->td_pcb->pcb_es = _udatasel; 396 /* leave user %fs and %gs untouched */ 397 PROC_LOCK(p); 398 mtx_lock(&psp->ps_mtx); 399} 400#endif /* COMPAT_FREEBSD4 */ 401 402void | 376 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 377 } 378 mtx_unlock(&psp->ps_mtx); 379 380 /* 381 * Copy the sigframe out to the user's stack. 382 */ 383 if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { --- 15 unchanged lines hidden (view full) --- 399 td->td_pcb->pcb_es = _udatasel; 400 /* leave user %fs and %gs untouched */ 401 PROC_LOCK(p); 402 mtx_lock(&psp->ps_mtx); 403} 404#endif /* COMPAT_FREEBSD4 */ 405 406void |
403ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) | 407ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) |
404{ 405 struct ia32_sigframe sf, *sfp; | 408{ 409 struct ia32_sigframe sf, *sfp; |
410 struct ia32_siginfo siginfo; |
|
406 struct proc *p; 407 struct thread *td; 408 struct sigacts *psp; 409 char *sp; 410 struct trapframe *regs; 411 int oonstack; | 411 struct proc *p; 412 struct thread *td; 413 struct sigacts *psp; 414 char *sp; 415 struct trapframe *regs; 416 int oonstack; |
417 int sig; |
|
412 | 418 |
419 siginfo_to_ia32siginfo(&ksi->ksi_info, &siginfo); |
|
413 td = curthread; 414 p = td->td_proc; 415 PROC_LOCK_ASSERT(p, MA_OWNED); | 420 td = curthread; 421 p = td->td_proc; 422 PROC_LOCK_ASSERT(p, MA_OWNED); |
423 sig = siginfo.si_signo; |
|
416 psp = p->p_sigacts; 417#ifdef COMPAT_FREEBSD4 418 if (SIGISMEMBER(psp->ps_freebsd4, sig)) { | 424 psp = p->p_sigacts; 425#ifdef COMPAT_FREEBSD4 426 if (SIGISMEMBER(psp->ps_freebsd4, sig)) { |
419 freebsd4_ia32_sendsig(catcher, sig, mask, code); | 427 freebsd4_ia32_sendsig(catcher, ksi, mask); |
420 return; 421 } 422#endif 423 mtx_assert(&psp->ps_mtx, MA_OWNED); 424 regs = td->td_frame; 425 oonstack = sigonstack(regs->tf_rsp); 426 427 /* Save user context. */ --- 46 unchanged lines hidden (view full) --- 474 sf.sf_signum = sig; 475 sf.sf_ucontext = (register_t)&sfp->sf_uc; 476 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 477 /* Signal handler installed with SA_SIGINFO. */ 478 sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si; 479 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 480 481 /* Fill in POSIX parts */ | 428 return; 429 } 430#endif 431 mtx_assert(&psp->ps_mtx, MA_OWNED); 432 regs = td->td_frame; 433 oonstack = sigonstack(regs->tf_rsp); 434 435 /* Save user context. */ --- 46 unchanged lines hidden (view full) --- 482 sf.sf_signum = sig; 483 sf.sf_ucontext = (register_t)&sfp->sf_uc; 484 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 485 /* Signal handler installed with SA_SIGINFO. */ 486 sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si; 487 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 488 489 /* Fill in POSIX parts */ |
490 sf.sf_si = siginfo; |
|
482 sf.sf_si.si_signo = sig; | 491 sf.sf_si.si_signo = sig; |
483 sf.sf_si.si_code = code; 484 sf.sf_si.si_addr = regs->tf_addr; | |
485 } else { 486 /* Old FreeBSD-style arguments. */ | 492 } else { 493 /* Old FreeBSD-style arguments. */ |
487 sf.sf_siginfo = code; 488 sf.sf_addr = regs->tf_addr; | 494 sf.sf_siginfo = siginfo.si_code; 495 sf.sf_addr = (u_int32_t)siginfo.si_addr; |
489 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 490 } 491 mtx_unlock(&psp->ps_mtx); 492 493 /* 494 * Copy the sigframe out to the user's stack. 495 */ 496 if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { --- 38 unchanged lines hidden (view full) --- 535 const struct freebsd4_freebsd32_ucontext *sigcntxp; 536 } */ *uap; 537{ 538 struct ia32_ucontext4 uc; 539 struct proc *p = td->td_proc; 540 struct trapframe *regs; 541 const struct ia32_ucontext4 *ucp; 542 int cs, eflags, error; | 496 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 497 } 498 mtx_unlock(&psp->ps_mtx); 499 500 /* 501 * Copy the sigframe out to the user's stack. 502 */ 503 if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { --- 38 unchanged lines hidden (view full) --- 542 const struct freebsd4_freebsd32_ucontext *sigcntxp; 543 } */ *uap; 544{ 545 struct ia32_ucontext4 uc; 546 struct proc *p = td->td_proc; 547 struct trapframe *regs; 548 const struct ia32_ucontext4 *ucp; 549 int cs, eflags, error; |
550 ksiginfo_t ksi; |
|
543 544 error = copyin(uap->sigcntxp, &uc, sizeof(uc)); 545 if (error != 0) 546 return (error); 547 ucp = &uc; 548 regs = td->td_frame; 549 eflags = ucp->uc_mcontext.mc_eflags; 550 /* --- 17 unchanged lines hidden (view full) --- 568 /* 569 * Don't allow users to load a valid privileged %cs. Let the 570 * hardware check for invalid selectors, excess privilege in 571 * other selectors, invalid %eip's and invalid %esp's. 572 */ 573 cs = ucp->uc_mcontext.mc_cs; 574 if (!CS_SECURE(cs)) { 575 printf("freebsd4_sigreturn: cs = 0x%x\n", cs); | 551 552 error = copyin(uap->sigcntxp, &uc, sizeof(uc)); 553 if (error != 0) 554 return (error); 555 ucp = &uc; 556 regs = td->td_frame; 557 eflags = ucp->uc_mcontext.mc_eflags; 558 /* --- 17 unchanged lines hidden (view full) --- 576 /* 577 * Don't allow users to load a valid privileged %cs. Let the 578 * hardware check for invalid selectors, excess privilege in 579 * other selectors, invalid %eip's and invalid %esp's. 580 */ 581 cs = ucp->uc_mcontext.mc_cs; 582 if (!CS_SECURE(cs)) { 583 printf("freebsd4_sigreturn: cs = 0x%x\n", cs); |
576 trapsignal(td, SIGBUS, T_PROTFLT); | 584 ksiginfo_init_trap(&ksi); 585 ksi.ksi_signo = SIGBUS; 586 ksi.ksi_code = BUS_OBJERR; 587 ksi.ksi_trapno = T_PROTFLT; 588 ksi.ksi_addr = (void *)regs->tf_rip; 589 trapsignal(td, &ksi); |
577 return (EINVAL); 578 } 579 580 /* Segment selectors restored by sigtramp.S */ 581 regs->tf_rdi = ucp->uc_mcontext.mc_edi; 582 regs->tf_rsi = ucp->uc_mcontext.mc_esi; 583 regs->tf_rbp = ucp->uc_mcontext.mc_ebp; 584 regs->tf_rbx = ucp->uc_mcontext.mc_ebx; --- 27 unchanged lines hidden (view full) --- 612 const struct freebsd32_ucontext *sigcntxp; 613 } */ *uap; 614{ 615 struct ia32_ucontext uc; 616 struct proc *p = td->td_proc; 617 struct trapframe *regs; 618 const struct ia32_ucontext *ucp; 619 int cs, eflags, error, ret; | 590 return (EINVAL); 591 } 592 593 /* Segment selectors restored by sigtramp.S */ 594 regs->tf_rdi = ucp->uc_mcontext.mc_edi; 595 regs->tf_rsi = ucp->uc_mcontext.mc_esi; 596 regs->tf_rbp = ucp->uc_mcontext.mc_ebp; 597 regs->tf_rbx = ucp->uc_mcontext.mc_ebx; --- 27 unchanged lines hidden (view full) --- 625 const struct freebsd32_ucontext *sigcntxp; 626 } */ *uap; 627{ 628 struct ia32_ucontext uc; 629 struct proc *p = td->td_proc; 630 struct trapframe *regs; 631 const struct ia32_ucontext *ucp; 632 int cs, eflags, error, ret; |
633 ksiginfo_t ksi; |
|
620 621 error = copyin(uap->sigcntxp, &uc, sizeof(uc)); 622 if (error != 0) 623 return (error); 624 ucp = &uc; 625 regs = td->td_frame; 626 eflags = ucp->uc_mcontext.mc_eflags; 627 /* --- 17 unchanged lines hidden (view full) --- 645 /* 646 * Don't allow users to load a valid privileged %cs. Let the 647 * hardware check for invalid selectors, excess privilege in 648 * other selectors, invalid %eip's and invalid %esp's. 649 */ 650 cs = ucp->uc_mcontext.mc_cs; 651 if (!CS_SECURE(cs)) { 652 printf("sigreturn: cs = 0x%x\n", cs); | 634 635 error = copyin(uap->sigcntxp, &uc, sizeof(uc)); 636 if (error != 0) 637 return (error); 638 ucp = &uc; 639 regs = td->td_frame; 640 eflags = ucp->uc_mcontext.mc_eflags; 641 /* --- 17 unchanged lines hidden (view full) --- 659 /* 660 * Don't allow users to load a valid privileged %cs. Let the 661 * hardware check for invalid selectors, excess privilege in 662 * other selectors, invalid %eip's and invalid %esp's. 663 */ 664 cs = ucp->uc_mcontext.mc_cs; 665 if (!CS_SECURE(cs)) { 666 printf("sigreturn: cs = 0x%x\n", cs); |
653 trapsignal(td, SIGBUS, T_PROTFLT); | 667 ksiginfo_init_trap(&ksi); 668 ksi.ksi_signo = SIGBUS; 669 ksi.ksi_code = BUS_OBJERR; 670 ksi.ksi_trapno = T_PROTFLT; 671 ksi.ksi_addr = (void *)regs->tf_rip; 672 trapsignal(td, &ksi); |
654 return (EINVAL); 655 } 656 657 ret = ia32_set_fpcontext(td, &ucp->uc_mcontext); 658 if (ret != 0) 659 return (ret); 660 661 /* Segment selectors restored by sigtramp.S */ --- 55 unchanged lines hidden (view full) --- 717 regs->tf_rbx = ps_strings; 718 load_cr0(rcr0() | CR0_MP | CR0_TS); 719 fpstate_drop(td); 720 721 /* Return via doreti so that we can change to a different %cs */ 722 pcb->pcb_flags |= PCB_FULLCTX; 723 td->td_retval[1] = 0; 724} | 673 return (EINVAL); 674 } 675 676 ret = ia32_set_fpcontext(td, &ucp->uc_mcontext); 677 if (ret != 0) 678 return (ret); 679 680 /* Segment selectors restored by sigtramp.S */ --- 55 unchanged lines hidden (view full) --- 736 regs->tf_rbx = ps_strings; 737 load_cr0(rcr0() | CR0_MP | CR0_TS); 738 fpstate_drop(td); 739 740 /* Return via doreti so that we can change to a different %cs */ 741 pcb->pcb_flags |= PCB_FULLCTX; 742 td->td_retval[1] = 0; 743} |
744 745void 746siginfo_to_ia32siginfo(siginfo_t *src, struct ia32_siginfo *dst) 747{ 748 dst->si_signo = src->si_signo; 749 dst->si_errno = src->si_errno; 750 dst->si_code = src->si_code; 751 dst->si_pid = src->si_pid; 752 dst->si_uid = src->si_uid; 753 dst->si_status = src->si_status; 754 dst->si_addr = dst->si_addr; 755 dst->si_value.sigval_int = src->si_value.sigval_int; 756 dst->si_band = src->si_band; 757 dst->__spare__[0] = src->si_trapno; 758} |
|