diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2006-01-30 21:23:25 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2006-01-30 21:23:25 +0000 |
commit | eb5d0663b74366fdf3577bc7a3f7f6881e867933 (patch) | |
tree | c19716625983b0ca1cfcb87d11d0366e120583c0 /sys/arch | |
parent | abae6e64f88771f4be25a2df346b59522c848938 (diff) |
Better siginfo field values for fpe failures.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/m68k/fpe/fpu_calcea.c | 34 | ||||
-rw-r--r-- | sys/arch/m68k/fpe/fpu_emulate.c | 82 | ||||
-rw-r--r-- | sys/arch/m68k/fpe/fpu_emulate.h | 16 | ||||
-rw-r--r-- | sys/arch/m68k/fpe/fpu_fmovecr.c | 6 | ||||
-rw-r--r-- | sys/arch/m68k/fpe/fpu_fscale.c | 13 | ||||
-rw-r--r-- | sys/arch/m68k/fpe/fpu_fstore.c | 11 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/trap.c | 6 |
7 files changed, 82 insertions, 86 deletions
diff --git a/sys/arch/m68k/fpe/fpu_calcea.c b/sys/arch/m68k/fpe/fpu_calcea.c index c05788f17eb..8d76a849158 100644 --- a/sys/arch/m68k/fpe/fpu_calcea.c +++ b/sys/arch/m68k/fpe/fpu_calcea.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu_calcea.c,v 1.10 2006/01/16 22:08:26 miod Exp $ */ +/* $OpenBSD: fpu_calcea.c,v 1.11 2006/01/30 21:23:22 miod Exp $ */ /* $NetBSD: fpu_calcea.c,v 1.16 2004/02/13 11:36:14 wiz Exp $ */ /* @@ -43,7 +43,7 @@ * Prototypes of local functions */ int decode_ea6(struct frame *frame, struct instruction *insn, - struct insn_ea *ea, int modreg); + struct insn_ea *ea, int modreg, int *typ); int fetch_immed(struct frame *frame, struct instruction *insn, int *dst); int fetch_disp(struct frame *frame, struct instruction *insn, @@ -59,11 +59,8 @@ int calc_ea(struct insn_ea *ea, char *ptr, char **eaddr); * Returns zero on success, else signal number. */ int -fpu_decode_ea(frame, insn, ea, modreg) - struct frame *frame; - struct instruction *insn; - struct insn_ea *ea; - int modreg; +fpu_decode_ea(struct frame *frame, struct instruction *insn, struct insn_ea *ea, + int modreg, int *typ) { int sig; @@ -160,7 +157,7 @@ fpu_decode_ea(frame, insn, ea, modreg) case 060: /* (d8,An,Xn) */ ea->ea_flags = EA_INDEXED; - sig = decode_ea6(frame, insn, ea, modreg); + sig = decode_ea6(frame, insn, ea, modreg, typ); break; case 070: /* misc. */ @@ -193,7 +190,7 @@ fpu_decode_ea(frame, insn, ea, modreg) case 3: /* (d8,PC,Xn) */ ea->ea_flags = EA_PC_REL | EA_INDEXED; - sig = decode_ea6(frame, insn, ea, modreg); + sig = decode_ea6(frame, insn, ea, modreg, typ); break; case 4: /* #data */ @@ -202,6 +199,7 @@ fpu_decode_ea(frame, insn, ea, modreg) #ifdef DEBUG_FPE printf("decode_ea: invalid addr mode (7,%d)\n", modreg & 7); #endif + *typ = ILL_ILLADR; return SIGILL; } /* switch for mode 7 */ break; @@ -216,11 +214,8 @@ fpu_decode_ea(frame, insn, ea, modreg) * Decode Mode=6 address modes */ int -decode_ea6(frame, insn, ea, modreg) - struct frame *frame; - struct instruction *insn; - struct insn_ea *ea; - int modreg; +decode_ea6(struct frame *frame, struct instruction *insn, struct insn_ea *ea, + int modreg, int *typ) { int idx; int basedisp, outerdisp; @@ -297,6 +292,7 @@ decode_ea6(frame, insn, ea, modreg) printf("decode_ea6: invalid indirect mode: ext word %02x\n", extword); #endif + *typ = ILL_ILLADR; return SIGILL; break; } @@ -317,11 +313,8 @@ decode_ea6(frame, insn, ea, modreg) * Returns zero on success, else signal number. */ int -fpu_load_ea(frame, insn, ea, dst) - struct frame *frame; - struct instruction *insn; - struct insn_ea *ea; - char *dst; +fpu_load_ea(struct frame *frame, struct instruction *insn, struct insn_ea *ea, + char *dst, int *typ) { int *reg; char *src; @@ -396,7 +389,7 @@ fpu_load_ea(frame, insn, ea, dst) #endif memcpy(dst, src, len); } else -#endif +#endif /* 0 */ if (ea->ea_flags & EA_IMMED) { #ifdef DEBUG_FPE printf("load_ea: immed %08x%08x%08x size %d\n", @@ -465,6 +458,7 @@ fpu_load_ea(frame, insn, ea, dst) #ifdef DEBUG printf("load_ea: tried to postincrement PC\n"); #endif + *typ = ILL_ILLADR; return SIGILL; } *reg += step; diff --git a/sys/arch/m68k/fpe/fpu_emulate.c b/sys/arch/m68k/fpe/fpu_emulate.c index a946181b986..b15023f9efe 100644 --- a/sys/arch/m68k/fpe/fpu_emulate.c +++ b/sys/arch/m68k/fpe/fpu_emulate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu_emulate.c,v 1.13 2006/01/16 22:08:26 miod Exp $ */ +/* $OpenBSD: fpu_emulate.c,v 1.14 2006/01/30 21:23:22 miod Exp $ */ /* $NetBSD: fpu_emulate.c,v 1.25 2003/09/22 14:18:34 cl Exp $ */ /* @@ -48,10 +48,10 @@ #include "fpu_emulate.h" -int fpu_emul_fmovmcr(struct fpemu *fe, struct instruction *insn); -int fpu_emul_fmovm(struct fpemu *fe, struct instruction *insn); -int fpu_emul_arith(struct fpemu *fe, struct instruction *insn); -int fpu_emul_type1(struct fpemu *fe, struct instruction *insn); +int fpu_emul_fmovmcr(struct fpemu *fe, struct instruction *insn, int *); +int fpu_emul_fmovm(struct fpemu *fe, struct instruction *insn, int *); +int fpu_emul_arith(struct fpemu *fe, struct instruction *insn, int *); +int fpu_emul_type1(struct fpemu *fe, struct instruction *insn, int *); int fpu_emul_brcc(struct fpemu *fe, struct instruction *insn); int test_cc(struct fpemu *fe, int pred); struct fpn *fpu_cmp(struct fpemu *fe); @@ -71,9 +71,7 @@ struct fpn *fpu_cmp(struct fpemu *fe); * (Typically: zero, SIGFPE, SIGILL, SIGSEGV) */ int -fpu_emulate(frame, fpf) - struct frame *frame; - struct fpframe *fpf; +fpu_emulate(struct frame *frame, struct fpframe *fpf, int *typ) { static struct instruction insn; static struct fpemu fe; @@ -133,6 +131,7 @@ fpu_emulate(frame, fpf) #ifdef DEBUG printf("fpu_emulate: bad coproc. id: opcode=0x%x\n", word); #endif + *typ = ILL_COPROC; return (SIGILL); } @@ -162,36 +161,36 @@ fpu_emulate(frame, fpf) #if DEBUG_FPE printf("fpu_emulate: fmovm FPr\n"); #endif - sig = fpu_emul_fmovm(&fe, &insn); + sig = fpu_emul_fmovm(&fe, &insn, typ); } else if ((word & 0xc000) == 0x8000) { #if DEBUG_FPE printf("fpu_emulate: fmovm FPcr\n"); #endif - sig = fpu_emul_fmovmcr(&fe, &insn); + sig = fpu_emul_fmovmcr(&fe, &insn, typ); } else if ((word & 0xe000) == 0x6000) { /* fstore = fmove FPn,mem */ #if DEBUG_FPE printf("fpu_emulate: fmove to mem\n"); #endif - sig = fpu_emul_fstore(&fe, &insn); + sig = fpu_emul_fstore(&fe, &insn, typ); } else if ((word & 0xfc00) == 0x5c00) { /* fmovecr */ #if DEBUG_FPE printf("fpu_emulate: fmovecr\n"); #endif - sig = fpu_emul_fmovecr(&fe, &insn); + sig = fpu_emul_fmovecr(&fe, &insn, typ); } else if ((word & 0xa07f) == 0x26) { /* fscale */ #if DEBUG_FPE printf("fpu_emulate: fscale\n"); #endif - sig = fpu_emul_fscale(&fe, &insn); + sig = fpu_emul_fscale(&fe, &insn, typ); } else { #if DEBUG_FPE printf("fpu_emulate: other type0\n"); #endif /* all other type0 insns are arithmetic */ - sig = fpu_emul_arith(&fe, &insn); + sig = fpu_emul_arith(&fe, &insn, typ); } if (sig == 0) { #if DEBUG_FPE @@ -211,7 +210,7 @@ fpu_emulate(frame, fpf) #if DEBUG_FPE printf("fpu_emulate: type1\n"); #endif - sig = fpu_emul_type1(&fe, &insn); + sig = fpu_emul_type1(&fe, &insn, typ); } else { /* type=4: fsave (privileged) */ /* type=5: frestore (privileged) */ @@ -220,6 +219,7 @@ fpu_emulate(frame, fpf) #ifdef DEBUG printf("fpu_emulate: bad opcode type: opcode=0x%x\n", insn.is_opcode); #endif + *typ = ILL_PRVOPC; sig = SIGILL; } @@ -252,6 +252,18 @@ fpu_emulate(frame, fpf) fe.fe_fpsr, fe.fe_fpcr); #endif + if (*typ == 0) + switch (sig) { + case SIGSEGV: + *typ = SEGV_MAPERR; + break; + case SIGILL: + *typ = ILL_ILLOPC; + break; + case SIGFPE: + *typ = FPE_FLTINV; + break; + } return (sig); } @@ -359,9 +371,7 @@ fpu_upd_fpsr(fe, fp) } int -fpu_emul_fmovmcr(fe, insn) - struct fpemu *fe; - struct instruction *insn; +fpu_emul_fmovmcr(struct fpemu *fe, struct instruction *insn, int *typ) { struct frame *frame = fe->fe_frame; struct fpframe *fpf = fe->fe_fpframe; @@ -376,7 +386,7 @@ fpu_emul_fmovmcr(fe, insn) insn->is_datasize = 4; insn->is_advance = 4; - sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode); + sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode, typ); if (sig) { return sig; } if (reglist != 1 && reglist != 2 && reglist != 4 && @@ -404,7 +414,7 @@ fpu_emul_fmovmcr(fe, insn) (char *)&fpf->fpf_fpcr); } else { sig = fpu_load_ea(frame, insn, &insn->is_ea, - (char *)&fpf->fpf_fpcr); + (char *)&fpf->fpf_fpcr, typ); } } if (sig) { return sig; } @@ -425,7 +435,7 @@ fpu_emul_fmovmcr(fe, insn) (char *)&fpf->fpf_fpsr); } else { sig = fpu_load_ea(frame, insn, &insn->is_ea, - (char *)&fpf->fpf_fpsr); + (char *)&fpf->fpf_fpsr, typ); } } if (sig) { return sig; } @@ -437,7 +447,7 @@ fpu_emul_fmovmcr(fe, insn) (char *)&fpf->fpf_fpiar); } else { sig = fpu_load_ea(frame, insn, &insn->is_ea, - (char *)&fpf->fpf_fpiar); + (char *)&fpf->fpf_fpiar, typ); } } return sig; @@ -454,9 +464,7 @@ fpu_emul_fmovmcr(fe, insn) * and the FPSR is not affected. */ int -fpu_emul_fmovm(fe, insn) - struct fpemu *fe; - struct instruction *insn; +fpu_emul_fmovm(struct fpemu *fe, struct instruction *insn, int *typ) { struct frame *frame = fe->fe_frame; struct fpframe *fpf = fe->fe_fpframe; @@ -490,7 +498,7 @@ fpu_emul_fmovm(fe, insn) reglist &= 0xFF; /* Get effective address. (modreg=opcode&077) */ - sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode); + sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode, typ); if (sig) { return sig; } /* Get address of soft coprocessor regs. */ @@ -517,7 +525,7 @@ fpu_emul_fmovm(fe, insn) #endif } else { /* mem to fpu */ sig = fpu_load_ea(frame, insn, &insn->is_ea, - (char *)&fpregs[regnum * 3]); + (char *)&fpregs[regnum * 3], typ); #if DEBUG_FPE printf("fpu_emul_fmovm: FP%d (%08x,%08x,%08x) loaded\n", regnum, fpregs[regnum * 3], fpregs[regnum * 3 + 1], @@ -587,9 +595,7 @@ fpu_cmp(fe) * arithmetic oprations */ int -fpu_emul_arith(fe, insn) - struct fpemu *fe; - struct instruction *insn; +fpu_emul_arith(struct fpemu *fe, struct instruction *insn, int *typ) { struct frame *frame = fe->fe_frame; u_int *fpregs = &(fe->fe_fpframe->fpf_regs[0]); @@ -651,12 +657,13 @@ fpu_emul_arith(fe, insn) insn->is_datasize = 12; } else { /* invalid or unsupported operand format */ - sig = SIGFPE; + *typ = ILL_ILLOPN; + sig = SIGILL; return sig; } /* Get effective address. (modreg=opcode&077) */ - sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode); + sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode, typ); if (sig) { #if DEBUG_FPE printf("fpu_emul_arith: error in fpu_decode_ea\n"); @@ -701,7 +708,7 @@ fpu_emul_arith(fe, insn) } #endif /* DEBUG_FPE */ - fpu_load_ea(frame, insn, &insn->is_ea, (char *)buf); + fpu_load_ea(frame, insn, &insn->is_ea, (char *)buf, typ); if (format == FTYPE_WRD) { /* sign-extend */ buf[0] &= 0xffff; @@ -1012,9 +1019,7 @@ test_cc(fe, pred) * (opcode & 0x01C0) == 0x0040 */ int -fpu_emul_type1(fe, insn) - struct fpemu *fe; - struct instruction *insn; +fpu_emul_type1(struct fpemu *fe, struct instruction *insn, int *typ) { struct frame *frame = fe->fe_frame; int advance, sig, branch; @@ -1077,7 +1082,8 @@ fpu_emul_type1(fe, insn) sig = 0; } else { /* trap */ - sig = SIGFPE; + sig = SIGILL; + *typ = ILL_ILLTRP; } break; } /* if ((insn->is_opcode & 7) < 2), fall through to FScc */ @@ -1085,7 +1091,7 @@ fpu_emul_type1(fe, insn) default: /* fscc */ insn->is_advance = 4; insn->is_datasize = 1; /* always byte */ - sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode); + sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode, typ); if (sig) { break; } diff --git a/sys/arch/m68k/fpe/fpu_emulate.h b/sys/arch/m68k/fpe/fpu_emulate.h index 5664731a827..6504aa254c3 100644 --- a/sys/arch/m68k/fpe/fpu_emulate.h +++ b/sys/arch/m68k/fpe/fpu_emulate.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu_emulate.h,v 1.5 2006/01/16 22:08:26 miod Exp $ */ +/* $OpenBSD: fpu_emulate.h,v 1.6 2006/01/30 21:23:22 miod Exp $ */ /* $NetBSD: fpu_emulate.h,v 1.11 2005/08/13 05:38:45 he Exp $ */ /* @@ -281,16 +281,16 @@ void fpu_implode(struct fpemu *fe, struct fpn *fp, int t, u_int *dst); * non-static emulation functions */ /* type 0 */ -int fpu_emul_fmovecr(struct fpemu *fe, struct instruction *insn); -int fpu_emul_fstore(struct fpemu *fe, struct instruction *insn); -int fpu_emul_fscale(struct fpemu *fe, struct instruction *insn); +int fpu_emul_fmovecr(struct fpemu *fe, struct instruction *insn, int *typ); +int fpu_emul_fstore(struct fpemu *fe, struct instruction *insn, int *typ); +int fpu_emul_fscale(struct fpemu *fe, struct instruction *insn, int *typ); /* * include function declarations of those which are called by fpu_emul_arith() */ #include "fpu_arith_proto.h" -int fpu_emulate(struct frame *frame, struct fpframe *fpf); +int fpu_emulate(struct frame *frame, struct fpframe *fpf, int *typ); /* * "helper" functions @@ -299,13 +299,13 @@ int fpu_emulate(struct frame *frame, struct fpframe *fpf); struct fpn *fpu_const(struct fpn *fp, u_int offset); /* update exceptions and FPSR */ int fpu_upd_excp(struct fpemu *fe); -u_int fpu_upd_fpsr(struct fpemu *fe, struct fpn *fp); +u_int fpu_upd_fpsr(struct fpemu *fe, struct fpn *fp) ; /* address mode decoder, and load/store */ int fpu_decode_ea(struct frame *frame, struct instruction *insn, - struct insn_ea *ea, int modreg); + struct insn_ea *ea, int modreg, int *typ); int fpu_load_ea(struct frame *frame, struct instruction *insn, - struct insn_ea *ea, char *dst); + struct insn_ea *ea, char *dst, int *typ); int fpu_store_ea(struct frame *frame, struct instruction *insn, struct insn_ea *ea, char *src); diff --git a/sys/arch/m68k/fpe/fpu_fmovecr.c b/sys/arch/m68k/fpe/fpu_fmovecr.c index a5ff1fd3041..1a050f048b7 100644 --- a/sys/arch/m68k/fpe/fpu_fmovecr.c +++ b/sys/arch/m68k/fpe/fpu_fmovecr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu_fmovecr.c,v 1.6 2006/01/16 22:08:26 miod Exp $ */ +/* $OpenBSD: fpu_fmovecr.c,v 1.7 2006/01/30 21:23:23 miod Exp $ */ /* $NetBSD: fpu_fmovecr.c,v 1.10 2003/07/15 02:43:09 lukem Exp $ */ /* @@ -98,9 +98,7 @@ fpu_const(fp, offset) } int -fpu_emul_fmovecr(fe, insn) - struct fpemu *fe; - struct instruction *insn; +fpu_emul_fmovecr(struct fpemu *fe, struct instruction *insn, int *typ) { int dstreg, offset; u_int *fpreg; diff --git a/sys/arch/m68k/fpe/fpu_fscale.c b/sys/arch/m68k/fpe/fpu_fscale.c index 790cd5d0073..77dbfde8c53 100644 --- a/sys/arch/m68k/fpe/fpu_fscale.c +++ b/sys/arch/m68k/fpe/fpu_fscale.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu_fscale.c,v 1.6 2006/01/16 22:08:26 miod Exp $ */ +/* $OpenBSD: fpu_fscale.c,v 1.7 2006/01/30 21:23:23 miod Exp $ */ /* $NetBSD: fpu_fscale.c,v 1.11 2003/07/15 02:43:10 lukem Exp $ */ /* @@ -46,9 +46,7 @@ #include "fpu_emulate.h" int -fpu_emul_fscale(fe, insn) - struct fpemu *fe; - struct instruction *insn; +fpu_emul_fscale(struct fpemu *fe, struct instruction *insn, int *typ) { struct frame *frame; u_int *fpregs; @@ -105,12 +103,13 @@ fpu_emul_fscale(fe, insn) insn->is_datasize = 12; } else { /* invalid or unsupported operand format */ - sig = SIGFPE; + *typ = ILL_ILLOPN; + sig = SIGILL; return sig; } /* Get effective address. (modreg=opcode&077) */ - sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode); + sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode, typ); if (sig) { #if DEBUG_FPE printf("fpu_emul_fscale: error in decode_ea\n"); @@ -146,7 +145,7 @@ fpu_emul_fscale(fe, insn) printf("%c%d@\n", regname, insn->is_ea.ea_regnum & 7); } #endif - fpu_load_ea(frame, insn, &insn->is_ea, (char *)buf); + fpu_load_ea(frame, insn, &insn->is_ea, (char *)buf, typ); #if DEBUG_FPE printf("fpu_emul_fscale: src = %08x%08x%08x, siz = %d\n", diff --git a/sys/arch/m68k/fpe/fpu_fstore.c b/sys/arch/m68k/fpe/fpu_fstore.c index 2ae5243f452..781ad071591 100644 --- a/sys/arch/m68k/fpe/fpu_fstore.c +++ b/sys/arch/m68k/fpe/fpu_fstore.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu_fstore.c,v 1.4 2006/01/16 22:08:26 miod Exp $ */ +/* $OpenBSD: fpu_fstore.c,v 1.5 2006/01/30 21:23:23 miod Exp $ */ /* $NetBSD: fpu_fstore.c,v 1.8 2003/07/15 02:43:10 lukem Exp $ */ /* @@ -40,9 +40,7 @@ * (word1 & 0xe000) == 0x6000 */ int -fpu_emul_fstore(fe, insn) - struct fpemu *fe; - struct instruction *insn; +fpu_emul_fstore(struct fpemu *fe, struct instruction *insn, int *typ) { struct frame *frame = fe->fe_frame; u_int *fpregs = fe->fe_fpframe->fpf_regs; @@ -79,7 +77,8 @@ fpu_emul_fstore(fe, insn) #if DEBUG_FPE printf(" fpu_emul_fstore: invalid format %d\n", format); #endif - sig = SIGFPE; + *typ = ILL_ILLOPN; + sig = SIGILL; } #if DEBUG_FPE printf(" fpu_emul_fstore: format %d, size %d\n", @@ -89,7 +88,7 @@ fpu_emul_fstore(fe, insn) fe->fe_fpsr &= ~FPSR_EXCP; /* Get effective address. (modreg=opcode&077) */ - sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode); + sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode, typ); if (sig) { #if DEBUG_FPE printf(" fpu_emul_fstore: failed in decode_ea sig=%d\n", sig); diff --git a/sys/arch/mac68k/mac68k/trap.c b/sys/arch/mac68k/mac68k/trap.c index 87e61325772..327f028a023 100644 --- a/sys/arch/mac68k/mac68k/trap.c +++ b/sys/arch/mac68k/mac68k/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.48 2006/01/16 21:46:25 miod Exp $ */ +/* $OpenBSD: trap.c,v 1.49 2006/01/30 21:23:24 miod Exp $ */ /* $NetBSD: trap.c,v 1.68 1998/12/22 08:47:07 scottr Exp $ */ /* @@ -412,11 +412,11 @@ copyfault: case T_FPEMULI|T_USER: case T_FPEMULD|T_USER: #ifdef FPU_EMULATE - i = fpu_emulate(&frame, &p->p_addr->u_pcb.pcb_fpregs); + i = fpu_emulate(&frame, &p->p_addr->u_pcb.pcb_fpregs, + &typ); /* XXX -- deal with tracing? (frame.f_sr & PSL_T) */ if (i == 0) goto out; - typ = i == SIGSEGV ? SEGV_MAPERR : ILL_COPROC; #else uprintf("pid %d killed: no floating point support.\n", p->p_pid); |