Loading arch/mips/kernel/traps.c +37 −52 Original line number Diff line number Diff line Loading @@ -675,35 +675,24 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) force_sig_info(SIGFPE, &info, current); } asmlinkage void do_bp(struct pt_regs *regs) static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, const char *str) { unsigned int opcode, bcode; siginfo_t info; if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) goto out_sigsegv; /* * There is the ancient bug in the MIPS assemblers that the break * code starts left to bit 16 instead to bit 6 in the opcode. * Gas is bug-compatible, but not always, grrr... * We handle both cases with a simple heuristics. --macro */ bcode = ((opcode >> 6) & ((1 << 20) - 1)); if (bcode < (1 << 10)) bcode <<= 10; char b[40]; /* * (A short test says that IRIX 5.3 sends SIGTRAP for all break * insns, even for break codes that indicate arithmetic failures. * Weird ...) * A short test says that IRIX 5.3 sends SIGTRAP for all trap * insns, even for trap and break codes that indicate arithmetic * failures. Weird ... * But should we continue the brokenness??? --macro */ switch (bcode) { case BRK_OVERFLOW << 10: case BRK_DIVZERO << 10: die_if_kernel("Break instruction in kernel code", regs); if (bcode == (BRK_DIVZERO << 10)) switch (code) { case BRK_OVERFLOW: case BRK_DIVZERO: scnprintf(b, sizeof(b), "%s instruction in kernel code", str); die_if_kernel(b, regs); if (code == BRK_DIVZERO) info.si_code = FPE_INTDIV; else info.si_code = FPE_INTOVF; Loading @@ -713,12 +702,34 @@ asmlinkage void do_bp(struct pt_regs *regs) force_sig_info(SIGFPE, &info, current); break; case BRK_BUG: die("Kernel bug detected", regs); die_if_kernel("Kernel bug detected", regs); force_sig(SIGTRAP, current); break; default: die_if_kernel("Break instruction in kernel code", regs); scnprintf(b, sizeof(b), "%s instruction in kernel code", str); die_if_kernel(b, regs); force_sig(SIGTRAP, current); } } asmlinkage void do_bp(struct pt_regs *regs) { unsigned int opcode, bcode; if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) goto out_sigsegv; /* * There is the ancient bug in the MIPS assemblers that the break * code starts left to bit 16 instead to bit 6 in the opcode. * Gas is bug-compatible, but not always, grrr... * We handle both cases with a simple heuristics. --macro */ bcode = ((opcode >> 6) & ((1 << 20) - 1)); if (bcode >= (1 << 10)) bcode >>= 10; do_trap_or_bp(regs, bcode, "Break"); return; out_sigsegv: Loading @@ -728,7 +739,6 @@ out_sigsegv: asmlinkage void do_tr(struct pt_regs *regs) { unsigned int opcode, tcode = 0; siginfo_t info; if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) goto out_sigsegv; Loading @@ -737,32 +747,7 @@ asmlinkage void do_tr(struct pt_regs *regs) if (!(opcode & OPCODE)) tcode = ((opcode >> 6) & ((1 << 10) - 1)); /* * (A short test says that IRIX 5.3 sends SIGTRAP for all trap * insns, even for trap codes that indicate arithmetic failures. * Weird ...) * But should we continue the brokenness??? --macro */ switch (tcode) { case BRK_OVERFLOW: case BRK_DIVZERO: die_if_kernel("Trap instruction in kernel code", regs); if (tcode == BRK_DIVZERO) info.si_code = FPE_INTDIV; else info.si_code = FPE_INTOVF; info.si_signo = SIGFPE; info.si_errno = 0; info.si_addr = (void __user *) regs->cp0_epc; force_sig_info(SIGFPE, &info, current); break; case BRK_BUG: die("Kernel bug detected", regs); break; default: die_if_kernel("Trap instruction in kernel code", regs); force_sig(SIGTRAP, current); } do_trap_or_bp(regs, tcode, "Trap"); return; out_sigsegv: Loading Loading
arch/mips/kernel/traps.c +37 −52 Original line number Diff line number Diff line Loading @@ -675,35 +675,24 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) force_sig_info(SIGFPE, &info, current); } asmlinkage void do_bp(struct pt_regs *regs) static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, const char *str) { unsigned int opcode, bcode; siginfo_t info; if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) goto out_sigsegv; /* * There is the ancient bug in the MIPS assemblers that the break * code starts left to bit 16 instead to bit 6 in the opcode. * Gas is bug-compatible, but not always, grrr... * We handle both cases with a simple heuristics. --macro */ bcode = ((opcode >> 6) & ((1 << 20) - 1)); if (bcode < (1 << 10)) bcode <<= 10; char b[40]; /* * (A short test says that IRIX 5.3 sends SIGTRAP for all break * insns, even for break codes that indicate arithmetic failures. * Weird ...) * A short test says that IRIX 5.3 sends SIGTRAP for all trap * insns, even for trap and break codes that indicate arithmetic * failures. Weird ... * But should we continue the brokenness??? --macro */ switch (bcode) { case BRK_OVERFLOW << 10: case BRK_DIVZERO << 10: die_if_kernel("Break instruction in kernel code", regs); if (bcode == (BRK_DIVZERO << 10)) switch (code) { case BRK_OVERFLOW: case BRK_DIVZERO: scnprintf(b, sizeof(b), "%s instruction in kernel code", str); die_if_kernel(b, regs); if (code == BRK_DIVZERO) info.si_code = FPE_INTDIV; else info.si_code = FPE_INTOVF; Loading @@ -713,12 +702,34 @@ asmlinkage void do_bp(struct pt_regs *regs) force_sig_info(SIGFPE, &info, current); break; case BRK_BUG: die("Kernel bug detected", regs); die_if_kernel("Kernel bug detected", regs); force_sig(SIGTRAP, current); break; default: die_if_kernel("Break instruction in kernel code", regs); scnprintf(b, sizeof(b), "%s instruction in kernel code", str); die_if_kernel(b, regs); force_sig(SIGTRAP, current); } } asmlinkage void do_bp(struct pt_regs *regs) { unsigned int opcode, bcode; if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) goto out_sigsegv; /* * There is the ancient bug in the MIPS assemblers that the break * code starts left to bit 16 instead to bit 6 in the opcode. * Gas is bug-compatible, but not always, grrr... * We handle both cases with a simple heuristics. --macro */ bcode = ((opcode >> 6) & ((1 << 20) - 1)); if (bcode >= (1 << 10)) bcode >>= 10; do_trap_or_bp(regs, bcode, "Break"); return; out_sigsegv: Loading @@ -728,7 +739,6 @@ out_sigsegv: asmlinkage void do_tr(struct pt_regs *regs) { unsigned int opcode, tcode = 0; siginfo_t info; if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) goto out_sigsegv; Loading @@ -737,32 +747,7 @@ asmlinkage void do_tr(struct pt_regs *regs) if (!(opcode & OPCODE)) tcode = ((opcode >> 6) & ((1 << 10) - 1)); /* * (A short test says that IRIX 5.3 sends SIGTRAP for all trap * insns, even for trap codes that indicate arithmetic failures. * Weird ...) * But should we continue the brokenness??? --macro */ switch (tcode) { case BRK_OVERFLOW: case BRK_DIVZERO: die_if_kernel("Trap instruction in kernel code", regs); if (tcode == BRK_DIVZERO) info.si_code = FPE_INTDIV; else info.si_code = FPE_INTOVF; info.si_signo = SIGFPE; info.si_errno = 0; info.si_addr = (void __user *) regs->cp0_epc; force_sig_info(SIGFPE, &info, current); break; case BRK_BUG: die("Kernel bug detected", regs); break; default: die_if_kernel("Trap instruction in kernel code", regs); force_sig(SIGTRAP, current); } do_trap_or_bp(regs, tcode, "Trap"); return; out_sigsegv: Loading