linux-mips
[Top] [All Lists]

[patch] Provide useful siginfo_t data for integer overflow traps

To: linux-mips@oss.sgi.com
Subject: [patch] Provide useful siginfo_t data for integer overflow traps
From: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
Date: Mon, 5 Aug 2002 14:38:04 +0200 (MET DST)
Cc: Ralf Baechle <ralf@uni-koblenz.de>
Organization: Technical University of Gdansk
Sender: owner-linux-mips@oss.sgi.com
Hello,

 Here is an update to the overflow trap handler that is used for
add/addi/sub/etc. signed integer operations that trap on the
2's-complement overflow.  With an example test program as follows:

$ cat addi.c
#define _GNU_SOURCE

#include <signal.h>
#include <stdint.h>
#include <stdio.h>

#define y 0x7654

static volatile sig_atomic_t fpe_caught;

static void catch_fpe(int sig, siginfo_t *info, void *ptr)
{
        struct sigcontext *sc;

        fpe_caught = 1;

        sc = ptr;

        printf("SIGFPE caught, info:\n");
        printf("si_code: %i\n", info->si_code);
        printf("si_addr: %08lx\n", (long)info->si_addr);

#if 0   /* Until the kernel is fixed not to advance...  */
        sc->sc_pc += 4;
#endif
}

int main(void)
{
        int32_t x = 0x7fff9876;
        int32_t z;

        printf("Testing 32-bit signed addition:\n");
        {
                struct sigaction sa, osa;
                long __r0;

                sa.sa_flags = SA_SIGINFO;
                sa.sa_sigaction = catch_fpe;
                sigemptyset(&sa.sa_mask);
                sigaction(SIGFPE, &sa, &osa);

                asm volatile(
                        "lw     %1,%2\n\t"
                        "addi   %1,%1,%3\n\t"
                        "sw     %1,%0\n\t"
                        : "=m" (z), "=r" (__r0)
                        : "m" (x), "i" (y)
                        : "memory"
                );

                sigaction(SIGFPE, &osa, NULL);

                if (!fpe_caught) {
                        printf("No signal caught, dumping status:\n");
                        printf("%08x + %08x = %08x\n",
                               x, (int32_t)y, z);
                }
        }

        return !fpe_caught;
}

I'm getting the following information without the patch:

$ ./addi
Testing 32-bit signed addition:
SIGFPE caught, info:
si_code: 128
si_addr: 00000000

and the following one with the patch:

$ ./addi
Testing 32-bit signed addition:
SIGFPE caught, info:
si_code: 2
si_addr: 0040095c

which is more useful to the userland and corresponds to what do_tr() and
do_bp() already do for explicitly coded multiply/divide overflow traps. 

 Any comments?

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

patch-mips-2.4.19-rc1-20020802-ov-0
diff -up --recursive --new-file 
linux-mips-2.4.19-rc1-20020802.macro/arch/mips/kernel/traps.c 
linux-mips-2.4.19-rc1-20020802/arch/mips/kernel/traps.c
--- linux-mips-2.4.19-rc1-20020802.macro/arch/mips/kernel/traps.c       
2002-07-23 03:00:18.000000000 +0000
+++ linux-mips-2.4.19-rc1-20020802/arch/mips/kernel/traps.c     2002-08-04 
19:32:38.000000000 +0000
@@ -462,10 +462,16 @@ asmlinkage void do_be(struct pt_regs *re
 
 asmlinkage void do_ov(struct pt_regs *regs)
 {
+       siginfo_t info;
+
        if (compute_return_epc(regs))
                return;
 
-       force_sig(SIGFPE, current);
+       info.si_code = FPE_INTOVF;
+       info.si_signo = SIGFPE;
+       info.si_errno = 0;
+       info.si_addr = (void *)regs->cp0_epc;
+       force_sig_info(SIGFPE, &info, current);
 }
 
 /*
diff -up --recursive --new-file 
linux-mips-2.4.19-rc1-20020802.macro/arch/mips64/kernel/traps.c 
linux-mips-2.4.19-rc1-20020802/arch/mips64/kernel/traps.c
--- linux-mips-2.4.19-rc1-20020802.macro/arch/mips64/kernel/traps.c     
2002-07-31 02:58:45.000000000 +0000
+++ linux-mips-2.4.19-rc1-20020802/arch/mips64/kernel/traps.c   2002-08-04 
19:36:55.000000000 +0000
@@ -365,9 +365,16 @@ asmlinkage void do_be(struct pt_regs *re
 
 asmlinkage void do_ov(struct pt_regs *regs)
 {
+       siginfo_t info;
+
        if (compute_return_epc(regs))
                return;
-       force_sig(SIGFPE, current);
+
+       info.si_code = FPE_INTOVF;
+       info.si_signo = SIGFPE;
+       info.si_errno = 0;
+       info.si_addr = (void *)regs->cp0_epc;
+       force_sig_info(SIGFPE, &info, current);
 }
 
 /*


<Prev in Thread] Current Thread [Next in Thread>
  • [patch] Provide useful siginfo_t data for integer overflow traps, Maciej W. Rozycki <=