Deleted Added
full compact
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}