diff --git a/sys/compat/irix/irix_signal.c b/sys/compat/irix/irix_signal.c index c47c33434548..bf74c87098ea 100644 --- a/sys/compat/irix/irix_signal.c +++ b/sys/compat/irix/irix_signal.c @@ -1,4 +1,4 @@ -/* $NetBSD: irix_signal.c,v 1.20 2002/08/02 22:52:36 manu Exp $ */ +/* $NetBSD: irix_signal.c,v 1.21 2002/09/25 19:09:50 manu Exp $ */ /*- * Copyright (c) 1994, 2001-2002 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: irix_signal.c,v 1.20 2002/08/02 22:52:36 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: irix_signal.c,v 1.21 2002/09/25 19:09:50 manu Exp $"); #include #include @@ -53,6 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: irix_signal.c,v 1.20 2002/08/02 22:52:36 manu Exp $" #include #include +#include #include @@ -64,13 +65,17 @@ __KERNEL_RCSID(0, "$NetBSD: irix_signal.c,v 1.20 2002/08/02 22:52:36 manu Exp $" #include #include +#include #include #include extern const int native_to_svr4_signo[]; extern const int svr4_to_native_signo[]; -static int irix_setinfo __P((struct proc *, int, irix_irix5_siginfo_t *)); +static int irix_wait_siginfo __P((struct proc *, int, + struct irix_irix5_siginfo *)); +static void irix_signal_siginfo __P((struct irix_irix5_siginfo *, + int, u_long, caddr_t)); static void irix_set_ucontext __P((struct irix_ucontext*, sigset_t *, int, struct proc *)); static void irix_set_sigcontext __P((struct irix_sigcontext*, sigset_t *, @@ -85,15 +90,16 @@ static void irix_get_sigcontext __P((struct irix_sigcontext*, struct proc *)); #define irix_sigaddset(s, n) ((s)->bits[irix_sigword(n)] |= irix_sigmask(n)) /* + * Build a struct siginfo wor waitsys/waitid * This is ripped from svr4_setinfo. See irix_sys_waitsys... */ static int -irix_setinfo(p, st, s) +irix_wait_siginfo(p, st, s) struct proc *p; int st; - irix_irix5_siginfo_t *s; + struct irix_irix5_siginfo *s; { - irix_irix5_siginfo_t i; + struct irix_irix5_siginfo i; int sig; memset(&i, 0, sizeof(i)); @@ -139,6 +145,85 @@ irix_setinfo(p, st, s) return copyout(&i, s, sizeof(i)); } +/* + * Build a struct siginfo for signal delivery + */ +static void +irix_signal_siginfo(isi, sig, code, addr) + struct irix_irix5_siginfo *isi; + int sig; + u_long code; + caddr_t addr; +{ + isi->isi_signo = native_to_svr4_signo[sig]; + isi->isi_errno = 0; + isi->isi_addr = (irix_app32_ptr_t)addr; + + switch (code) { + case T_TLB_MOD: + case T_TLB_LD_MISS: + case T_TLB_ST_MISS: + switch (sig) { + case SIGSEGV: + isi->isi_code = IRIX_SEGV_MAPERR; + isi->isi_errno = IRIX_EFAULT; + break; + case SIGBUS: + isi->isi_code = IRIX_BUS_ADRERR; + isi->isi_errno = IRIX_EACCES; + break; + case SIGKILL: + isi->isi_code = IRIX_SEGV_MAPERR; + isi->isi_errno = IRIX_ENOMEM; + break; + default: + isi->isi_code = 0; + } + break; + + case T_ADDR_ERR_LD: + case T_ADDR_ERR_ST: + case T_BUS_ERR_IFETCH: + case T_BUS_ERR_LD_ST: + /* NetBSD issues a SIGSEGV here, IRIX rather uses SIGBUS */ + isi->isi_code = IRIX_SEGV_MAPERR; + isi->isi_errno = IRIX_EFAULT; + break; + + case T_BREAK: + isi->isi_code = IRIX_TRAP_BRKPT; + break; + + case T_RES_INST: + case T_COP_UNUSABLE: + /* NetBSD issues SIGSEGV here, IRIX rather uses SIGILL */ + isi->isi_code = IRIX_SEGV_MAPERR; + isi->isi_errno = IRIX_EFAULT; + break; + + case T_OVFLOW: + isi->isi_errno = IRIX_EOVERFLOW; + case T_TRAP: + isi->isi_code = IRIX_FPE_INTOVF; + break; + + case T_FPE: + isi->isi_code = IRIX_FPE_FLTINV; + break; + + case T_WATCH: + case T_VCEI: + case T_VCED: + case T_INT: + case T_SYSCALL: + default: + isi->isi_code = 0; +#ifdef DEBUG_IRIX + printf("irix_signal_siginfo: sig %d code %ld\n", sig, code); +#endif + break; + } +} void native_to_irix_sigset(bss, sss) @@ -221,10 +306,13 @@ irix_sendsig(sig, mask, code) * Build the signal frame */ bzero(&sf, sizeof(sf)); - if (SIGACTION(p, sig).sa_flags & SA_SIGINFO) - irix_set_ucontext(&sf.isf_ctx.iuc, mask, code, p); - else + if (SIGACTION(p, sig).sa_flags & SA_SIGINFO) { + irix_set_ucontext(&sf.isf_ctx.iss.iuc, mask, code, p); + irix_signal_siginfo(&sf.isf_ctx.iss.iis, sig, + code, (caddr_t)f->f_regs[BADVADDR]); + } else { irix_set_sigcontext(&sf.isf_ctx.isc, mask, code, p); + } /* * Compute the new stack address after copying sigframe @@ -248,28 +336,33 @@ irix_sendsig(sig, mask, code) /* NOTREACHED */ } + /* * Set up signal trampoline arguments. */ - f->f_regs[A0] = native_to_svr4_signo[sig]; /* signo/signo */ - f->f_regs[A1] = 0; /* code/siginfo */ - f->f_regs[A2] = (unsigned long)sp; /* sigcontext/ucontext */ + f->f_regs[A0] = native_to_svr4_signo[sig]; /* signo */ + f->f_regs[A1] = 0; /* NULL */ + f->f_regs[A2] = (unsigned long)sp; /* ucontext/sigcontext */ f->f_regs[A3] = (unsigned long)catcher; /* signal handler address */ /* * When siginfo is selected, the higher bit of A0 is set - * This is how the signal trampoline is able to discover if - * A2 points to a struct irix_sigcontext or struct irix_ucontext. + * This is how the signal trampoline is able to discover if A2 + * points to a struct irix_sigcontext or struct irix_ucontext. + * Also, A1 points to struct siginfo instead of being NULL. */ - if (SIGACTION(p, sig).sa_flags & SA_SIGINFO) + if (SIGACTION(p, sig).sa_flags & SA_SIGINFO) { f->f_regs[A0] |= 0x80000000; + f->f_regs[A1] = (u_long)sp + + ((u_long)&sf.isf_ctx.iss.iis - (u_long)&sf); + } /* * Set up the new stack pointer */ f->f_regs[SP] = (unsigned long)sp; #ifdef DEBUG_IRIX - printf("stack pointer at %p\n", sp); + printf("stack pointer at %p, A1 = %p\n", sp, (void *)f->f_regs[A1]); #endif /* DEBUG_IRIX */ /* @@ -445,11 +538,11 @@ irix_sys_sigreturn(p, v, retval) if (usf == NULL) { usf = (void *)SCARG(uap, ucp); - if ((error = copyin(usf, &ksf.isf_ctx.iuc, + if ((error = copyin(usf, &ksf.isf_ctx.iss.iuc, sizeof(ksf.isf_ctx))) != 0) return error; - irix_get_ucontext(&ksf.isf_ctx.iuc, p); + irix_get_ucontext(&ksf.isf_ctx.iss.iuc, p); } else { if ((error = copyin(usf, &ksf.isf_ctx.isc, sizeof(ksf.isf_ctx))) != 0) @@ -716,7 +809,7 @@ out: * and not in the SVR4 version. * Both version could be merged by creating a svr4_sys_waitsys1() with the * rusage argument, and by calling it with NULL from svr4_sys_waitsys(). - * irix_setinfo is here because 1) svr4_setinfo is static and cannot be + * irix_wait_siginfo is here because 1) svr4_setinfo is static and cannot be * used here and 2) because struct irix_irix5_siginfo is quite different * from svr4_siginfo. In order to merge, we need to include irix_signal.h * from svr4_misc.c, or push the irix_irix5_siginfo into svr4_siginfo.h @@ -778,7 +871,7 @@ loop: #ifdef DEBUG_IRIX printf("irix_sys_wait(): found %d\n", q->p_pid); #endif - if ((error = irix_setinfo(q, q->p_xstat, + if ((error = irix_wait_siginfo(q, q->p_xstat, SCARG(uap, info))) != 0) return error; @@ -859,7 +952,7 @@ loop: if (((SCARG(uap, options) & SVR4_WNOWAIT)) == 0) q->p_flag |= P_WAITED; *retval = 0; - return irix_setinfo(q, W_STOPCODE(q->p_xstat), + return irix_wait_siginfo(q, W_STOPCODE(q->p_xstat), SCARG(uap, info)); } } @@ -869,7 +962,7 @@ loop: if (SCARG(uap, options) & SVR4_WNOHANG) { *retval = 0; - if ((error = irix_setinfo(NULL, 0, SCARG(uap, info))) != 0) + if ((error = irix_wait_siginfo(NULL, 0, SCARG(uap, info))) != 0) return error; return 0; } diff --git a/sys/compat/irix/irix_signal.h b/sys/compat/irix/irix_signal.h index bf55a2de19e7..eb19bbb954e2 100644 --- a/sys/compat/irix/irix_signal.h +++ b/sys/compat/irix/irix_signal.h @@ -1,4 +1,4 @@ -/* $NetBSD: irix_signal.h,v 1.11 2002/07/04 23:32:10 thorpej Exp $ */ +/* $NetBSD: irix_signal.h,v 1.12 2002/09/25 19:09:50 manu Exp $ */ /*- * Copyright (c) 2001-2002 The NetBSD Foundation, Inc. @@ -112,6 +112,68 @@ typedef struct irix_ucontext { } irix_ucontext_t; /* From IRIX's */ +#define IRIX_ILL_ILLOPC 1 +#define IRIX_ILL_ILLOPN 2 +#define IRIX_ILL_ILLADR 3 +#define IRIX_ILL_ILLTRP 4 +#define IRIX_ILL_PRVOPC 5 +#define IRIX_ILL_PRVREG 6 +#define IRIX_ILL_COPROC 7 +#define IRIX_ILL_BADSTK 8 + +#define IRIX_FPE_INTDIV 1 +#define IRIX_FPE_INTOVF 2 +#define IRIX_FPE_FLTDIV 3 +#define IRIX_FPE_FLTOVF 4 +#define IRIX_FPE_FLTUND 5 +#define IRIX_FPE_FLTRES 6 +#define IRIX_FPE_FLTINV 7 +#define IRIX_FPE_FLTSUB 8 + +#define IRIX_SEGV_MAPERR 1 +#define IRIX_SEGV_ACCERR 2 + +#define IRIX_BUS_ADRALN 1 +#define IRIX_BUS_ADRERR 2 +#define IRIX_BUS_OBJERR 3 + +#define IRIX_TRAP_BRKPT 1 +#define IRIX_TRAP_TRACE 2 + +#define IRIX_CLD_EXITED 1 +#define IRIX_CLD_KILLED 2 +#define IRIX_CLD_DUMPED 3 +#define IRIX_CLD_TRAPPED 4 +#define IRIX_CLD_STOPPED 5 +#define IRIX_CLD_CONTINUED 6 + +#define IRIX_POLL_IN 1 +#define IRIX_POLL_OUT 2 +#define IRIX_POLL_MSG 3 +#define IRIX_POLL_ERR 4 +#define IRIX_POLL_PRI 5 +#define IRIX_POLL_HUP 6 + +#define IRIX_UME_ECCERR 1 + +/* From IRIX's */ +#define IRIX_FLTILL 1 +#define IRIX_FLTPRIV 2 +#define IRIX_FLTBPT 3 +#define IRIX_FLTTRACE 4 +#define IRIX_FLTACCESS 5 +#define IRIX_FLTBOUNDS 6 +#define IRIX_FLTIOVF 7 +#define IRIX_FLTIZDIV 8 +#define IRIX_FLTFPE 9 +#define IRIX_FLTSTACK 10 +#define IRIX_FLTPAGE 11 +#define IRIX_FLTPCINVAL 12 +#define IRIX_FLTWATCH 13 +#define IRIX_FLTKWATCH 14 +#define IRIX_FLTSCWATCH 15 + + #define IRIX_SI_MAXSZ 128 #define IRIX_SI_PAD ((IRIX_SI_MAXSZ / sizeof(__int32_t)) - 3) @@ -151,11 +213,12 @@ typedef struct irix_irix5_siginfo { union irix_irix5_sigval __value; } __data; } irix_irix5_siginfo_t; + #define isi_pid __data.__proc.__pid #define isi_stime __data.__proc.__pdata.__cld.__stime #define isi_utime __data.__proc.__pdata.__cld.__utime #define isi_status __data.__proc.__pdata.__cld.__status -#define isi_addr __data.__fault.__addr; +#define isi_addr __data.__fault.__addr #define isi_trap /* @@ -171,8 +234,11 @@ struct irix_sigframe { struct irix_sigcontext *isf_scp; struct irix_ucontext *isf_ucp; union { - struct irix_ucontext iuc; struct irix_sigcontext isc; + struct irix_sigcontext_siginfo { + struct irix_ucontext iuc; + struct irix_irix5_siginfo iis; + } iss; } isf_ctx; };