diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-12-19 18:25:57 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-12-19 18:25:57 +0000 |
commit | 759b2834ea84e43f57288791603087736c1d2778 (patch) | |
tree | af9a2142a48c29b1fc430d194023f09ee2594070 /arch/mips/kernel/traps.c | |
parent | 5cad05408e1fd657196e5b2fac3e1d64e28efba5 (diff) |
Handle break 6/7 instructions properly. From Maciej.
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r-- | arch/mips/kernel/traps.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 1b1038c19..d55619720 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -27,6 +27,7 @@ #include <asm/jazz.h> #include <asm/pgtable.h> #include <asm/io.h> +#include <asm/siginfo.h> #include <asm/watch.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -436,6 +437,7 @@ static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) void do_bp(struct pt_regs *regs) { + siginfo_t info; unsigned int opcode, bcode; /* @@ -451,12 +453,28 @@ void do_bp(struct pt_regs *regs) * (A short test says that IRIX 5.3 sends SIGTRAP for all break * insns, even for break codes that indicate arithmetic failures. * Weird ...) + * But should we continue the brokenness??? --macro */ - force_sig(SIGTRAP, current); + switch (bcode) { + case 6: + case 7: + if (bcode == 7) + info.si_code = FPE_INTDIV; + else + info.si_code = FPE_INTOVF; + info.si_signo = SIGFPE; + info.si_errno = 0; + info.si_addr = (void *)compute_return_epc(regs); + force_sig_info(SIGFPE, &info, current); + break; + default: + force_sig(SIGTRAP, current); + } } void do_tr(struct pt_regs *regs) { + siginfo_t info; unsigned int opcode, bcode; if (get_insn_opcode(regs, &opcode)) @@ -467,8 +485,23 @@ void do_tr(struct pt_regs *regs) * (A short test says that IRIX 5.3 sends SIGTRAP for all break * insns, even for break codes that indicate arithmetic failures. * Weird ...) + * But should we continue the brokenness??? --macro */ - force_sig(SIGTRAP, current); + switch (bcode) { + case 6: + case 7: + if (bcode == 7) + info.si_code = FPE_INTDIV; + else + info.si_code = FPE_INTOVF; + info.si_signo = SIGFPE; + info.si_errno = 0; + info.si_addr = (void *)compute_return_epc(regs); + force_sig_info(SIGFPE, &info, current); + break; + default: + force_sig(SIGTRAP, current); + } } #if !defined(CONFIG_CPU_HAS_LLSC) |