From 01430d7930ae6409e1bc520e06b1c499cba11c8c Mon Sep 17 00:00:00 2001 From: deraadt Date: Mon, 27 Jan 1997 22:47:57 +0000 Subject: [PATCH] add another parameter to trapsignal() and sendsig() -- fault addr to be delivered with in the siginfo information --- sys/arch/i386/i386/freebsd_machdep.c | 5 +- sys/arch/i386/i386/linux_machdep.c | 5 +- sys/arch/i386/i386/machdep.c | 14 +-- sys/arch/i386/i386/svr4_machdep.c | 7 +- sys/arch/i386/i386/trap.c | 23 ++--- sys/arch/i386/i386/vm86.c | 4 +- sys/arch/i386/include/freebsd_machdep.h | 2 +- sys/arch/i386/include/linux_machdep.h | 2 +- sys/arch/i386/include/svr4_machdep.h | 2 +- sys/arch/i386/isa/npx.c | 2 +- sys/arch/m68k/m68k/sunos_machdep.c | 7 +- sys/arch/mvme68k/mvme68k/machdep.c | 96 +++++++++++++++++++- sys/arch/mvme68k/mvme68k/trap.c | 11 +-- sys/arch/sparc/fpu/fpu.c | 8 +- sys/arch/sparc/include/svr4_machdep.h | 2 +- sys/arch/sparc/sparc/machdep.c | 115 ++++++++++++++++++++++-- sys/arch/sparc/sparc/svr4_machdep.c | 13 +-- sys/arch/sparc/sparc/trap.c | 26 +++--- sys/compat/ibcs2/ibcs2_exec.c | 4 +- sys/compat/sunos/sunos.h | 4 +- sys/kern/kern_sig.c | 9 +- sys/sys/proc.h | 4 +- sys/sys/signalvar.h | 7 +- 23 files changed, 286 insertions(+), 86 deletions(-) diff --git a/sys/arch/i386/i386/freebsd_machdep.c b/sys/arch/i386/i386/freebsd_machdep.c index 40439f62b9e..a27a24630ef 100644 --- a/sys/arch/i386/i386/freebsd_machdep.c +++ b/sys/arch/i386/i386/freebsd_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: freebsd_machdep.c,v 1.7 1996/08/27 10:46:51 downsj Exp $ */ +/* $OpenBSD: freebsd_machdep.c,v 1.8 1997/01/27 22:47:57 deraadt Exp $ */ /* $NetBSD: freebsd_machdep.c,v 1.10 1996/05/03 19:42:05 christos Exp $ */ /*- @@ -76,10 +76,11 @@ * specified pc, psl. */ void -freebsd_sendsig(catcher, sig, mask, code) +freebsd_sendsig(catcher, sig, mask, code, addr) sig_t catcher; int sig, mask; u_long code; + caddr_t addr; { register struct proc *p = curproc; register struct trapframe *tf; diff --git a/sys/arch/i386/i386/linux_machdep.c b/sys/arch/i386/i386/linux_machdep.c index 163dc0d4710..52d9bcd578a 100644 --- a/sys/arch/i386/i386/linux_machdep.c +++ b/sys/arch/i386/i386/linux_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_machdep.c,v 1.8 1996/05/07 07:21:42 deraadt Exp $ */ +/* $OpenBSD: linux_machdep.c,v 1.9 1997/01/27 22:47:58 deraadt Exp $ */ /* $NetBSD: linux_machdep.c,v 1.29 1996/05/03 19:42:11 christos Exp $ */ /* @@ -104,10 +104,11 @@ int linux_write_ldt __P((struct proc *, struct linux_sys_modify_ldt_args *, */ void -linux_sendsig(catcher, sig, mask, code) +linux_sendsig(catcher, sig, mask, code, addr) sig_t catcher; int sig, mask; u_long code; + caddr_t addr; { register struct proc *p = curproc; register struct trapframe *tf; diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index a114f1715bb..ee7a6538052 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.35 1997/01/27 01:16:12 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.36 1997/01/27 22:47:59 deraadt Exp $ */ /* $NetBSD: machdep.c,v 1.202 1996/05/18 15:54:59 christos Exp $ */ /*- @@ -565,17 +565,18 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) } #ifdef COMPAT_IBCS2 -void ibcs2_sendsig __P((sig_t, int, int, u_long)); +void ibcs2_sendsig __P((sig_t, int, int, u_long, caddr_t)); void -ibcs2_sendsig(catcher, sig, mask, code) +ibcs2_sendsig(catcher, sig, mask, code, addr) sig_t catcher; int sig, mask; u_long code; + caddr_t addr; { extern int bsd_to_ibcs2_sig[]; - sendsig(catcher, bsd_to_ibcs2_sig[sig], mask, code); + sendsig(catcher, bsd_to_ibcs2_sig[sig], mask, code, addr); } #endif @@ -590,10 +591,11 @@ ibcs2_sendsig(catcher, sig, mask, code) * specified pc, psl. */ void -sendsig(catcher, sig, mask, code) +sendsig(catcher, sig, mask, code, addr) sig_t catcher; int sig, mask; u_long code; + caddr_t addr; { register struct proc *p = curproc; register struct trapframe *tf; @@ -665,7 +667,7 @@ sendsig(catcher, sig, mask, code) if (psp->ps_siginfo & sigmask(sig)) { frame.sf_sip = &fp->sf_si; initsiginfo(frame.sf_sip, sig); - fixsiginfo(frame.sf_sip, sig, code, (caddr_t)rcr2()); + fixsiginfo(frame.sf_sip, sig, code, addr); if (sig == SIGSEGV) { /* try to be more specific about read or write */ if (tf->tf_err & PGEX_W) diff --git a/sys/arch/i386/i386/svr4_machdep.c b/sys/arch/i386/i386/svr4_machdep.c index 68b9cf259d7..1d3a1c241bd 100644 --- a/sys/arch/i386/i386/svr4_machdep.c +++ b/sys/arch/i386/i386/svr4_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: svr4_machdep.c,v 1.8 1997/01/27 01:17:08 deraadt Exp $ */ +/* $OpenBSD: svr4_machdep.c,v 1.9 1997/01/27 22:48:00 deraadt Exp $ */ /* $NetBSD: svr4_machdep.c,v 1.24 1996/05/03 19:42:26 christos Exp $ */ /* @@ -315,10 +315,11 @@ svr4_getsiginfo(si, sig, code, addr) * will return to the user pc, psl. */ void -svr4_sendsig(catcher, sig, mask, code) +svr4_sendsig(catcher, sig, mask, code, addr) sig_t catcher; int sig, mask; u_long code; + caddr_t addr; { register struct proc *p = curproc; register struct trapframe *tf; @@ -353,7 +354,7 @@ svr4_sendsig(catcher, sig, mask, code) */ svr4_getcontext(p, &frame.sf_uc, mask, oonstack); - svr4_getsiginfo(&frame.sf_si, sig, code, (caddr_t) tf->tf_eip); + svr4_getsiginfo(&frame.sf_si, sig, code, addr); frame.sf_signum = frame.sf_si.svr4_si_signo; frame.sf_sip = &fp->sf_si; diff --git a/sys/arch/i386/i386/trap.c b/sys/arch/i386/i386/trap.c index f29f4aa7759..2d90e9b7911 100644 --- a/sys/arch/i386/i386/trap.c +++ b/sys/arch/i386/i386/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.13 1997/01/18 15:17:38 niklas Exp $ */ +/* $OpenBSD: trap.c,v 1.14 1997/01/27 22:48:01 deraadt Exp $ */ /* $NetBSD: trap.c,v 1.95 1996/05/05 06:50:02 mycroft Exp $ */ #undef DEBUG @@ -282,16 +282,16 @@ trap(frame) #endif case T_SEGNPFLT|T_USER: case T_STKFLT|T_USER: - trapsignal(p, SIGSEGV, type &~ T_USER); + trapsignal(p, SIGSEGV, type &~ T_USER, (caddr_t)rcr2()); goto out; case T_ALIGNFLT|T_USER: - trapsignal(p, SIGBUS, type &~ T_USER); + trapsignal(p, SIGBUS, type &~ T_USER, (caddr_t)rcr2()); goto out; case T_PRIVINFLT|T_USER: /* privileged instruction fault */ case T_FPOPFLT|T_USER: /* coprocessor operand fault */ - trapsignal(p, SIGILL, type &~ T_USER); + trapsignal(p, SIGILL, type &~ T_USER, (caddr_t)rcr2()); goto out; case T_ASTFLT|T_USER: /* Allow process switch */ @@ -310,12 +310,12 @@ trap(frame) goto trace; return; } - trapsignal(p, rv, type &~ T_USER); + trapsignal(p, rv, type &~ T_USER, (caddr_t)rcr2()); goto out; #else printf("pid %d killed due to lack of floating point\n", p->p_pid); - trapsignal(p, SIGKILL, type &~ T_USER); + trapsignal(p, SIGKILL, type &~ T_USER, (caddr_t)rcr2()); goto out; #endif } @@ -323,11 +323,11 @@ trap(frame) case T_BOUND|T_USER: case T_OFLOW|T_USER: case T_DIVIDE|T_USER: - trapsignal(p, SIGFPE, type &~ T_USER); + trapsignal(p, SIGFPE, type &~ T_USER, (caddr_t)rcr2()); goto out; case T_ARITHTRAP|T_USER: - trapsignal(p, SIGFPE, frame.tf_err); + trapsignal(p, SIGFPE, frame.tf_err, (caddr_t)rcr2()); goto out; case T_PAGEFLT: /* allow page faults in kernel mode */ @@ -355,8 +355,9 @@ trap(frame) vm_prot_t ftype; extern vm_map_t kernel_map; unsigned nss, v; + caddr_t vv = (caddr_t)rcr2(); - va = trunc_page((vm_offset_t)rcr2()); + va = trunc_page((vm_offset_t)vv); /* * It is only a kernel address space fault iff: * 1. (type & T_USER) == 0 and @@ -426,7 +427,7 @@ trap(frame) map, va, ftype, rv); goto we_re_toast; } - trapsignal(p, SIGSEGV, T_PAGEFLT); + trapsignal(p, SIGSEGV, T_PAGEFLT, vv); break; } @@ -442,7 +443,7 @@ trap(frame) #if defined(MATH_EMULATE) || defined(GPL_MATH_EMULATE) trace: #endif - trapsignal(p, SIGTRAP, type &~ T_USER); + trapsignal(p, SIGTRAP, type &~ T_USER, (caddr_t)rcr2()); break; #include "isa.h" diff --git a/sys/arch/i386/i386/vm86.c b/sys/arch/i386/i386/vm86.c index a968c811bc9..ba61d16555b 100644 --- a/sys/arch/i386/i386/vm86.c +++ b/sys/arch/i386/i386/vm86.c @@ -253,7 +253,7 @@ vm86_return(p, retval) sigexit(p, SIGILL); /* NOTREACHED */ } - trapsignal(p, SIGURG, retval); + trapsignal(p, SIGURG, retval, 0); } #define CLI 0xFA @@ -369,7 +369,7 @@ vm86_gpfault(p, type) } if (trace && tf->tf_eflags & PSL_VM) - trapsignal(p, SIGTRAP, T_TRCTRAP); + trapsignal(p, SIGTRAP, T_TRCTRAP, 0); return; bad: diff --git a/sys/arch/i386/include/freebsd_machdep.h b/sys/arch/i386/include/freebsd_machdep.h index 4001bd410db..7ee92189afd 100644 --- a/sys/arch/i386/include/freebsd_machdep.h +++ b/sys/arch/i386/include/freebsd_machdep.h @@ -157,6 +157,6 @@ struct freebsd_ptrace_reg { /* sys/i386/include/exec.h */ #define FREEBSD___LDPGSZ 4096 -void freebsd_sendsig __P((sig_t, int, int, u_long)); +void freebsd_sendsig __P((sig_t, int, int, u_long, caddr_t)); #endif /* _FREEBSD_MACHDEP_H */ diff --git a/sys/arch/i386/include/linux_machdep.h b/sys/arch/i386/include/linux_machdep.h index 1c26026594f..c5a09d1cc93 100644 --- a/sys/arch/i386/include/linux_machdep.h +++ b/sys/arch/i386/include/linux_machdep.h @@ -76,7 +76,7 @@ struct linux_sigframe { sig_t sf_handler; }; -void linux_sendsig __P((sig_t, int, int, u_long)); +void linux_sendsig __P((sig_t, int, int, u_long, caddr_t)); dev_t linux_fakedev __P((dev_t)); /* diff --git a/sys/arch/i386/include/svr4_machdep.h b/sys/arch/i386/include/svr4_machdep.h index 0a5f5c8a8ee..fd39dd6c121 100644 --- a/sys/arch/i386/include/svr4_machdep.h +++ b/sys/arch/i386/include/svr4_machdep.h @@ -71,7 +71,7 @@ struct svr4_ucontext; void svr4_getcontext __P((struct proc *, struct svr4_ucontext *, int, int)); int svr4_setcontext __P((struct proc *p, struct svr4_ucontext *)); -void svr4_sendsig __P((sig_t, int, int, u_long)); +void svr4_sendsig __P((sig_t, int, int, u_long, caddr_t)); typedef struct { svr4_gregset_t greg; diff --git a/sys/arch/i386/isa/npx.c b/sys/arch/i386/isa/npx.c index 309ee672032..6774126fd5b 100644 --- a/sys/arch/i386/isa/npx.c +++ b/sys/arch/i386/isa/npx.c @@ -448,7 +448,7 @@ npxintr(arg) #else code = 0; /* XXX */ #endif - trapsignal(p, SIGFPE, code); + trapsignal(p, SIGFPE, code, 0); } else { /* * Nested interrupt. These losers occur when: diff --git a/sys/arch/m68k/m68k/sunos_machdep.c b/sys/arch/m68k/m68k/sunos_machdep.c index 5f52538807b..7eb4e91d62a 100644 --- a/sys/arch/m68k/m68k/sunos_machdep.c +++ b/sys/arch/m68k/m68k/sunos_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sunos_machdep.c,v 1.8 1997/01/13 11:51:14 niklas Exp $ */ +/* $OpenBSD: sunos_machdep.c,v 1.9 1997/01/27 22:48:13 deraadt Exp $ */ /* $NetBSD: sunos_machdep.c,v 1.12 1996/10/13 03:19:22 christos Exp $ */ /* @@ -95,10 +95,11 @@ struct sunos_sigframe { * SIG_DFL for "dangerous" signals. */ void -sunos_sendsig(catcher, sig, mask, code) +sunos_sendsig(catcher, sig, mask, code, addr) sig_t catcher; int sig, mask; u_long code; + caddr_t addr; { register struct proc *p = curproc; register struct sunos_sigframe *fp; @@ -172,7 +173,7 @@ sunos_sendsig(catcher, sig, mask, code) kfp.sf_signum = sig; kfp.sf_code = code; kfp.sf_scp = &fp->sf_sc; - kfp.sf_addr = ~0; /* means: not computable */ + kfp.sf_addr = (u_int)addr; /* * Build the signal context to be used by sigreturn. diff --git a/sys/arch/mvme68k/mvme68k/machdep.c b/sys/arch/mvme68k/mvme68k/machdep.c index 57fec537bcf..46a1d3dfac8 100644 --- a/sys/arch/mvme68k/mvme68k/machdep.c +++ b/sys/arch/mvme68k/mvme68k/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.13 1997/01/16 20:43:38 kstailey Exp $ */ +/* $OpenBSD: machdep.c,v 1.14 1997/01/27 22:48:16 deraadt Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -633,9 +633,11 @@ struct sigframe { int sf_signum; /* signo for handler */ int sf_code; /* additional info for handler */ struct sigcontext *sf_scp; /* context ptr for handler */ + siginfo_t *sf_sip; sig_t sf_handler; /* handler addr for u_sigc */ struct sigstate sf_state; /* state of the hardware */ struct sigcontext sf_sc; /* actual context */ + siginfo_t sf_si; }; #ifdef COMPAT_HPUX @@ -680,10 +682,11 @@ int sigpid = 0; * Send an interrupt to process. */ void -sendsig(catcher, sig, mask, code) +sendsig(catcher, sig, mask, code, addr) sig_t catcher; int sig, mask; u_long code; + caddr_t addr; { register struct proc *p = curproc; register struct sigframe *fp, *kfp; @@ -749,6 +752,8 @@ sendsig(catcher, sig, mask, code) kfp->sf_code = code; kfp->sf_scp = &fp->sf_sc; kfp->sf_handler = catcher; + kfp->sf_sip = NULL; + /* * Save necessary hardware state. Currently this includes: * - general registers @@ -806,6 +811,22 @@ sendsig(catcher, sig, mask, code) kfp->sf_sc.sc_ap = (int)&fp->sf_state; kfp->sf_sc.sc_pc = frame->f_pc; kfp->sf_sc.sc_ps = frame->f_sr; + + if (psp->ps_siginfo & sigmask(sig)) { + kfp->sf_sip = &kfp->sf_si; + initsiginfo(kfp->sf_sip, sig); + fixsiginfo(kfp->sf_sip, sig, code, addr); + if (sig == SIGSEGV) { + /* try to be more specific about read or write */ +#if 0 + if (WRFAULT(frame->f_pad)) + kfp->sf_si.si_code |= SEGV_ACCERR; + else + kfp->sf_si.si_code |= SEGV_MAPERR; +#endif + } + } + #ifdef COMPAT_HPUX /* * Create an HP-UX style sigcontext structure and associated goo @@ -1035,6 +1056,77 @@ sys_sigreturn(p, v, retval) return (EJUSTRETURN); } +void +fixsiginfo(si, sig, code, addr) + siginfo_t *si; + int sig; + u_long code; + caddr_t addr; +{ + si->si_addr = addr; + + switch (code) { +#if 0 + case T_PRIVINFLT: + si->si_code = ILL_PRVOPC; + si->si_trapno = T_PRIVINFLT; + break; + case T_BREAKPOINT: + si->si_code = TRAP_BRKPT; + si->si_trapno = T_BREAKPOINT; + break; + case T_ARITHTRAP: + si->si_code = FPE_INTOVF; + si->si_trapno = T_DIVIDE; + break; + case T_PROTFLT: + si->si_code = SEGV_ACCERR; + si->si_trapno = T_PROTFLT; + break; + case T_TRCTRAP: + si->si_code = TRAP_TRACE; + si->si_trapno = T_TRCTRAP; + break; + case T_PAGEFLT: + si->si_code = SEGV_ACCERR; + si->si_trapno = T_PAGEFLT; + break; + case T_ALIGNFLT: + si->si_code = BUS_ADRALN; + si->si_trapno = T_ALIGNFLT; + break; + case T_DIVIDE: + si->si_code = FPE_FLTDIV; + si->si_trapno = T_DIVIDE; + break; + case T_OFLOW: + si->si_code = FPE_FLTOVF; + si->si_trapno = T_DIVIDE; + break; + case T_BOUND: + si->si_code = FPE_FLTSUB; + si->si_trapno = T_BOUND; + break; + case T_DNA: + si->si_code = FPE_FLTINV; + si->si_trapno = T_DNA; + break; + case T_FPOPFLT: + si->si_code = FPE_FLTINV; + si->si_trapno = T_FPOPFLT; + break; + case T_SEGNPFLT: + si->si_code = SEGV_MAPERR; + si->si_trapno = T_SEGNPFLT; + break; + case T_STKFLT: + si->si_code = ILL_BADSTK; + si->si_trapno = T_STKFLT; + break; +#endif + } +} + int waittime = -1; static struct haltvec *halts; diff --git a/sys/arch/mvme68k/mvme68k/trap.c b/sys/arch/mvme68k/mvme68k/trap.c index 05ee76df038..2b139bfbfd1 100644 --- a/sys/arch/mvme68k/mvme68k/trap.c +++ b/sys/arch/mvme68k/mvme68k/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.8 1996/12/24 20:29:02 deraadt Exp $ */ +/* $OpenBSD: trap.c,v 1.9 1997/01/27 22:48:17 deraadt Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -237,7 +237,7 @@ again: } else if (sig = writeback(fp, fromtrap)) { beenhere = 1; oticks = p->p_sticks; - trapsignal(p, sig, faultaddr); + trapsignal(p, sig, T_MMUFLT, (caddr_t)faultaddr); goto again; } } @@ -310,7 +310,7 @@ copyfault: case T_BUSERR|T_USER: /* bus error */ case T_ADDRERR|T_USER: /* address error */ - ucode = v; + ucode = code & ~T_USER; i = SIGBUS; break; @@ -610,12 +610,13 @@ copyfault: type, code); goto dopanic; } - ucode = v; + frame.f_pad = code & 0xffff; + ucode = T_MMUFLT; i = SIGSEGV; break; } } - trapsignal(p, i, ucode); + trapsignal(p, i, ucode, (caddr_t)v); if ((type & T_USER) == 0) return; out: diff --git a/sys/arch/sparc/fpu/fpu.c b/sys/arch/sparc/fpu/fpu.c index f5212b9ae2d..3b1c8a0dbf9 100644 --- a/sys/arch/sparc/fpu/fpu.c +++ b/sys/arch/sparc/fpu/fpu.c @@ -114,7 +114,7 @@ fpu_cleanup(p, fs) /* XXX missing trap address! */ if ((i = fsr & FSR_CX) == 0) panic("fpu ieee trap, but no exception"); - trapsignal(p, SIGFPE, fpu_codes[i - 1]); + trapsignal(p, SIGFPE, fpu_codes[i - 1], 0); break; /* XXX should return, but queue remains */ case FSR_TT_UNFIN: @@ -131,7 +131,7 @@ fpu_cleanup(p, fs) log(LOG_ERR, "fpu hardware error (%s[%d])\n", p->p_comm, p->p_pid); uprintf("%s[%d]: fpu hardware error\n", p->p_comm, p->p_pid); - trapsignal(p, SIGFPE, -1); /* ??? */ + trapsignal(p, SIGFPE, -1, 0); /* ??? */ goto out; default: @@ -155,11 +155,11 @@ fpu_cleanup(p, fs) case FPE: trapsignal(p, SIGFPE, - fpu_codes[(fs->fs_fsr & FSR_CX) - 1]); + fpu_codes[(fs->fs_fsr & FSR_CX) - 1], 0); break; case NOTFPU: - trapsignal(p, SIGILL, 0); /* ??? code? */ + trapsignal(p, SIGILL, 0, 0); /* ??? code? */ break; default: diff --git a/sys/arch/sparc/include/svr4_machdep.h b/sys/arch/sparc/include/svr4_machdep.h index d2687a7a896..2c716b37714 100644 --- a/sys/arch/sparc/include/svr4_machdep.h +++ b/sys/arch/sparc/include/svr4_machdep.h @@ -101,7 +101,7 @@ struct svr4_ucontext; void svr4_getcontext __P((struct proc *, struct svr4_ucontext *, int, int)); int svr4_setcontext __P((struct proc *p, struct svr4_ucontext *)); -void svr4_sendsig __P((sig_t, int, int, u_long)); +void svr4_sendsig __P((sig_t, int, int, u_long, caddr_t)); int svr4_trap __P((int, struct proc *)); #endif /* !_SPARC_SVR4_MACHDEP_H_ */ diff --git a/sys/arch/sparc/sparc/machdep.c b/sys/arch/sparc/sparc/machdep.c index 6b84e987d6b..938f4ee72c5 100644 --- a/sys/arch/sparc/sparc/machdep.c +++ b/sys/arch/sparc/sparc/machdep.c @@ -423,8 +423,12 @@ struct sigframe { #else int sf_xxx; /* placeholder */ #endif - int sf_addr; /* SunOS compat, always 0 for now */ + union { + int sfu_addr; /* SunOS compat */ + siginfo_t *sfu_sip; /* native */ + } sf_u; struct sigcontext sf_sc; /* actual sigcontext */ + siginfo_t sf_si; }; /* @@ -456,19 +460,23 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) * Send an interrupt to process. */ void -sendsig(catcher, sig, mask, code) +sendsig(catcher, sig, mask, code, addr) sig_t catcher; int sig, mask; u_long code; + caddr_t addr; { register struct proc *p = curproc; register struct sigacts *psp = p->p_sigacts; register struct sigframe *fp; register struct trapframe *tf; - register int addr, oonstack, oldsp, newsp; + register int caddr, oonstack, oldsp, newsp; struct sigframe sf; extern char sigcode[], esigcode[]; #define szsigcode (esigcode - sigcode) +#ifdef COMPAT_SUNOS + extern struct emul emul_sunos; +#endif tf = p->p_md.md_tf; oldsp = tf->tf_out[6]; @@ -498,10 +506,13 @@ sendsig(catcher, sig, mask, code) */ sf.sf_signo = sig; sf.sf_code = code; + sf.sf_u.sfu_sip = NULL; #ifdef COMPAT_SUNOS - sf.sf_scp = &fp->sf_sc; + if (p->p_emul == &emul_sunos) { + sf.sf_scp = &fp->sf_sc; + sf.sf_u.sfu_addr = (u_int)addr; + } #endif - sf.sf_addr = 0; /* XXX */ /* * Build the signal context to be used by sigreturn. @@ -515,6 +526,21 @@ sendsig(catcher, sig, mask, code) sf.sf_sc.sc_g1 = tf->tf_global[1]; sf.sf_sc.sc_o0 = tf->tf_out[0]; + if (psp->ps_siginfo & sigmask(sig)) { + sf.sf_u.sfu_sip = &fp->sf_si; + initsiginfo(sf.sf_u.sfu_sip, sig); + fixsiginfo(sf.sf_u.sfu_sip, sig, code, addr); +#if 0 + if (sig == SIGSEGV) { + /* try to be more specific about read or write */ + if (tf->tf_err & PGEX_W) + sf.sf_si.si_code = SEGV_ACCERR; + else + sf.sf_si.si_code = SEGV_MAPERR; + } +#endif + } + /* * Put the stack in a consistent state before we whack away * at it. Note that write_user_windows may just dump the @@ -550,15 +576,15 @@ sendsig(catcher, sig, mask, code) */ #ifdef COMPAT_SUNOS if (psp->ps_usertramp & sigmask(sig)) { - addr = (int)catcher; /* user does his own trampolining */ + caddr = (int)catcher; /* user does his own trampolining */ } else #endif { - addr = (int)PS_STRINGS - szsigcode; + caddr = (int)PS_STRINGS - szsigcode; tf->tf_global[1] = (int)catcher; } - tf->tf_pc = addr; - tf->tf_npc = addr + 4; + tf->tf_pc = caddr; + tf->tf_npc = caddr + 4; tf->tf_out[6] = newsp; #ifdef DEBUG if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) @@ -623,6 +649,77 @@ sys_sigreturn(p, v, retval) return (EJUSTRETURN); } +void +fixsiginfo(si, sig, code, addr) + siginfo_t *si; + int sig; + u_long code; + caddr_t addr; +{ + si->si_addr = addr; + +#if 0 + switch (code) { + case T_PRIVINFLT: + si->si_code = ILL_PRVOPC; + si->si_trapno = T_PRIVINFLT; + break; + case T_BPTFLT: + si->si_code = TRAP_BRKPT; + si->si_trapno = T_BPTFLT; + break; + case T_ARITHTRAP: + si->si_code = FPE_INTOVF; + si->si_trapno = T_DIVIDE; + break; + case T_PROTFLT: + si->si_code = SEGV_ACCERR; + si->si_trapno = T_PROTFLT; + break; + case T_TRCTRAP: + si->si_code = TRAP_TRACE; + si->si_trapno = T_TRCTRAP; + break; + case T_PAGEFLT: + si->si_code = SEGV_ACCERR; + si->si_trapno = T_PAGEFLT; + break; + case T_ALIGNFLT: + si->si_code = BUS_ADRALN; + si->si_trapno = T_ALIGNFLT; + break; + case T_DIVIDE: + si->si_code = FPE_FLTDIV; + si->si_trapno = T_DIVIDE; + break; + case T_OFLOW: + si->si_code = FPE_FLTOVF; + si->si_trapno = T_DIVIDE; + break; + case T_BOUND: + si->si_code = FPE_FLTSUB; + si->si_trapno = T_BOUND; + break; + case T_DNA: + si->si_code = FPE_FLTINV; + si->si_trapno = T_DNA; + break; + case T_FPOPFLT: + si->si_code = FPE_FLTINV; + si->si_trapno = T_FPOPFLT; + break; + case T_SEGNPFLT: + si->si_code = SEGV_MAPERR; + si->si_trapno = T_SEGNPFLT; + break; + case T_STKFLT: + si->si_code = ILL_BADSTK; + si->si_trapno = T_STKFLT; + break; + } +#endif +} + int waittime = -1; void diff --git a/sys/arch/sparc/sparc/svr4_machdep.c b/sys/arch/sparc/sparc/svr4_machdep.c index 6f8acd7fda0..f36f5991c27 100644 --- a/sys/arch/sparc/sparc/svr4_machdep.c +++ b/sys/arch/sparc/sparc/svr4_machdep.c @@ -462,16 +462,17 @@ svr4_getsiginfo(si, sig, code, addr) * will return to the user pc, psl. */ void -svr4_sendsig(catcher, sig, mask, code) +svr4_sendsig(catcher, sig, mask, code, addr) sig_t catcher; int sig, mask; u_long code; + caddr_t addr; { register struct proc *p = curproc; register struct trapframe *tf; struct svr4_sigframe *fp, frame; struct sigacts *psp = p->p_sigacts; - int oonstack, oldsp, newsp, addr; + int oonstack, oldsp, newsp, caddr; extern char svr4_sigcode[], svr4_esigcode[]; @@ -499,7 +500,7 @@ svr4_sendsig(catcher, sig, mask, code) /* * Build the argument list for the signal handler. */ - svr4_getsiginfo(&frame.sf_si, sig, code, (caddr_t) tf->tf_pc); + svr4_getsiginfo(&frame.sf_si, sig, code, addr); svr4_getcontext(p, &frame.sf_uc, mask, oonstack); frame.sf_signum = frame.sf_si.svr4_si_signo; frame.sf_sip = &fp->sf_si; @@ -534,11 +535,11 @@ svr4_sendsig(catcher, sig, mask, code) /* * Build context to run handler in. */ - addr = (int)PS_STRINGS - (svr4_esigcode - svr4_sigcode); + caddr = (int)PS_STRINGS - (svr4_esigcode - svr4_sigcode); tf->tf_global[1] = (int)catcher; - tf->tf_pc = addr; - tf->tf_npc = addr + 4; + tf->tf_pc = caddr; + tf->tf_npc = caddr + 4; tf->tf_out[6] = newsp; } diff --git a/sys/arch/sparc/sparc/trap.c b/sys/arch/sparc/sparc/trap.c index e44f163ccb8..a2866f17b3d 100644 --- a/sys/arch/sparc/sparc/trap.c +++ b/sys/arch/sparc/sparc/trap.c @@ -337,7 +337,7 @@ badtrap: /* ... but leave it in until we find anything */ printf("%s[%d]: unimplemented software trap 0x%x\n", p->p_comm, p->p_pid, type); - trapsignal(p, SIGILL, type); + trapsignal(p, SIGILL, type, (caddr_t)pc); break; #ifdef COMPAT_SVR4 @@ -357,11 +357,11 @@ badtrap: break; /* the work is all in userret() */ case T_ILLINST: - trapsignal(p, SIGILL, 0); /* XXX code?? */ + trapsignal(p, SIGILL, 0, (caddr_t)pc); /* XXX code?? */ break; case T_PRIVINST: - trapsignal(p, SIGILL, 0); /* XXX code?? */ + trapsignal(p, SIGILL, 0, (caddr_t)pc); /* XXX code?? */ break; case T_FPDISABLED: { @@ -380,7 +380,7 @@ badtrap: fpu_emulate(p, tf, fs); break; #else - trapsignal(p, SIGFPE, 0); /* XXX code?? */ + trapsignal(p, SIGFPE, 0, (caddr_t)pc); /* XXX code?? */ break; #endif } @@ -465,7 +465,7 @@ badtrap: break; case T_ALIGN: - trapsignal(p, SIGBUS, 0); /* XXX code?? */ + trapsignal(p, SIGBUS, 0, (caddr_t)pc); /* XXX code?? */ break; case T_FPE: @@ -490,21 +490,21 @@ badtrap: break; case T_TAGOF: - trapsignal(p, SIGEMT, 0); /* XXX code?? */ + trapsignal(p, SIGEMT, 0, (caddr_t)pc); /* XXX code?? */ break; case T_CPDISABLED: uprintf("coprocessor instruction\n"); /* XXX */ - trapsignal(p, SIGILL, 0); /* XXX code?? */ + trapsignal(p, SIGILL, 0, (caddr_t)pc); /* XXX code?? */ break; case T_BREAKPOINT: - trapsignal(p, SIGTRAP, 0); + trapsignal(p, SIGTRAP, 0, (caddr_t)pc); break; case T_DIV0: ADVANCE; - trapsignal(p, SIGFPE, FPE_INTDIV_TRAP); + trapsignal(p, SIGFPE, FPE_INTDIV_TRAP, (caddr_t)pc); break; case T_FLUSHWIN: @@ -524,7 +524,7 @@ badtrap: case T_RANGECHECK: uprintf("T_RANGECHECK\n"); /* XXX */ ADVANCE; - trapsignal(p, SIGILL, 0); /* XXX code?? */ + trapsignal(p, SIGILL, 0, (caddr_t)pc); /* XXX code?? */ break; case T_FIXALIGN: @@ -535,7 +535,7 @@ badtrap: case T_INTOF: uprintf("T_INTOF\n"); /* XXX */ ADVANCE; - trapsignal(p, SIGFPE, FPE_INTOVF_TRAP); + trapsignal(p, SIGFPE, FPE_INTOVF_TRAP, (caddr_t)pc); break; } userret(p, pc, sticks); @@ -743,7 +743,7 @@ kfault: tf->tf_npc = onfault + 4; return; } - trapsignal(p, SIGSEGV, (u_int)v); + trapsignal(p, SIGSEGV, (u_int)v, (caddr_t)v); } out: if ((psr & PSR_PS) == 0) { @@ -1015,7 +1015,7 @@ kfault: tf->tf_npc = onfault + 4; return; } - trapsignal(p, SIGSEGV, (u_int)sfva); + trapsignal(p, SIGSEGV, (u_int)sfva, (caddr_t)sfva); } out: if ((psr & PSR_PS) == 0) { diff --git a/sys/compat/ibcs2/ibcs2_exec.c b/sys/compat/ibcs2/ibcs2_exec.c index 6f660dd40dd..f7c394017ba 100644 --- a/sys/compat/ibcs2/ibcs2_exec.c +++ b/sys/compat/ibcs2/ibcs2_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ibcs2_exec.c,v 1.5 1997/01/23 16:12:16 niklas Exp $ */ +/* $OpenBSD: ibcs2_exec.c,v 1.6 1997/01/27 22:48:30 deraadt Exp $ */ /* $NetBSD: ibcs2_exec.c,v 1.12 1996/10/12 02:13:52 thorpej Exp $ */ /* @@ -77,7 +77,7 @@ static int coff_find_section __P((struct proc *, struct vnode *, extern int bsd2ibcs_errno[]; extern struct sysent ibcs2_sysent[]; extern char *ibcs2_syscallnames[]; -extern void ibcs2_sendsig __P((sig_t, int, int, u_long)); +extern void ibcs2_sendsig __P((sig_t, int, int, u_long, caddr_t)); extern char sigcode[], esigcode[]; const char ibcs2_emul_path[] = "/emul/ibcs2"; diff --git a/sys/compat/sunos/sunos.h b/sys/compat/sunos/sunos.h index c43aa2381b2..65ef0e58073 100644 --- a/sys/compat/sunos/sunos.h +++ b/sys/compat/sunos/sunos.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sunos.h,v 1.4 1996/08/02 20:20:30 niklas Exp $ */ +/* $OpenBSD: sunos.h,v 1.5 1997/01/27 22:48:33 deraadt Exp $ */ /* $NetBSD: sunos.h,v 1.8 1996/05/05 16:07:43 veego Exp $ */ #define SUNM_RDONLY 0x01 /* mount fs read-only */ @@ -146,6 +146,6 @@ struct sunos_audio_info { __BEGIN_DECLS /* Defined in arch/m68k/m68k/sunos_machdep.c -- sparc uses regular sendsig() */ #ifndef sparc -void sunos_sendsig __P((sig_t, int, int, u_long)); +void sunos_sendsig __P((sig_t, int, int, u_long, caddr_t)); #endif __END_DECLS diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 1c9f7b23c2c..e8f19c40b25 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.14 1997/01/27 01:15:32 deraadt Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.15 1997/01/27 22:48:36 deraadt Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -519,10 +519,11 @@ pgsignal(pgrp, signum, checkctty) * Otherwise, post it normally. */ void -trapsignal(p, signum, code) +trapsignal(p, signum, code, addr) struct proc *p; register int signum; u_long code; + caddr_t addr; { register struct sigacts *ps = p->p_sigacts; int mask; @@ -537,7 +538,7 @@ trapsignal(p, signum, code) p->p_sigmask, code); #endif (*p->p_emul->e_sendsig)(ps->ps_sigact[signum], signum, - p->p_sigmask, code); + p->p_sigmask, code, addr); p->p_sigmask |= ps->ps_catchmask[signum]; if ((ps->ps_sigreset & mask) != 0) { p->p_sigcatch &= ~mask; @@ -1002,7 +1003,7 @@ postsig(signum) code = ps->ps_code; ps->ps_code = 0; } - (*p->p_emul->e_sendsig)(action, signum, returnmask, code); + (*p->p_emul->e_sendsig)(action, signum, returnmask, code, 0); } } diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 187e2d871b3..6d83564a554 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.11 1996/11/24 01:39:23 kstailey Exp $ */ +/* $OpenBSD: proc.h,v 1.12 1997/01/27 22:48:41 deraadt Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -80,7 +80,7 @@ struct emul { char e_name[8]; /* Symbolic name */ int *e_errno; /* Errno array */ /* Signal sending function */ - void (*e_sendsig) __P((sig_t, int, int, u_long)); + void (*e_sendsig) __P((sig_t, int, int, u_long, caddr_t)); int e_nosys; /* Offset of the nosys() syscall */ int e_nsysent; /* Number of system call entries */ struct sysent *e_sysent; /* System call array */ diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index c416f4cd3c9..e3282f9ae56 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: signalvar.h,v 1.4 1997/01/27 01:15:30 deraadt Exp $ */ +/* $OpenBSD: signalvar.h,v 1.5 1997/01/27 22:48:42 deraadt Exp $ */ /* $NetBSD: signalvar.h,v 1.17 1996/04/22 01:23:31 christos Exp $ */ /* @@ -161,7 +161,7 @@ void pgsignal __P((struct pgrp *pgrp, int sig, int checkctty)); void postsig __P((int sig)); void psignal __P((struct proc *p, int sig)); void siginit __P((struct proc *p)); -void trapsignal __P((struct proc *p, int sig, u_long code)); +void trapsignal __P((struct proc *p, int sig, u_long code, caddr_t addr)); void sigexit __P((struct proc *, int)); void setsigvec __P((struct proc *, int, struct sigaction *)); int killpg1 __P((struct proc *, int, int, int)); @@ -169,7 +169,8 @@ int killpg1 __P((struct proc *, int, int, int)); /* * Machine-dependent functions: */ -void sendsig __P((sig_t action, int sig, int returnmask, u_long code)); +void sendsig __P((sig_t action, int sig, int returnmask, u_long code, + caddr_t addr)); struct core; struct vnode; struct ucred; -- 2.20.1